Skip to content

Commit

Permalink
Add unary not operator
Browse files Browse the repository at this point in the history
  • Loading branch information
mukul-rathi committed Dec 21, 2019
1 parent 3393f7f commit 0c606de
Show file tree
Hide file tree
Showing 16 changed files with 49 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/ast/ast_types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,7 @@ let string_of_bin_op = function
| BinOpOr -> "||"
| BinOpEq -> "=="
| BinOpNotEq -> "!="

type un_op = UnOpNot

let string_of_un_op UnOpNot = "!"
4 changes: 4 additions & 0 deletions src/ast/ast_types.mli
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ type bin_op =
| BinOpNotEq

val string_of_bin_op : bin_op -> string

type un_op = UnOpNot

val string_of_un_op : un_op -> string
1 change: 1 addition & 0 deletions src/parsing/parsed_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type expr =
| FinishAsync of loc * expr * expr * expr
| If of loc * expr * expr * expr
| BinOp of loc * bin_op * expr * expr
| UnOp of loc * un_op * expr

and constructor_arg = ConstructorArg of Field_name.t * expr

Expand Down
1 change: 1 addition & 0 deletions src/parsing/parsed_ast.mli
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type expr =
(** first async expr, second async expr, next expr after async exection completed *)
| If of loc * expr * expr * expr (** If ___ then ___ else ___ *)
| BinOp of loc * bin_op * expr * expr
| UnOp of loc * un_op * expr

and constructor_arg = ConstructorArg of Field_name.t * expr (** read as (f: ___) *)

Expand Down
5 changes: 5 additions & 0 deletions src/parsing/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ bin_op:
| EQUAL EQUAL {BinOpEq}
| EXCLAMATION_MARK EQUAL {BinOpNotEq}

un_op:
| EXCLAMATION_MARK {UnOpNot}


tfield:
| TYPE_INT {TFieldInt}
| TYPE_BOOL {TFieldBool}
Expand All @@ -163,6 +167,7 @@ args:
| LPAREN separated_nonempty_list(COMMA, expr) RPAREN {$2}

expr:
| un_op expr { UnOp($startpos, $1, $2) }
| LPAREN expr bin_op expr RPAREN {BinOp($startpos, $3, $2, $4)}
| simple_expr { $1 }
| LET ID EQUAL expr {Let($startpos, Var_name.of_string $2, $4)}
Expand Down
3 changes: 3 additions & 0 deletions src/parsing/pprint_past.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ let rec pprint_expr ppf ~indent expr =
print_expr (Fmt.str "Bin Op: %s" (string_of_bin_op bin_op)) ;
pprint_expr ppf ~indent:new_indent expr1 ;
pprint_expr ppf ~indent:new_indent expr2
| UnOp (_, un_op, expr) ->
print_expr (Fmt.str "Unary Op: %s" (string_of_un_op un_op)) ;
pprint_expr ppf ~indent:new_indent expr

and pprint_constructor_arg ppf ~indent (ConstructorArg (field_name, expr)) =
let new_indent = indent_space ^ indent in
Expand Down
4 changes: 4 additions & 0 deletions src/typing/core_lang/pprint_tast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ let rec pprint_expr ppf ~indent expr =
pprint_type_expr ppf ~indent:new_indent type_expr ;
pprint_expr ppf ~indent:new_indent expr1 ;
pprint_expr ppf ~indent:new_indent expr2
| UnOp (_, type_expr, un_op, expr) ->
print_expr (Fmt.str "Unary Op: %s" (string_of_un_op un_op)) ;
pprint_type_expr ppf ~indent:new_indent type_expr ;
pprint_expr ppf ~indent:new_indent expr

and pprint_constructor_arg ppf indent (ConstructorArg (type_expr, field_name, expr)) =
let new_indent = indent_space ^ indent in
Expand Down
12 changes: 12 additions & 0 deletions src/typing/core_lang/type_expr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,18 @@ let rec infer_type_expr class_defns trait_defns function_defns (expr : Parsed_as
else type_mismatch_error TEBool expr1_type
| BinOpEq | BinOpNotEq ->
Ok (Typed_ast.BinOp (loc, TEBool, bin_op, typed_expr1, typed_expr2), TEBool) )
| Parsed_ast.UnOp (loc, UnOpNot, expr) -> (
infer_type_with_defns expr env
>>= fun (typed_expr, expr_type) ->
match expr_type with
| TEBool -> Ok (Typed_ast.UnOp (loc, TEBool, UnOpNot, typed_expr), TEBool)
| _ ->
Error
(Error.of_string
(Fmt.str
"%s Type error - %s expected operand of type %s, but it was of type %s@."
(string_of_loc loc) (string_of_un_op UnOpNot) (string_of_type TEBool)
(string_of_type expr_type))) )

