|
|
@@ -70,6 +70,10 @@ VAR
|
|
|
outSel : CARDINAL; (* 0 = file, else nestBufs[outSel-1] *)
|
|
|
nInit : CARDINAL;
|
|
|
initNames : ARRAY [0 .. 31] OF QVal;
|
|
|
+ nExtInit : CARDINAL;
|
|
|
+ extInitNames : ARRAY [0 .. 31] OF QVal;
|
|
|
+ programMode : BOOLEAN; (* separate objects: FALSE emits no main *)
|
|
|
+ separateMode : BOOLEAN; (* per-object mode (no def code, empty inits) *)
|
|
|
nFini : CARDINAL;
|
|
|
finiNames : ARRAY [0 .. 31] OF QVal;
|
|
|
sessBuf : ARRAY [0 .. 8388607] OF CHAR; (* whole image, buffered (8 MiB:
|
|
|
@@ -316,6 +320,32 @@ PROCEDURE SetModule (name: ARRAY OF CHAR);
|
|
|
Cpy(curModName, name)
|
|
|
END SetModule;
|
|
|
|
|
|
+PROCEDURE SetProgramMode (isProgram: BOOLEAN);
|
|
|
+(* Separate compilation: FALSE makes EndModule emit a library object
|
|
|
+ (no main, no ExitCode return); TRUE keeps the program image. *)
|
|
|
+ BEGIN
|
|
|
+ programMode := isProgram
|
|
|
+ END SetProgramMode;
|
|
|
+
|
|
|
+PROCEDURE SetSeparateMode (b: BOOLEAN);
|
|
|
+(* TRUE for M2 -c: Lower emits an empty init for bodyless modules and
|
|
|
+ the driver skips lowering definition units. *)
|
|
|
+ BEGIN
|
|
|
+ separateMode := b
|
|
|
+ END SetSeparateMode;
|
|
|
+
|
|
|
+PROCEDURE NoteExternalInit (mod: ARRAY OF CHAR);
|
|
|
+(* Program object: call an imported module's <mod>_init before the
|
|
|
+ target module's init. The driver adds one per imported DEFINITION. *)
|
|
|
+ VAR sym : QVal;
|
|
|
+ BEGIN
|
|
|
+ IF nExtInit > HIGH(extInitNames) THEN RETURN END;
|
|
|
+ Cpy(sym, mod);
|
|
|
+ App(sym, "_init");
|
|
|
+ Cpy(extInitNames[nExtInit], sym);
|
|
|
+ INC(nExtInit)
|
|
|
+ END NoteExternalInit;
|
|
|
+
|
|
|
PROCEDURE SymRef (name: ARRAY OF CHAR; VAR ref: QVal);
|
|
|
(* "$<mod>_<sym>" for module-level entries (avoids cross-module
|
|
|
collisions); "$<name>" fallback otherwise. *)
|
|
|
@@ -596,7 +626,8 @@ PROCEDURE OpenModule (name: ARRAY OF CHAR);
|
|
|
nLoc := 0; nPar := 0; nArg := 0; nn := 0; callDepth := 0;
|
|
|
recvArmed := FALSE;
|
|
|
funcDepth := 0; scopeTop := 0; scopeBase[0] := 0;
|
|
|
- nInit := 0; nFini := 0;
|
|
|
+ nInit := 0; nFini := 0; nExtInit := 0;
|
|
|
+ programMode := TRUE;
|
|
|
outSel := 0;
|
|
|
sessUsed := 0; sessBuf[0] := CHR(0);
|
|
|
delayTop := 0;
|
|
|
@@ -613,7 +644,7 @@ PROCEDURE DataLine (name: ARRAY OF CHAR; isReal: BOOLEAN;
|
|
|
init: ARRAY OF CHAR);
|
|
|
BEGIN
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
IF isReal THEN W(" = { d ") ELSE W(" = { w ") END;
|
|
|
W(init);
|
|
|
WL(" }")
|
|
|
@@ -623,7 +654,7 @@ PROCEDURE DataLineB (name: ARRAY OF CHAR; init: ARRAY OF CHAR);
|
|
|
(* A one-byte global (BYTE/SBYTE). *)
|
|
|
BEGIN
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
W(" = { b ");
|
|
|
W(init);
|
|
|
WL(" }")
|
|
|
@@ -633,7 +664,7 @@ PROCEDURE DataLineH (name: ARRAY OF CHAR; init: ARRAY OF CHAR);
|
|
|
(* A 16-bit global (WORD16/INTEGER16). *)
|
|
|
BEGIN
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
W(" = { h ");
|
|
|
W(init);
|
|
|
WL(" }")
|
|
|
@@ -645,7 +676,7 @@ PROCEDURE DataLinePacked (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
BEGIN
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
nb := SymTab.SetBytes(t);
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
W(" = { ");
|
|
|
IF nb = 1 THEN W("b 0")
|
|
|
ELSIF nb = 2 THEN W("h 0")
|
|
|
@@ -657,7 +688,7 @@ PROCEDURE DataLinePacked (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
PROCEDURE DataLineL (name: ARRAY OF CHAR; init: ARRAY OF CHAR);
|
|
|
BEGIN
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
W(" = { l ");
|
|
|
W(init);
|
|
|
WL(" }")
|
|
|
@@ -811,6 +842,11 @@ PROCEDURE BeginBody;
|
|
|
INC(i)
|
|
|
END;
|
|
|
i := 0;
|
|
|
+ WHILE i < nExtInit DO
|
|
|
+ W(" call $"); W(extInitNames[i]); WL("()");
|
|
|
+ INC(i)
|
|
|
+ END;
|
|
|
+ i := 0;
|
|
|
WHILE i < nInit DO
|
|
|
W(" call $"); W(initNames[i]); WL("()");
|
|
|
INC(i)
|
|
|
@@ -826,7 +862,7 @@ PROCEDURE FlushSets;
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
k := 0;
|
|
|
WHILE k < setN DO
|
|
|
- W("data $"); W(setNam[k]); W(" = { ");
|
|
|
+ W("export data $"); W(setNam[k]); W(" = { ");
|
|
|
w := setW[k];
|
|
|
IF w = 0 THEN w := 1 END;
|
|
|
i := 0;
|
|
|
@@ -880,18 +916,20 @@ PROCEDURE EndModule (name: ARRAY OF CHAR);
|
|
|
not flush/close/write while the legacy emit is suppressed. The
|
|
|
real session image is written by Lower.EndSession. *)
|
|
|
IF noEmit THEN RETURN END;
|
|
|
- IF NOT inBody THEN BeginBody END;
|
|
|
- EmitFiniCalls(name);
|
|
|
- IF SymTab.Lookup("ExitCode")
|
|
|
+ IF programMode THEN
|
|
|
+ IF NOT inBody THEN BeginBody END;
|
|
|
+ EmitFiniCalls(name);
|
|
|
+ IF SymTab.Lookup("ExitCode")
|
|
|
AND (SymTab.SymKind("ExitCode") = SymTab.KindVar)
|
|
|
AND SymTab.IsIntFamily(SymTab.SymType("ExitCode")) THEN
|
|
|
- Cpy(ref, "$"); App(ref, name); App(ref, "_ExitCode");
|
|
|
- W(" %ec =w loadw "); WL(ref);
|
|
|
- WL(" ret %ec")
|
|
|
- ELSE
|
|
|
- WL(" ret 0")
|
|
|
+ Cpy(ref, "$"); App(ref, name); App(ref, "_ExitCode");
|
|
|
+ W(" %ec =w loadw "); WL(ref);
|
|
|
+ WL(" ret %ec")
|
|
|
+ ELSE
|
|
|
+ WL(" ret 0")
|
|
|
+ END;
|
|
|
+ WL("}")
|
|
|
END;
|
|
|
- WL("}");
|
|
|
(* hoisted nested functions, then deferred data *)
|
|
|
i := 0;
|
|
|
WHILE i <= HIGH(nestBufs) DO
|
|
|
@@ -1054,9 +1092,13 @@ PROCEDURE ResClass (t: INTEGER): CHAR;
|
|
|
END ResClass;
|
|
|
|
|
|
PROCEDURE Mangled (pname: ARRAY OF CHAR; uid: CARDINAL; VAR q: QVal);
|
|
|
-(* External procedures bind to their C link name; everything else
|
|
|
- mangles to <name>_<uid> (deterministic, collision-free). *)
|
|
|
- VAR link, base : SymTab.Name;
|
|
|
+(* External procedures bind to their C link name. Module-level
|
|
|
+ procedures get a stable, module-qualified name (<module>__<name>)
|
|
|
+ so objects compiled in separate sessions agree. Nested procedures
|
|
|
+ are local to their module object; they keep a deterministic uid
|
|
|
+ suffix, prefixed by the module to avoid cross-object collisions. *)
|
|
|
+ VAR link, base, mod : SymTab.Name;
|
|
|
+ depth : CARDINAL; classIdx : INTEGER; num : QVal;
|
|
|
BEGIN
|
|
|
IF SymTab.ProcLink(pname, link) THEN
|
|
|
Cpy(q, link);
|
|
|
@@ -1065,9 +1107,36 @@ PROCEDURE Mangled (pname: ARRAY OF CHAR; uid: CARDINAL; VAR q: QVal);
|
|
|
IF NOT SymTab.SymBase(pname, base) THEN
|
|
|
IF NOT SymTab.ProcBaseByUid(uid, base) THEN Cpy(base, pname) END
|
|
|
END;
|
|
|
- Cpy(q, base);
|
|
|
- App(q, "_");
|
|
|
- AppNum(q, uid)
|
|
|
+ IF SymTab.SymBase(pname, base) THEN
|
|
|
+ IF SymTab.ProcLink(base, link) THEN
|
|
|
+ Cpy(q, link);
|
|
|
+ RETURN
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ IF SymTab.ProcModuleByUid(uid, mod, depth)
|
|
|
+ AND (mod[0] # CHR(0)) THEN
|
|
|
+ Cpy(q, mod);
|
|
|
+ App(q, "__");
|
|
|
+ App(q, base);
|
|
|
+ classIdx := SymTab.ProcClassByUid(uid);
|
|
|
+ IF classIdx # SymTab.InvalidType THEN
|
|
|
+ IF SymTab.TypeStableName(classIdx, link, base) THEN
|
|
|
+ App(q, "_"); App(q, link); App(q, "__"); App(q, base)
|
|
|
+ ELSE
|
|
|
+ App(q, "_c");
|
|
|
+ IntStr(classIdx, num);
|
|
|
+ App(q, num)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ IF depth > 0 THEN
|
|
|
+ App(q, "_");
|
|
|
+ AppNum(q, uid)
|
|
|
+ END
|
|
|
+ ELSE
|
|
|
+ Cpy(q, base);
|
|
|
+ App(q, "_");
|
|
|
+ AppNum(q, uid)
|
|
|
+ END
|
|
|
END Mangled;
|
|
|
|
|
|
PROCEDURE AllocLocal (t: INTEGER; VAR slot: QVal);
|
|
|
@@ -2425,7 +2494,7 @@ PROCEDURE ArrData (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
|
|
|
BEGIN
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
W(" = { ");
|
|
|
ArrBodyItems(name, t);
|
|
|
WL(" }");
|
|
|
@@ -2553,12 +2622,19 @@ PROCEDURE RecItems (t: SymTab.TypeIndex; prefix: ARRAY OF CHAR;
|
|
|
END RecItems;
|
|
|
|
|
|
PROCEDURE VtRef (t: INTEGER; VAR q: QVal);
|
|
|
-(* The class's vtable symbol ($vt_<typeindex>). *)
|
|
|
- VAR bv: QVal;
|
|
|
+(* Stable vtable symbol: $<module>__<class>__vt. Fall back to a
|
|
|
+ module-qualified type index for anonymous types. *)
|
|
|
+ VAR bv: QVal; mod, nm: SymTab.Name;
|
|
|
BEGIN
|
|
|
- Cpy(q, "$vt_");
|
|
|
- IntStr(t, bv);
|
|
|
- App(q, bv)
|
|
|
+ IF SymTab.TypeStableName(t, mod, nm) THEN
|
|
|
+ Cpy(q, "$"); App(q, mod); App(q, "__"); App(q, nm); App(q, "__vt")
|
|
|
+ ELSE
|
|
|
+ Cpy(q, "$");
|
|
|
+ App(q, curModName);
|
|
|
+ App(q, "_vt_");
|
|
|
+ IntStr(t, bv);
|
|
|
+ App(q, bv)
|
|
|
+ END
|
|
|
END VtRef;
|
|
|
|
|
|
PROCEDURE EmitVTables;
|
|
|
@@ -2566,31 +2642,38 @@ PROCEDURE EmitVTables;
|
|
|
method code addresses. *)
|
|
|
VAR k, j, n: CARDINAL;
|
|
|
t: INTEGER;
|
|
|
- nm: SymTab.Name;
|
|
|
+ nm, cname, cmod: SymTab.Name;
|
|
|
mg, vt: QVal;
|
|
|
+ own: BOOLEAN;
|
|
|
BEGIN
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
k := 0;
|
|
|
WHILE k < SymTab.VtClassCount() DO
|
|
|
t := SymTab.VtClassAt(k);
|
|
|
- n := SymTab.VtCount(t);
|
|
|
- VtRef(t, vt);
|
|
|
- W("data "); W(vt); W(" = { ");
|
|
|
- j := 0;
|
|
|
- WHILE j < n DO
|
|
|
- IF SymTab.VtName(t, j, nm) THEN
|
|
|
- IF j > 0 THEN W(", ") END;
|
|
|
- IF SymTab.VtHasBody(t, j) THEN
|
|
|
- Mangled(nm, SymTab.VtUid(t, j), mg);
|
|
|
- W("l $"); W(mg)
|
|
|
- ELSE
|
|
|
- W("l 0") (* declared but never implemented *)
|
|
|
- END
|
|
|
+ own := TRUE;
|
|
|
+ IF SymTab.TypeStableName(t, cmod, cname) THEN
|
|
|
+ own := SymTab.Equal(cmod, curModName) OR NOT separateMode
|
|
|
+ END;
|
|
|
+ IF own THEN
|
|
|
+ n := SymTab.VtCount(t);
|
|
|
+ VtRef(t, vt);
|
|
|
+ W("export data "); W(vt); W(" = { ");
|
|
|
+ j := 0;
|
|
|
+ WHILE j < n DO
|
|
|
+ IF SymTab.VtName(t, j, nm) THEN
|
|
|
+ IF j > 0 THEN W(", ") END;
|
|
|
+ IF SymTab.VtHasBody(t, j) THEN
|
|
|
+ Mangled(nm, SymTab.VtUid(t, j), mg);
|
|
|
+ W("l $"); W(mg)
|
|
|
+ ELSE
|
|
|
+ W("l 0") (* declared but never implemented *)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ INC(j)
|
|
|
END;
|
|
|
- INC(j)
|
|
|
+ IF n = 0 THEN W("l 0") END;
|
|
|
+ WL(" }")
|
|
|
END;
|
|
|
- IF n = 0 THEN W("l 0") END;
|
|
|
- WL(" }");
|
|
|
INC(k)
|
|
|
END
|
|
|
END EmitVTables;
|
|
|
@@ -2604,11 +2687,11 @@ PROCEDURE DeclRec (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
(* variant record: fields overlay, so emit one zero-filled blob
|
|
|
of the record's (max) size *)
|
|
|
IntStr(VAL(INTEGER, SymTab.TypeSize(t)), sz);
|
|
|
- W("data $"); W(name); W(" = { z "); W(sz); WL(" }");
|
|
|
+ W("export data $"); W(name); W(" = { z "); W(sz); WL(" }");
|
|
|
RETURN
|
|
|
END;
|
|
|
RecStatics(name, t);
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
W(" = { ");
|
|
|
first := TRUE;
|
|
|
(* a class with a vtable stores its vtable pointer at offset 0 *)
|
|
|
@@ -2681,7 +2764,7 @@ PROCEDURE DeclSet (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
w := SymTab.SetWords(t);
|
|
|
IF w = 0 THEN w := 1 END;
|
|
|
- W("data $"); W(name);
|
|
|
+ W("export data $"); W(name);
|
|
|
W(" = { w 0");
|
|
|
i := 1;
|
|
|
WHILE i < w DO
|
|
|
@@ -2702,7 +2785,8 @@ PROCEDURE PoolSet (mask: ARRAY OF CARDINAL; words: CARDINAL; VAR q: QVal);
|
|
|
END;
|
|
|
WHILE k <= 15 DO setMask[setN][k] := 0; INC(k) END;
|
|
|
setW[setN] := words;
|
|
|
- Cpy(setNam[setN], "set"); AppNum(setNam[setN], setN);
|
|
|
+ Cpy(setNam[setN], curModName); App(setNam[setN], "_set");
|
|
|
+ AppNum(setNam[setN], setN);
|
|
|
Cpy(q, "$"); App(q, setNam[setN]);
|
|
|
INC(setN)
|
|
|
END PoolSet;
|
|
|
@@ -3681,6 +3765,32 @@ PROCEDURE CopyOldNestedToView (dst, src: ARRAY OF CHAR;
|
|
|
END
|
|
|
END CopyOldNestedToView;
|
|
|
|
|
|
+PROCEDURE IsCtorRef (v: ARRAY OF CHAR): BOOLEAN;
|
|
|
+(* TRUE for $ctoN and $<module>_ctoN. *)
|
|
|
+ VAR i: CARDINAL;
|
|
|
+ BEGIN
|
|
|
+ IF (v[0] # "$") OR (v[1] = CHR(0)) THEN RETURN FALSE END;
|
|
|
+ IF (v[1] = "c") AND (v[2] = "t") AND (v[3] = "o") THEN RETURN TRUE END;
|
|
|
+ i := 1;
|
|
|
+ WHILE (i <= HIGH(v)) AND (v[i] # CHR(0)) AND (v[i] # "_") DO INC(i) END;
|
|
|
+ RETURN (i + 3 <= HIGH(v)) AND (v[i] = "_")
|
|
|
+ AND (v[i + 1] = "c") AND (v[i + 2] = "t") AND (v[i + 3] = "o")
|
|
|
+ END IsCtorRef;
|
|
|
+
|
|
|
+PROCEDURE IsStrRef (v: ARRAY OF CHAR): BOOLEAN;
|
|
|
+(* TRUE when v names a recorded string literal ($strN or $<mod>_strN). *)
|
|
|
+ VAR j: CARDINAL;
|
|
|
+ sv: QVal;
|
|
|
+ BEGIN
|
|
|
+ j := 0;
|
|
|
+ WHILE j < nStr DO
|
|
|
+ Cpy(sv, "$"); App(sv, strNams[j]);
|
|
|
+ IF SymTab.Equal(sv, v) THEN RETURN TRUE END;
|
|
|
+ INC(j)
|
|
|
+ END;
|
|
|
+ RETURN FALSE
|
|
|
+ END IsStrRef;
|
|
|
+
|
|
|
PROCEDURE CopyArray (dst: ARRAY OF CHAR; src: ARRAY OF CHAR;
|
|
|
t: INTEGER);
|
|
|
(* Whole-array copy with runtime count check + blit. Nested levels
|
|
|
@@ -3696,8 +3806,7 @@ PROCEDURE CopyArray (dst: ARRAY OF CHAR; src: ARRAY OF CHAR;
|
|
|
ltop, lbody, lend: QVal;
|
|
|
BEGIN
|
|
|
IF SymTab.IsMultiArray(t) THEN
|
|
|
- IF (src[0] = "$") AND (src[1] = "c") AND (src[2] = "t")
|
|
|
- AND (src[3] = "o") THEN
|
|
|
+ IF IsCtorRef(src) THEN
|
|
|
CopyOldNestedToView(dst, src, t, SymTab.ArrayDepth(t))
|
|
|
ELSE
|
|
|
(* src/dst are ArrayView pointers; copy the flat payload only. *)
|
|
|
@@ -3803,7 +3912,8 @@ PROCEDURE DeclStr (text: ARRAY OF CHAR; VAR q: QVal);
|
|
|
appear outside functions, but literals occur mid-body. *)
|
|
|
VAR nm: QVal;
|
|
|
BEGIN
|
|
|
- Cpy(nm, "str");
|
|
|
+ Cpy(nm, curModName);
|
|
|
+ App(nm, "_str");
|
|
|
AppNum(nm, nStr);
|
|
|
IF nStr <= HIGH(strNams) THEN
|
|
|
Cpy(strNams[nStr], nm);
|
|
|
@@ -3872,7 +3982,7 @@ PROCEDURE DeclUStr (text: ARRAY OF CHAR; VAR q: QVal;
|
|
|
IF cnt = 1 THEN
|
|
|
single := TRUE; cp := ustrPool[base]
|
|
|
ELSE
|
|
|
- Cpy(nm, "ustr"); AppNum(nm, ustrN);
|
|
|
+ Cpy(nm, curModName); App(nm, "_ustr"); AppNum(nm, ustrN);
|
|
|
IF ustrN <= HIGH(ustrNams) THEN
|
|
|
Cpy(ustrNams[ustrN], nm);
|
|
|
ustrStart[ustrN] := base; ustrCount[ustrN] := cnt; INC(ustrN)
|
|
|
@@ -3888,7 +3998,7 @@ PROCEDURE FlushUStrings;
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
k := 0;
|
|
|
WHILE k < ustrN DO
|
|
|
- W("data $"); W(ustrNams[k]); W(" = { l ");
|
|
|
+ W("export data $"); W(ustrNams[k]); W(" = { l ");
|
|
|
IntStr(VAL(INTEGER, ustrCount[k]), bv); W(bv);
|
|
|
i := 0;
|
|
|
WHILE i < ustrCount[k] DO
|
|
|
@@ -3998,7 +4108,7 @@ PROCEDURE FlushStrings;
|
|
|
WHILE k < nStr DO
|
|
|
L := Len(strTexts[k]);
|
|
|
IF L >= 2 THEN
|
|
|
- W("data $"); W(strNams[k]);
|
|
|
+ W("export data $"); W(strNams[k]);
|
|
|
W(" = { l ");
|
|
|
IntStr(VAL(INTEGER, L - 2), bv);
|
|
|
W(bv);
|
|
|
@@ -4048,7 +4158,7 @@ PROCEDURE DeclMultiArr (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
ELSE
|
|
|
Cpy(nxt, "0")
|
|
|
END;
|
|
|
- W("data $"); W(lab); W(" = { l ");
|
|
|
+ W("export data $"); W(lab); W(" = { l ");
|
|
|
IntStr(VAL(INTEGER, count), bv); W(bv);
|
|
|
W(", l "); IntStr(VAL(INTEGER, stride), sv); W(sv);
|
|
|
W(", l "); W(sv);
|
|
|
@@ -4057,7 +4167,7 @@ PROCEDURE DeclMultiArr (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
cur := SymTab.ArrayElem(cur);
|
|
|
INC(k)
|
|
|
END;
|
|
|
- W("data $"); W(name); W("_data = { z ");
|
|
|
+ W("export data $"); W(name); W("_data = { z ");
|
|
|
IntStr(VAL(INTEGER, payload), pv); W(pv); WL(" }")
|
|
|
END DeclMultiArr;
|
|
|
|
|
|
@@ -4080,13 +4190,14 @@ PROCEDURE DeclArr (name: ARRAY OF CHAR; t: INTEGER);
|
|
|
|
|
|
PROCEDURE IsBakeOp (v: ARRAY OF CHAR): BOOLEAN;
|
|
|
(* TRUE when v may be embedded in a static descriptor: an immediate,
|
|
|
- or a pooled constructor/label reference ($ctoN). A plain global
|
|
|
- address ($mod_var) is NOT bakeable into an inline field. *)
|
|
|
+ or a pooled constructor/label reference ($ctoN / $<mod>_ctoN).
|
|
|
+ A plain global address ($mod_var) is NOT bakeable into an inline
|
|
|
+ field. *)
|
|
|
+ VAR i: CARDINAL;
|
|
|
BEGIN
|
|
|
IF (v[0] = CHR(0)) OR (v[0] = "%") THEN RETURN FALSE END;
|
|
|
IF v[0] # "$" THEN RETURN TRUE END;
|
|
|
- (* accept $ctoN only *)
|
|
|
- RETURN (v[1] = "c") AND (v[2] = "t") AND (v[3] = "o")
|
|
|
+ RETURN IsCtorRef(v)
|
|
|
END IsBakeOp;
|
|
|
|
|
|
PROCEDURE CtorItem (VAR buf: ARRAY OF CHAR; v: ARRAY OF CHAR;
|
|
|
@@ -4259,7 +4370,8 @@ PROCEDURE StrDesc (v: ARRAY OF CHAR; elemT: INTEGER; VAR out: QVal);
|
|
|
INC(i)
|
|
|
END;
|
|
|
App(buf, ", b 0");
|
|
|
- Cpy(ctorNam[ctorN], "cto"); AppNum(ctorNam[ctorN], ctorN);
|
|
|
+ Cpy(ctorNam[ctorN], curModName); App(ctorNam[ctorN], "_cto");
|
|
|
+ AppNum(ctorNam[ctorN], ctorN);
|
|
|
Cpy(ctorTxt[ctorN], buf);
|
|
|
ctorUse[ctorN] := TRUE;
|
|
|
INC(ctorN);
|
|
|
@@ -4290,8 +4402,7 @@ PROCEDURE CtorElem (v: ARRAY OF CHAR);
|
|
|
t := ctorTyp[ctorTop - 1];
|
|
|
elemT := CtorElemType(t, ctorCnt[ctorTop - 1]);
|
|
|
cls := SymTab.ClassOf(elemT);
|
|
|
- isStr := (Len(v) > 3) AND (v[0] = "$")
|
|
|
- AND (v[1] = "s") AND (v[2] = "t");
|
|
|
+ isStr := IsStrRef(v);
|
|
|
IF cls = SymTab.ClChar THEN
|
|
|
IF isStr AND FindStrPos(v, cnt) THEN
|
|
|
k := 1;
|
|
|
@@ -4500,7 +4611,7 @@ PROCEDURE CtorRecStatic (VAR s: ARRAY OF CHAR; lvl: CARDINAL;
|
|
|
IF (v[0] # CHR(0)) AND (cls = SymTab.ClArray)
|
|
|
AND SymTab.IsMultiArray(ft) THEN
|
|
|
flat[0] := CHR(0);
|
|
|
- IF (v[0] = "$") AND (v[1] = "c") THEN
|
|
|
+ IF IsCtorRef(v) THEN
|
|
|
FlattenCtorText(v, ft, flat)
|
|
|
END;
|
|
|
IF first THEN first := FALSE ELSE App(s, ", ") END;
|
|
|
@@ -4600,7 +4711,8 @@ PROCEDURE CtorEnd (VAR q: QVal);
|
|
|
ELSE
|
|
|
CtorRecStatic(s, ctorTop, t, ctorCnt[ctorTop])
|
|
|
END;
|
|
|
- Cpy(ctorNam[ctorN], "cto"); AppNum(ctorNam[ctorN], ctorN);
|
|
|
+ Cpy(ctorNam[ctorN], curModName); App(ctorNam[ctorN], "_cto");
|
|
|
+ AppNum(ctorNam[ctorN], ctorN);
|
|
|
Cpy(ctorTxt[ctorN], s);
|
|
|
ctorUse[ctorN] := TRUE;
|
|
|
INC(ctorN);
|
|
|
@@ -4700,7 +4812,7 @@ PROCEDURE FlushCtors;
|
|
|
k := 0;
|
|
|
WHILE k < ctorN DO
|
|
|
IF ctorUse[k] THEN
|
|
|
- W("data $"); W(ctorNam[k]); W(" = { "); W(ctorTxt[k]); WL(" }")
|
|
|
+ W("export data $"); W(ctorNam[k]); W(" = { "); W(ctorTxt[k]); WL(" }")
|
|
|
END;
|
|
|
INC(k)
|
|
|
END
|
|
|
@@ -4940,7 +5052,7 @@ PROCEDURE DeclRecTemplate (varName: ARRAY OF CHAR; rec: INTEGER);
|
|
|
IF NOT opened THEN RETURN END;
|
|
|
Cpy(g, curModName); App(g, "_"); App(g, varName); App(g, "_tmpl");
|
|
|
RecStatics(g, rec);
|
|
|
- W("data $"); W(g); W(" = { ");
|
|
|
+ W("export data $"); W(g); W(" = { ");
|
|
|
first := TRUE;
|
|
|
RecItems(rec, g, first);
|
|
|
WL(" }")
|