Eval:
PROC [symTab: SymTab.Ref, expr:
ROPE]
RETURNS [AMTypes.
TV] =
BEGIN
tv: AMTypes.TV;
none: BOOL;
err: ROPE;
[tv, err, none] ← Interpreter.Evaluate[rope: expr, symTab: symTab];
IF err #
NIL
THEN
ERROR Error[CouldNotEval, Rope.Cat["Could not evaluate '", expr, "', error was '", err, "'."]]
ELSE
IF none
THEN
ERROR Error[NoValue, Rope.Cat["Expression '", expr, "' did not return a value."]];
RETURN [tv];
END;
Assign:
PUBLIC
PROC [symTab: SymTab.Ref, line:
ROPE]
RETURNS [
BOOL] =
BEGIN
var, expr: ROPE;
start, end, operatorPos: INT;
operator: CHAR;
tv: AMTypes.TV;
TrimWhite:
PROC [in:
ROPE]
RETURNS [
ROPE] =
BEGIN
i, j: INT;
i ← Rope.SkipOver[in, 0, whiteSpace];
FOR j ← Rope.Length[in] - 1, j ← j - 1
WHILE j >= 0
DO
ch: CHAR ← Rope.Fetch[in, j];
IF ch # ' AND ch # '\n AND ch # '\t THEN EXIT;
ENDLOOP;
RETURN [IF j < i THEN "" ELSE Rope.Substr[in, i, j - i + 1]];
END;
operatorPos ← Rope.SkipTo[line, 0, "←~="];
IF operatorPos = Rope.Length[line]
THEN
ERROR Error[Syntax, Rope.Cat["No '←', '=', or '~' operator in '", line, "', evaluation not done."]];
operator ← Rope.Fetch[line, operatorPos];
IF operatorPos = Rope.Length[line] - 1
THEN
ERROR Error[Syntax, Rope.Cat["Empty expression in '", line, "', assignment not done."]];
expr ← Rope.Substr[line, operatorPos + 1, Rope.Length[line] - operatorPos];
-- evaluate RHS unless ~ (store as ROPE)
tv ← IF operator = '← THEN Eval[symTab, expr] ELSE TVFromRef[NEW [ROPE ← TrimWhite[expr]]];
-- parse the destination
var ← Rope.Substr[line, 0, operatorPos];
start ← Rope.SkipOver[var, 0, whiteSpace];
end ← Rope.SkipTo[var, 0, whiteSpace];
IF (end + 1 < Rope.Length[var])
AND (Rope.SkipOver[var, end + 1, whiteSpace] # Rope.Length[var])
THEN
ERROR Error[Syntax, Rope.Cat["Variable '", var, "' is malformed, assignment not done."]];
-- add into table
var ← Rope.Substr[var, start, end - start];
RETURN [SymTab.Store[symTab, var, tv]];
ReadStream:
PUBLIC
PROC [stream:
IO.
STREAM]
RETURNS [symTab: SymTab.Ref] =
BEGIN
symTab ← SymTab.Create[37];
DO
EOF: BOOL ← FALSE;
i: INT;
line: ROPE;
line ← stream.GetLineRope[ ! IO.EndOfStream => {EOF ← TRUE; CONTINUE}];
IF EOF THEN EXIT;
i ← Rope.SkipOver[line, 0, whiteSpace];
IF i = Rope.Length[line] THEN LOOP;
IF Rope.Fetch[line, i] = '- AND i+1 < Rope.Length[line] AND Rope.Fetch[line, i+1] = '- THEN LOOP;
[] ← Assign[symTab, line];
ENDLOOP;
END;
ReadFile:
PUBLIC
PROC [fileName:
ROPE]
RETURNS [symTab: SymTab.Ref] =
BEGIN
file: IO.STREAM ← NIL;
msg: ROPE ← NIL;
file ← FS.StreamOpen[fileName !FS.Error => IF error.group = user THEN {
msg ← error.explanation; CONTINUE }];
IF msg # NIL THEN ERROR Error[FileError, msg];
RETURN [ReadStream[file]];
END;