Build link list based on imports, not on modules compiled by compiler instance.

This commit is contained in:
David Brown 2016-12-18 13:03:59 +00:00
parent 4a71f43e72
commit 460b879829
7 changed files with 100 additions and 51 deletions

View file

@ -125,7 +125,7 @@ Alternatively the Oakwood module Out can be used to write directly to stdout:
MODULE hello;
IMPORT Out;
BEGIN
Out.String("Hello."); Out.Ln;
Out.String("Hello."); Out.Ln
END hello.
```
@ -144,7 +144,7 @@ Execute as usual on Linux (`./hello`) or Windows (`hello`).
In order to see the definition of a module's interface, use the "showdef" program.
```
$ showdef Out.sym
$ showdef Out
DEFINITION Out;
VAR

View file

@ -6,9 +6,6 @@ MODULE Compiler; (* J. Templ 3.2.95 *)
OPV, OPC, OPM,
extTools, Strings, VT100;
VAR mname: ARRAY 256 OF CHAR; (* noch *)
PROCEDURE Module*(VAR done: BOOLEAN);
VAR ext, new: BOOLEAN; p: OPT.Node;
BEGIN
@ -20,11 +17,12 @@ MODULE Compiler; (* J. Templ 3.2.95 *)
OPT.Export(ext, new);
IF OPM.noerr THEN
OPM.OpenFiles(OPT.SelfName);
OPM.DeleteObj(OPT.SelfName); (* Make sure old object file isn't left hanging around. *)
OPC.Init;
OPV.Module(p);
IF OPM.noerr THEN
IF (OPM.mainprog IN OPM.Options) & (OPM.modName # "SYSTEM") THEN
OPM.DeleteNewSym;
OPM.DeleteNewSym(OPT.SelfName);
OPM.LogVT100(VT100.Green); OPM.LogWStr(" Main program."); OPM.LogVT100(VT100.ResetAll);
ELSE
IF new THEN
@ -36,7 +34,7 @@ MODULE Compiler; (* J. Templ 3.2.95 *)
END
END;
ELSE
OPM.DeleteNewSym
OPM.DeleteNewSym(OPT.SelfName)
END
END
END;
@ -83,17 +81,48 @@ MODULE Compiler; (* J. Templ 3.2.95 *)
END PropagateElementaryTypeSizes;
PROCEDURE FindLocalObjectFiles(VAR objectnames: ARRAY OF CHAR);
VAR
l: OPT.Link;
fn: ARRAY 64 OF CHAR;
id: Platform.FileIdentity;
BEGIN
objectnames[0] := 0X;
l := OPT.Links; WHILE l # NIL DO
(* Tell linker to link this module as an object file if both a symbol
and an object file exist in the current directory. *)
COPY(l.name, fn); Strings.Append('.sym', fn);
IF Platform.IdentifyByName(fn, id) = 0 THEN
COPY(l.name, fn); Strings.Append(Configuration.objext, fn);
IF Platform.IdentifyByName(fn, id) = 0 THEN
Strings.Append(' ', objectnames);
Strings.Append(fn, objectnames)
ELSE
(* Found symbol file but no object file. *)
OPM.LogVT100(VT100.Yellow);
OPM.LogWStr("Link warning: a local symbol file is present for module "); OPM.LogWStr(l.name);
OPM.LogWStr(", but local object file '"); OPM.LogWStr(fn); OPM.LogWStr("' is missing.");
OPM.LogVT100(VT100.ResetAll); OPM.LogWLn
END
ELSE
(* No symbol file present in current directory.
Assume this referenced module is in a library. *)
END;
l := l.next
END
END FindLocalObjectFiles;
PROCEDURE Translate*;
VAR
done: BOOLEAN;
modulesobj: ARRAY 2048 OF CHAR; (* here we hold all modules name given on the command line, to add corresponding .o files to the external compiler options *)
done: BOOLEAN;
linkfiles: ARRAY 2048 OF CHAR; (* Object files to be linked into main program. *)
BEGIN
modulesobj := "";
IF OPM.OpenPar() THEN
(* gclock(); slightly faster translation but may lead to opening "too many files" *)
LOOP
OPM.Init(done, mname); (* Get next module name from command line *)
OPM.Init(done); (* Get next module name from command line *)
IF ~done THEN RETURN END ;
OPM.InitOptions; (* Get options for this module *)
@ -116,12 +145,10 @@ MODULE Compiler; (* J. Templ 3.2.95 *)
IF ~(OPM.mainprog IN OPM.Options) THEN
(* Assemble non main program and add object name to link list *)
extTools.Assemble(OPM.modName);
Strings.Append(" ", modulesobj);
Strings.Append(OPM.modName, modulesobj);
Strings.Append(Configuration.objext, modulesobj)
ELSE
(* Assemble and link main program *)
extTools.LinkMain(OPM.modName, OPM.mainlinkstat IN OPM.Options, modulesobj)
FindLocalObjectFiles(linkfiles);
extTools.LinkMain(OPM.modName, OPM.mainlinkstat IN OPM.Options, linkfiles)
END
END
END

View file

@ -76,7 +76,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
BFext = ".c"; (* body file extension *)
HFext = ".h"; (* header file extension *)
SFtag = 0F7X; (* symbol file tag *)
SFver = 082X; (* symbol file version. Increment if symbol file format is changed. *)
SFver = 083X; (* symbol file version. Increment if symbol file format is changed. *)
@ -353,7 +353,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
END InitOptions;
PROCEDURE Init*(VAR done: BOOLEAN; VAR mname : ARRAY OF CHAR); (* get the source for one translation *)
PROCEDURE Init*(VAR done: BOOLEAN); (* get the source for one translation *)
VAR
T: Texts.Text;
beg, end, time: LONGINT;
@ -367,7 +367,6 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
NEW(T); Texts.Open(T, s);
LogWStr(s); LogWStr(" ");
COPY(s, mname);
COPY(s, SourceFileName); (* to keep it also in this module -- noch *)
IF T.len = 0 THEN
@ -636,9 +635,16 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
IF (modName # "SYSTEM") OR (mainprog IN Options) THEN Files.Register(newSFile) END
END RegisterNewSym;
PROCEDURE DeleteNewSym*;
PROCEDURE DeleteNewSym*(VAR modulename: ARRAY OF CHAR);
VAR fn: FileName; res: INTEGER;
BEGIN MakeFileName(modulename, fn, SFext); Files.Delete(fn, res)
END DeleteNewSym;
PROCEDURE DeleteObj*(VAR modulename: ARRAY OF CHAR);
VAR fn: FileName; res: INTEGER;
BEGIN MakeFileName(modulename, fn, Configuration.objext); Files.Delete(fn, res)
END DeleteObj;
PROCEDURE NewSym*(VAR modName: ARRAY OF CHAR);
VAR fileName: FileName;
BEGIN MakeFileName(modName, fileName, SFext);
@ -742,7 +748,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
END Append;
PROCEDURE OpenFiles*(VAR moduleName: ARRAY OF CHAR);
VAR FName: ARRAY 32 OF CHAR;
VAR FName: FileName;
BEGIN
COPY(moduleName, modName);
HFile := Files.New("");
@ -756,7 +762,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
END OpenFiles;
PROCEDURE CloseFiles*;
VAR FName: ARRAY 32 OF CHAR; res: INTEGER;
VAR FName: FileName; res: INTEGER;
BEGIN
IF noerr THEN LogWStr(" "); LogWNum(Files.Pos(R[BodyFile]), 0); LogWStr(" chars.") END;
IF noerr THEN
@ -779,7 +785,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
(* === Installation directory discovery === *)
PROCEDURE IsProbablyInstallDir(s: ARRAY OF CHAR): BOOLEAN;
VAR testpath: ARRAY 1024 OF CHAR; identity: Platform.FileIdentity;
VAR testpath: ARRAY 4096 OF CHAR; identity: Platform.FileIdentity;
BEGIN
COPY(InstallDir, testpath);
Strings.Append("/lib/lib", testpath);

View file

@ -922,7 +922,7 @@ MODULE OPP; (* NW, RC 6.3.89 / 10.2.94 *) (* object model 4.12.93 *)
OPT.Insert(OPS.name, obj); obj^.mode := OPT.Typ; obj^.typ := OPT.undftyp;
CheckMark(obj^.vis);
IF sym = OPS.eql THEN
IF (obj^.name = "SHORTINT") OR
IF (obj^.name = "SHORTINT") OR
(obj^.name = "INTEGER") OR
(obj^.name = "LONGINT") OR
(obj^.name = "HUGEINT") OR
@ -931,7 +931,7 @@ MODULE OPP; (* NW, RC 6.3.89 / 10.2.94 *) (* object model 4.12.93 *)
(obj^.name = "SET") OR
(obj^.name = "CHAR") OR
(obj^.name = "TRUE") OR (obj^.name = "FALSE") THEN
OPM.Mark(-310, OPM.curpos); (* notice about aliasing of predefined type *)
OPM.Mark(-310, OPM.curpos); (* notice about aliasing of predefined type *)
END;
OPS.Get(sym); TypeDecl(obj^.typ, obj^.typ)
ELSIF (sym = OPS.becomes) OR (sym = OPS.colon) THEN
@ -1005,17 +1005,7 @@ MODULE OPP; (* NW, RC 6.3.89 / 10.2.94 *) (* object model 4.12.93 *)
c: LONGINT; done: BOOLEAN;
BEGIN
OPS.Init; LoopLevel := 0; level := 0; OPS.Get(sym);
IF sym = OPS.module THEN OPS.Get(sym) ELSE
(* Debug intermittent failure only found on OpenBSD *)
OPM.LogWLn;
OPM.LogWStr("Unexpected symbol found when MODULE expected:"); OPM.LogWLn;
OPM.LogWStr(" sym: "); OPM.LogWNum(sym,1); OPM.LogWLn;
OPM.LogWStr(" OPS.name: "); OPM.LogWStr(OPS.name); OPM.LogWLn;
OPM.LogWStr(" OPS.str: "); OPM.LogWStr(OPS.str); OPM.LogWLn;
OPM.LogWStr(" OPS.numtyp: "); OPM.LogWNum(OPS.numtyp,1); OPM.LogWLn;
OPM.LogWStr(" OPS.intval: "); OPM.LogWNum(OPS.intval,1); OPM.LogWLn;
err(16)
END;
IF sym = OPS.module THEN OPS.Get(sym) ELSE err(16) END;
IF sym = OPS.ident THEN
OPM.LogWStr("compiling "); OPM.LogWStr(OPS.name); OPM.LogW(".");
OPT.Init(OPS.name, opt); OPS.Get(sym); CheckSym(OPS.semicolon);

View file

@ -176,7 +176,7 @@ CONST
Srvar* = 22; Svalpar* = 23; Svarpar* = 24; Sfld* = 25; Srfld* = 26;
Shdptr* = 27; Shdpro* = 28; Stpro* = 29; Shdtpro* = 30; Sxpro* = 31;
Sipro* = 32; Scpro* = 33; Sstruct* = 34; Ssys* = 35; Sptr* = 36;
Sarr* = 37; Sdarr* = 38; Srec* = 39; Spro* = 40;
Sarr* = 37; Sdarr* = 38; Srec* = 39; Spro* = 40; Slink* = 37;
TYPE
ImpCtxt = RECORD
@ -207,6 +207,18 @@ VAR
recno: LONGINT; (* number of anonymous record types *)
(* Linking control - modules whose object files will be required to link a module. *)
TYPE
Link* = POINTER TO LinkDesc;
LinkDesc* = RECORD
name-: OPS.Name;
next-: Link
END;
VAR
Links-: Link;
PROCEDURE InitRecno*; BEGIN recno := 0 END InitRecno;
PROCEDURE err(n: INTEGER); BEGIN OPM.err(n) END err;
@ -392,7 +404,8 @@ BEGIN
topScope := universe; OpenScope(0, NIL); SYSimported := FALSE;
SelfName := name; topScope^.name := name;
GlbMod[0] := topScope; nofGmod := 1;
newsf := nsf IN opt; findpc := fpc IN opt; extsf := newsf OR (esf IN opt); sfpresent := TRUE
newsf := nsf IN opt; findpc := fpc IN opt; extsf := newsf OR (esf IN opt); sfpresent := TRUE;
NEW(Links); Links.name := name
END Init;
PROCEDURE Close*;
@ -733,6 +746,20 @@ BEGIN
END
END InMod;
PROCEDURE InLinks; (* Load a list of all modules whose object files we will need to link with *)
VAR linkname: OPS.Name; l: Link;
BEGIN
InName(linkname);
WHILE linkname[0] # 0X DO
l := Links; WHILE (l # NIL) & (l.name # linkname) DO l := l.next END;
IF l = NIL THEN
l := Links; NEW(Links);
Links.next := l; Links.name := linkname
END;
InName(linkname)
END
END InLinks;
PROCEDURE InConstant(f: LONGINT; conval: Const);
VAR ch: CHAR; i: INTEGER; ext: ConstExt; rval: REAL;
BEGIN
@ -1022,7 +1049,7 @@ BEGIN
impCtxt.self := aliasName = "@self"; impCtxt.reffp := 0;
OPM.OldSym(name, done);
IF done THEN
InMod(mno);
InMod(mno); InLinks;
impCtxt.nextTag := OPM.SymRInt();
WHILE ~OPM.eofSF() DO
obj := InObj(mno); impCtxt.nextTag := OPM.SymRInt()
@ -1057,6 +1084,13 @@ END Import;
END
END OutMod;
PROCEDURE OutLinks;
VAR l: Link;
BEGIN
l := Links; WHILE l # NIL DO OutName(l.name); l := l.next END;
OPM.SymWCh(0X)
END OutLinks;
PROCEDURE ^OutStr(typ: Struct);
PROCEDURE ^OutFlds(fld: Object; adr: LONGINT; visible: BOOLEAN);
@ -1235,7 +1269,7 @@ END Import;
IF OPM.noerr THEN (* ~OPM.noerr => ~done *)
OPM.NewSym(SelfName);
IF OPM.noerr THEN
OPM.SymWInt(Smname); OutName(SelfName);
OPM.SymWInt(Smname); OutName(SelfName); OutLinks;
expCtxt.reffp := 0; expCtxt.ref := FirstRef(*Comp+1*);
expCtxt.nofm := 1; expCtxt.locmno[0] := 0;
i := 1; WHILE i < maxImps DO expCtxt.locmno[i] := -1; INC(i) END;
@ -1248,7 +1282,7 @@ END Import;
END;
newsf := FALSE; symNew := FALSE; (* because of call to FPrintErr from OPL *)
IF ~OPM.noerr OR findpc THEN
OPM.DeleteNewSym
OPM.DeleteNewSym(SelfName)
END
(* OPM.RegisterNewSym is called in OP2 after writing the object file *)
END
@ -1256,6 +1290,8 @@ END Import;
END Export; (* no new symbol file if ~OPM.noerr or findpc *)
(*------------------------- Initialise types --------------------------*)
PROCEDURE InitStruct(VAR typ: Struct; form: SHORTINT);
BEGIN
typ := NewStr(form, Basic); typ^.ref := form; typ^.size := 1; typ^.allocated := TRUE;

View file

@ -790,7 +790,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
OPM.WriteString("__X(");
OPC.Len(r.obj, r.typ, 0); OPM.WriteString(" * "); OPM.WriteInt(r.typ.BaseTyp.size);
OPM.WriteString(", ");
OPM.WriteInt(l.typ.size+1); (* _X vaidates 0 .. n-1 so we need to +1. *)
OPM.WriteInt(l.typ.size+1); (* _X validates 0 .. n-1 so we need top+1. *)
OPM.Write(")")
ELSE (* Array to array copy. *)
ASSERT(r.typ.comp = OPT.Array); ASSERT(r.typ.size <= l.typ.size);

View file

@ -645,21 +645,11 @@ Especially Length would become fairly complex.
PROCEDURE Register* (f: File);
VAR idx, errcode: INTEGER; f1: File;
BEGIN
(*
Out.String("Files.Register f.registerName = "); Out.String(f.registerName);
Out.String(", fd = "); Out.Int(f.fd,1); Out.Ln;
*)
IF (f.state = create) & (f.registerName # "") THEN f.state := close (* shortcut renaming *) END;
Close(f);
IF f.registerName # "" THEN
Deregister(f.registerName);
Rename(f.workName, f.registerName, errcode);
(*
Out.String("Renamed (for register) f.fd = "); Out.Int(f.fd,1);
Out.String(" from workname "); Out.String(f.workName);
Out.String(" to registerName "); Out.String(f.registerName);
Out.String(" errorcode = "); Out.Int(errcode,1); Out.Ln;
*)
IF errcode # 0 THEN Err("Couldn't rename temp name as register name", f, errcode) END;
f.workName := f.registerName; f.registerName := ""; f.tempFile := FALSE
END