(* Top level statement to infer type of overall program expr *)
let type_expr class_defns trait_defns function_defns (expr : Parsed_ast.expr) =
Expand Down
1 change: 1 addition & 0 deletions src/typing/core_lang/typed_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type expr =
| FinishAsync of loc * type_expr * expr * expr * expr
| If of loc * type_expr * expr * expr * expr
| BinOp of loc * type_expr * bin_op * expr * expr
| UnOp of loc * type_expr * un_op * expr

(* overall type is that of the next_expr *)
and constructor_arg = ConstructorArg of type_expr * Field_name.t * expr
Expand Down
1 change: 1 addition & 0 deletions src/typing/core_lang/typed_ast.mli
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type expr =
(** overall type is that of the next_expr *)
| If of loc * type_expr * expr * expr * expr
| BinOp of loc * type_expr * bin_op * expr * expr
| UnOp of loc * type_expr * un_op * expr

and constructor_arg = ConstructorArg of type_expr * Field_name.t * expr

Expand Down
1 change: 1 addition & 0 deletions src/typing/data_race/type_async_expr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ let rec type_async_expr_helper class_defns trait_defns expr =
>>| union_envs
| BinOp (_, _, _, expr1, expr2) ->
Result.all (List.map ~f:type_async_expr_with_defns [expr1; expr2]) >>| union_envs
| UnOp (_, _, _, expr) -> type_async_expr_with_defns expr
| FinishAsync (loc, _, async_expr1, async_expr2, next_expr) ->
type_async_expr_with_defns async_expr1
>>= fun async_expr1_env ->
Expand Down
2 changes: 2 additions & 0 deletions src/typing/data_race/type_linear_ownership.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ let rec type_linear_ownership_helper class_defns trait_defns function_defns expr
| Boolean (_, _) -> Ok NonLinear
| BinOp (_, _, _, _, _) ->
Ok NonLinear (* since binary operators return either an int or a bool *)
| UnOp (_, _, _, _) ->
Ok NonLinear (* since the only unary op is NOT which returns a bool *)
| Variable (loc, var_type, _) ->
if has_linear_cap var_type class_defns loc then Ok LinearOwned else Ok NonLinear
| App (loc, _, func_name, args_exprs) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ let%expect_test "Comparison operators" =

let%expect_test "Boolean operators" =
print_parsed_ast "
( (true || false) && false)
( (true || false) && !false)
" ;
[%expect
{|
Expand All @@ -69,4 +69,5 @@ let%expect_test "Boolean operators" =
└──Expr: Bin Op: ||
└──Expr: Bool:true
└──Expr: Bool:false
└──Expr: Bool:false |}]
└──Expr: Unary Op: !
└──Expr: Bool:false |}]
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,14 @@ let%expect_test "Bool logical operators on object" =
{
let x = new Foo();
let y = new Foo(f:true);
!x;
(x && x);
(x || y)
}
" ;
[%expect
{|
Line:11 Position:7 Type error - && expected operands of type Bool, but they were of type Class: Foo |}]
Line:11 Position:7 Type error - ! expected operand of type Bool, but it was of type Class: Foo |}]

let%expect_test "Binary operator's operands' types mismatch " =
print_typed_ast
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ let%expect_test "Comparison operators" =

let%expect_test "Boolean operators" =
print_typed_ast "
( (true || false) && false)
( (true || false) && !false)
" ;
[%expect
{|
Expand All @@ -90,4 +90,6 @@ let%expect_test "Boolean operators" =
└──Type expr: Bool
└──Expr: Bool:true
└──Expr: Bool:false
└──Expr: Bool:false |}]
└──Expr: Unary Op: !
└──Type expr: Bool
└──Expr: Bool:false |}]
2 changes: 1 addition & 1 deletion tests/expect/typing_data_race/good_consume_variable.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let%expect_test "Consume variable" =
{
{
let x = new Foo(f:4, g:5, h:6);
let y = if true then new Foo(f:1, g:2, h:3) else consume x; (* Consume linear variable *)
let y = if !(x.f < x.g) then new Foo(f:1, g:2, h:3) else consume x; (* Consume linear variable *)
let z = 5;
let w = consume z; (* Can consume an int *)
y.h
Expand Down

0 comments on commit 0c606de

Please sign in to comment.