public override void visit(DynamicDispatch ddisp) { int ar_size = AR_BASE_SIZE + ddisp.actual.Length; emit_push(ar_size); emit_sw("fp", ar_size * WORD_SIZE, "sp"); emit_sw("s0", ar_size * WORD_SIZE - WORD_SIZE, "sp"); int formal_offset = 8; foreach (var e in ddisp.actual) { e.accept(this); emit_sw("a0", formal_offset, "sp"); formal_offset += WORD_SIZE; } emit_addiu("fp", "sp", 4); ddisp.obj.accept(this); emit_lw("t1", 8, "a0"); var tmp = method_tbl[ddisp.obj.type.value]; emit_lw("t1", tmp[ddisp.method.value] * WORD_SIZE, "t1"); emit_jalr("t1"); }
public override void visit(DynamicDispatch dyn) { List <Symbol> disptypes = new List <Symbol>(); // get type of object that dispatches dyn.obj.accept(this); Symbol obj_type = dyn.obj.type; // get types of all arguments to dispatch foreach (var expr in dyn.actual) { expr.accept(this); disptypes.Add(expr.type); } if (obj_type == curr_class) { obj_type = curr_class; } if (!mtbl[obj_type].ContainsKey(dyn.method)) { error(dyn, "method " + dyn.method.value + " is not defined in this class"); dyn.type = Constants.OBJECT; return; } bool result = true; for (int i = 0; i < disptypes.Count; i++) { if (!is_subtype(disptypes[i], mtbl[obj_type][dyn.method][i])) { result = false; break; } } if (result) { int length = mtbl[obj_type][dyn.method].Count; dyn.type = mtbl[obj_type][dyn.method][length - 1]; } else { error(dyn, "type mismatch in one of the arguments of the dispatch"); dyn.type = Constants.OBJECT; } }
public override void visit(DynamicDispatch dynamicDispatch) { for (int i = 0; i < depth * 2; i++) { sw.Write(" "); } depth++; sw.WriteLine("_dynamicDispach (" + dynamicDispatch.method + ") : " + dynamicDispatch.type); dynamicDispatch.obj.accept(this); foreach (var item in dynamicDispatch.actual) { item.accept(this); } depth--; }
public abstract void visit(DynamicDispatch dynamicDispatch);