Skip to content

Commit

Permalink
make in a Binop and remove EIn (closes #6224) (#6471)
Browse files Browse the repository at this point in the history
* make `in` a Binop and remove `EIn` (closes #6224)

* use make_binop

* fix enumIndex in tests

* change OpIn precedence to be lessthan OpAssign(Op)
  • Loading branch information
nadako authored and Simn committed Aug 2, 2017
1 parent cacbebb commit 52f680c
Show file tree
Hide file tree
Showing 22 changed files with 84 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/display/display.ml
Expand Up @@ -239,7 +239,7 @@ module DocumentSymbols = struct
| EFunction(Some s,f) ->
add s Function p;
func parent f
| EIn((EConst(Ident s),p),e2) ->
| EBinop(OpIn,(EConst(Ident s),p),e2) ->
add s Variable p;
expr parent e2;
| _ ->
Expand Down
2 changes: 1 addition & 1 deletion src/generators/gencommon/dynamicOperators.ml
Expand Up @@ -118,7 +118,7 @@ let init com handle_strings (should_change:texpr->bool) (equals_handler:texpr->t
{ e with eexpr = TBinop (op, mk_cast com.basic.tbool (run e1), mk_cast com.basic.tbool (run e2)) }
| OpAnd | OpOr | OpXor | OpShl | OpShr | OpUShr ->
{ e with eexpr = TBinop (op, mk_cast com.basic.tint (run e1), mk_cast com.basic.tint (run e2)) }
| OpAssign | OpAssignOp _ | OpInterval | OpArrow ->
| OpAssign | OpAssignOp _ | OpInterval | OpArrow | OpIn ->
assert false)

| TUnop (Increment as op, flag, e1)
Expand Down
3 changes: 3 additions & 0 deletions src/generators/gencpp.ml
Expand Up @@ -4092,6 +4092,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_
| OpMod -> "%"
| OpInterval -> "..."
| OpArrow -> "->"
| OpIn -> " in "
| OpAssign | OpAssignOp _ -> abort "Unprocessed OpAssign" pos
and string_of_path path =
"::" ^ (join_class_path_remap path "::") ^ "_obj"
Expand Down Expand Up @@ -7035,6 +7036,7 @@ let cppia_op_info = function
| IaBinOp OpMod -> ("%", 120)
| IaBinOp OpInterval -> ("...", 121)
| IaBinOp OpArrow -> ("=>", 122)
| IaBinOp OpIn -> (" in ", 123)
| IaBinOp OpAssignOp OpAdd -> ("+=", 201)
| IaBinOp OpAssignOp OpMult -> ("*=", 202)
| IaBinOp OpAssignOp OpDiv -> ("/=", 203)
Expand All @@ -7051,6 +7053,7 @@ let cppia_op_info = function
| IaBinOp OpAssignOp OpShl -> ("<<=", 219)
| IaBinOp OpAssignOp OpMod -> ("%=", 220)

| IaBinOp OpAssignOp OpIn
| IaBinOp OpAssignOp OpInterval
| IaBinOp OpAssignOp OpAssign
| IaBinOp OpAssignOp OpEq
Expand Down
2 changes: 1 addition & 1 deletion src/generators/genhl.ml
Expand Up @@ -2316,7 +2316,7 @@ and eval_expr ctx e =
free ctx r;
binop r r b;
r))
| OpInterval | OpArrow ->
| OpInterval | OpArrow | OpIn ->
assert false)
| TUnop (Not,_,v) ->
let tmp = alloc_tmp ctx HBool in
Expand Down
2 changes: 1 addition & 1 deletion src/generators/genpy.ml
Expand Up @@ -1053,7 +1053,7 @@ module Printer = struct
| OpShr -> ">>"
| OpUShr -> ">>"
| OpMod -> "%"
| OpInterval | OpArrow | OpAssignOp _ -> assert false
| OpInterval | OpArrow | OpIn | OpAssignOp _ -> assert false

let print_string s =
Printf.sprintf "\"%s\"" (Ast.s_escape s)
Expand Down
2 changes: 1 addition & 1 deletion src/generators/genswf9.ml
Expand Up @@ -1691,7 +1691,7 @@ and gen_binop ctx retval op e1 e2 t p =
gen_op A3OLt
| OpLte ->
gen_op A3OLte
| OpInterval | OpArrow ->
| OpInterval | OpArrow | OpIn ->
assert false

