Move Value module into Env
This commit is contained in:
		
							parent
							
								
									995d95df41
								
							
						
					
					
						commit
						05797676ce
					
				
					 4 changed files with 110 additions and 110 deletions
				
			
		
							
								
								
									
										102
									
								
								ast.ml
									
										
									
									
									
								
							
							
						
						
									
										102
									
								
								ast.ml
									
										
									
									
									
								
							|  | @ -30,6 +30,7 @@ type t = | ||||||
|   | Unary of operator * t |   | Unary of operator * t | ||||||
|   | Binop of t * operator * t |   | Binop of t * operator * t | ||||||
|   | Apply of t * t list (* function application *) |   | Apply of t * t list (* function application *) | ||||||
|  |   (* these will be seperated into (toplevel) directives. *) | ||||||
|   | Set_binop_pre of operator * t |   | Set_binop_pre of operator * t | ||||||
|   | Get_binop_pre of operator |   | Get_binop_pre of operator | ||||||
|   | Set_binop_aso of operator * string |   | Set_binop_aso of operator * string | ||||||
|  | @ -41,49 +42,7 @@ and operator = | ||||||
|   | Exp (* exponentation *) |   | Exp (* exponentation *) | ||||||
|   | Negate |   | Negate | ||||||
| 
 | 
 | ||||||
| exception Invalid_type of Type.t | let op_to_string = function | ||||||
| 
 |  | ||||||
| module Value = struct |  | ||||||
|   type expr = t |  | ||||||
| 
 |  | ||||||
|   type t = |  | ||||||
|   | Int of int |  | ||||||
|   | Float of float |  | ||||||
|   | String of string |  | ||||||
|   | Function of string list * expr |  | ||||||
|   | External of string |  | ||||||
|   | Nop (* return of system operations (will be deprecated) *) |  | ||||||
| 
 |  | ||||||
|   let to_string = function |  | ||||||
|     | Int n -> string_of_int n |  | ||||||
|     | Float n -> string_of_float n |  | ||||||
|     | String s -> "\"" ^ s ^ "\"" |  | ||||||
|     | Function (vars, _) -> |  | ||||||
|       Printf.sprintf "function with %d arguments" @@ List.length vars |  | ||||||
|     | External f -> "external " ^ f |  | ||||||
|     | Nop -> "nop" |  | ||||||
| 
 |  | ||||||
|   let typeof = function |  | ||||||
|     | Int _ -> Type.Int |  | ||||||
|     | Float _ -> Type.Float |  | ||||||
|     | String _ -> Type.String |  | ||||||
|     | Function _ -> Type.Function |  | ||||||
|     | External _ -> Type.External |  | ||||||
|     | Nop -> failwith "Value.typeof" |  | ||||||
| 
 |  | ||||||
|   let promote = function |  | ||||||
|     | Int n -> Float (float n) |  | ||||||
|     | Float n -> Float n |  | ||||||
|     | _ -> failwith "Value.promote" |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| (* operators *) |  | ||||||
| module Operator = struct |  | ||||||
|   type t = operator |  | ||||||
| 
 |  | ||||||
|   exception Unavailable of t |  | ||||||
| 
 |  | ||||||
|   let to_string = function |  | ||||||
|   | Add -> "+" |   | Add -> "+" | ||||||
|   | Sub -> "-" |   | Sub -> "-" | ||||||
|   | Mul -> "*" |   | Mul -> "*" | ||||||
|  | @ -92,51 +51,6 @@ module Operator = struct | ||||||
|   | Exp -> "^" |   | Exp -> "^" | ||||||
|   | Negate -> "-" |   | Negate -> "-" | ||||||
| 
 | 
 | ||||||
|   open Value |  | ||||||
| 
 |  | ||||||
|   let negate = function |  | ||||||
|     | Int n -> Int ~-n |  | ||||||
|     | Float n -> Float ~-.n |  | ||||||
|     | _ -> failwith "Operator.negate" |  | ||||||
| 
 |  | ||||||
|   let vi f a b = |  | ||||||
|     match a, b with |  | ||||||
|     | Int a, Int b -> Int (f a b) |  | ||||||
|     | _ -> raise @@ Invalid_type Int |  | ||||||
| 
 |  | ||||||
|   let vf f a b = |  | ||||||
|     match a, b with |  | ||||||
|     | Float a, Float b -> Float (f a b) |  | ||||||
|     | _ -> raise @@ Invalid_type Float |  | ||||||
| 
 |  | ||||||
