MODULE ConsInterp; (* A. V. Shiryaev, 2012.09 *) IMPORT Console, Strings, Dialog, DevCommanders, TextModels, StdLog; VAR textR: TextModels.Reader; PROCEDURE ShowStdLog; VAR c: CHAR; BEGIN StdLog.text.Append(StdLog.buf); textR.SetPos(0); textR.ReadChar(c); WHILE ~textR.eot DO IF c = 0DX THEN Console.WriteLn ELSE Console.WriteChar(c) END; textR.ReadChar(c) END; StdLog.text.Delete(0, StdLog.text.Length()) END ShowStdLog; PROCEDURE Call1 (IN s: ARRAY OF CHAR; i: INTEGER): BOOLEAN; VAR j: INTEGER; res: INTEGER; par: DevCommanders.Par; m: TextModels.Model; w: TextModels.Writer; BEGIN (* ASSERT 0X in s[ i:LEN(s) ) *) j := i; WHILE s[j] # 0X DO INC(j) END; IF j > i THEN m := TextModels.dir.New(); w := m.NewWriter(NIL); WHILE i < j DO w.WriteChar(s[i]); INC(i) END; NEW(par); par.text := m; par.beg := 0; par.end := m.Length() - 1; DevCommanders.par := par END; Dialog.Call(s, " ", res); DevCommanders.par := NIL; ShowStdLog; RETURN res = 0 END Call1; PROCEDURE Call0 (VAR s: ARRAY OF CHAR): BOOLEAN; VAR i: INTEGER; res: BOOLEAN; inStr: BOOLEAN; BEGIN (* ASSERT s is 0X terminated and not empty *) i := 0; WHILE (s[i] # 0X) & (s[i] # ' ') & (s[i] # '(') DO INC(i) END; IF s[i] = 0X THEN res := Call1(s, i) ELSIF s[i] = ' ' THEN s[i] := 0X; res := Call1(s, i + 1) ELSE (* s[i] = '(' *) INC(i); inStr := FALSE; WHILE (s[i] # 0X) & ~(~inStr & (s[i] = ')')) DO IF s[i] = "'" THEN inStr := ~inStr END; INC(i) END; IF s[i] # 0X THEN INC(i); IF s[i] = 0X THEN res := Call1(s, i) ELSE s[i] := 0X; res := Call1(s, i + 1) END ELSE res := FALSE END END; RETURN res END Call0; PROCEDURE Call (VAR s: ARRAY OF CHAR): BOOLEAN; VAR i: INTEGER; res: BOOLEAN; BEGIN i := 0; WHILE (i < LEN(s)) & (s[i] # 0AX) & (s[i] # 0DX) & (s[i] # 0X) DO INC(i) END; IF (i < LEN(s)) & (s[i] # 0X) THEN IF (i > 0) & (s[0] # '#') THEN s[i] := 0X; res := Call0(s) ELSE (* skip empty strings and comments *) res := TRUE END ELSE (* end of input *) res := FALSE END; RETURN res END Call; PROCEDURE Run*; VAR s: ARRAY 1024 OF CHAR; BEGIN Console.ReadLn(s); WHILE Call(s) DO Console.ReadLn(s) END END Run; BEGIN textR := StdLog.text.NewReader(NIL) END ConsInterp.