{{task heading|AST interpreter}} An AST interpreter interprets an [https://en.wikipedia.org/wiki/Abstract_syntax_tree Abstract Syntax Tree (AST)] produced by a [[Compiler/syntax_analyzer|Syntax Analyzer]]. ;Task Take the AST output from the Syntax analyzer [[Compiler/syntax_analyzer|task]], and interpret it as appropriate. Refer to the [[Compiler/syntax_analyzer|Syntax analyzer task]] for details of the AST. ;Loading the AST from the syntax analyzer is as simple as (pseudo code): def load_ast() line = readline() # Each line has at least one token line_list = tokenize the line, respecting double quotes text = line_list[0] # first token is always the node type if text == ";" # a terminal node return NULL node_type = text # could convert to internal form if desired # A line with two tokens is a leaf node # Leaf nodes are: Identifier, Integer, String # The 2nd token is the value if len(line_list) > 1 return make_leaf(node_type, line_list[1]) left = load_ast() right = load_ast() return make_node(node_type, left, right) ; The interpreter algorithm is relatively simple: interp(x) if x == NULL return NULL elif x.node_type == Integer return x.value converted to an integer elif x.node_type == Ident return the current value of variable x.value elif x.node_type == String return x.value elif x.node_type == Assign globals[x.left.value] = interp(x.right) return NULL elif x.node_type is a binary operator return interp(x.left) operator interp(x.right) elif x.node_type is a unary operator, return return operator interp(x.left) elif x.node_type == If if (interp(x.left)) then interp(x.right.left) else interp(x.right.right) return NULL elif x.node_type == While while (interp(x.left)) do interp(x.right) return NULL elif x.node_type == Prtc print interp(x.left) as a character, no newline return NULL elif x.node_type == Prti print interp(x.left) as an integer, no newline return NULL elif x.node_type == Prts print interp(x.left) as a string, respecting newlines ("\n") return NULL elif x.node_type == Sequence interp(x.left) interp(x.right) return NULL else error("unknown node type") Notes: Because of the simple nature of our tiny language, Semantic analysis is not needed. Your interpreter should use C like division semantics, for both division and modulus. For division of positive operands, only the non-fractional portion of the result should be returned. In other words, the result should be truncated towards 0. This means, for instance, that 3 / 2 should result in 1. For division when one of the operands is negative, the result should be truncated towards 0. This means, for instance, that 3 / -2 should result in -1. ; Test program {| class="wikitable" |- ! prime.t ! lex <prime.t | parse | interp |- | style="vertical-align:top" | /* Simple prime number generator */ count = 1; n = 1; limit = 100; while (n < limit) { k=3; p=1; n=n+2; while ((k*k<=n) && (p)) { p=n/k*k!=n; k=k+2; } if (p) { print(n, " is prime\n"); count = count + 1; } } print("Total primes found: ", count, "\n"); | style="vertical-align:top" |
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime
31 is prime
37 is prime
41 is prime
43 is prime
47 is prime
53 is prime
59 is prime
61 is prime
67 is prime
71 is prime
73 is prime
79 is prime
83 is prime
89 is prime
97 is prime
101 is prime
Total primes found: 26
|} ; Additional examples Your solution should pass all the test cases above and the additional tests found '''[[Compiler/Sample_programs|Here]]'''. {{task heading|Reference}} The C and Python versions can be considered reference implementations. ;Related Tasks * [[Compiler/lexical_analyzer|Lexical Analyzer task]] * [[Compiler/syntax_analyzer|Syntax Analyzer task]] * [[Compiler/code_generator|Code Generator task]] * [[Compiler/virtual_machine_interpreter|Virtual Machine Interpreter task]]
__TOC__