From fe546c63f63c8e8abbbe931da708303b2e711982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Romildo?= Date: Mon, 28 Mar 2022 11:11:44 -0300 Subject: [PATCH] Some development --- src/absyn.ml | 2 +- src/{test1.ml => examples.ml} | 10 ++++- src/interpreter.ml | 14 +++--- src/maxargs.ml | 23 ++++++++++ src/parser_.mly | 82 +++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 10 deletions(-) rename src/{test1.ml => examples.ml} (89%) create mode 100644 src/parser_.mly diff --git a/src/absyn.ml b/src/absyn.ml index 1c592ba..406479b 100644 --- a/src/absyn.ml +++ b/src/absyn.ml @@ -9,6 +9,6 @@ type stm = CompoundStm of stm * stm | PrintStm of exp list and exp = IdExp of id - | NumExp of float + | NumExp of int | OpExp of exp * binop * exp | EseqExp of stm * exp diff --git a/src/test1.ml b/src/examples.ml similarity index 89% rename from src/test1.ml rename to src/examples.ml index 9738ddf..ebc3500 100644 --- a/src/test1.ml +++ b/src/examples.ml @@ -1,8 +1,11 @@ +open Absyn + (* - altura := 1.73 + altura := 173 *) -let prog1 = AssignStm ("altura", NumExp 1.73) +let prog1 = AssignStm ("altura", NumExp 173) + (* print(43, 7, 0) @@ -10,6 +13,7 @@ let prog1 = AssignStm ("altura", NumExp 1.73) let prog2 = PrintStm [NumExp 43; NumExp 7; NumExp 0] + (* x := 2 + 3; print(x) @@ -19,6 +23,7 @@ let prog3 = CompoundStm (AssignStm ("x", OpExp (NumExp 2, Plus, NumExp 3)), PrintStm [IdExp "x"]) + (* x := 2 + 3 * 4; print(x) @@ -34,6 +39,7 @@ let prog4 = NumExp 4))), PrintStm [IdExp "x"]) + (* a := 5 + 3; b := (print(a, a-1), 10*a); diff --git a/src/interpreter.ml b/src/interpreter.ml index cbb9bff..23f96c7 100644 --- a/src/interpreter.ml +++ b/src/interpreter.ml @@ -1,28 +1,28 @@ open Absyn -type memory = (id, float) Hashtbl.t +type memory = (id, int) Hashtbl.t let rec run m prog = match prog with | CompoundStm (s1, s2) -> run m s1; run m s2 | AssignStm (v, e) -> Hashtbl.replace m v (eval m e) | PrintStm list -> List.iter - (fun e -> print_float (eval m e); print_char ' ') + (fun e -> print_int (eval m e); print_char ' ') list; print_newline () and eval m exp = match exp with | NumExp cte -> cte | IdExp v -> ( try Hashtbl.find m v - with Not_found -> 0.0 + with Not_found -> 0 ) | OpExp (e1, op, e2) -> let v1 = eval m e1 in let v2 = eval m e2 in ( match op with - | Plus -> v1 +. v2 - | Minus -> v1 -. v2 - | Times -> v1 *. v2 - | Div -> v1 /. v2 + | Plus -> v1 + v2 + | Minus -> v1 - v2 + | Times -> v1 * v2 + | Div -> v1 / v2 ) | EseqExp (s, e) -> run m s; eval m e diff --git a/src/maxargs.ml b/src/maxargs.ml index 488e86e..8c38576 100644 --- a/src/maxargs.ml +++ b/src/maxargs.ml @@ -1,5 +1,27 @@ open Absyn +let rec maxargs statement = + match statement with + | CompoundStm (s1, s2) -> max (maxargs s1) (maxargs s2) + | AssignStm (_, e) -> maxargs_exp e + | PrintStm e_list -> max (maxargs_exp_list e_list) (List.length e_list) + +and maxargs_exp expression = + match expression with + | IdExp _ -> 0 + | NumExp _ -> 0 + | OpExp (e1, _, e2) -> max (maxargs_exp e1) (maxargs_exp e2) + | EseqExp (s, e) -> max (maxargs s) (maxargs_exp e) + +and maxargs_exp_list = function + | [] -> 0 + | e :: rest -> max (maxargs_exp e) (maxargs_exp_list rest) + + +(* + +(* Definição alternativa, usando List.fold_left *) + let rec maxargs statement = match statement with | PrintStm args -> List.fold_left @@ -17,3 +39,4 @@ and maxargs_exp expression = | EseqExp (s, e) -> max (maxargs s) (maxargs_exp e) + *) diff --git a/src/parser_.mly b/src/parser_.mly new file mode 100644 index 0000000..6ebd875 --- /dev/null +++ b/src/parser_.mly @@ -0,0 +1,82 @@ +/* parser.mly */ + +%{ + +module A = Absyn + +(* +let pos n x = mkloc { loc_start = Parsing.rhs_start_pos n; + loc_end = Parsing.rhs_end_pos n; + } + x + +let loc x = mkloc { loc_start = Parsing.symbol_start_pos (); + loc_end = Parsing.symbol_end_pos (); + } + x + *) + +let loc x = x + +let parse_error msg = + match ! Location.lexbuf_ref with + | Some lexbuf -> + Error.error (Location.curr_loc lexbuf) (Error.Syntax (Lexing.lexeme lexbuf)) + | None -> + Error.internal "lexbuf_ref is unset" + +%} + +%token NUM +%token ID +%token PRINT +%token LPAREN RPAREN +%token COMMA SEMI +%token PLUS MINUS TIMES DIV +%token ASSIGN +%token EOF + +%right SEMI +%nonassoc ASSIGN +%left PLUS MINUS +%left TIMES DIV + +%start prog +%type prog + +%% + +prog: + stm { $1 } +; + +stm: + stm SEMI stm { loc (A.CompoundStm ($1, $3)) } +| ID ASSIGN exp { loc (A.AssignStm ($1, $3)) } +| PRINT LPAREN args RPAREN { loc (A.PrintStm $3) } +; + +exp: + NUM { loc (A.NumExp $1) } +| ID { loc (A.IdExp $1) } +| exp PLUS exp { loc (A.OpExp ($1, A.Plus, $3)) } +| exp MINUS exp { loc (A.OpExp ($1, A.Minus, $3)) } +| exp TIMES exp { loc (A.OpExp ($1, A.Times, $3)) } +| exp DIV exp { loc (A.OpExp ($1, A.Div, $3)) } +| LPAREN stm COMMA exp RPAREN { loc (A.EseqExp ($2, $4)) } +; + +args: + /* empty */ { [] } +| exp { $1 :: [] } +| exp COMMA args_rest { $1 :: $3 } +| error COMMA args_rest { $3 } +; + +args_rest: + exp { $1 :: [] } +| exp COMMA args_rest { $1 :: $3 } +| error COMMA args_rest { $3 } +; + +%%