DEADSOFTWARE

expressions interpreted in lazy mode
[cpc.git] / src / generic / Dev / Mod / CPR.cp
index b43b539bd2beebe3747961b7bd2aa1acb037a02e..b3ef0524cb2474b2bafbbd6249c362ad5c3dac04 100644 (file)
@@ -7,13 +7,10 @@ MODULE DevCPR;
 
     (* symbol values *)
     null = 0;
-    if = 1; then = 2; else = 3; elsif = 4; end = 5; new = 6;
-    ident = 7; plus = 8; minus = 9;
-    not = 10; and = 11; or = 12; rpar = 13; lpar = 14;
-    endcom = 15; eof = 16;
-
-    (* func numbers *)
-    var = 0; defined = 1;
+    if = 1; then = 2; else = 3; elsif = 4; end = 5;
+    new = 6; error = 7; ident = 8; plus = 9; minus = 10;
+    not = 11; and = 12; or = 13; rpar = 14; lpar = 15; defined = 16;
+    endcom = 17; eof = 18;
 
   TYPE
     Context = POINTER TO RECORD
@@ -26,12 +23,11 @@ MODULE DevCPR;
     Selector = POINTER TO RECORD
       next: Selector;
       name: DevCPT.Name;
-      val: BOOLEAN;
-      num: BYTE
+      val: BOOLEAN
     END;
 
   VAR
-    ch: CHAR; (* current character *)
+    ch-: CHAR; (* current character *)
     name: DevCPT.Name; (* ident *)
 
   VAR
@@ -39,6 +35,7 @@ MODULE DevCPR;
     fold: INTEGER; (* condition folding *)
     scope: Selector;
     top: Context;
+    skip-: BOOLEAN;
 
   PROCEDURE err (n: SHORTINT);
   BEGIN DevCPM.err(n)
@@ -70,29 +67,30 @@ MODULE DevCPR;
         IF ch = ">" THEN sym := endcom; DevCPM.Get(ch) END
     | "+": sym := plus; DevCPM.Get(ch)
     | "-": sym := minus; DevCPM.Get(ch)
+    | "D": Identifier(sym); IF name = "DEFINED" THEN sym := defined END
     | "E": Identifier(sym);
         IF name = "END" THEN sym := end
         ELSIF name = "ELSE" THEN sym := else
         ELSIF name = "ELSIF" THEN sym := elsif
+        ELSIF name = "ERROR" THEN sym := error
         END
     | "I": Identifier(sym); IF name = "IF" THEN sym := if END
     | "N": Identifier(sym); IF name = "NEW" THEN sym := new END
     | "O": Identifier(sym); IF name = "OR" THEN sym := or END
     | "T": Identifier(sym); IF name = "THEN" THEN sym := then END
-    | "A".."D", "J".."M", "P".."S", "U".."Z", "a".."z", "_": Identifier(sym)
+    | "A".."C", "J".."M", "P".."S", "U".."Z", "a".."z", "_": Identifier(sym)
     | "~": sym := not; DevCPM.Get(ch)
     ELSE
       IF Strings.IsIdent(ch) THEN Identifier(sym) ELSE sym := null; DevCPM.Get(ch) END
     END
   END Get;
 
