Compiler/AST interpreter: Difference between revisions

Content added Content deleted
(→‎{{header|zkl}}: added code)
Line 626: Line 626:


=={{header|zkl}}==
=={{header|zkl}}==
<lang zkl>const{ var _n=-1; var[proxy]N=fcn{ _n+=1 }; } // enumerator
<lang zkl></lang>
const FETCH=N, STORE=N, PUSH=N, ADD=N, SUB=N, MUL=N, DIV=N, MOD=N,
<lang zkl></lang>
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
}</lang>
<lang zkl>fcn load_ast(file){
line:=file.readln().strip(); // one or two tokens
if(line[0]==";") return(Void);
parts,type,value := line.split(),parts[0],parts[1,*].concat(" ");
type=all_syms[type];
if(value){
try{ value=value.toInt() }catch{}
if(type==nd_String) value=value[1,-1].replace("\\n","\n");
return(Node(type,value));
}
left,right := load_ast(file),load_ast(file);
Node(type,Void,left,right)
}</lang>
<lang zkl>ast:=load_ast(File(vm.nthArg(0)));
runNode(ast);</lang>
{{out}}
{{out}}
<pre>
<pre>
$ zkl runAST.zkl primeAST.txt
3 is prime
5 is prime
7 is prime
11 is prime
...
89 is prime
97 is prime
101 is prime
Total primes found: 26
</pre>
</pre>