|   let operators = |  | ||||||
|     let open Type in |  | ||||||
|     let ip = Int, Int and fp = Float, Float in |  | ||||||
|     [ |  | ||||||
|       Add, [ip, vi Int.add; fp, vf Float.add]; |  | ||||||
|       Sub, [ip, vi Int.sub; fp, vf Float.sub]; |  | ||||||
|       Mul, [ip, vi Int.mul; fp, vf Float.mul]; |  | ||||||
|       Div, [ip, vi Int.div; fp, vf Float.div]; |  | ||||||
|       Mod, [ip, vi Int.rem; fp, vf Float.rem]; |  | ||||||
|       Exp, [fp, vf Float.pow]; |  | ||||||
|     ] |  | ||||||
|     |> List.to_seq |  | ||||||
|     |> Hashtbl.of_seq |  | ||||||
| 
 |  | ||||||
|   let get_types op = |  | ||||||
|     match Hashtbl.find_opt operators op with |  | ||||||
|     | None -> raise @@ Unavailable op |  | ||||||
|     | Some p -> List.map fst p |  | ||||||
| 
 |  | ||||||
|   let get_unary = function |  | ||||||
|     | Negate -> negate |  | ||||||
|     | op -> raise @@ Unavailable op |  | ||||||
| 
 |  | ||||||
|   let get_binary op typ = |  | ||||||
|     Hashtbl.find operators op |  | ||||||
|     |> List.assoc_opt typ |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| let unary op t = | let unary op t = | ||||||
|   Unary (op, t) |   Unary (op, t) | ||||||
| 
 | 
 | ||||||
|  | @ -159,23 +73,23 @@ let print ast = | ||||||
|     | Let (v, e) -> |     | Let (v, e) -> | ||||||
|       pr "(let %s " v; aux e; pr ")" |       pr "(let %s " v; aux e; pr ")" | ||||||
|     | Unary (op, t) -> |     | Unary (op, t) -> | ||||||
|       let op = Operator.to_string op in |       let op = op_to_string op in | ||||||
|       pr "(%s " op; aux t; pr ")" |       pr "(%s " op; aux t; pr ")" | ||||||
|     | Binop (left, op, right) -> |     | Binop (left, op, right) -> | ||||||
|       let op = Operator.to_string op in |       let op = op_to_string op in | ||||||
|       pr "(%s " op; aux left; pr " "; aux right; pr ")" |       pr "(%s " op; aux left; pr " "; aux right; pr ")" | ||||||
|     | Apply (f, args) -> |     | Apply (f, args) -> | ||||||
|       pr "("; List.iter aux @@ f::args; pr ")" |       pr "("; List.iter aux @@ f::args; pr ")" | ||||||
| 
 | 
 | ||||||
|     | Set_binop_pre (op, pre) -> |     | Set_binop_pre (op, pre) -> | ||||||
|       pr "(set_pre %s " (Operator.to_string op); |       pr "(set_pre %s " (op_to_string op); | ||||||
|       aux pre; |       aux pre; | ||||||
|       pr ")" |       pr ")" | ||||||
|     | Get_binop_pre op -> |     | Get_binop_pre op -> | ||||||
|       pr "(get_pre %s)" (Operator.to_string op) |       pr "(get_pre %s)" (op_to_string op) | ||||||
|     | Set_binop_aso (op, aso) -> |     | Set_binop_aso (op, aso) -> | ||||||
|       pr "(set_assoc %s %s)" (Operator.to_string op) aso |       pr "(set_assoc %s %s)" (op_to_string op) aso | ||||||
|     | Get_binop_aso op -> |     | Get_binop_aso op -> | ||||||
|       pr "(get_pre %s)" (Operator.to_string op) |       pr "(get_pre %s)" (op_to_string op) | ||||||
|   in |   in | ||||||
|   aux ast; pr "\n" |   aux ast; pr "\n" | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								env.ml
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								env.ml
									
										
									
									
									
								
							|  | @ -1,10 +1,44 @@ | ||||||
| module Value = Ast.Value |  | ||||||
| 
 |  | ||||||
