Пример #1
0
        public AsmContext Assemble(string content, string fileName = null)
        {
            var symbols = new AsmSymbols();
            IList<Token> tokens = new List<Token>();
            LoadRecursive(content, tokens, fileName);

            tokens = ProcessSymbolConstants(tokens, symbols);

            AsmContext last = null;
            for (var i = 1; i < 10; i++) {
                var context = new AsmContext {
                    Queue = new TokensQueue(tokens),
                    Symbols = symbols,
                    Pass = i
                };
                var parser = new AsmParser(context);
                AssemblePass(context, parser);
                if (TheSame(last, context)) break;
                last = context;
            }
            return last;
        }
Пример #2
0
 private static void ProcessReserveWords(AsmParser parser, AsmSection output)
 {
     var cnt = parser.CalculateExpression();
     output.ReserveBytes((int)cnt * 2);
 }
Пример #3
0
 private static void ProcessOrg(AsmParser parser, AsmSection output)
 {
     var val = parser.CalculateExpression();
     output.Offset = (int)val;
 }
Пример #4
0
        private static void ProcessDataWords(AsmParser parser, AsmSection output)
        {
            do {
                if (parser.IsEndOfLine) {
                    throw new TokenException("expected data words", parser.LastReadToken);
                }

                var token = parser.PeekToken();

                if (token.Type == TokenType.String) {
                    token = parser.ReadToken(TokenType.String);
                    foreach (var ch in token.StringValue) {
                        output.EmitWord(ch);
                    }
                } else {
                    var val = parser.ReadUshort();
                    output.EmitWord(val);
                }

                if (parser.IsEndOfLine) break;

                var commaPreview = parser.PeekToken();
                if (commaPreview.Type != TokenType.Comma) break;
                parser.ReadToken(TokenType.Comma);
            } while (true);
        }
Пример #5
0
 private static void ProcessDataDirective(Token token, AsmParser parser, AsmSection output)
 {
     switch (token.StringValue.ToLower()) {
         case "db":
             ProcessDataBytes(parser, output);
             break;
         case "dw":
             ProcessDataWords(parser, output);
             break;
         case "rb":
             ProcessReserveBytes(parser, output);
             break;
         case "rw":
             ProcessReserveWords(parser, output);
             break;
         default:
             throw new TokenException("invalid directive " + token.StringValue, token);
     }
 }
Пример #6
0
        private static void ProcessDataBytes(AsmParser parser, AsmSection output)
        {
            do {
                if (parser.IsEndOfLine) {
                    throw new TokenException("expected data bytes", parser.LastReadToken);
                }

                var token = parser.PeekToken();

                if (token.Type == TokenType.String) {
                    token = parser.ReadToken(TokenType.String);
                    foreach (var ch in token.StringValue) {
                        if (ch > 255) {
                            throw new TokenException("unicode character cannot be translated to byte", token);
                        }
                        output.EmitByte((byte)ch);
                    }
                } else {
                    var val = parser.ReadByte();
                    output.EmitByte(val);
                }

                if (parser.IsEndOfLine) break;

                var commaPreview = parser.PeekToken();
                if (commaPreview.Type != TokenType.Comma) break;
                parser.ReadToken(TokenType.Comma);
            } while (true);
        }
Пример #7
0
 private static bool CheckData(Token token, AsmContext context, AsmParser parser)
 {
     if (IsDataDirective(token)) {
         ProcessDataDirective(token, parser, context.CurrentSection);
         return true;
     }
     if (!context.Queue.IsEndOfLine) {
         var preview = context.Queue.Peek();
         if (IsDataDirective(preview)) {
             context.Queue.Read(TokenType.Literal);
             context.DefineLabel(token);
             ProcessDataDirective(preview, parser, context.CurrentSection);
             return true;
         }
     }
     return false;
 }
Пример #8
0
        private static void AssemblePass(AsmContext context, AsmParser parser)
        {
            while (context.Queue.Count > 0) {
                SkipEmptyLines(context);
                if (context.Queue.Count == 0) break;

                AssembleLine(context, parser);
            }
        }
Пример #9
0
        private static void AssembleLine(AsmContext context, AsmParser parser)
        {
            var token = context.Queue.Read(TokenType.Literal);
            try {
                if (CheckLabel(token, context)) {
                    return;
                }
                if (CheckData(token, context, parser)) {
                    return;
                }

                switch (token.StringValue.ToLower()) {
                    case "section":
                        ProcessSection(context);
                        break;
                    case "org":
                        ProcessOrg(parser, context.CurrentSection);
                        break;
                    default:
                        var opcode = AvrOpcodes.Get(token.StringValue);
                        if (opcode != null) {
                            opcode.Compile(parser, context.CurrentSection);
                        } else {
                            throw new TokenException("Illegal instruction " + token.StringValue, token);
                        }
                        break;
                }
                if (context.Queue.Count > 0) {
                    var nl = context.Queue.Peek();
                    if (nl.Type != TokenType.NewLine) {
                        throw new TokenException("Extra characters on line", nl);
                    }
                }
            } catch (PureSectionDataException exc) {
                throw new PureSectionDataException(exc.Message, token);
            }
        }