Last active
October 8, 2015 11:01
-
-
Save hsk/621b37cd826b17796318 to your computer and use it in GitHub Desktop.
calc.ml
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
type c = | |
| Int of int | |
| Add | |
| Sub | |
| Load of string | |
| Save of string | |
| Ret | |
let rec lookup e v = | |
match e with | |
| [] -> assert false | |
| (a,r)::e when a = v -> r | |
| _::e -> lookup e v | |
let rec sec = function | |
| (a::s,e,Ret::c) -> a | |
| (s,e,Int i::c) -> sec(i::s, e, c) | |
| (a::b::s,e,Add::c) -> sec(a+b::s,e,c) | |
| (a::b::s,e,Sub::c) -> sec(a-b::s,e,c) | |
| (a::s,e,Save(v)::c) -> sec(s,(v,a)::e,c) | |
| (s,e,Load(v)::c) -> sec(lookup e v::s,e,c) | |
| _ -> assert false | |
let _ = | |
Printf.printf "%d\n" (sec([],[],[Int 1;Int 2; Add; Save("a"); Int 10; Int 20; Sub; Save("b"); Load("a"); Load("b"); Add; Ret])) | |
type e = | |
| EInt of int | |
| EVar of string | |
| EAdd of e * e | |
| ESub of e * e | |
| ELet of string * e * e | |
let rec comp = function | |
| EInt i -> [Int i] | |
| EVar s -> [Load s] | |
| EAdd(a,b) -> comp b @ comp a @ [Add] | |
| ESub(a,b) -> comp b @ comp a @ [Sub] | |
| ELet(s,a,b) -> comp a @ Save s :: comp b | |
let compile e = comp e @ [Ret] | |
let _ = | |
Printf.printf "%d\n" (sec([],[], compile( | |
ELet("a", EAdd(EInt 1, EInt 2), | |
ELet("b", ESub(EInt 20,EInt 10), | |
EAdd(EVar("a"),EVar("b")))) ))) | |
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
let rec lookup e v = | |
match e with | |
| [] -> assert false | |
| (a,r)::e when a = v -> r | |
| _::e -> lookup e v | |
type e = | |
| EInt of int | |
| EVar of string | |
| EAdd of e * e | |
| ESub of e * e | |
| ELet of string * e * e | |
let rec eval env = function | |
| EInt i -> i | |
| EVar s -> lookup env s | |
| EAdd(a,b) -> eval env a + eval env b | |
| ESub(a,b) -> eval env a - eval env b | |
| ELet(s,a,b) -> eval ((s, eval env a)::env) b | |
let _ = | |
Printf.printf "%d\n" (eval [] ( | |
ELet("a", EAdd(EInt 1, EInt 2), | |
ELet("b", ESub(EInt 20,EInt 10), | |
EAdd(EVar("a"),EVar("b")))) )) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment