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); } }
public IList<BaseExpression> ParseArguments(TokensQueue tokens) { var res = new List<BaseExpression>(); while (!tokens.IsEndOfLine) { var preview = tokens.Peek(); if (preview.Type == TokenType.CloseParenthesis) return res; var arg = Parse(tokens); res.Add(arg); preview = tokens.Peek(); if (preview.Type != TokenType.Comma) break; tokens.Read(TokenType.Comma); } return res; }
private BaseExpression ParseWithPriority(TokensQueue tokens, int priority) { BaseExpression left = ParseOperand(tokens); while (tokens.Count > 0) { var preview = tokens.Peek(); switch (preview.Type) { case TokenType.NewLine: case TokenType.Comma: case TokenType.CloseParenthesis: return left; } var tokenPriority = GetPriority(preview.Type); if (tokenPriority >= 0 && tokenPriority < priority) { if (left != null) return left; throw new Exception("some case"); } var token = tokens.Read(); switch (token.Type) { case TokenType.Plus: case TokenType.Minus: case TokenType.Multiply: case TokenType.Divide: case TokenType.Mod: case TokenType.LeftShift: case TokenType.RightShift: case TokenType.BitOr: case TokenType.BitAnd: case TokenType.BitXor: left = ProcessBinaryExpression(token, left, tokens); break; default: throw new TokenException("unexpected token " + token.StringValue, token); } } return left; }
private BaseExpression ParseOperand(TokensQueue tokens) { if (tokens.IsEndOfLine) { throw new TokenException("operand expected", tokens.LastReadToken); } var token = tokens.Read(); switch (token.Type) { case TokenType.Integer: return new NumberExpression { Value = token.IntegerValue }; case TokenType.Literal: return ParseLiteral(token, tokens); case TokenType.NewLine: throw new TokenException("value expected", token); case TokenType.Minus: return new NegateExpression(ParseOperand(tokens)); case TokenType.OpenParenthesis: var inner = Parse(tokens); if (tokens.IsEndOfLine) { throw new TokenException("missing closing parenthesis", tokens.LastReadToken); } tokens.Read(TokenType.CloseParenthesis); return inner; default: throw new TokenException("unexpected token " + token.StringValue, token); } }