Exemplo n.º 1
0
        //this is very similar to parseFunctionParameters. Difference being in parseFunctionParameters, we expect the parameters to be
        //identifiers wherease here when we are calling/invoking that function the arguments passed to those parameters can be Expressions such as
        //(5, foobar, foobar+5)
        private List <AST_Helper.Expression> parseExpressionList(TokenHelper.TokenType endToken)
        {
            List <AST_Helper.Expression> args = new List <AST_Helper.Expression>();

            if (this.peekTokenIs(endToken))
            {
                this.nextToken();
                return(args);
            }

            this.nextToken();
            args.Add(this.parseExpression(Parser_Helper.precedence.LOWEST));

            while (this.peekTokenIs(TokenHelper.TokenType.COMMA))
            {
                this.nextToken();
                this.nextToken();

                args.Add(this.parseExpression(Parser_Helper.precedence.LOWEST));
            }

            if (!this.expectPeek(endToken))
            {
                return(null);
            }

            return(args);
        }
Exemplo n.º 2
0
 private bool expectPeek(TokenHelper.TokenType t)  //if the expected token is present, this also advances the cursor to next token
 {
     if (this.peekTokenIs(t))                      //and this should be reflected in the func name.
     {
         this.nextToken();
         return(true);
     }
     else
     {
         this.peekError(t);
         return(false);
     }
 }
Exemplo n.º 3
0
 public Token(TokenHelper.TokenType type, string literal)
 {
     Type = type; Literal = literal;
 }
Exemplo n.º 4
0
 void registerInfix(TokenHelper.TokenType t, Parser_Helper.infixParseFn fn)
 {
     this.infixParseFns[t] = fn;
 }
Exemplo n.º 5
0
 void registerPrefix(TokenHelper.TokenType t, Parser_Helper.prefixParserFn fn)
 {
     this.prefixParseFns[t] = fn;
 }
Exemplo n.º 6
0
        void peekError(TokenHelper.TokenType t)
        {
            string message = string.Format("expected next token to be {0}, got {1} instead", t, this.peekToken.Type);

            this.errors.Add(message);
        }
Exemplo n.º 7
0
 private bool curTokenIs(TokenHelper.TokenType t)
 {
     return(this.curToken.Type == t);
 }
Exemplo n.º 8
0
 private bool peekTokenIs(TokenHelper.TokenType t)
 {
     return(this.peekToken.Type == t);
 }
Exemplo n.º 9
0
        private void noPrefixParseFnError(TokenHelper.TokenType type)
        {
            string message = string.Format("no prefix parse function for {0} found", type);

            this.errors.Add(message);
        }
Exemplo n.º 10
0
        public Token NextToken()
        {
            Token tok;

            this.skipWhiteSpace();
            switch (this.ch)
            {
            case '"':
                tok = new Token(TokenHelper.TokenType.STRING, this.readString());
                //even though we have already read the next char in readString, we still want to call readchar() again(below). Therefore, in this case, do not return here.
                break;

            case '=':
                if (this.peekChar() == '=')
                {
                    var temp_ch = this.ch;
                    this.readChar();
                    string literal = temp_ch.ToString() + this.ch.ToString();
                    tok = new Token(TokenHelper.TokenType.EQ, literal);
                }
                else
                {
                    tok = new Token(TokenHelper.TokenType.ASSIGN, this.ch.ToString());
                }
                break;

            case ';':
                tok = new Token(TokenHelper.TokenType.SEMICOLON, this.ch.ToString());
                break;

            case ':':
                tok = new Token(TokenHelper.TokenType.COLON, this.ch.ToString());
                break;

            case '(':
                tok = new Token(TokenHelper.TokenType.LPAREN, this.ch.ToString());
                break;

            case ')':
                tok = new Token(TokenHelper.TokenType.RPAREN, this.ch.ToString());
                break;

            case ',':
                tok = new Token(TokenHelper.TokenType.COMMA, this.ch.ToString());
                break;

            case '+':
                tok = new Token(TokenHelper.TokenType.PLUS, this.ch.ToString());
                break;

            case '{':
                tok = new Token(TokenHelper.TokenType.LBRACE, this.ch.ToString());
                break;

            case '}':
                tok = new Token(TokenHelper.TokenType.RBRACE, this.ch.ToString());
                break;

            case '[':
                tok = new Token(TokenHelper.TokenType.LBRACKET, this.ch.ToString());
                break;

            case ']':
                tok = new Token(TokenHelper.TokenType.RBRACKET, this.ch.ToString());
                break;

            case '-':
                tok = new Token(TokenHelper.TokenType.MINUS, this.ch.ToString());
                break;

            case '!':
                if (this.peekChar() == '=')
                {
                    var temp_ch = this.ch;
                    this.readChar();
                    string literal = temp_ch.ToString() + this.ch.ToString();
                    tok = new Token(TokenHelper.TokenType.NOT_EQ, literal);
                }
                else
                {
                    tok = new Token(TokenHelper.TokenType.BANG, this.ch.ToString());
                }
                break;

            case '/':
                tok = new Token(TokenHelper.TokenType.SLASH, this.ch.ToString());
                break;

            case '*':
                tok = new Token(TokenHelper.TokenType.ASTERISK, this.ch.ToString());
                break;

            case '<':
                tok = new Token(TokenHelper.TokenType.LT, this.ch.ToString());
                break;

            case '>':
                tok = new Token(TokenHelper.TokenType.GT, this.ch.ToString());
                break;

            case '\0':
                tok = new Token(TokenHelper.TokenType.EOF, this.ch.ToString());    //todo:??
                break;

            default:
                if (this.isLetter(this.ch))
                {
                    string literal             = this.readIdentifier();
                    TokenHelper.TokenType type = TokenHelper.LookupIdent(literal);

                    tok = new Token(type, literal);
                    //we don't want to call readchar() again(below) as we have already read the next char in readIdentifier. Therefore return here.
                    return(tok);
                }
                else if (this.isDigit(this.ch))
                {
                    string literal             = this.readNumber();
                    TokenHelper.TokenType type = TokenHelper.TokenType.INT;

                    tok = new Token(type, literal);
                    //we don't want to call readchar() again(below) as we have already read the next char in readNumber. Therefore return here.
                    return(tok);
                }
                else
                {
                    tok = new Token(TokenHelper.TokenType.ILLEGAL, this.ch.ToString());
                }
                break;
            }

            this.readChar();
            return(tok);
        }