Exemple #1
0
        public Instr Emit_Asgn(AsgnNode node)
        {
            // 先编译右值
            node.cdr.Compile(this);

            // 然后把堆栈中的值赋给左值
            return(GenAssignment(node.car, vm.CurrentScope.sp));
        }
Exemple #2
0
        private void GenAssignment(CodeGenScope s, AstNode tree, int sp, int val)
        {
            int      idx;
            AsgnNode asgnNode = tree.As <AsgnNode> ();

            Gen(s, asgnNode.cdr, VAL);
            Pop(s);

            switch (asgnNode.car.type)
            {
            case AstNodeType.GVAR:
                idx = NewSym(s, asgnNode.car.As <GlobalVarNode>().name);
                GenOp_2(s, OpCode.SetGV, sp, idx);
                break;

            case AstNodeType.ARG:
            case AstNodeType.LVAR:
                idx = s.FindLocalVarIdx(asgnNode.car.As <SymNode> ().name);
                if (idx != -1)
                {
                    if (idx != sp)
                    {
                        GenMove(s, idx, sp, val == 1);
                        if (val == 1 && s.parser.on_eval)
                        {
                            GenOp_0(s, OpCode.Nop);
                        }
                    }
                    break;
                }
                else
                {
                    int          lv = 0;
                    CodeGenScope up = s.prev;

                    while (up != null)
                    {
                        idx = up.FindLocalVarIdx(asgnNode.car.As <SymNode> ().name);
                        if (idx != -1)
                        {
                            GenOp_3(s, OpCode.SetUpVar, sp, idx, lv);
                            break;
                        }

                        lv++;
                        up = up.prev;
                    }
                }
                break;

            case AstNodeType.IVAR:
                idx = NewSym(s, nsym(asgnNode.car));
                GenOp_2(s, OpCode.SetIV, sp, idx);
                break;

            case AstNodeType.CVAR:
                idx = NewSym(s, nsym(asgnNode.car));
                GenOp_2(s, OpCode.SetCV, sp, idx);
                break;

            case AstNodeType.CONST:
                idx = NewSym(s, nsym(asgnNode.car));
                GenOp_2(s, OpCode.SetConst, sp, idx);
                break;

            case AstNodeType.COLON2:
                // TODO:
                break;

            case AstNodeType.CALL:
            case AstNodeType.SCALL:
                Push(s);
                GenCall(s, asgnNode.car, sp, NOVAL, asgnNode.car.type == AstNodeType.SCALL);
                Pop(s);
                if (val != NOVAL)
                {
                    GenMove(s, s.sp, sp, false);
                }
                break;

            case AstNodeType.MASGN:
                // TODO:
                break;

            case AstNodeType.NIL:
                break;

            default:
                Console.WriteLine($"unknown lhs {asgnNode.car.type}\n");
                break;
            }

            if (val != NOVAL)
            {
                Push(s);
            }
        }