s/BUILTINOP = (IFOP,/BUILTINOP = (IFOP,LOADOP,/ /^ currentExp: EXP;/{N;N;N;N;d;} /end; (\* mkEnv \*)/a\ \ (* emptyEnv - return an environment with no bindings *)\ function emptyEnv: ENV;\ begin\ \ emptyEnv := mkEnv(nil, nil)\ end; (* emptyEnv *) /printNames\[i\] := 'if '; i := i+1;/a\ \ printNames[i] := 'load '; i := i+1; / \* INPUT \*/{ n a\ \ (* r_e_p_l is the read-eval-print loop. It needs the following variables\ \ because recursive calls need to pick up in the input where we left off *)\ procedure r_e_p_l(var infile: text);\ var\ \ userinput: array [1..MAXINPUT] of char;\ \ inputleng, pos: 0..MAXINPUT;\ \ currentExp: EXP;\ \ infile_all_read: Boolean; } /^procedure reader;/s/procedure reader;/procedure reader (var infile: text);/ s/read(c)/read(infile,c)/ s/eoln/eoln(infile)/ s/until eoln(infile);/until (eof(infile) or eoln(infile));/ s/until pos <= inputleng/until (pos <= inputleng) or eof(infile)/ /(\* emptyEnv - return an environment with no bindings \*)/{ N;N;N;N;N;d;} /(\* applyCtrlOp - apply CONTROLOP op to args in rho \*)/i\ (* loadfile - evaluate the expressions in the given file (for side effects).\ \ The file name is taken as a variable name.\ \ E.g., (load foo/bar) loads from the file named "foo/bar".\ \ This limits file names to NAMELENG chars. *)\ \ function loadfile (fn: EXP): NUMBER; (* EDIT THIS *)\ \ var\ \ ldfile: text;\ \ begin\ \ write('starting to read from ');\ \ writeln(printNames[fn^.varble]);\ \ \ reset(ldfile, printNames[fn^.varble]); (* no error checking... *)\ \ r_e_p_l(ldfile);\ \ close(ldfile);\ \ \ write('done reading from ');\ \ writeln(printNames[fn^.varble]);\ \ \ (* the rest is to construct the appropriate return value *)\ \ (* EDIT THIS *)\ \ loadfile := 0;\ \ end; (* loadfile *)\ /IFOP:/i\ \ LOADOP:\ \ applyCtrlOp := loadfile(head); / \* READ-EVAL-PRINT LOOP \*/{ n a\ \ begin (* r_e_p_l *)\ \ infile_all_read := false;\ \ while not quittingtime and not infile_all_read do begin\ \ reader(infile);\ \ if (userinput[pos] = COMMENTCHAR)\ \ then infile_all_read := true\ \ else if matches(pos, 4, 'quit ')\ \ then quittingtime := true\ \ else if (userinput[pos] = '(') and\ \ matches(skipblanks(pos+1), 6, 'define ')\ \ then begin\ \ prName(parseDef);\ \ writeln\ \ end\ \ else begin\ \ currentExp := parseExp;\ \ prValue(eval(currentExp, emptyEnv));\ \ writeln;\ \ writeln\ \ end\ \ (* infile_all_read = eof(infile) *)\ \ end; (* while *)\ \end; (* r_e_p_l *) } /while not quittingtime do begin/a\ \ r_e_p_l(input);\ \ end (* while *)\ end.\ (* check that the body of r_e_p_l matches above, then delete what follows\ \ EDIT THIS \ \ $a\ *)