From: DeaDDooMER Date: Sat, 14 Dec 2019 21:26:24 +0000 (+0300) Subject: fix directive/expression interpretation in false blocks X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=5adfcb4517689a90c7640ff2add9761ba042677a;p=cpc.git fix directive/expression interpretation in false blocks --- diff --git a/src/generic/Dev/Mod/CPR.cp b/src/generic/Dev/Mod/CPR.cp index b178739..7791454 100644 --- a/src/generic/Dev/Mod/CPR.cp +++ b/src/generic/Dev/Mod/CPR.cp @@ -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*; diff --git a/src/generic/Dev/Mod/CPS.odc b/src/generic/Dev/Mod/CPS.odc index 3670f18..615ec6a 100644 Binary files a/src/generic/Dev/Mod/CPS.odc and b/src/generic/Dev/Mod/CPS.odc differ