structure MyC = struct structure MyCLrVals = MyCLrValsFun(structure Token = LrParser.Token) structure MyCLex = MyCLexFun(structure Tokens = MyCLrVals.Tokens) structure MyCParser = Join(structure LrParser = LrParser structure ParserData = MyCLrVals.ParserData structure Lex = MyCLex) (*** ↓ここから重要ポイント ***) fun lookup x env = env x (* 環境envから変数xの値を探す *) fun update x i env = (* 環境envにおける変数xの値をiにする *) (fn y => if x = y then i else lookup y env) fun exec stmt env = (* 文stmtを環境envの下で実行し、その後の環境を返す *) let fun execs stmts env = (* 文の列stmtsを環境envの下で実行し、その後の環境を返す *) case stmts of [] => env (* 列が空の場合 *) | stmt :: stmts' => (* 列が空でない場合 *) let val env' = exec stmt env in execs stmts' env' end in case stmt of Syntax.Const(x, i) => update x i env | Syntax.Add(x, y, z) => update x (lookup y env + lookup z env) env | Syntax.While(x, y, stmt') => if lookup x env > lookup y env (* 条件が成り立っていたら*) then let val env' = exec stmt' env (* 一回実行 *) in exec stmt env' (* 繰り返し *) end else env (* 条件が成り立っていなければループ終了 *) | Syntax.Seq(stmts) => execs stmts env | Syntax.Print(x) => (print (Int.toString (lookup x env)); print "\n"; env) end (*** ↑ここまで重要ポイント ***) fun print_error (s, _, _) = (print s; print "\n") fun loop env lexer = let val (result, lexer') = MyCParser.parse(0, lexer, print_error, ()) val env' = exec result env val (next, lexer'') = MyCParser.Stream.get lexer' in loop env' lexer'' end val env = fn x => 0 (* すべての変数の値が0の初期環境 *) val lexer = MyCParser.makeLexer (fn _ => valOf (TextIO.inputLine TextIO.stdIn)) fun run () = loop env lexer end