[Oberon] SystemV- Heap + Module Space
Andreas Pirklbauer
andreas_pirklbauer at yahoo.com
Sat Jan 5 16:22:16 CET 2019
> I would have defined all of those res values as exported named constants in module Modules.
As in ...
Modules.Mod:
~~~~~~~~~~~~
MODULE Modules;
...
CONST ...
noerr* = 0; nofile* = 1; badversion* = 2; badkey* = 3; badfile* = 4; nocmd* = 5; badcmd* = 6; nospace* = 7; nomod* = 8;
PROCEDURE Load*(name: ARRAY OF CHAR; VAR newmod: Module);
(*search module in list; if not found, load module.
res = noerr: already present or loaded;
res = nofile: file not available;
res = badversion: bad file version;
res = badkey: key conflict;
res = badfile: corrupted file;
res = nospace: insufficient space*)
VAR ...
BEGIN mod := root; res := noerr; nofimps := 0;
WHILE (mod # NIL) & (name # mod.name) DO mod := mod.next END ;
IF mod = NIL THEN (*load*)
Check(name);
IF res = 0 THEN F := ThisFile(name) ELSE F := NIL END ;
IF F # NIL THEN
Files.Set(R, F, 0); Files.ReadString(R, name1); Files.ReadInt(R, key); Files.Read(R, ch);
Files.ReadInt(R, size); importing := name1;
IF ch = versionkey THEN
Files.ReadString(R, impname); (*imports*)
WHILE (impname[0] # 0X) & (res = noerr) DO
Files.ReadInt(R, impkey);
Load(impname, impmod); import[nofimps] := impmod;
IF res = noerr THEN importing := name1;
IF impmod.key = impkey THEN INC(impmod.refcnt); INC(nofimps)
ELSE error(badkey, name1); imported := impname
END
END ;
Files.ReadString(R, impname)
END
ELSE error(badversion, name1)
END
ELSE error(nofile, name)
END ;
IF res = noerr THEN (*search for a hole in the list allocate and link*)
… etc ...
Oberon.Mod:
~~~~~~~~~~
PROCEDURE Call* (name: ARRAY OF CHAR; VAR Mname, Cname: ARRAY OF CHAR; VAR res: INTEGER);
VAR mod: Modules.Module; P: Modules.Command;
i, j: INTEGER; ch: CHAR;
BEGIN i := 0; ch := name[0];
IF ("0" <= ch) & (ch <= "9") THEN (*module number*) j := 0;
REPEAT j := 10*j + (ORD(ch) - 30H); INC(i); ch := name[i] UNTIL (ch < "0") OR (ch > "9");
IF ch = "." THEN INC(i); mod := Modules.root;
WHILE (mod # NIL) & (mod.num # j) DO mod := mod.next END ;
IF (mod # NIL) & (mod.name[0] # 0X) THEN res := Modules.noerr; j := 0;
REPEAT ch := mod.name[j]; Mname[j] := ch; INC(j) UNTIL ch = 0X
ELSE res := Modules.nomod
END
ELSE res := Modules.badcmd
END
ELSIF (ch >= "A") & (ch <= "Z") OR (ch >= "a") & (ch <= "z") OR (ch = "*") THEN (*module name*)
REPEAT Mname[i] := ch; INC(i); ch := name[i] UNTIL (ch = ".") OR (ch = 0X);
IF ch = "." THEN Mname[i] := 0X; INC(i); Modules.Load(Mname, mod); res := Modules.res ELSE res := Modules.badcmd END
ELSE res := Modules.badcmd
END ;
IF res = Modules.noerr THEN
j := 0; ch := name[i]; INC(i);
WHILE ch # 0X DO Cname[j] := ch; INC(j); ch := name[i]; INC(i) END ;
Cname[j] := 0X;
P := Modules.ThisCommand(mod, Cname); res := Modules.res;
IF Modules.res = Modules.noerr THEN P END
END
END Call;
PROCEDURE Activate*(F: Viewers.Frame; T: Texts.Text; pos: LONGINT); (*command*)
VAR S: Texts.Scanner; res: INTEGER;
Mname, Cname: ARRAY 32 OF CHAR;
BEGIN
Texts.OpenScanner(S, T, pos); Texts.Scan(S);
IF ((S.class = Texts.Name) OR (S.class = Texts.String)) & (S.line = 0) THEN (*strings allowed*)
SetPar(F, T, pos + S.len); Call(S.s, Mname, Cname, res);
IF (res # Modules.noerr) & (Log # NIL) THEN
Texts.WriteString(W, "Call error: ");
IF res = Modules.nofile THEN Texts.WriteString(W, Modules.importing); Texts.WriteString(W, " module not found")
ELSIF res = Modules.badversion THEN Texts.WriteString(W, Modules.importing); Texts.WriteString(W, " bad version")
ELSIF res = Modules.badkey THEN Texts.WriteString(W, Modules.importing); Texts.WriteString(W, " imports ");
Texts.WriteString(W, Modules.imported); Texts.WriteString(W, " with bad key")
ELSIF res = Modules.badfile THEN Texts.WriteString(W, Modules.importing); Texts.WriteString(W, " corrupted obj file")
ELSIF res = Modules.nocmd THEN Texts.WriteString(W, Mname); Texts.WriteString(W, " command not found")
ELSIF res = Modules.badcmd THEN Texts.WriteString(W, S.s); Texts.WriteString(W, " invalid command")
ELSIF res = Modules.nospace THEN Texts.WriteString(W, Modules.importing); Texts.WriteString(W, " insufficient space")
ELSIF res = Modules.nomod THEN Texts.WriteString(W, Mname); Texts.WriteString(W, " module not found")
END ;
Texts.WriteLn(W); Texts.Append(Log, W.buf)
END
END
END Activate;
TextFrames.Mod:
~~~~~~~~~~~~~
PROCEDURE Edit* (F: Frame; X, Y: INTEGER; Keys: SET);
…
BEGIN
…
ELSIF 1 IN Keys THEN (*MM: call*)
TrackWord(F, X, Y, pos, keysum);
IF (pos >= 0) & ~(0 IN keysum) THEN Oberon.Activate(F, F.text, pos) END
ELSIF 2 IN Keys THEN (*ML: set caret*)
…
END
END Edit;
More information about the Oberon
mailing list