X-Git-Url: https://deadsoftware.ru/gitweb?p=cpc.git;a=blobdiff_plain;f=src%2Fgeneric%2FDev%2FMod%2FCPR.cp;h=b3ef0524cb2474b2bafbbd6249c362ad5c3dac04;hp=b43b539bd2beebe3747961b7bd2aa1acb037a02e;hb=d04c6367a927c536552ae595c92cc15347d3a65f;hpb=e52a3df8538aa38dde9851e00b98b0cffe3c6750 diff --git a/src/generic/Dev/Mod/CPR.cp b/src/generic/Dev/Mod/CPR.cp index b43b539..b3ef052 100644 --- a/src/generic/Dev/Mod/CPR.cp +++ b/src/generic/Dev/Mod/CPR.cp @@ -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.