Skip to content

Commit

Permalink
Fix arithmetic comparisons (winbat).
Browse files Browse the repository at this point in the history
Compile arithmetic comparisons to if statements.
Split subexpressions of arithmetic comparisions.
  • Loading branch information
BYVoid committed Oct 20, 2013
1 parent 21fc146 commit e6e44fc
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ let test_cases = "Batsh Unit Tests" >::: [
"[Bash]Function" >:: test "function" test_bash;
"[Bash]Recursion" >:: test "recursion" test_bash;
"[Winbat]Block" >:: test "block" test_winbat;
(* "[Winbat]Arith" >:: test "arith" test_winbat; *)
"[Winbat]Arith" >:: test "arith" test_winbat;
"[Winbat]Assignment" >:: test "assignment" test_winbat;
(* "[Winbat]Array" >:: test "array" test_winbat; *)
(* "[Winbat]Expressions" >:: test "expr" test_winbat; *)
Expand Down
1 change: 1 addition & 0 deletions src/winbat_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type varstring = [
and varstrings = varstring list

type comparison = [
| `UniCompare of (string * varstrings)
| `StrCompare of (string * varstrings * varstrings)
]

Expand Down
45 changes: 41 additions & 4 deletions src/winbat_compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ let compile_expression_to_comparison
~(scope : Symbol_table.Scope.t)
: comparison =
match expr with
| ArithUnary (operator, sub_expr) ->
let sub_expr = compile_expression sub_expr ~symtable ~scope in
`UniCompare (operator, sub_expr)
| StrCompare (operator, left, right)
| ArithBinary (operator, left, right) ->
let left = compile_expression left ~symtable ~scope in
Expand All @@ -113,9 +116,9 @@ let compile_expression_to_comparison
let lvalue = `Var (compile_leftvalue lvalue ~symtable ~scope) in
`StrCompare ("==", [lvalue], [`Str "1"])
| Bool true | Int 1 ->
`StrCompare ("==", [`Str "1"], [`Str "1"])
`UniCompare ("", [`Str "1"])
| Bool false | Int _ ->
`StrCompare ("==", [`Str "0"], [`Str "1"])
`UniCompare ("!", [`Str "1"])
| _ ->
failwith "Expression can not compile to comparison"

Expand Down Expand Up @@ -181,6 +184,38 @@ let rec compile_expression_statement
Sexp.output_hum stderr (Batsh_ast.sexp_of_expression expr);
assert false (* TODO *)

let compile_arith_assignment
(lvalue : Batsh_ast.leftvalue)
(expr : Batsh_ast.expression)
~(symtable : Symbol_table.t)
~(scope : Symbol_table.Scope.t)
: statements =
match expr with
| ArithBinary ("===", _, _)
| ArithBinary ("!==", _, _)
| ArithBinary (">", _, _)
| ArithBinary ("<", _, _)
| ArithBinary (">=", _, _)
| ArithBinary ("<=", _, _)
| ArithUnary ("!", _) ->
let cond = compile_expression_to_comparison expr ~symtable ~scope in
let lvalue = compile_leftvalue lvalue ~symtable ~scope in
let true_stmt = [`ArithAssign (lvalue, `Int 1)] in
let false_stmt = [`ArithAssign (lvalue, `Int 0)] in
[`IfElse (cond, true_stmt, false_stmt)]
| Bool _
| Int _
| Float _
| ArithUnary _
| ArithBinary _ ->
let lvalue = compile_leftvalue lvalue ~symtable ~scope in
let arith = compile_expression_to_arith expr ~symtable ~scope in
[`ArithAssign (lvalue, arith)]
| _ ->
Sexp.output_hum stderr (Batsh_ast.sexp_of_leftvalue lvalue);
Sexp.output_hum stderr (Batsh_ast.sexp_of_expression expr);
failwith "Can not reach here."

let rec compile_statement
(stmt : Batsh_ast.statement)
~(symtable : Symbol_table.t)
Expand Down Expand Up @@ -241,8 +276,7 @@ and compile_assignment
| Float _
| ArithUnary _
| ArithBinary _ ->
let lvalue = compile_leftvalue lvalue ~symtable ~scope in
[`ArithAssign (lvalue, compile_expression_to_arith expr ~symtable ~scope)]
compile_arith_assignment lvalue expr ~symtable ~scope
| List exprs ->
List.concat (List.mapi exprs ~f: (fun i expr ->
compile_assignment (ListAccess (lvalue, (Int i))) expr ~symtable ~scope
Expand Down Expand Up @@ -338,6 +372,9 @@ let compile_function_comparison
~(scope : Symbol_table.Scope.t)
: comparison =
match cond with
| `UniCompare (operator, expr) ->
`UniCompare (operator,
compile_function_varstrings expr ~symtable ~scope)
| `StrCompare (operator, left, right) ->
`StrCompare (operator,
compile_function_varstrings left ~symtable ~scope,
Expand Down
10 changes: 10 additions & 0 deletions src/winbat_format.ml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ let print_parameters buf (params : parameters) =

let print_comparison buf (condition : comparison) =
match condition with
| `UniCompare (operator, expr) -> (
let sign = match operator with
| "" -> "EQU"
| "!" -> "NEQ"
| _ -> failwith ("Unknown operator: " ^ operator)
in
bprintf buf "%a %s 1"
print_varstrings expr
sign
)
| `StrCompare (operator, left, right) -> (
let sign = match operator with
| "==" | "===" -> "EQU"
Expand Down
12 changes: 10 additions & 2 deletions src/winbat_transform.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,22 @@ let rec split_expression
| Bool _ | Int _ | Float _ | Leftvalue _ ->
Dlist.empty (), expr
| ArithUnary (operator, expr) ->
let split = match operator with
| "!" -> true
| _ -> false
in
let assignments, expr = split_expression expr ~symtable ~scope
~split_arith:false
~split_arith:split
~split_string:true
in
split_when ~cond:split_arith assignments (ArithUnary (operator, expr))
| ArithBinary (operator, left, right) ->
let split = match operator with
| "===" | "!==" | ">" | "<" | ">=" | "<=" -> true
| _ -> false
in
let assignments, (left, right) = split_binary (left, right)
~split_arith:false
~split_arith:split
~split_string:true
in
split_when ~cond:split_arith
Expand Down
2 changes: 2 additions & 0 deletions tests/arith.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ println(4 < 5);
println(6 >= 2);
println(19 <= 30);
println(!true);
println(!false);
println(!(2 - 1));
2 changes: 2 additions & 0 deletions tests/output/arith.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
1
1
0
1
0

0 comments on commit e6e44fc

Please sign in to comment.