Skip to content

Commit

Permalink
Merge pull request #3 from patricoferris/global-scope
Browse files Browse the repository at this point in the history
Add sequences, let and global functions
  • Loading branch information
patricoferris committed Mar 16, 2019
2 parents 987632c + 3beded6 commit 14514ea
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 15 deletions.
3 changes: 3 additions & 0 deletions examples/sequences_and_global.duck
@@ -0,0 +1,3 @@
(func add(x, y) => x + y end);
(let z = 4);
(add(3, z));;
27 changes: 17 additions & 10 deletions src/interp_stack.ml
Expand Up @@ -130,17 +130,24 @@ let step = function

(* COMPILING THE TYPES.ML TO STACK INSTRUCTIONS *)
let rec compile = function
| Integer n -> [PUSH (INT n)]
| Boolean b -> [PUSH (BOOLEAN b)]
| Var x -> [LOOKUP x]
| Conditional (e1, e2, e3) -> (compile e1) @ [TEST(compile e2, compile e3)]
| Operator(e1, op, e2) -> (compile e1) @ (compile e2) @ [OPER op]
| Lambda (vars, e) -> let bound_variables = bind_vars vars in
| Integer n -> [PUSH (INT n)]
| Boolean b -> [PUSH (BOOLEAN b)]
| Var x -> [LOOKUP x]
| Conditional (e1, e2, e3) -> (compile e1) @ [TEST(compile e2, compile e3)]
| Operator(e1, op, e2) -> (compile e1) @ (compile e2) @ [OPER op]
| VariableAssign (var, e) -> (compile e) @ [BIND var]
| Sequence [] -> []
| Sequence [e] -> (compile e)
| Sequence (e::rest) -> (compile e) @ (compile (Sequence rest))
| Lambda (vars, e) -> let bound_variables = bind_vars vars in
[MK_CLOSURE(bound_variables @ (compile e) @ leave_scope)]
| Func (f, (vars, e), e2) -> let bound_variables = bind_vars vars in
| Func (f, (vars, e), e2) -> let bound_variables = bind_vars vars in
(MK_CLOSURE(bound_variables @ (compile e) @ leave_scope)) ::
(BIND f) :: (compile e2) @ leave_scope
| Application (e1, e2) -> let compiled_arguments = compile_arg e2 in
| GlobalFunc (f, (vars, e)) -> let bound_variables = bind_vars vars in
(MK_CLOSURE(bound_variables @ (compile e) @ leave_scope)) ::
[(BIND f)]
| Application (e1, e2) -> let compiled_arguments = compile_arg e2 in
(compiled_arguments) @ (compile e1) @ [APPLY; SWAP; POP]

and bind_vars = function
Expand All @@ -155,10 +162,10 @@ and compile_arg = function
let empty_env = []

let rec driver n state =
let _ = if false
let _ = if true
then print_string ("N: " ^ (string_of_int n) ^ " : " ^ (string_stack state)) else ()
in match state with
| ([], [V v]) -> v
| ([], (V v)::_) -> v
| _ -> driver (n + 1) (step state)

let interpret_top e =
Expand Down
8 changes: 6 additions & 2 deletions src/lexer.mll
Expand Up @@ -12,7 +12,7 @@ let next_line lexbuf =

}

