DEADSOFTWARE

fix directive/expression interpretation in false blocks
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Sat, 14 Dec 2019 21:26:24 +0000 (00:26 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Sat, 14 Dec 2019 21:26:24 +0000 (00:26 +0300)
src/generic/Dev/Mod/CPR.cp
src/generic/Dev/Mod/CPS.odc

index b1787397516a9f973992d5c622f678c85bc985c4..7791454cd607538d29b831f4d9ef1532a24fe4c3 100644 (file)
@@ -35,6 +35,7 @@ MODULE DevCPR;
     fold: INTEGER; (* condition folding *)
     scope: Selector;
     top: Context;
+    skip-: BOOLEAN;
 
   PROCEDURE err (n: SHORTINT);
   BEGIN DevCPM.err(n)
@@ -123,18 +124,19 @@ MODULE DevCPR;
     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);
+  PROCEDURE Factor (VAR x: BOOLEAN; use: BOOLEAN);
   BEGIN
+    x := FALSE;
     IF sym = ident THEN
-      x := Old(name).val; Get(sym);
+      IF use THEN x := Old(name).val END; Get(sym);
     ELSIF sym = defined THEN
       Get(sym);
       IF sym = lpar THEN
         Get(sym);
         IF sym = ident THEN
-          x := Find(name) # NIL;
+          IF use THEN x := Find(name) # NIL END;
           Get(sym)
         ELSE err(48)
         END;
@@ -144,47 +146,54 @@ MODULE DevCPR;
       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
-      x := FALSE;
       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); IF use 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); IF use 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;
 
@@ -193,46 +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 Printable* (): BOOLEAN;
-    VAR c: Context;
-  BEGIN
-    c := top;
-    WHILE (c # NIL) & c.val DO c := c.next END;
-    RETURN c = NIL
-  END Printable;
-
   PROCEDURE Parse*;
-    VAR val: BOOLEAN; s: Selector;
+    VAR val: BOOLEAN; s: Selector; use: BOOLEAN;
   BEGIN
-    ch := " "; Get(sym);
+    ch := " "; Get(sym); use := ~skip;
     IF sym = new THEN
       Get(sym);
       IF sym = ident THEN
-        s := New(name); Get(sym);
+        IF use THEN s := New(name) END; Get(sym);
         IF (sym = plus) OR (sym = minus) THEN
-          s.val := sym = plus; Get(sym)
+          IF use THEN s.val := sym = plus END; Get(sym)
         END
       ELSE err(48)
       END
     ELSIF sym = ident THEN
-      s := Old(name); Get(sym);
+      IF use THEN s := Old(name) END; Get(sym);
       IF (sym = plus) OR (sym = minus) THEN
-        s.val := sym = plus; Get(sym)
+        IF use THEN s.val := sym = plus END; Get(sym)
       ELSE err(41)
       END
     ELSIF sym = error THEN
-      IF Printable() THEN err(501) END; Get(sym)
+      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
@@ -256,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*;
index 3670f1835ba017505235d5584b5e2bab31387b53..615ec6aa2943f1c3416bb512ceb6128dfa909726 100644 (file)
Binary files a/src/generic/Dev/Mod/CPS.odc and b/src/generic/Dev/Mod/CPS.odc differ