and gen_expr ctx retval e =
Expand Down
2 changes: 1 addition & 1 deletion src/macro/eval/evalJit.ml
Expand Up @@ -64,7 +64,7 @@ let get_binop_fun op p = match op with
| OpShr -> op_shr p
| OpUShr -> op_ushr p
| OpMod -> op_mod p
| OpAssign | OpBoolAnd | OpBoolOr | OpAssignOp _ | OpInterval | OpArrow -> assert false
| OpAssign | OpBoolAnd | OpBoolOr | OpAssignOp _ | OpInterval | OpArrow | OpIn -> assert false

open EvalJitContext

Expand Down
68 changes: 33 additions & 35 deletions src/macro/macroApi.ml
Expand Up @@ -331,6 +331,7 @@ let rec encode_binop op =
| OpAssignOp op -> 20, [encode_binop op]
| OpInterval -> 21, []
| OpArrow -> 22, []
| OpIn -> 23, []
in
encode_enum IBinop tag pl

Expand Down Expand Up @@ -496,14 +497,12 @@ and encode_expr e =
12, [encode_array (List.map loop el)]
| EFor (e,eloop) ->
13, [loop e;loop eloop]
| EIn (e1,e2) ->
14, [loop e1;loop e2]
| EIf (econd,e,eelse) ->
15, [loop econd;loop e;null loop eelse]
14, [loop econd;loop e;null loop eelse]
| EWhile (econd,e,flag) ->
16, [loop econd;loop e;vbool (match flag with NormalWhile -> true | DoWhile -> false)]
15, [loop econd;loop e;vbool (match flag with NormalWhile -> true | DoWhile -> false)]
| ESwitch (e,cases,eopt) ->
17, [loop e;encode_array (List.map (fun (ecl,eg,e,p) ->
16, [loop e;encode_array (List.map (fun (ecl,eg,e,p) ->
encode_obj OCase [
"values",encode_array (List.map loop ecl);
"guard",null loop eg;
Expand All @@ -512,7 +511,7 @@ and encode_expr e =
]
) cases);null (fun (e,_) -> encode_null_expr e) eopt]
| ETry (e,catches) ->
18, [loop e;encode_array (List.map (fun (v,t,e,p) ->
17, [loop e;encode_array (List.map (fun (v,t,e,p) ->
encode_obj OCatch [
"name",encode_placed_name v;
"name_pos",encode_pos (pos v);
Expand All @@ -522,27 +521,27 @@ and encode_expr e =
]
) catches)]
| EReturn eo ->
19, [null loop eo]
18, [null loop eo]
| EBreak ->
20, []
19, []
| EContinue ->
21, []
20, []
| EUntyped e ->
22, [loop e]
21, [loop e]
| EThrow e ->
23, [loop e]
22, [loop e]
| ECast (e,t) ->
24, [loop e; null encode_ctype t]
23, [loop e; null encode_ctype t]
| EDisplay (e,flag) ->
25, [loop e; vbool flag]
24, [loop e; vbool flag]
| EDisplayNew t ->
26, [encode_path t]
25, [encode_path t]
| ETernary (econd,e1,e2) ->
27, [loop econd;loop e1;loop e2]
26, [loop econd;loop e1;loop e2]
| ECheckType (e,t) ->
28, [loop e; encode_ctype t]
27, [loop e; encode_ctype t]
| EMeta (m,e) ->
29, [encode_meta_entry m;loop e]
28, [encode_meta_entry m;loop e]
in
encode_obj OExpr [
"pos", encode_pos p;
Expand Down Expand Up @@ -605,6 +604,7 @@ let rec decode_op op =
| 20, [op] -> OpAssignOp (decode_op op)
| 21, [] -> OpInterval
| 22,[] -> OpArrow
| 23,[] -> OpIn
| _ -> raise Invalid_expr

let decode_unop op =
Expand Down Expand Up @@ -764,45 +764,43 @@ and decode_expr v =
EBlock (List.map loop (decode_array el))
| 13, [e1;e2] ->
EFor (loop e1, loop e2)
| 14, [e1;e2] ->
EIn (loop e1, loop e2)
| 15, [e1;e2;e3] ->
| 14, [e1;e2;e3] ->
EIf (loop e1, loop e2, opt loop e3)
| 16, [e1;e2;flag] ->
| 15, [e1;e2;flag] ->
EWhile (loop e1,loop e2,if decode_bool flag then NormalWhile else DoWhile)
| 17, [e;cases;eo] ->
| 16, [e;cases;eo] ->
let cases = List.map (fun c ->
(List.map loop (decode_array (field c "values")),opt loop (field c "guard"),opt loop (field c "expr"),maybe_decode_pos (field c "pos"))
) (decode_array cases) in
ESwitch (loop e,cases,opt (fun v -> (if field v "expr" = vnull then None else Some (decode_expr v)),Globals.null_pos) eo)
| 18, [e;catches] ->
| 17, [e;catches] ->
let catches = List.map (fun c ->
((decode_placed_name (field c "name_pos") (field c "name")),(decode_ctype (field c "type")),loop (field c "expr"),maybe_decode_pos (field c "pos"))
) (decode_array catches) in
ETry (loop e, catches)
| 19, [e] ->
| 18, [e] ->
EReturn (opt loop e)
| 20, [] ->
| 19, [] ->
EBreak
| 21, [] ->
| 20, [] ->
EContinue
| 22, [e] ->
| 21, [e] ->
EUntyped (loop e)
| 23, [e] ->
| 22, [e] ->
EThrow (loop e)
| 24, [e;t] ->
| 23, [e;t] ->
ECast (loop e,opt decode_ctype t)
| 25, [e;f] ->
| 24, [e;f] ->
EDisplay (loop e,decode_bool f)
| 26, [t] ->
| 25, [t] ->
EDisplayNew (decode_path t)
| 27, [e1;e2;e3] ->
| 26, [e1;e2;e3] ->
ETernary (loop e1,loop e2,loop e3)
| 28, [e;t] ->
| 27, [e;t] ->
ECheckType (loop e, (decode_ctype t))
| 29, [m;e] ->
| 28, [m;e] ->
EMeta (decode_meta_entry m,loop e)
| 30, [e;f] ->
| 29, [e;f] ->
EField (loop e, decode_string f) (*** deprecated EType, keep until haxe 3 **)
| _ ->
raise Invalid_expr
Expand Down
1 change: 1 addition & 0 deletions src/optimization/analyzerTexpr.ml
Expand Up @@ -620,6 +620,7 @@ module Fusion = struct
| OpBoolOr
| OpAssignOp _
| OpInterval
| OpIn
| OpArrow ->
false

Expand Down
2 changes: 1 addition & 1 deletion src/optimization/analyzerTexprTransformer.ml
Expand Up @@ -731,7 +731,7 @@ and func ctx i =
| OpAdd | OpMult | OpDiv | OpSub | OpAnd
| OpOr | OpXor | OpShl | OpShr | OpUShr | OpMod ->
true
| OpAssignOp _ | OpInterval | OpArrow | OpAssign | OpEq
| OpAssignOp _ | OpInterval | OpArrow | OpIn | OpAssign | OpEq
| OpNotEq | OpGt | OpGte | OpLt | OpLte | OpBoolAnd | OpBoolOr ->
false
in
Expand Down
11 changes: 6 additions & 5 deletions src/optimization/optimizer.ml
Expand Up @@ -914,8 +914,9 @@ let standard_precedence op =
| OpBoolAnd -> 14, left
| OpBoolOr -> 15, left
| OpArrow -> 16, left
| OpAssignOp OpAssign -> 17, right (* mimics ?: *)
| OpAssign | OpAssignOp _ -> 18, right
| OpIn -> 17, right
| OpAssignOp OpAssign -> 18, right (* mimics ?: *)
| OpAssign | OpAssignOp _ -> 19, right

let rec need_parent e =
match e.eexpr with
Expand Down Expand Up @@ -1503,18 +1504,18 @@ let optimize_completion_expr e =
let e = map e in
old();
e
| EFor ((EIn ((EConst (Ident n),_) as id,it),p),efor) ->
| EFor ((EBinop (OpIn,((EConst (Ident n),_) as id),it),p),efor) ->
let it = loop it in
let old = save() in
let etmp = (EConst (Ident "$tmp"),p) in
decl n None (Some (EBlock [
(EVars [("$tmp",null_pos),None,None],p);
(EFor ((EIn (id,it),p),(EBinop (OpAssign,etmp,(EConst (Ident n),p)),p)),p);
(EFor ((EBinop (OpIn,id,it),p),(EBinop (OpAssign,etmp,(EConst (Ident n),p)),p)),p);
etmp
],p));
let efor = loop efor in
old();
(EFor ((EIn (id,it),p),efor),p)
(EFor ((EBinop (OpIn,id,it),p),efor),p)
| EReturn _ ->
typing_side_effect := true;
map e
Expand Down
10 changes: 3 additions & 7 deletions src/syntax/ast.ml
Expand Up @@ -87,6 +87,7 @@ type binop =
| OpAssignOp of binop
| OpInterval
| OpArrow
| OpIn

type unop =
| Increment
Expand Down Expand Up @@ -182,7 +183,6 @@ and expr_def =
| EFunction of string option * func
| EBlock of expr list
| EFor of expr * expr
| EIn of expr * expr
| EIf of expr * expr * expr option
| EWhile of expr * expr * while_flag
| ESwitch of expr * (expr list * expr option * expr option * pos) list * (expr option * pos) option
Expand Down Expand Up @@ -431,6 +431,7 @@ let rec s_binop = function
| OpAssignOp op -> s_binop op ^ "="
| OpInterval -> "..."
| OpArrow -> "=>"
| OpIn -> " in "

let s_unop = function
| Increment -> "++"
Expand Down Expand Up @@ -607,10 +608,6 @@ let map_expr loop (e,p) =
let e1 = loop e1 in
let e2 = loop e2 in
EFor (e1,e2)
| EIn (e1,e2) ->
let e1 = loop e1 in
let e2 = loop e2 in
EIn (e1,e2)
| EIf (e,e1,e2) ->
let e = loop e in
let e1 = loop e1 in
Expand Down Expand Up @@ -665,7 +662,7 @@ let iter_expr loop (e,p) =
| EConst _ | EContinue | EBreak | EDisplayNew _ | EReturn None -> ()
| EParenthesis e1 | EField(e1,_) | EUnop(_,_,e1) | EReturn(Some e1) | EThrow e1 | EMeta(_,e1)
| ECheckType(e1,_) | EDisplay(e1,_) | ECast(e1,_) | EUntyped e1 -> loop e1;
| EArray(e1,e2) | EBinop(_,e1,e2) | EIn(e1,e2) | EFor(e1,e2) | EWhile(e1,e2,_) | EIf(e1,e2,None) -> loop e1; loop e2;
| EArray(e1,e2) | EBinop(_,e1,e2) | EFor(e1,e2) | EWhile(e1,e2,_) | EIf(e1,e2,None) -> loop e1; loop e2;
| ETernary(e1,e2,e3) | EIf(e1,e2,Some e3) -> loop e1; loop e2; loop e3;
| EArrayDecl el | ENew(_,el) | EBlock el -> List.iter loop el
| ECall(e1,el) -> loop e1; exprs el;
Expand Down Expand Up @@ -706,7 +703,6 @@ let s_expr e =
| EBlock [] -> "{ }"
| EBlock el -> s_block tabs el "{" "\n" "}"
| EFor (e1,e2) -> "for (" ^ s_expr_inner tabs e1 ^ ") " ^ s_expr_inner tabs e2
| EIn (e1,e2) -> s_expr_inner tabs e1 ^ " in " ^ s_expr_inner tabs e2
| EIf (e,e1,None) -> "if (" ^ s_expr_inner tabs e ^ ") " ^ s_expr_inner tabs e1
| EIf (e,e1,Some e2) -> "if (" ^ s_expr_inner tabs e ^ ") " ^ s_expr_inner tabs e1 ^ " else " ^ s_expr_inner tabs e2
| EWhile (econd,e,NormalWhile) -> "while (" ^ s_expr_inner tabs econd ^ ") " ^ s_expr_inner tabs e
Expand Down
8 changes: 4 additions & 4 deletions src/syntax/parser.mly
Expand Up @@ -120,7 +120,8 @@ let precedence op =
| OpBoolAnd -> 7, left
| OpBoolOr -> 8, left
| OpArrow -> 9, right
| OpAssign | OpAssignOp _ -> 10, right
| OpIn -> 10, right
| OpAssign | OpAssignOp _ -> 11, right

let is_not_assign = function
| OpAssign | OpAssignOp _ -> false
Expand Down Expand Up @@ -210,6 +211,7 @@ let reify in_macro =
| OpAssignOp o -> mk_enum "Binop" "OpAssignOp" [to_binop o p] p
| OpInterval -> op "OpInterval"
| OpArrow -> op "OpArrow"
| OpIn -> op "OpIn"
in
let to_string s p =
let len = String.length s in
Expand Down Expand Up @@ -432,8 +434,6 @@ let reify in_macro =
expr "EBlock" [to_expr_array el p]
| EFor (e1,e2) ->
expr "EFor" [loop e1;loop e2]
| EIn (e1,e2) ->
expr "EIn" [loop e1;loop e2]
| EIf (e1,e2,eelse) ->
expr "EIf" [loop e1;loop e2;to_opt to_expr eelse p]
| EWhile (e1,e2,flag) ->
Expand Down Expand Up @@ -1515,7 +1515,7 @@ and expr_next e1 = parser
| [< '(Question,_); e2 = expr; '(DblDot,_); e3 = expr >] ->
(ETernary (e1,e2,e3),punion (pos e1) (pos e3))
| [< '(Kwd In,_); e2 = expr >] ->
(EIn (e1,e2), punion (pos e1) (pos e2))
make_binop OpIn e1 e2
| [< >] -> e1

and parse_guard = parser
Expand Down
2 changes: 1 addition & 1 deletion src/typing/type.ml
Expand Up @@ -2540,7 +2540,7 @@ module TExprToExpr = struct
EVars ([(v.v_name,v.v_pos), mk_type_hint v.v_type v.v_pos, eopt eo])
| TBlock el -> EBlock (List.map convert_expr el)
| TFor (v,it,e) ->
let ein = (EIn ((EConst (Ident v.v_name),it.epos),convert_expr it),it.epos) in
let ein = (EBinop (OpIn,(EConst (Ident v.v_name),it.epos),convert_expr it),it.epos) in
EFor (ein,convert_expr e)
| TIf (e,e1,e2) -> EIf (convert_expr e,convert_expr e1,eopt e2)
| TWhile (e1,e2,flag) -> EWhile (convert_expr e1, convert_expr e2, flag)
Expand Down
6 changes: 3 additions & 3 deletions src/typing/typer.ml
Expand Up @@ -2166,6 +2166,8 @@ and type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op wt p =
mk (TNew ((match t with TInst (c,[]) -> c | _ -> assert false),[],[e1;e2])) t p
| OpArrow ->
error "Unexpected =>" p
| OpIn ->
error "Unexpected in" p
| OpAssign
| OpAssignOp _ ->
assert false
Expand Down Expand Up @@ -3381,7 +3383,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
| _ -> error "Identifier expected" (pos e1)
in
let rec loop display e1 = match fst e1 with
| EIn(e1,e2) -> loop_ident display e1,e2
| EBinop(OpIn,e1,e2) -> loop_ident display e1,e2
| EDisplay(e1,_) -> loop true e1
| _ -> error "For expression should be 'v in expr'" (snd it)
in
Expand Down Expand Up @@ -3428,8 +3430,6 @@ and type_expr ctx (e,p) (with_type:with_type) =
ctx.in_loop <- old_loop;
old_locals();
e
| EIn _ ->
error "This expression is not allowed outside a for loop" p
| ETernary (e1,e2,e3) ->
type_expr ctx (EIf (e1,e2,Some e3),p) with_type
| EIf (e,e1,e2) ->
Expand Down

2 comments on commit 52f680c

@hughsando
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this node make it to the backend?
Adding a cppia op code is not going to do much without a change to hxcpp too. Perhaps I should generate a "unsupported operation" error?

@Simn
Copy link
Member

@Simn Simn commented on 52f680c Aug 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't make it to the backend. But maybe it's still better to have it as "unsupported operation" error like you say.

Please sign in to comment.