scope and comparison
This commit is contained in:
parent
3545f2430e
commit
f8628905fe
22
src/exec.ml
22
src/exec.ml
|
|
@ -2,23 +2,31 @@ open Types
|
|||
|
||||
let update m x v = fun y -> if x=y then v else m y
|
||||
|
||||
let rec builtin_iop f =
|
||||
let iop1 m v =
|
||||
match m "", v with
|
||||
| VInt a, VInt b -> EInt (f a b)
|
||||
| _, _ -> raise (Failure "iop: not int") in
|
||||
VFn (builtin, "", EFnB iop1)
|
||||
let rec _builtin_iop: 'a. ('a->exp) -> (int->int->'a) -> value =
|
||||
fun ret f ->
|
||||
let iop1 m v =
|
||||
match m "", v with
|
||||
| VInt a, VInt b -> ret (f a b)
|
||||
| _, _ -> raise (Failure "not int") in
|
||||
VFn (builtin, "", EFnB iop1)
|
||||
and builtin_iop x = _builtin_iop (fun x -> EInt x) x
|
||||
and builtin_cop a = _builtin_iop (fun x -> EBool x) a
|
||||
and builtin_bop f =
|
||||
let bop1 m v =
|
||||
match m "", v with
|
||||
| VBool a, VBool b -> EBool (f a b)
|
||||
| _, _ -> raise (Failure "bop: not bool") in
|
||||
| _, _ -> raise (Failure "not bool") in
|
||||
VFn (builtin, "", EFnB bop1)
|
||||
and builtin = function
|
||||
| "add" -> builtin_iop (+)
|
||||
| "sub" -> builtin_iop (-)
|
||||
| "mul" -> builtin_iop ( * )
|
||||
| "div" -> builtin_iop (/)
|
||||
| "lt" -> builtin_cop (<)
|
||||
| "gt" -> builtin_cop (>)
|
||||
| "ge" -> builtin_cop (>=)
|
||||
| "le" -> builtin_cop (<=)
|
||||
| "eq" -> builtin_cop (=)
|
||||
| "and" -> builtin_bop (&&)
|
||||
| "or" -> builtin_bop (||)
|
||||
| _ -> raise (Failure "undefined var")
|
||||
|
|
|
|||
|
|
@ -6,14 +6,19 @@ rule token = parse
|
|||
{ token lexbuf }
|
||||
| '(' { LPAREN }
|
||||
| ')' { RPAREN }
|
||||
(* | '{' { LBRACE } *)
|
||||
(* | '}' { RBRACE } *)
|
||||
| '{' { LBRACE }
|
||||
| '}' { RBRACE }
|
||||
| ';' { SEMICOLON }
|
||||
| '=' { EQUAL }
|
||||
| '+' { PLUS }
|
||||
| '-' { MINUS }
|
||||
| '*' { TIMES }
|
||||
| '/' { DIVIDE }
|
||||
| '<' { LT }
|
||||
| '>' { GT }
|
||||
| "<=" { LE }
|
||||
| ">=" { GE }
|
||||
| "==" { EQ }
|
||||
| "&&" { AND }
|
||||
| "||" { OR }
|
||||
| "if" { IF }
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
open Types
|
||||
let app2 x a b = EApp (EApp (EVar x, a), b)
|
||||
%}
|
||||
%token LPAREN RPAREN SEMICOLON EQUAL OR AND PLUS MINUS TIMES DIVIDE EOF
|
||||
%token IF THEN ELSE TRUE FALSE FN
|
||||
%token LPAREN RPAREN LBRACE RBRACE SEMICOLON EQUAL OR AND PLUS MINUS TIMES DIVIDE EOF
|
||||
%token IF THEN ELSE TRUE FALSE FN LT GT LE GE EQ
|
||||
%token<int> NUM
|
||||
%token<string> VAR
|
||||
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
%nonassoc TRUE FALSE
|
||||
%left PLUS MINUS
|
||||
%left TIMES DIVIDE
|
||||
%nonassoc LT GT LE GE EQ
|
||||
%nonassoc NUM VAR
|
||||
%right LPAREN RPAREN
|
||||
%nonassoc EOF
|
||||
|
|
@ -48,8 +49,19 @@ parse_exp:
|
|||
{ app2 "mul" $1 $3 }
|
||||
| parse_exp DIVIDE parse_exp
|
||||
{ app2 "div" $1 $3 }
|
||||
| parse_exp LT parse_exp
|
||||
{ app2 "lt" $1 $3 }
|
||||
| parse_exp GT parse_exp
|
||||
{ app2 "gt" $1 $3 }
|
||||
| parse_exp LE parse_exp
|
||||
{ app2 "le" $1 $3 }
|
||||
| parse_exp GE parse_exp
|
||||
{ app2 "ge" $1 $3 }
|
||||
| parse_exp EQ parse_exp
|
||||
{ app2 "eq" $1 $3 }
|
||||
| FN VAR parse_exp
|
||||
{ EFn ($2,$3) }
|
||||
| LBRACE parse_stmt RBRACE { EScope $2 }
|
||||
|
||||
exp:
|
||||
| NUM { EInt $1 }
|
||||
|
|
|
|||
Loading…
Reference in a new issue