summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/mod_student/translator.ml115
1 files changed, 110 insertions, 5 deletions
diff --git a/source/mod_student/translator.ml b/source/mod_student/translator.ml
index 1514319..6831038 100644
--- a/source/mod_student/translator.ml
+++ b/source/mod_student/translator.ml
@@ -114,6 +114,8 @@ module Make() = struct
let i32_0 = Int32.of_int 0
let i32_1 = Int32.of_int 1
+ let int32_of_bool b = Int32.of_int (
+ if b then 1 else 0 )
(* --------------------------------------------------- *)
let rec translate_expression env current_bb = function
@@ -121,8 +123,74 @@ module Make() = struct
current_bb, E_Int (Int32.of_int @@ Char.code value)
| Ast.EXPR_Id {id; _} ->
+
current_bb, E_Reg (Environment.lookup_var id env)
-
+ | Ast.EXPR_Int {value;_} ->
+ current_bb, E_Int value
+
+ | Ast.EXPR_Bool {value; _} ->
+ current_bb, E_Int (int32_of_bool value)
+
+ | Ast.EXPR_Binop {lhs;rhs;op=Ast.BINOP_Add;tag;_} ->
+ let reg= allocate_register() in
+ let current_bb,lhs = translate_expression env current_bb lhs in
+ let current_bb,rhs = translate_expression env current_bb rhs in
+ begin
+ match Hashtbl.find node2type tag with
+ | TP_Int -> append_instruction current_bb @@ I_Add ( reg, lhs, rhs)
+ | TP_Array _ -> append_instruction current_bb @@ I_Concat ( reg, lhs, rhs)
+ | TP_Bool -> failwith "Internal error"
+ end;
+ current_bb, E_Reg reg
+
+ | Ast.EXPR_Binop {lhs;rhs;op=Ast.BINOP_Sub;_} ->
+ let reg= allocate_register() in
+ let current_bb,lhs = translate_expression env current_bb lhs in
+ let current_bb,rhs = translate_expression env current_bb rhs in
+ append_instruction current_bb @@ I_Sub ( reg, lhs, rhs);
+ current_bb, E_Reg reg
+
+ | Ast.EXPR_Binop {lhs;rhs;op=Ast.BINOP_Mult;_} ->
+ let reg= allocate_register() in
+ let current_bb,lhs = translate_expression env current_bb lhs in
+ let current_bb,rhs = translate_expression env current_bb rhs in
+ append_instruction current_bb @@ I_Mul ( reg, lhs, rhs);
+ current_bb, E_Reg reg
+
+ | Ast.EXPR_Binop {lhs;rhs;op=Ast.BINOP_Div;_} ->
+ let reg= allocate_register() in
+ let current_bb,lhs = translate_expression env current_bb lhs in
+ let current_bb,rhs = translate_expression env current_bb rhs in
+ append_instruction current_bb @@ I_Div ( reg, lhs, rhs);
+ current_bb, E_Reg reg
+
+ | Ast.EXPR_Binop {lhs;rhs;op=Ast.BINOP_Rem;_} ->
+ let reg= allocate_register() in
+ let current_bb,lhs = translate_expression env current_bb lhs in
+ let current_bb,rhs = translate_expression env current_bb rhs in
+ append_instruction current_bb @@ I_Rem ( reg, lhs, rhs);
+ current_bb, E_Reg reg
+ | Ast.EXPR_Call call ->
+ let reg =allocate_register() in
+ let current_bb,env = translate_call env current_bb call [reg] in
+ current_bb, E_Reg reg
+ | Ast.EXPR_Relation {op;lhs;rhs;_} ->
+ begin
+ let convert_rel = function
+ | Ast.RELOP_Eq -> COND_Eq
+ | Ast.RELOP_Ne -> COND_Ne
+ | Ast.RELOP_Lt -> COND_Lt
+ | Ast.RELOP_Gt -> COND_Gt
+ | Ast.RELOP_Le -> COND_Le
+ | Ast.RELOP_Ge -> COND_Ge
+ in
+ let reg = allocate_register() in
+ let current_bb,lhs = translate_expression env current_bb lhs in
+ let current_bb,rhs = translate_expression env current_bb rhs in
+ append_instruction current_bb @@ I_Set(reg,convert_rel op,lhs,rhs);
+ current_bb, E_Reg reg
+
+ end
| _ ->
failwith "not yet implemented"
@@ -134,9 +202,9 @@ module Make() = struct
| Ast.EXPR_Bool {value=false; _} ->
set_jump current_bb else_bb;
allocate_block ()
-
+
(* Zaimplementuj dodatkowe przypadki *)
-
+
| e ->
let current_bb, res = translate_expression env current_bb e in
let next_bb = allocate_block () in
@@ -145,14 +213,51 @@ module Make() = struct
(* --------------------------------------------------- *)
-
+ and translate_call env current_bb (Ast.Call {callee;arguments;tag;_}) returns =
+ begin
+ let rec aux current_bb = function
+ | [] -> []
+ | x::xs -> let current_bb,r =
+ translate_expression env current_bb x
+ in r::(aux current_bb xs)
+ in
+ let arguments = aux current_bb arguments in
+ append_instruction current_bb @@ I_Call ( returns, Environment.lookup_proc callee env, arguments, []);
+ current_bb,env
+ end
let rec translate_statement env current_bb = function
+ | Ast.STMT_Return {values;_} ->
+ begin
+ let rec aux current_bb = function
+ | [] -> []
+ | x::xs -> let current_bb,r =
+ translate_expression env current_bb x
+ in r::(aux current_bb xs)
+ in
+ set_return current_bb (aux current_bb values);
+ current_bb,env
+ end
+ | STMT_Assign {lhs=Ast.LVALUE_Id{id;_};rhs;_} ->
+ let current_bb, reg = translate_expression env current_bb rhs in
+ let my_reg = allocate_register() in
+ append_instruction current_bb @@ I_Move (my_reg, reg);
+ current_bb, (Environment.add_var id my_reg env)
+ | STMT_Call call ->
+ translate_call env current_bb call []
| _ ->
failwith "not yet implemented"
and translate_block env current_bb (Ast.STMTBlock {body; _}) =
- failwith "not yet implemented"
+ begin
+ let rec aux env current_bb = function
+ | [] -> env,current_bb
+ | x::xs -> let current_bb,env =
+ translate_statement env current_bb x
+ in aux env current_bb xs
+ in aux env current_bb body
+ end
+
let bind_var_declaration env vardecl =
let r = allocate_register () in