let generate_refinesw (klass, ret, args, dispatchuid, cases) =
let rettype = match ret with
| None -> "void "
| Some(atype) -> Format.sprintf "struct %s*" atype in
let this = (Format.sprintf "struct %s*" klass, "this") in
let formals = List.mapi (fun i t -> (Format.sprintf "struct %s*" t, Format.sprintf "varg_%d" i)) args in
let signature = String.concat ", " (List.map (fun (t, v) -> t ^ v) (this::formals)) in
let actuals = List.map snd formals in
let withthis kname = String.concat ", " ((Format.sprintf "(struct %s*) this" kname)::actuals) in
let invoc fuid kname = Format.sprintf "%s(%s)" fuid (withthis kname) in
let execute fuid kname = match ret with
| None -> Format.sprintf "%s; return;" (invoc fuid kname)
| Some(atype) -> Format.sprintf "return ((struct %s*)(%s));" (String.trim atype) (invoc fuid kname) in
let unroll_case (kname, fuid) =
Format.sprintf "\tif( IS_CLASS( this, \"%s\") )\n\t\t{ %s }\n" (String.trim kname) (execute fuid kname) in
let generated = List.map unroll_case cases in
let fail = Format.sprintf "REFINE_FAIL(\"%s\")" (String.trim klass) in
Format.sprintf "%s%s(%s)\n{\n%s\n\t%s\n}\n\n" rettype dispatchuid signature (String.concat "" generated) fail