scope and comparison

This commit is contained in:
caandt 2026-05-09 13:14:37 -05:00
parent 3545f2430e
commit f8628905fe
3 changed files with 36 additions and 11 deletions

View file

@ -2,23 +2,31 @@ open Types
let update m x v = fun y -> if x=y then v else m y let update m x v = fun y -> if x=y then v else m y
let rec builtin_iop f = let rec _builtin_iop: 'a. ('a->exp) -> (int->int->'a) -> value =
let iop1 m v = fun ret f ->
match m "", v with let iop1 m v =
| VInt a, VInt b -> EInt (f a b) match m "", v with
| _, _ -> raise (Failure "iop: not int") in | VInt a, VInt b -> ret (f a b)
VFn (builtin, "", EFnB iop1) | _, _ -> 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 = and builtin_bop f =
let bop1 m v = let bop1 m v =
match m "", v with match m "", v with
| VBool a, VBool b -> EBool (f a b) | VBool a, VBool b -> EBool (f a b)
| _, _ -> raise (Failure "bop: not bool") in | _, _ -> raise (Failure "not bool") in
VFn (builtin, "", EFnB bop1) VFn (builtin, "", EFnB bop1)
and builtin = function and builtin = function
| "add" -> builtin_iop (+) | "add" -> builtin_iop (+)
| "sub" -> builtin_iop (-) | "sub" -> builtin_iop (-)
| "mul" -> builtin_iop ( * ) | "mul" -> builtin_iop ( * )
| "div" -> builtin_iop (/) | "div" -> builtin_iop (/)
| "lt" -> builtin_cop (<)
| "gt" -> builtin_cop (>)
| "ge" -> builtin_cop (>=)
| "le" -> builtin_cop (<=)
| "eq" -> builtin_cop (=)
| "and" -> builtin_bop (&&) | "and" -> builtin_bop (&&)
| "or" -> builtin_bop (||) | "or" -> builtin_bop (||)
| _ -> raise (Failure "undefined var") | _ -> raise (Failure "undefined var")

View file

@ -6,14 +6,19 @@ rule token = parse
{ token lexbuf } { token lexbuf }
| '(' { LPAREN } | '(' { LPAREN }
| ')' { RPAREN } | ')' { RPAREN }
(* | '{' { LBRACE } *) | '{' { LBRACE }
(* | '}' { RBRACE } *) | '}' { RBRACE }
| ';' { SEMICOLON } | ';' { SEMICOLON }
| '=' { EQUAL } | '=' { EQUAL }
| '+' { PLUS } | '+' { PLUS }
| '-' { MINUS } | '-' { MINUS }
| '*' { TIMES } | '*' { TIMES }
| '/' { DIVIDE } | '/' { DIVIDE }
| '<' { LT }
| '>' { GT }
| "<=" { LE }
| ">=" { GE }
| "==" { EQ }
| "&&" { AND } | "&&" { AND }
| "||" { OR } | "||" { OR }
| "if" { IF } | "if" { IF }

View file

@ -2,8 +2,8 @@
open Types open Types
let app2 x a b = EApp (EApp (EVar x, a), b) let app2 x a b = EApp (EApp (EVar x, a), b)
%} %}
%token LPAREN RPAREN SEMICOLON EQUAL OR AND PLUS MINUS TIMES DIVIDE EOF %token LPAREN RPAREN LBRACE RBRACE SEMICOLON EQUAL OR AND PLUS MINUS TIMES DIVIDE EOF
%token IF THEN ELSE TRUE FALSE FN %token IF THEN ELSE TRUE FALSE FN LT GT LE GE EQ
%token<int> NUM %token<int> NUM
%token<string> VAR %token<string> VAR
@ -14,6 +14,7 @@
%nonassoc TRUE FALSE %nonassoc TRUE FALSE
%left PLUS MINUS %left PLUS MINUS
%left TIMES DIVIDE %left TIMES DIVIDE
%nonassoc LT GT LE GE EQ
%nonassoc NUM VAR %nonassoc NUM VAR
%right LPAREN RPAREN %right LPAREN RPAREN
%nonassoc EOF %nonassoc EOF
@ -48,8 +49,19 @@ parse_exp:
{ app2 "mul" $1 $3 } { app2 "mul" $1 $3 }
| parse_exp DIVIDE parse_exp | parse_exp DIVIDE parse_exp
{ app2 "div" $1 $3 } { 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 | FN VAR parse_exp
{ EFn ($2,$3) } { EFn ($2,$3) }
| LBRACE parse_stmt RBRACE { EScope $2 }
exp: exp:
| NUM { EInt $1 } | NUM { EInt $1 }