-  PROCEDURE New (IN name: DevCPT.Name; val: BOOLEAN): Selector;
+  PROCEDURE New (IN name: DevCPT.Name): Selector;
     VAR s: Selector;
   BEGIN
     s := scope;
     WHILE (s.next # NIL) & (s.next.name$ # name$) DO s := s.next END;
-    IF s.next = NIL THEN
-      NEW(s.next); s.next.name := name$; s.next.num := var; s.next.val := val
+    IF s.next = NIL THEN NEW(s.next); s.next.name := name$; s.next.val := FALSE
     ELSE err(1)
     END;
     RETURN s.next
@@ -104,7 +102,7 @@ MODULE DevCPR;
     s := scope;
     WHILE (s.next # NIL) & (s.next.name$ # name$) DO s := s.next END;
     IF s.next = NIL THEN
-      err(0); NEW(s.next); s.next.name := name$; s.next.num := var; s.next.val := FALSE
+      err(0); NEW(s.next); s.next.name := name$; s.next.val := FALSE
     END;
     RETURN s.next
   END Old;
@@ -123,72 +121,79 @@ MODULE DevCPR;
     s := scope;
     WHILE (s.next # NIL) & (s.next.name$ # name$) DO s := s.next END;
     IF s.next = NIL THEN NEW(s.next) END;
-    s.next.name := name$; s.next.num := var; s.next.val := val
+    s.next.name := name$; s.next.val := val
   END Set;
 
-  PROCEDURE ^ Expression (VAR x: BOOLEAN);
+  PROCEDURE ^ Expression (VAR x: BOOLEAN; use: BOOLEAN);
 
-  PROCEDURE Factor (VAR x: BOOLEAN);
-    VAR s: Selector;
-  BEGIN x := FALSE;
+  PROCEDURE Factor (VAR x: BOOLEAN; use: BOOLEAN);
+  BEGIN
+    x := FALSE;
     IF sym = ident THEN
-      s := Old(name); Get(sym);
-      IF s.num = var THEN
-         x := s.val
-      ELSIF sym = lpar THEN
+      IF use THEN x := Old(name).val END; Get(sym);
+    ELSIF sym = defined THEN
+      Get(sym);
+      IF sym = lpar THEN
         Get(sym);
-        ASSERT(s.num = defined);
         IF sym = ident THEN
-          x := Find(name) # NIL; Get(sym)
+          IF use THEN x := Find(name) # NIL END;
+          Get(sym)
         ELSE err(48)
         END;
         IF sym # rpar THEN err(23)
         ELSE Get(sym)
         END
-      ELSE
-        err(40)
-      END
+      ELSE err(40)
+      END      
     ELSIF sym = lpar THEN
-      Get(sym); Expression(x);
+      Get(sym); Expression(x, use);
       IF sym # rpar THEN err(23)
       ELSE Get(sym)
       END
     ELSIF sym = not THEN
-      Get(sym); Factor(x); x := ~x
+      Get(sym); Factor(x, use); IF use THEN x := ~x END
     ELSE
       err(13)
     END
   END Factor;
 
-  PROCEDURE Term (VAR x: BOOLEAN);
+  PROCEDURE Term (VAR x: BOOLEAN; use: BOOLEAN);
     VAR y: BOOLEAN;
   BEGIN
-    Factor(x);
+    Factor(x, use);
     WHILE sym = and DO
-      Get(sym); Factor(y); x := x & y
+      Get(sym); Factor(y, use & x); IF use & x THEN x := x & y END
     END
   END Term;
 
-  PROCEDURE Expression (VAR x: BOOLEAN);
+  PROCEDURE Expression (VAR x: BOOLEAN; use: BOOLEAN);
     VAR y: BOOLEAN;
   BEGIN
-    Term(x);
+    Term(x, use);
     WHILE sym = or DO
-      Get(sym); Term(y); x := x OR y
+      Get(sym); Term(y, use & ~x); IF use & ~x THEN x := x OR y END
     END
   END Expression;
 
+  PROCEDURE Printable (): BOOLEAN;
+    VAR c: Context;
+  BEGIN
+    c := top;
+    WHILE (c # NIL) & c.val DO c := c.next END;
+    RETURN c = NIL
+  END Printable;
+
   PROCEDURE If (cond: BOOLEAN);
     VAR c: Context;
   BEGIN
     NEW(c); c.next := top; c.alt := FALSE; c.val := cond; c.ref := 0; top := c;
-    INC(fold)
+    INC(fold); skip := ~Printable()
   END If;
 
   PROCEDURE Else;
   BEGIN
     IF top.alt THEN err(14) (* double ELSE *)
-    ELSE top.alt := TRUE; top.val := ~top.val;
+    ELSE top.alt := TRUE; top.val := ~top.val; skip := ~Printable()
     END
   END Else;
 
@@ -197,32 +202,39 @@ MODULE DevCPR;
   BEGIN
     i := 0; ref := top.ref; DEC(fold, ref + 1);
     WHILE (top # NIL) & (i <= ref) DO top := top.next; INC(i) END;
-    IF top = NIL THEN err(51); fold := 0; If(TRUE) END
+    IF top = NIL THEN err(51); fold := 0; If(TRUE) END;
+    skip := ~Printable()
   END End;
 
   PROCEDURE Parse*;
-    VAR val: BOOLEAN; s: Selector;
+    VAR val: BOOLEAN; s: Selector; use: BOOLEAN;
   BEGIN
-    Get(sym);
+    ch := " "; Get(sym); use := ~skip;
     IF sym = new THEN
       Get(sym);
-      IF sym = ident THEN s := New(name, FALSE); Get(sym)
+      IF sym = ident THEN
+        IF use THEN s := New(name) END; Get(sym);
+        IF (sym = plus) OR (sym = minus) THEN
+          IF use THEN s.val := sym = plus END; Get(sym)
+        END
       ELSE err(48)
       END
     ELSIF sym = ident THEN
-      Get(sym);
-      IF sym = plus THEN Old(name).val := TRUE; Get(sym)
-      ELSIF sym = minus THEN Old(name).val := FALSE; Get(sym)
+      IF use THEN s := Old(name) END; Get(sym);
+      IF (sym = plus) OR (sym = minus) THEN
+        IF use THEN s.val := sym = plus END; Get(sym)
       ELSE err(41)
       END
+    ELSIF sym = error THEN
+      IF use THEN err(501) END; Get(sym)
     ELSIF sym = if THEN
-      Get(sym); Expression(val); If(val);
+      Get(sym); Expression(val, use); If(val);
       IF sym = then THEN Get(sym)
       ELSE err(27)
       END
     ELSIF sym = elsif THEN
       IF fold <= 1 THEN err(14) END; (* ELSIF without IF *)
-      Else; Get(sym); Expression(val); If(val); INC(top.ref);
+      Else; Get(sym); Expression(val, use); If(val); INC(top.ref);
       IF sym = then THEN Get(sym)
       ELSE err(27)
       END
@@ -238,14 +250,6 @@ MODULE DevCPR;
     IF sym # endcom THEN err(5) ELSE DevCPM.errpos := DevCPM.curpos - 1 END
   END Parse;
 
-  PROCEDURE Printable* (): BOOLEAN;
-    VAR c: Context;
-  BEGIN
-    c := top;
-    WHILE (c # NIL) & c.val DO c := c.next END;
-    RETURN c = NIL
-  END Printable;
-
   PROCEDURE Check*;
   BEGIN
     IF fold # 1 THEN err(14) END
@@ -254,7 +258,8 @@ MODULE DevCPR;
   PROCEDURE Close*;
   BEGIN
     ch := " "; sym := eof; name := "";
-    fold := 0; top := NIL; scope := NIL
+    fold := 0; top := NIL; scope := NIL;
+    skip := FALSE
   END Close;
 
   PROCEDURE Init*;
@@ -263,9 +268,8 @@ MODULE DevCPR;
     Close;
     If(TRUE);
     NEW(scope);
-    s := New("TRUE", TRUE);
-    s := New("FALSE", FALSE);
-    s := New("DEFINED", FALSE); s.num := defined
+    Set("TRUE", TRUE);
+    Set("FALSE", FALSE)
   END Init;
 
 END DevCPR.