mirror of
https://github.com/vishapoberon/compiler.git
synced 2026-04-05 22:12:24 +00:00
Build link list based on imports, not on modules compiled by compiler instance.
This commit is contained in:
parent
4a71f43e72
commit
460b879829
7 changed files with 100 additions and 51 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue