[Oberon] SystemV- Heap + Module Space
Jörg Straube
joerg.straube at iaeth.ch
Sat Jan 5 16:48:26 CET 2019
Oberon.Activate(): even better with a CASE😊
Jörg
Am 05.01.2019 um 16:22 schrieb Andreas Pirklbauer <andreas_pirklbauer at yahoo.com>:
>> 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;
>
>
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon
More information about the Oberon
mailing list