let newline = ('\r' | '\n' | "\r\n")
let newline = ('\r' | '\n' | "\r\n" | "\010" | "\013")
let ident_reg_exp = ['A'-'Z' 'a'-'z']+ ['0'-'9' 'A'-'Z' 'a'-'z' '_' '\'']*
let int_reg_exp = ['0'-'9']+
let bool_reg_exp = ("true" | "false")
Expand All @@ -33,13 +33,17 @@ rule token = parse
| "else" { ELSE }
| "&&" { AND }
| "||" { OR }
| ';' { SEMI }
| ";;" { DOUBLESEMI }
| "let" { LET }
| '=' { ASSIGN }
| "=>" { ARROW }
| "lambda" { LAMBDA }
| "func" { FUNC }
| "end" { END }
| int_reg_exp { INT (int_of_string (Lexing.lexeme lexbuf)) }
| bool_reg_exp { BOOLEAN (bool_of_string (Lexing.lexeme lexbuf)) }
| ident_reg_exp { ID (Lexing.lexeme lexbuf) }
| newline { next_line lexbuf; token lexbuf }
| newline { Lexing.new_line lexbuf; token lexbuf }
| eof { EOF }
| _ { raise (SyntaxError ("Unexpected Char: " ^ Lexing.lexeme lexbuf)) }
13 changes: 10 additions & 3 deletions src/parser.mly
Expand Up @@ -3,8 +3,8 @@
%token <string> ID
%token LPAREN LCURLY
%token RPAREN RCURLY
%token EOF LAMBDA ARROW END FUNC IF THEN ELSE COMMA
%token ADD SUB MULT DIV AND OR
%token EOF LAMBDA ARROW END FUNC IF THEN ELSE COMMA SEMI DOUBLESEMI
%token ADD SUB MULT DIV AND OR LET ASSIGN

%left ADD SUB OR
%left MULT DIV AND
Expand All @@ -31,9 +31,16 @@ expr:
| e1 = expr; DIV; e2 = expr { Types.Operator (e1, Types.DIV, e2) }
| e1 = expr; AND; e2 = expr { Types.Operator (e1, Types.AND, e2) }
| e1 = expr; OR; e2 = expr { Types.Operator (e1, Types.OR, e2) }
| LET; var = ID; ASSIGN; e = expr { Types.VariableAssign (var, e) }
| es = expression_list { Types.Sequence (es) }
| IF; e1 = expr; THEN; e2 = expr; ELSE; e3 = expr; { Types.Conditional (e1, e2, e3) }
| LAMBDA; LPAREN; idents = ident_list; RPAREN; ARROW; e = expr; END { Types.Lambda (idents, e) }
| FUNC; fname = ID; LPAREN; idents = ident_list; RPAREN; ARROW; e1 = expr; LCURLY; e2 = expr; RCURLY { Types.Func (fname, (idents, e1), e2) };
| FUNC; fname = ID; LPAREN; idents = ident_list; RPAREN; ARROW; e1 = expr; LCURLY; e2 = expr; RCURLY { Types.Func (fname, (idents, e1), e2) }
| FUNC; fname = ID; LPAREN; idents = ident_list; RPAREN; ARROW; e1 = expr; END; { Types.GlobalFunc (fname, (idents, e1)) };

expression_list:
| e = expr; DOUBLESEMI { [e] }
| e = expr; SEMI; rest = expression_list { e :: rest }

application_list:
| a = separated_list(COMMA, expr) { a }
Expand Down
6 changes: 6 additions & 0 deletions src/types.ml
Expand Up @@ -6,8 +6,11 @@ type expr =
| Operator of expr * boper * expr
| Lambda of lambda
| Func of var * lambda * expr
| GlobalFunc of var * lambda
| Sequence of expr list
| Application of expr * (expr list)
| Var of var
| VariableAssign of var * expr
| Conditional of expr * expr * expr
and var = string
and lambda = (var list) * expr
Expand All @@ -32,9 +35,12 @@ let rec pp_expr ppf = function
| Operator (e1, op, e2) -> fprintf ppf "(%a %a %a)" pp_expr e1 pp_binary op pp_expr e2
| Lambda (_, expr) -> fprintf ppf "(~lambda %a => %a)" fstring "tuple" pp_expr expr
| Func (func, (_, e1), e2) -> fprintf ppf "(FUNC:%a(%a) => %a in %a)" fstring func fstring "tuple" pp_expr e1 pp_expr e2
| GlobalFunc (func, (_, e1)) -> fprintf ppf "(FUNC:%a(%a) => %a)" fstring func fstring "tuple" pp_expr e1
| Application (e1, _) -> fprintf ppf "(Applying %a)" pp_expr e1
| Var (var) -> fstring ppf var
| VariableAssign (var, _) -> fstring ppf ("Assigning " ^ var)
| Conditional(_, _, _) -> fstring ppf "If..."
| Sequence _ -> fstring ppf "Sequence"

let print_expr e =
let _ = pp_expr std_formatter e
Expand Down

0 comments on commit 14514ea

Please sign in to comment.