84 lines
3.2 KiB
Plaintext
84 lines
3.2 KiB
Plaintext
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 {Interpret Tokens}
|
|
fun {Aux Tokens Stack} % create auxiliary function to surrogate the stack
|
|
case Tokens of
|
|
nil then Stack
|
|
[] number(N)|Tail then
|
|
{Aux Tail N|Stack}
|
|
[] operator(type:Op)|Tail then % operators are binary (arity 2)
|
|
case Stack of X|Y|StackTail then
|
|
{Aux 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 % arity 1
|
|
case Stack of X|StackTail then
|
|
{Aux Tail (case Op
|
|
of duplicate then X|Stack
|
|
[] negate then (~X)|StackTail
|
|
else raise unexpectedOperator end end
|
|
)}
|
|
else raise stackUnderflow end end
|
|
% handle commands separately, as they deal with the stack in unique ways
|
|
[] command(print)|Tail then
|
|
{Show Stack}
|
|
{Aux Tail Stack}
|
|
[] command(clear)|Tail then
|
|
{Aux Tail nil}
|
|
end
|
|
end
|
|
in {Aux Tokens nil} % this is where Interpret starts
|
|
end
|
|
|
|
|
|
% this is just a stripped down Interpret. it resembles the shunting-yard algorithm
|
|
fun {ExpressionTree Tokens}
|
|
fun {ExpressionTreeInternal Tokens ExpressionStack}
|
|
case Tokens of
|
|
nil then ExpressionStack
|
|
[] number(N)|Tail then
|
|
{ExpressionTreeInternal Tail N|ExpressionStack}
|
|
[] operator(type:Op)|Tail then
|
|
case ExpressionStack of X|Y|ExpressionStackTail then
|
|
{ExpressionTreeInternal Tail (case Op
|
|
% return the tree records rather than the arithmetic result of the operators
|
|
of plus then plus(X Y)
|
|
[] minus then minus(X Y)
|
|
[] multiply then multiply(X Y)
|
|
[] divide then divide(X Y)
|
|
else raise unexpectedOperator end end
|
|
)|ExpressionStackTail}
|
|
else raise stackUnderflow end end
|
|
else raise unexpectedToken end end
|
|
end
|
|
in {ExpressionTreeInternal Tokens nil} % this is where ExpressionTree starts
|
|
end
|
|
{Show {Interpret {Tokenize {Lex "3 10 9 * - 7 +"}}}}
|
|
end
|