public long CalculateExpression(out Token firstToken) { if (_context.Queue.IsEndOfLine) { throw new TokenException("expression expected", _context.Queue.LastReadToken); } firstToken = _context.Queue.Peek(); return _calculator.Parse(_context.Queue).Evaluate(); }
public void ParseRegisterTest() { for (var i = 0; i < 255; i++) { var lowerToken = new Token { StringValue = "r" + i }; var lowerRes = lowerToken.ParseRegister(); Assert.AreEqual(i < 32 ? i : 255, lowerRes); var upperToken = new Token { StringValue = "R" + i }; var upperRes = upperToken.ParseRegister(); Assert.AreEqual(i < 32 ? i : 255, upperRes); } }
protected BaseExpression ParseLiteral(Token token, TokensQueue queue) { if (queue.Count > 0) { var preview = queue.Peek(); if (preview.Type == TokenType.OpenParenthesis) { return Func(token, queue); } } if (token.StringValue == "$") { return new NumberExpression { Value = _context.Offset }; } var lblValue = _context.GetLabel(token); if (lblValue == null) { throw new TokenException("unknown symbol " + token.StringValue, token); } return new NumberExpression { Value = (long)lblValue }; }
protected BaseExpression Func(Token nameToken, TokensQueue tokens) { tokens.Read(TokenType.OpenParenthesis); var args = ParseArguments(tokens); tokens.Read(TokenType.CloseParenthesis); switch (nameToken.StringValue.ToLower()) { case "low": if (args.Count != 1) { throw new TokenException("expected 1 argument", nameToken); } return new LowByteExpression(args.First()); case "high": if (args.Count != 1) { throw new TokenException("expected 1 argument", nameToken); } return new HighByteExpression(args.First()); default: throw new TokenException("unknown function " + nameToken.StringValue, nameToken); } }
private BaseExpression ProcessBinaryExpression(Token opToken, BaseExpression left, TokensQueue tokens) { var tokenPriority = GetPriority(opToken.Type); var other = ParseWithPriority(tokens, tokenPriority + 1); switch (opToken.Type) { case TokenType.Plus: return new AddExpression(left, other); case TokenType.Minus: return new SubExpression(left, other); case TokenType.Multiply: return new MulExpression(left, other); case TokenType.Divide: return new DivExpression(left, other); case TokenType.Mod: return new ModExpression(left, other); case TokenType.LeftShift: return new ShiftLeftExpression(left, other); case TokenType.RightShift: return new ShiftRightExpression(left, other); case TokenType.BitOr: return new BitOrExpression(left, other); case TokenType.BitAnd: return new BitAndExpression(left, other); case TokenType.BitXor: return new BitXorExpression(left, other); default: throw new TokenException("unexpected operator", opToken); } }
public void DefineLabel(Token token) { if (LabelDefined(token)) { throw new TokenException("duplicate label", token); } if (!token.StringValue.StartsWith(".")) { LastGlobalLabel = token.StringValue; } var fullname = GetFullLabelName(token); _passLabels[fullname] = (ushort)Offset; Symbols.Labels[fullname] = (ushort)Offset; }
private bool LabelDefined(Token token) { var fullname = GetFullLabelName(token); return _passLabels.ContainsKey(fullname); }
public ushort? GetLabel(Token token) { var fullname = GetFullLabelName(token); ushort val; if (_passLabels.TryGetValue(fullname, out val)) { return val; } if (Symbols.Labels.TryGetValue(fullname, out val)) { return val; } if (Pass <= 1) return 0; return null; }
public string GetFullLabelName(Token token) { var name = token.StringValue; if (name.StartsWith(".")) { if (string.IsNullOrWhiteSpace(LastGlobalLabel)) { throw new TokenException("local label must be preceded by global name", token); } return LastGlobalLabel + name; } return name; }
public PureSectionDataException(string message, Token token) : base(message, token) { }
public TokenException(string message, Token token) : base(message) { _token = token; }
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); } }
private static bool IsDataDirective(Token token) { if (token.Type != TokenType.Literal) return false; switch (token.StringValue.ToLower()) { case "db": return true; case "dw": return true; case "rb": return true; case "rw": return true; default: return false; } }
private static bool CheckLabel(Token token, AsmContext context) { if (context.Queue.Count > 0) { var next = context.Queue.Peek(); if (next.Type == TokenType.Colon) { context.Queue.Read(); context.DefineLabel(token); return true; } } return false; }
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; }
public Token Read() { _lastToken = _queue.Dequeue(); return _lastToken; }