[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