let c_instruction (i: instruction) (out: out_channel) (pl: element list) (proct: proc_table) : element list = match i with
(CPY,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ ";\n"); pl
| (AGET,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (array_get a b) ^ ";\n"); pl
| (ASET,a,b,c) -> output_string out ((array_get a b) ^ "\t=\t" ^ (c_element c) ^ ";\n"); pl
| (ADD,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ "+" ^ (c_element b) ^ ";\n"); pl
| (SUB,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ "-" ^ (c_element b) ^ ";\n"); pl
| (MUL,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ "*" ^ (c_element b) ^ ";\n"); pl
| (DIV,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ "/" ^ (c_element b) ^ ";\n"); pl
| (AND,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ "&&" ^ (c_element b) ^ ";\n"); pl
| (OR,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ "||" ^ (c_element b) ^ ";\n"); pl
| (NOT,a,b,c) -> output_string out ((c_element c) ^ "= !" ^ (c_element a) ^ ";\n"); pl
| (CNE,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ "!=" ^ (c_element b) ^ ";\n"); pl
| (CG,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ ">" ^ (c_element b) ^ ";\n"); pl
| (CGE,a,b,c) -> output_string out ((c_element c) ^ "\t=\t" ^ (c_element a) ^ ">=" ^ (c_element b) ^ ";\n"); pl
| (JNE,a,b,c) -> output_string out ("if (" ^ (c_element a) ^ "!=" ^ (c_element b) ^ ") goto " ^ (c_element c) ^ ";\n"); pl
| (GOTO,a,b,c) -> output_string out ("goto " ^ (c_element a) ^ ";\n"); pl
| (HALT,a,b,c) -> output_string out ("exit(0);\n"); pl
| (OUT,a,b,c) -> (
match a with
Reg(r,t) -> (
match t with
DInt -> output_string out ("printf(\"%d\\n\", reg[" ^ (string_of_int r) ^ "].i);\n"); pl
| DFloat -> output_string out ("printf(\"%f\\n\", reg[" ^ (string_of_int r) ^ "].f);\n"); pl
| _ -> raise (TYPE_ERROR "Unable to retrieve data type")
)
| Off(o,tp,b) -> (match tp with
DInt -> (
if b then (
(output_string out (
"printf(\"%d\\n\", stack[baseptr + " ^ (string_of_int o) ^ "]" ^ (getElementType a) ^
");\n"
)); pl
) else (
(output_string out (
"printf(\"%d\\n\", stack[" ^ (string_of_int o) ^ "]" ^ (getElementType a) ^ ");\n"
)); pl
)
)
| DFloat -> (
if b then (
(output_string out (
"printf(\"%f\\n\", stack[baseptr + " ^ (string_of_int o) ^ "]" ^ (getElementType a) ^
");\n"
)); pl
) else (
(output_string out (
"printf(\"%f\\n\", stack[" ^ (string_of_int o) ^ "]" ^ (getElementType a) ^ ");\n"
)); pl
)
)
| _ -> raise (TYPE_ERROR "Unable to retrieve data type")
)
| _ -> (raise (CONFIRM_RULE "The output is only for variables, so this case never occurs"))
)
| (NOP,a,b,c) -> output_string out ("\n"); pl
| (PARAM,a,b,c) -> let newpl = a::pl in newpl
| (CALL,a,b,c) -> (push_params a pl proct out); output_string out (c_subroutine a c); []
| (RET,a,b,c) -> output_string out ("return " ^ (c_element a) ^ ";\n"); pl