let rec expr_to_cstr (exptype, expr_detail) = exprdetail_to_cstr expr_detail
and exprdetail_to_cstr castexpr_detail =
let generate_deref obj index =
let arrtype = fst obj in
Format.sprintf "((struct %s*)(%s))[INTEGER_OF((%s))]" arrtype (expr_to_cstr obj) (expr_to_cstr index) in
let generate_field obj field =
let exptype = fst obj in
Format.sprintf "(%s)->%s.%s" (expr_to_cstr obj) (GenCast.from_tname exptype) field in
let generate_invocation recvr fname args =
let this = Format.sprintf "((struct %s*)(%s))" (fst recvr) (expr_to_cstr recvr) in
let vals = List.map expr_to_cstr args in
Format.sprintf "%s(%s)" fname (String.concat ", " (this::vals)) in
let generate_vreference vname = function
| Sast.Local -> vname
| Sast.Instance(klass) -> Format.sprintf "(this->%s).%s" klass vname in
let generate_allocation klass fname args =
let vals = List.map expr_to_cstr args in
let alloc = Format.sprintf "MAKE_NEW(%s)" klass in
Format.sprintf "%s(%s)" fname (String.concat ", " (alloc::vals)) in
let generate_array_alloc _ fname args =
let vals = List.map expr_to_cstr args in
Format.sprintf "%s(%s)" fname (String.concat ", " vals) in
let generate_refine args ret = function
| Sast.Switch(_, _, dispatch) ->
let vals = List.map expr_to_cstr args in
Format.sprintf "%s(%s)" dispatch (String.concat ", " ("this"::vals))
| _ -> raise(Failure("Wrong switch applied to refine -- compiler error.")) in
let generate_refinable = function
| Sast.Test(_, _, dispatchby) -> Format.sprintf "%s(this)" dispatchby
| _ -> raise(Failure("Wrong switch applied to refinable -- compiler error.")) in
match castexpr_detail with
| This -> "this"
| Null -> "NULL"
| Id(vname, varkind) -> generate_vreference vname varkind
| NewObj(classname, fname, args) -> generate_allocation classname fname args
| NewArr(arrtype, fname, args) -> generate_array_alloc arrtype fname args
| Literal(lit) -> lit_to_str lit
| Assign((vtype, _) as memory, data) -> Format.sprintf "%s = ((struct %s*)(%s))" (expr_to_cstr memory) vtype (expr_to_cstr data)
| Deref(carray, index) -> generate_deref carray index
| Field(obj, fieldname) -> generate_field obj fieldname
| Invoc(recvr, fname, args) -> generate_invocation recvr fname args
| Unop(op, expr) -> stringify_unop op (expr_to_cstr expr) (fst expr)
| Binop(lop, op, rop) -> stringify_binop op (expr_to_cstr lop) (expr_to_cstr rop) ((fst lop), (fst rop))
| Refine(args, ret, switch) -> generate_refine args ret switch
| Refinable(switch) -> generate_refinable switch
and vdecl_to_cstr (vtype, vname) = Format.sprintf "struct %s*%s" vtype vname