59 lines
1.9 KiB
Plaintext
59 lines
1.9 KiB
Plaintext
\insert './List.oz'
|
|
|
|
local
|
|
fun {Lex Input}
|
|
{String.tokens Input & }
|
|
end
|
|
|
|
fun {Tokenize Lexemes}
|
|
case Lexemes of Head|Tail then
|
|
(case Head
|
|
of "+" then operator(type:plus)
|
|
[] "-" then operator(type:minus)
|
|
[] "*" then operator(type:multiply)
|
|
[] "/" then operator(type:divide)
|
|
[] "d" then unary(type:duplicate)
|
|
[] "i" then unary(type:negate)
|
|
[] "p" then command(print)
|
|
[] "c" then command(clear)
|
|
else number({String.toInt Head}) end
|
|
)|{Tokenize Tail}
|
|
else nil end
|
|
end
|
|
|
|
fun {InterpretAux Tokens Stack}
|
|
case Tokens of
|
|
nil then Stack
|
|
[] number(N)|Tail then
|
|
{InterpretAux Tail N|Stack}
|
|
[] operator(type:Op)|Tail then
|
|
case Stack of Y|X|StackTail then
|
|
{InterpretAux Tail (case Op
|
|
of plus then X + Y
|
|
[] minus then X - Y
|
|
[] multiply then X * Y
|
|
[] divide then X div Y
|
|
else raise unexpectedOperator end end
|
|
)|StackTail}
|
|
else raise stackUnderflow end end
|
|
[] unary(type:Op)|Tail then
|
|
case Stack of X|StackTail then
|
|
{InterpretAux Tail (case Op
|
|
of duplicate then X|Stack
|
|
[] negate then (~X)|StackTail
|
|
else raise unexpectedOperator end end
|
|
)}
|
|
else raise stackUnderflow end end
|
|
[] command(print)|Tail then
|
|
{Show Stack}
|
|
{InterpretAux Tail Stack}
|
|
[] command(clear)|Tail then
|
|
{InterpretAux Tail nil}
|
|
end
|
|
end
|
|
|
|
fun {Interpret Tokens}
|
|
{InterpretAux Tokens nil}
|
|
end
|
|
{Show {Interpret {Tokenize {Lex "4 2 /"}}}}
|
|
end |