| type t = { | type t = { | ||||||
|   vars : (string, Value.t) Hashtbl.t; |   vars : (string, value) Hashtbl.t; | ||||||
|   parent : t option; |   parent : t option; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | and value = | ||||||
|  |   | Int of int | ||||||
|  |   | Float of float | ||||||
|  |   | String of string | ||||||
|  |   | Function of string list * expr | ||||||
|  |   | External of string | ||||||
|  |   | Nop (* return of system operations (will be deprecated) *) | ||||||
|  | 
 | ||||||
|  | and expr = Ast.t | ||||||
|  | 
 | ||||||
|  | module Value = struct | ||||||
|  |   module Type = Ast.Type | ||||||
|  |   type t = value | ||||||
|  | 
 | ||||||
|  |   let to_string = function | ||||||
|  |     | Int n -> string_of_int n | ||||||
|  |     | Float n -> string_of_float n | ||||||
|  |     | String s -> "\"" ^ s ^ "\"" | ||||||
|  |     | Function (vars, _) -> | ||||||
|  |       Printf.sprintf "function with %d arguments" @@ List.length vars | ||||||
|  |     | External f -> "external " ^ f | ||||||
|  |     | Nop -> "nop" | ||||||
|  | 
 | ||||||
|  |   let typeof = function | ||||||
|  |     | Int _ -> Type.Int | ||||||
|  |     | Float _ -> Type.Float | ||||||
|  |     | String _ -> Type.String | ||||||
|  |     | Function _ -> Type.Function | ||||||
|  |     | External _ -> Type.External | ||||||
|  |     | Nop -> failwith "Value.typeof" | ||||||
|  | 
 | ||||||
|  |   let promote = function | ||||||
|  |     | Int n -> Float (float n) | ||||||
|  |     | _ -> failwith "Value.promote" | ||||||
|  | end | ||||||
|  | 
 | ||||||
| let init_global () = { | let init_global () = { | ||||||
|   vars = Hashtbl.create 100; |   vars = Hashtbl.create 100; | ||||||
|   parent = None; |   parent = None; | ||||||
|  |  | ||||||
							
								
								
									
										56
									
								
								eval.ml
									
										
									
									
									
								
							
							
						
						
									
										56
									
								
								eval.ml
									
										
									
									
									
								
							|  | @ -1,12 +1,65 @@ | ||||||
| open Ast | open Ast | ||||||
| open Ast.Value | open Env | ||||||
|  | open Env.Value | ||||||
| 
 | 
 | ||||||
| exception No_operation | exception No_operation | ||||||
| exception No_such_variable of string | exception No_such_variable of string | ||||||
| exception No_such_function of string | exception No_such_function of string | ||||||
|  | exception Invalid_type of Type.t | ||||||
| 
 | 
 | ||||||
| exception Too_many_arguments | exception Too_many_arguments | ||||||
| 
 | 
 | ||||||
|  | (* operators *) | ||||||
|  | module Operator = struct | ||||||
|  |   type t = Ast.operator | ||||||
|  | 
 | ||||||
|  |   exception Unavailable of t | ||||||
|  | 
 | ||||||
|  |   let to_string = Ast.op_to_string | ||||||
|  | 
 | ||||||
|  |   let negate = function | ||||||
|  |     | Int n -> Int ~-n | ||||||
|  |     | Float n -> Float ~-.n | ||||||
|  |     | _ -> failwith "Operator.negate" | ||||||
|  | 
 | ||||||
|  |   let vi f a b = | ||||||
|  |     match a, b with | ||||||
|  |     | Int a, Int b -> Int (f a b) | ||||||
|  |     | _ -> raise @@ Invalid_type Int | ||||||
|  | 
 | ||||||
|  |   let vf f a b = | ||||||
|  |     match a, b with | ||||||
|  |     | Float a, Float b -> Float (f a b) | ||||||
|  |     | _ -> raise @@ Invalid_type Float | ||||||
|  | 
 | ||||||
|  |   let operators = | ||||||
|  |     let open Type in | ||||||
|  |     let ip = Int, Int and fp = Float, Float in | ||||||
|  |     [ | ||||||
|  |       Add, [ip, vi Int.add; fp, vf Float.add]; | ||||||
|  |       Sub, [ip, vi Int.sub; fp, vf Float.sub]; | ||||||
|  |       Mul, [ip, vi Int.mul; fp, vf Float.mul]; | ||||||
|  |       Div, [ip, vi Int.div; fp, vf Float.div]; | ||||||
|  |       Mod, [ip, vi Int.rem; fp, vf Float.rem]; | ||||||
|  |       Exp, [fp, vf Float.pow]; | ||||||
|  |     ] | ||||||
|  |     |> List.to_seq | ||||||
|  |     |> Hashtbl.of_seq | ||||||
|  | 
 | ||||||
|  |   let get_types op = | ||||||
|  |     match Hashtbl.find_opt operators op with | ||||||
|  |     | None -> raise @@ Unavailable op | ||||||
|  |     | Some p -> List.map fst p | ||||||
|  | 
 | ||||||
|  |   let get_unary = function | ||||||
|  |     | Negate -> negate | ||||||
|  |     | op -> raise @@ Unavailable op | ||||||
|  | 
 | ||||||
|  |   let get_binary op typ = | ||||||
|  |     Hashtbl.find operators op | ||||||
|  |     |> List.assoc_opt typ | ||||||
|  | end | ||||||
|  | 
 | ||||||
| let assert_same_length vars args = | let assert_same_length vars args = | ||||||
|   let vl = List.length vars |   let vl = List.length vars | ||||||
|   and al = List.length args in |   and al = List.length args in | ||||||
|  | @ -14,7 +67,6 @@ let assert_same_length vars args = | ||||||
|     failwith "assert_same_length" |     failwith "assert_same_length" | ||||||
|   else if vl < al then |   else if vl < al then | ||||||
|     raise Too_many_arguments |     raise Too_many_arguments | ||||||
|   else () |  | ||||||
| 
 | 
 | ||||||
| let resolve_type op tp = | let resolve_type op tp = | ||||||
|   let optypes = Operator.get_types op in |   let optypes = Operator.get_types op in | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								main.ml
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								main.ml
									
										
									
									
									
								
							|  | @ -8,7 +8,7 @@ let error_to_string e = | ||||||
|   | Lex.Expected c -> sprintf "expected %c" c |   | Lex.Expected c -> sprintf "expected %c" c | ||||||
|   | Parser.Expected t -> sprintf "expected %s" t |   | Parser.Expected t -> sprintf "expected %s" t | ||||||
|   | Parser.Unexpected_token t -> sprintf "unexpected token \"%s\"" t |   | Parser.Unexpected_token t -> sprintf "unexpected token \"%s\"" t | ||||||
|   | Ast.Invalid_type t -> sprintf "invalid type %s" (Ast.Type.to_string t) |   | Eval.Invalid_type t -> sprintf "invalid type %s" (Ast.Type.to_string t) | ||||||
|   | Eval.No_such_variable v -> sprintf "no such variable %s" v |   | Eval.No_such_variable v -> sprintf "no such variable %s" v | ||||||
|   | Eval.No_such_function f -> sprintf "no such function \"%s\"" f |   | Eval.No_such_function f -> sprintf "no such function \"%s\"" f | ||||||
|   | Eval.Too_many_arguments -> "applied too many arguments" |   | Eval.Too_many_arguments -> "applied too many arguments" | ||||||
|  | @ -24,7 +24,7 @@ let stdlib = [ | ||||||
|   "deg"; "rad"; |   "deg"; "rad"; | ||||||
| ] | ] | ||||||
|   |> List.to_seq |   |> List.to_seq | ||||||
|   |> Seq.map (fun v -> v, Ast.Value.External v) |   |> Seq.map (fun v -> v, Env.External v) | ||||||
| 
 | 
 | ||||||
| let g = | let g = | ||||||
|   let g = Env.init_global () in |   let g = Env.init_global () in | ||||||
|  | @ -46,12 +46,12 @@ let rep env : unit = | ||||||
|   | Nop -> () |   | Nop -> () | ||||||
|   | _ -> |   | _ -> | ||||||
|     Env.set env "ans" v; |     Env.set env "ans" v; | ||||||
|     printf "%s\n" @@ Ast.Value.to_string v |     printf "%s\n" @@ Env.Value.to_string v | ||||||
| 
 | 
 | ||||||
| exception Reset_line (* used to indicate ^C is pressed *) | exception Reset_line (* used to indicate ^C is pressed *) | ||||||
| 
 | 
 | ||||||
| let init_repl () = | let init_repl () = | ||||||
|   Env.set g "ans" (Ast.Value.Int 0); |   Env.set g "ans" (Env.Int 0); | ||||||
|   (* treat Ctrl-C as to reset line *) |   (* treat Ctrl-C as to reset line *) | ||||||
|   let reset_line _ = raise Reset_line in |   let reset_line _ = raise Reset_line in | ||||||
|   Sys.(set_signal sigint (Signal_handle reset_line)) |   Sys.(set_signal sigint (Signal_handle reset_line)) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue