示例#1
0
        private AssignStat AssignStat()
        {
            string first = "id";

            this.SkipErrors(first);

            var    lookaheadToken = this.TokenStream.Peek();
            string lookahead      = lookaheadToken.AToCCFormat();

            if (first.HasToken(lookahead))
            {
                this.ApplyDerivation("assignStat -> variable '=' expr");

                var assignStatement = new AssignStat(lookaheadToken.SourceLocation);

                var variable = Variable();
                Match("=");
                var expr = Expr();

                assignStatement.Variable        = variable;
                assignStatement.ExpressionValue = expr;

                return(assignStatement);
            }

            return(null);
        }
 public override void Visit(AssignStat assignStat)
 {
     if (assignStat.ExpressionValue is Node expression)
     {
         if (assignStat.Variable.SemanticalType != expression.SemanticalType)
         {
             ErrorManager.Add($"Could not convert {expression.SemanticalType} to a {assignStat.Variable.SemanticalType}.", assignStat.Location);
         }
         assignStat.SemanticalType = expression.SemanticalType;
     }
     else
     {
         ErrorManager.Add($"Could not establish an expression value.", assignStat.Location);
     }
 }
    }         // NT_Stat

    private static void NT_IncDecAssignOrCallStat(out Stat s)
    {
        int    spix = 0;
        Symbol sy = null;
        Expr   lhs = null, e = null;
        SrcPos sp = null;

        s = null;

        for (;;)
        {
            switch (Syn.Interpret())
            {
            case 0:
                return;

            case 1:
                Lex.GETidentAttr(out spix);
                break;

            case 2: // SEM
                sy = SymTab.SymbolOf(spix, Symbol.Kind.varKind,
                                     Symbol.Kind.parKind,
                                     Symbol.Kind.funcKind);

                break;

            case 3: // SEM
                s = new IncStat(sp, new VarOperand(sy));

                break;

            case 4: // SEM
                s = new DecStat(sp, new VarOperand(sy));

                break;

            case 5: // SEM
                lhs = new VarOperand(sy);

                break;

            case 6: // SEM
                sp = new SrcPos();

                break;

            case 7:
                NT_Expr(out e);
                break;

            case 8: // SEM
                lhs = new ArrIdxOperator(sp, new VarOperand(sy), e);

                break;

            case 9: // SEM
                sp = new SrcPos();

                break;

            case 10:
                NT_Expr(out e);
                break;

            case 11: // SEM
                s = new AssignStat(sp, lhs, e);

                break;

            case 12: // SEM
                sp = new SrcPos();

                break;

            case 13:
                NT_ActParList(out e);
                break;

            case 14: // SEM
                s = new CallStat(sp, sy, e);

                break;
            } // switch
        }     // for
    }         // NT_IncDecAssignOrCallStat
    }         // NT_ConstDecl

    private static void NT_Init(out Stat s,
                                ref Symbol sy)
    {
        int fact = 1, number = 0;

        s = null;

        for (;;)
        {
            switch (Syn.Interpret())
            {
            case 0:
                return;

            case 1: // SEM
                if (sy.type != Type.boolType)
                {
                    SemErr("invalid type");
                }
                sy.val = 0;

                break;

            case 2: // SEM
                if (sy.type != Type.boolType)
                {
                    SemErr("invalid type");
                }
                sy.val = 1;

                break;

            case 3: // SEM
                fact = -1;

                break;

            case 4:
                Lex.GETnumberAttr(out number);
                break;

            case 5: // SEM
                if (sy.type.IsPtrType())
                {
                    if (number != 0)
                    {
                        SemErr("invalid value");
                    }
                }
                else if (sy.type.kind != Type.Kind.intKind)
                {
                    SemErr("invalid type");
                }
                sy.val = fact * number;

                break;

            case 6: // SEM
                if (sy.kind == Symbol.Kind.varKind && loopLevel > 0)
                {
                    s = new AssignStat(new SrcPos(),
                                       new VarOperand(sy),
                                       new LitOperand(sy.type, sy.val));
                }

                break;
            } // switch
        }     // for
    }         // NT_Init
示例#5
0
        private static void CgAssignStat(FuncInfo fi, AssignStat node)
        {
            var exps  = RemoveTailNil(node.ExpList);
            var nExps = exps.Count;
            var nVars = node.VarList.Count;

            var tRegs   = new int[nVars];
            var kRegs   = new int[nVars];
            var vRegs   = new int[nVars];
            var oldRegs = fi.UsedRegs;

            for (var i = 0; i < node.VarList.Count; i++)
            {
                var exp = node.VarList[i];

                if (exp is TableAccessExp tableAccessExp)
                {
                    tRegs[i] = fi.AllocReg();
                    CgExp(fi, tableAccessExp.PrefixExp, tRegs[i], 1);
                    kRegs[i] = fi.AllocReg();
                    CgExp(fi, tableAccessExp.KeyExp, kRegs[i], 1);
                }
                else if (exp is NameExp nameExp)
                {
                    var name = nameExp.Name;

                    if (fi.SlotOfLocVar(name) < 0 && fi.IndexOfUpval(name) < 0)
                    {
                        kRegs[i] = -1;
                        fi.IndexOfConstant(name, out var constIdx);
                        if (constIdx > 0xff)
                        {
                            kRegs[i] = fi.AllocReg();
                        }
                    }
                }
            }

            for (var i = 0; i < nVars; i++)
            {
                vRegs[i] = fi.UsedRegs + i;
            }

            if (nExps >= nVars)
            {
                for (var i = 0; i < exps.Count; i++)
                {
                    var exp = exps[i];
                    var a   = fi.AllocReg();
                    if (i >= nVars && i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        CgExp(fi, exp, a, 0);
                    }
                    else
                    {
                        CgExp(fi, exp, a, 1);
                    }
                }
            }
            else
            {
                var multRet = false;

                for (var i = 0; i < exps.Count; i++)
                {
                    var exp = exps[i];
                    var a   = fi.AllocReg();
                    if (i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        multRet = true;
                        var n = nVars - nExps + 1;
                        CgExp(fi, exp, a, n);
                        fi.AllocRegs(n - 1);
                    }
                    else
                    {
                        CgExp(fi, exp, a, 1);
                    }
                }

                if (!multRet)
                {
                    var n = nVars - nExps;
                    var a = fi.AllocRegs(n);
                    fi.EmitLoadNil(a, n);
                }
            }

            for (var i = 0; i < node.VarList.Count; i++)
            {
                var exp = node.VarList[i];

                if (exp is NameExp nameExp)
                {
                    var varName = nameExp.Name;
                    var a       = fi.SlotOfLocVar(varName);

                    if (a >= 0)
                    {
                        fi.EmitMove(a, vRegs[i]);
                    }
                    else
                    {
                        var b = fi.IndexOfUpval(varName);
                        if (b >= 0)
                        {
                            fi.EmitSetUpval(vRegs[i], b);
                        }
                        else
                        {
                            a = fi.SlotOfLocVar("_ENV");
                            if (a >= 0)
                            {
                                if (kRegs[i] < 0)
                                {
                                    fi.IndexOfConstant(varName, out var constIdx);
                                    b = 0x100 + constIdx;
                                    fi.EmitSetTable(a, b, vRegs[i]);
                                }
                                else
                                {
                                    fi.EmitSetTable(a, kRegs[i], vRegs[i]);
                                }
                            }
                            else
                            {
                                a = fi.IndexOfUpval("_ENV");
                                if (kRegs[i] < 0)
                                {
                                    fi.IndexOfConstant(varName, out var idx);
                                    b = 0x100 + idx;
                                    fi.EmitSetTabUp(a, b, vRegs[i]);
                                }
                                else
                                {
                                    fi.EmitSetTable(a, kRegs[i], vRegs[i]);
                                }
                            }
                        }
                    }
                }
                else
                {
                    fi.EmitSetTable(tRegs[i], kRegs[i], vRegs[i]);
                }
            }

            fi.UsedRegs = oldRegs;
        }
示例#6
0
    } // DumpSymTab

    // === generate source text from symbol table and AST ===

    public static void WriteStat(Stat stat)
    {
        switch (stat.kind)
        {
        case Stat.Kind.emptyStatKind:
            genMcpp.WriteLine(Indent() + ";");
            break;

        case Stat.Kind.blockStatKind:
            BlockStat b_s = (BlockStat)stat;
            genMcpp.WriteLine(Indent() + "{");
            IncIndent();
            WriteStatList(b_s.statList);
            DecIndent();
            genMcpp.WriteLine(Indent() + "}");
            break;

        case Stat.Kind.incStatKind:
            IncStat i_s = (IncStat)stat;
            genMcpp.WriteLine(Indent() + i_s.vo.sy + "++;");
            break;

        case Stat.Kind.decStatKind:
            DecStat d_s = (DecStat)stat;
            genMcpp.WriteLine(Indent() + d_s.vo.sy + "--;");
            break;

        case Stat.Kind.assignStatKind:
            AssignStat a_s = (AssignStat)stat;
            genMcpp.WriteLine(Indent() + a_s.lhs + " = " + a_s.rhs + ";");
            break;

        case Stat.Kind.callStatKind:
            CallStat c_s = (CallStat)stat;
            genMcpp.WriteLine(Indent() + c_s.func + "(" + c_s.apl + ");");
            break;

        case Stat.Kind.ifStatKind:
            IfStat if_s = (IfStat)stat;
            genMcpp.WriteLine(Indent() + "if (" + if_s.cond + ")");
            IncIndent();
            WriteStatList(if_s.thenStat);
            DecIndent();
            if (if_s.elseStat != null)
            {
                genMcpp.WriteLine(Indent() + "else ");
                IncIndent();
                WriteStatList(if_s.elseStat);
                DecIndent();
            } // if
            break;

        case Stat.Kind.whileStatKind:
            WhileStat w_s = (WhileStat)stat;
            genMcpp.WriteLine(Indent() + "while (" + w_s.cond + ")");
            IncIndent();
            WriteStatList(w_s.body);
            DecIndent();
            break;

        case Stat.Kind.breakStatKind:
            genMcpp.WriteLine(Indent() + "break;");
            break;

        case Stat.Kind.inputStatKind:
            InputStat in_s = (InputStat)stat;
            genMcpp.WriteLine(Indent() + "cin >> " + in_s.vo.sy + ";");
            break;

        case Stat.Kind.outputStatKind:
            OutputStat out_s = (OutputStat)stat;
            genMcpp.Write(Indent() + "cout");
            foreach (Object o in out_s.values)
            {
                genMcpp.Write(" << ");
                if (o is Expr)
                {
                    genMcpp.Write(o);
                }
                else if (o is String)
                {
                    String s = o as String;
                    if (s == "\n")
                    {
                        genMcpp.Write("endl");
                    }
                    else
                    {
                        genMcpp.Write('"' + s + '"');
                    }
                }
                else
                {
                    throw new Exception("invalid value");
                }
            } // foreach
            genMcpp.WriteLine(";");
            break;

        case Stat.Kind.deleteStatKind:
            DeleteStat del_s = (DeleteStat)stat;
            genMcpp.WriteLine(Indent() + "delete[] " +
                              NameList.NameOf(del_s.vo.sy.spix) + ";");
            break;

        case Stat.Kind.returnStatKind:
            ReturnStat r_s = (ReturnStat)stat;
            genMcpp.Write(Indent() + "return");
            if (r_s.e != null)
            {
                genMcpp.Write(" " + r_s.e);
            }
            genMcpp.WriteLine(";");
            break;

        default:
            throw new Exception("invalid statement kind");
        } // switch
    }     // WriteStatList
示例#7
0
 public virtual void Visit(AssignStat assignStat)
 {
 }
 public override void Visit(AssignStat assignStat)
 {
     this.LoadAndStore(assignStat.ExpressionValue, assignStat.Variable, assignStat.ExpressionValue.NodeMemorySize, $"{assignStat}");
 }