Пример #1
0
        public override bool Std(out Stmt s)
        {
            s = null;
            bool afterRes = false;

            Tokenizer.SetLocalLabelParsingEnable(true);

            if (this.Column != 0)
                throw new ParseException("DAT must be in 1st column", this);
            Tokenizer.Advance();	// past "DAT"
            if (Tokenizer.Current.Text == "(eol)")
                Tokenizer.Advance("(eol)");

            while (!(Tokenizer.Current is BlockDesignatorToken) && Tokenizer.Current.Text != "(eof)")
            {
                IdToken labelToken = null;
                if (Tokenizer.Current is IdToken)
                {
                    labelToken = Tokenizer.GetToken() as IdToken;
                }
                if (Tokenizer.Current.Text.ToUpper() == "ORG")
                {
                    SimpleToken orgToken = Tokenizer.GetToken();
                    if (labelToken != null)
                        SymbolTable.AddDatLabelEntry(4, labelToken, false);
                    Expr orgExpr = null;
                    if (Tokenizer.Current.Text != "(eol)")
                        orgExpr = ParseExpression(Tokenizer, 13);
                    else
                        Tokenizer.PrintWarning("ORG without address (defaults to 0)", Tokenizer.Current);
                    SymbolTable.AddDatOrgEntry(orgToken, orgExpr, Tokenizer.Current.LineNumber);
                    Tokenizer.Advance("(eol)");
                    afterRes = false;
                    continue;
                }
                else if (Tokenizer.Current.Text.ToUpper() == "ORGX")
                {
                    SimpleToken orgxToken = Tokenizer.GetToken();
                    if (labelToken != null)
                        SymbolTable.AddDatLabelEntry(0, labelToken, false);
                    SymbolTable.AddDatOrgxEntry(orgxToken);
                    Tokenizer.Advance("(eol)");
                    afterRes = false;
                    continue;
                }
                else if (Tokenizer.Current.Text.ToUpper() == "RES")
                {
                    SimpleToken resToken = Tokenizer.GetToken();
                    if (labelToken != null)
                        SymbolTable.AddDatLabelEntry(4, labelToken, false);
                    Expr e = null;
                    if (Tokenizer.Current.Text != "(eol)")
                        e = ParseExpression(Tokenizer, 13);
                    else
                        Tokenizer.PrintWarning("RES without count (defaults to 1)", Tokenizer.Current);
                    SymbolTable.AddDatResEntry(resToken, e, Tokenizer.Current.LineNumber);

                    Tokenizer.Advance("(eol)");
                    afterRes = true;
                    continue;
                }
                else if (Tokenizer.Current.Text.ToUpper() == "FIT")
                {
                    SimpleToken fitToken = Tokenizer.GetToken();
                    if (labelToken != null)
                        SymbolTable.AddDatLabelEntry(0, labelToken, false);
                    Expr e = null;
                    if (Tokenizer.Current.Text != "(eol)")
                        e = ParseExpression(Tokenizer, 13);
                    SymbolTable.AddDatFitEntry(fitToken, e);
                    Tokenizer.Advance("(eol)");
                    continue;
                }
                else if (Tokenizer.Current.Text.ToUpper() == "FILE")
                {
                    if (afterRes)
                        Tokenizer.PrintWarning("FILE after RES", Tokenizer.Current);
                    SimpleToken fileToken = Tokenizer.GetToken();
                    if (labelToken != null)
                        SymbolTable.AddDatLabelEntry(0, labelToken, false);
                    SimpleToken filenameToken = Tokenizer.Current;
                    string filename = "";
                    while (true)
                    {
                        Expr e = ParseExpression(Tokenizer, 13);
                        filename += (char)(Expr.EvaluateIntConstant(e));
                        if (Tokenizer.Current.Text != ",")
                            break;
                        Tokenizer.Advance(",");
                    }
                    try
                    {
                        filenameToken.Text = filename;
                        string path = Options.TryPaths(filenameToken);
                        FileStream fs = new FileStream(path + filename, FileMode.Open);
                        BinaryReader br = new BinaryReader(fs);
                        byte[] bytes = br.ReadBytes((int)fs.Length);
                        SymbolTable.AddDatFileEntry(fileToken, filenameToken, bytes, Tokenizer.Current.LineNumber);
                    }
                    catch (Exception e)
                    {
                        throw new ParseException(e.Message, filenameToken);
                    }
                    Tokenizer.Advance("(eol)");
                    continue;
                }
                if (Tokenizer.Current.Text == "(eol)")
                {
                    if (labelToken != null)
                        SymbolTable.AddDatLabelEntry(0, labelToken, true);
                }
                else if (Tokenizer.Current is SizeToken)
                {
                    if (afterRes)
                        Tokenizer.PrintWarning("Data after RES", Tokenizer.Current);
                    SizeToken alignmentToken = Tokenizer.GetToken() as SizeToken;
                    int alignment = SizeSpecifier(alignmentToken.Text);

                    SimpleToken firstToken = alignmentToken;

                    if (labelToken != null)
                    {
                        SymbolTable.AddDatLabelEntry(alignment, labelToken, false);
                        firstToken = labelToken;
                    }

                    if (Tokenizer.Current.Text != "(eol)")
                    {
                        while (true)
                        {
                            int size = alignment;
                            if (Tokenizer.Current is SizeToken)
                            {
                                SizeToken sizeToken = Tokenizer.GetToken() as SizeToken;
                                size = SizeSpecifier(sizeToken.Text);
                                if (size < alignment)
                                    throw new ParseException("Size override must be larger", sizeToken);
                            }
                            Expr dataExpr = ParseExpression(Tokenizer, 13);
                            Expr countExpr = null;
                            if (Tokenizer.Current.Text == "[")
                            {
                                Tokenizer.Advance("[");
                                countExpr = ParseExpression(Tokenizer, 13);
                                Tokenizer.Advance("]");
                            }
                            SymbolTable.AddDatDataEntry(alignment, size, dataExpr, countExpr, firstToken);
                            if (Tokenizer.Current.Text != ",")
                                break;
                            Tokenizer.Advance(",");
                        }
                    }
                    else
                    {
                        SymbolTable.AddDatDataEntry(alignment, alignment, new IntExpr(null, 0), new IntExpr(null, 0), firstToken);
                    }
                    SymbolTable.AddDatSourceReference(Tokenizer.Current);
                }
                else	// assembly language
                {
                    if (labelToken != null)						// handle label if there is one
                        SymbolTable.AddDatLabelEntry(4, labelToken, false);

                    SimpleToken token = Tokenizer.Current;

                    int cond = 0x0f;			// default is IF_ALWAYS
                    CondToken condToken = null;
                    if (Tokenizer.Current is CondToken)
                    {
                        condToken = Tokenizer.GetToken() as CondToken;
                        cond = condToken.CondValue;
                    }
                    if (!(Tokenizer.Current is IPropInstruction))
                        throw new ParseException("Expected instruction mnemonic", Tokenizer.Current);

                    if (afterRes)
                        Tokenizer.PrintWarning("Assembly language after RES", Tokenizer.Current);

                    string mnemonic = Tokenizer.Current.Text.ToUpper();
                    IPropInstruction instruction = Tokenizer.GetToken() as IPropInstruction;
                    if (instruction.Propcode == 0)
                    {
                        if (condToken != null)
                            throw new ParseException("Condition not allowed on NOP", condToken);
                        cond = 0;
                    }
                    Expr eD = null;
                    Expr eS = null;
                    bool immediate = false;
                    if (instruction.InstructionType == InstructionTypeEnum.D || instruction.InstructionType == InstructionTypeEnum.DS)
                    {
                        eD = ParseExpression(Tokenizer, 13);
                    }
                    if (instruction.InstructionType == InstructionTypeEnum.DS)
                    {
                        Tokenizer.Advance(",");
                    }
                    if (instruction.InstructionType == InstructionTypeEnum.S || instruction.InstructionType == InstructionTypeEnum.DS)
                    {
                        if ((mnemonic == "JMP" || mnemonic == "DJNZ" || mnemonic == "TJNZ" || mnemonic == "TJZ") && Tokenizer.Current.Text != "#")
                            Tokenizer.PrintWarning(mnemonic + " with non-immediate operand", Tokenizer.Current);
                        if (Tokenizer.Current.Text == "#" || mnemonic == "CALL")
                        {
                            Tokenizer.Advance("#");
                            immediate = true;
                        }
                        eS = ParseExpression(Tokenizer, 13);
                    }
                    if (mnemonic == "CALL")
                    {
                        if (!(eS is IdExpr))
                            throw new ParseException("Expected label", eS.Token);
                        eD = new IdExpr(new SimpleToken(Tokenizer, SimpleTokenType.Id, eS.Token.Text + "_ret", eS.Token.LineNumber, eS.Token.Column));
                    }
                    bool memoryInstruction = mnemonic.StartsWith("RD") || mnemonic.StartsWith("WR");
                    int effect = 0;	// bit 0 - WR
                    // bit 1 - WC
                    // bit 2 - WZ
                    // bit 3 - NR
                    if (Tokenizer.Current is EffectToken && instruction.Propcode != 0)	// No effects allowed on NOP
                    {
                        while (true)
                        {
                            Token effectToken = Tokenizer.GetToken();
                            int e = (effectToken as EffectToken).Effect;
                            if (e == 1)		// WR
                            {
                                if (memoryInstruction)
                                    throw new ParseException("Memory instructions cannot use WR/NR", effectToken);
                                effect &= 7;	// clear NR bit
                            }
                            else if (e == 8)	// NR?
                            {
                                if (memoryInstruction)
                                    throw new ParseException("Memory instructions cannot use WR/NR", effectToken);
                                effect &= 0xe;	// clear WR bit
                            }
                            effect |= e;
                            if (Tokenizer.Current.Text == "(eol)")
                                break;
                            Tokenizer.Advance(",");
                        }
                    }
                    SymbolTable.AddDatInstructionEntry(instruction, cond, eD, eS, immediate, effect, token, Tokenizer.Current.LineNumber);
                }
                Tokenizer.Advance("(eol)");
            }
            Tokenizer.SetLocalLabelParsingEnable(false);
            return true;
        }
Пример #2
0
 public void Visit(IdExpr e)
 {
     SymbolInfo symbolInfo = e.SymbolTable.LookupExisting(e.Token);
     if (symbolInfo is DatSymbolInfo)
     {
         if (insideDat)
         {
             int x = (symbolInfo as DatSymbolInfo).CogAddressX4;
             if ((x & 3) != 0)
                 throw new ParseException("Address is not long", e.Token);
             result = new FloInt(x / 4);
             return;
         }
         // else
         result = new FloInt((symbolInfo as DatSymbolInfo).Dp);
         return;
     }
     ConSymbolInfo conSymbolInfo = e.SymbolTable.LookupExisting(e.Token) as ConSymbolInfo;
     if (conSymbolInfo == null)
         throw new ParseException("Non-constant symbol", e.Token);
     result = conSymbolInfo.Value;
 }