예제 #1
0
        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");
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        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--;
        }
예제 #4
0
 public abstract void visit(DynamicDispatch dynamicDispatch);