Created
October 12, 2025 17:52
-
-
Save swatson555/698f8b97581c2199ec4ea3fd60c19f06 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* A tiger program that evaluates a lisp program. | |
| */ | |
| let type tokens = { head: string, tail: tokens } | |
| function stridx (input: string, i: int): string = | |
| substring (input,i,1) | |
| function numeric (s : string): int = | |
| ord (s) >= ord ("0") & ord (s) <= ord ("9") | ord (s) = ord ("-") | |
| function atoi (str: string): int = | |
| let var start := stridx (str, 0) = "-" | |
| var val := 0 | |
| in for i := start to size (str)-1 | |
| do val := val * 10 + ord(stridx (str, i)) - ord("0"); | |
| if start = 1 | |
| then -val | |
| else val | |
| end | |
| function analyze (input: string): tokens = | |
| let function loop (i: int): tokens = | |
| if i = size(input) | |
| then nil | |
| else if stridx (input, i) = " " | |
| then loop (i+1) | |
| else if stridx (input, i) = "(" | |
| then tokens { head="(", tail=loop(i+1) } | |
| else if stridx (input, i) = ")" | |
| then tokens { head=")", tail=loop(i+1) } | |
| else let var n := i | |
| in while size(input) <> i & | |
| stridx (input, i) <> "(" & | |
| stridx (input, i) <> ")" & | |
| stridx (input, i) <> " " | |
| do i := i+1; | |
| tokens { head=substring (input,n,i-n), tail=loop(i) } | |
| end | |
| in loop (0) | |
| end | |
| type list = { head: exp, tail: list } | |
| type exp = { id: string, pair: list } | |
| function read (program: tokens): exp = | |
| let var begin := program | |
| function eat (): string = | |
| let var token := begin.head | |
| in begin := begin.tail; | |
| token | |
| end | |
| function peek (): string = | |
| begin.head | |
| function exp (): exp = | |
| let var tok := eat () | |
| in if tok = "(" | |
| then exp { id="", pair=list () } | |
| else exp { id=tok, pair=nil } | |
| end | |
| function list (): list = | |
| let var tok := peek () | |
| in if tok = ")" | |
| then (eat (); nil) | |
| else list { head=exp (), tail=list () } | |
| end | |
| in exp () | |
| end | |
| function readin (): string = | |
| let var buffer := getchar () | |
| var text := "" | |
| in while buffer<>"\n" | |
| do (text := concat (text, buffer); | |
| buffer := getchar ()); | |
| text | |
| end | |
| function display (i: int) = | |
| let function f (i: int) = | |
| if i > 0 | |
| then (f( i/10); print (chr (i-i/10*10+ord ("0")))) | |
| in if i < 0 | |
| then (print ("-"); f (-i)) | |
| else if i > 0 | |
| then f (i) | |
| else print ("0") | |
| end | |
| type env = { entry: binding, tail: env } | |
| type binding = { id: string, value: int } | |
| var top: env := nil | |
| function put (id: string, val: int) = | |
| top := env { entry=binding { id=id, value=val }, tail=top } | |
| function get (id: string): int = | |
| let function search (env: env): int = | |
| if env.entry.id = id | |
| then env.entry.value | |
| else search (env.tail) | |
| in search (top) | |
| end | |
| function eval (e: exp): int = | |
| if numeric (e.id) | |
| then atoi (e.id) | |
| else if e.id <> "" | |
| then get (e.id) | |
| else if e.pair.head.id = "+" | |
| then eval (e.pair.tail.head) + eval (e.pair.tail.tail.head) | |
| else if e.pair.head.id = "-" | |
| then eval (e.pair.tail.head) - eval (e.pair.tail.tail.head) | |
| else if e.pair.head.id = "*" | |
| then eval (e.pair.tail.head) * eval (e.pair.tail.tail.head) | |
| else if e.pair.head.id = "/" | |
| then eval (e.pair.tail.head) / eval (e.pair.tail.tail.head) | |
| else if e.pair.head.id = "set!" | |
| then (put (e.pair.tail.head.id, eval (e.pair.tail.tail.head)); 1) | |
| else 0 | |
| function repl () = | |
| (print (">> "); | |
| display (eval (read (analyze (readin ())))); | |
| print ("\n")) | |
| in while 1 | |
| do repl () | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment