59 lines
2.5 KiB
Text
59 lines
2.5 KiB
Text
const{ var _n=-1; var[proxy]N=fcn{ _n+=1 }; } // enumerator
|
|
const FETCH=N, STORE=N, PUSH=N, ADD=N, SUB=N, MUL=N, DIV=N, MOD=N,
|
|
LT=N, GT=N, LE=N, GE=N, EQ=N, NE=N,
|
|
AND=N, OR=N, NEG=N, NOT=N,
|
|
JMP=N, JZ=N, PRTC=N, PRTS=N, PRTI=N, HALT=N;
|
|
const nd_String=N, nd_Sequence=N, nd_If=N, nd_While=N;
|
|
var [const]
|
|
all_syms=Dictionary(
|
|
"Identifier" ,FETCH, "String" ,nd_String,
|
|
"Integer" ,PUSH, "Sequence" ,nd_Sequence,
|
|
"If" ,nd_If, "Prtc" ,PRTC,
|
|
"Prts" ,PRTS, "Prti" ,PRTI,
|
|
"While" ,nd_While, "Assign" ,STORE,
|
|
"Negate" ,NEG, "Not" ,NOT,
|
|
"Multiply" ,MUL, "Divide" ,DIV,
|
|
"Mod" ,MOD, "Add" ,ADD,
|
|
"Subtract" ,SUB, "Less" ,LT,
|
|
"LessEqual" ,LE, "Greater" ,GT,
|
|
"GreaterEqual",GE, "Equal" ,EQ,
|
|
"NotEqual" ,NE, "And" ,AND,
|
|
"Or" ,OR, "halt" ,HALT),
|
|
bops=Dictionary(ADD,'+, SUB,'-, MUL,'*, DIV,'/, MOD,'%,
|
|
LT,'<, GT,'>, LE,'<=, GE,'>=, NE,'!=, EQ,'==, NE,'!=);
|
|
|
|
class Node{
|
|
fcn init(_node_type, _value, _left=Void, _right=Void){
|
|
var type=_node_type, left=_left, right=_right, value=_value;
|
|
}
|
|
}
|
|
|
|
fcn runNode(node){
|
|
var vars=Dictionary(); // fcn local static var
|
|
if(Void==node) return();
|
|
switch(node.type){
|
|
case(PUSH,nd_String){ return(node.value) }
|
|
case(FETCH){ return(vars[node.value]) }
|
|
case(STORE){ vars[node.left.value]=runNode(node.right); return(Void); }
|
|
case(nd_If){
|
|
if(runNode(node.left)) runNode(node.right.left);
|
|
else runNode(node.right.right);
|
|
}
|
|
case(nd_While)
|
|
{ while(runNode(node.left)){ runNode(node.right) } return(Void) }
|
|
case(nd_Sequence){ runNode(node.left); runNode(node.right); return(Void) }
|
|
case(PRTC) { print(runNode(node.left).toAsc()) }
|
|
case(PRTI,PRTS) { print(runNode(node.left)) }
|
|
case(NEG) { return(-runNode(node.left)) }
|
|
case(NOT) { return(not runNode(node.left)) }
|
|
case(AND) { return(runNode(node.left) and runNode(node.right)) }
|
|
case(OR) { return(runNode(node.left) or runNode(node.right)) }
|
|
else{
|
|
if(op:=bops.find(node.type))
|
|
return(op(runNode(node.left),runNode(node.right)));
|
|
else throw(Exception.AssertionError(
|
|
"Unknown node type: %d".fmt(node.type)))
|
|
}
|
|
}
|
|
Void
|
|
}
|