Compiler/AST interpreter: Difference between revisions
Content added Content deleted
m (→{{header|Python}}: added zkl) |
(→{{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 |
|||
⚫ | |||
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 |
|||
⚫ | |||
<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 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> |