Example #1
0
        private void MultiLineComment()
        {
            // we start inside a multi-line comment.
            // but it could be nested
            while ((Peek() == '*' && PeekNext() == '/') == false && !isAtEnd())
            {
                // Move through the body of the multi
                if (Peek() == '\n')
                {
                    Line++;
                }

                // We are already in a comment so eating chars is safe
                // We start this method INSIDE the comment.
                if (Match('/') && Match('*'))
                {
                    MultiLineComment();
                }
                Advance();
            }

            if (isAtEnd())
            {
                CSLox.Error(this.Line, "Unterminated multi-line comment");
            }
            Advance(); Advance();
        }
Example #2
0
 public Unit VisitVariableExpr(Expr.Variable expr)
 {
     if (_Scopes.Count != 0 && _Scopes[_Scopes.Count - 1].ContainsKey(expr.Name.Lexeme) &&
         _Scopes[_Scopes.Count - 1][expr.Name.Lexeme] == false)
     {
         CSLox.Error(expr.Name, "Can't read local variable in it own initalizer.");
     }
     ResolveLocal(expr, expr.Name);
     return(new Unit());
 }
Example #3
0
 public void Interpret(Expr expression)
 {
     try
     {
         Object value = Evaluate(expression);
         Console.WriteLine(Stringfy(value));
     }
     catch (RuntimeError ex)
     {
         CSLox.RuntimeError(ex);
     }
 }
Example #4
0
        private void Declare(Token name)
        {
            if (_Scopes.Count == 0)
            {
                return;
            }
            Dictionary <string, bool> scope = _Scopes[_Scopes.Count - 1];

            if (scope.ContainsKey(name.Lexeme))
            {
                CSLox.Error(name, "Already a variabled with this name in this scope .");
            }

            scope.Add(name.Lexeme, false);
        }
Example #5
0
        private void String()
        {
            while (Peek() != '"' && !isAtEnd())
            {
                if (Peek() == '\n')
                {
                    Line++;
                }
                Advance();
            }

            if (isAtEnd())
            {
                CSLox.Error(Line, "Unterminated string");
                return;
            }
            Advance();
            // ignore the surrounding quotes!
            var value = Source.Substring(Start + 1, (Current - 1) - (Start + 1));

            AddToken(TokenType.STRING, value);
        }
Example #6
0
        private void ScanToken()
        {
            char c = Advance();

            switch (c)
            {
            case '(': AddToken(TokenType.LEFT_PAREN); break;

            case ')': AddToken(TokenType.RIGHT_PAREN); break;

            case '{': AddToken(TokenType.LEFT_BRACE); break;

            case '}': AddToken(TokenType.RIGHT_BRACE); break;

            case ',': AddToken(TokenType.COMMA); break;

            case '.': AddToken(TokenType.DOT); break;

            case '-': AddToken(TokenType.MINUS); break;

            case '+': AddToken(TokenType.PLUS); break;

            case ';': AddToken(TokenType.SEMICOLON); break;

            case '*': AddToken(TokenType.STAR); break;

            case '?': AddToken(TokenType.QUESTION); break;

            case ':': AddToken(TokenType.SEMICOLON); break;

            case '!': AddToken(Match('=') ? TokenType.BANG_EQUAL : TokenType.BANG); break;

            case '=': AddToken(Match('=') ? TokenType.EQUAL_EQUAL : TokenType.EQUAL); break;

            case '<': AddToken(Match('=') ? TokenType.LESS_EQUAL : TokenType.LESS); break;

            case '>': AddToken(Match('=') ? TokenType.GREATER_EQUAL : TokenType.GREATER); break;

            case '/':
                if (Match('/'))
                {
                    // A comment goes until the end of a line.
                    while (Peek() != '\n' && !isAtEnd())
                    {
                        Advance();
                    }
                }
                else if (Match('*'))
                {
                    MultiLineComment();
                }
                else
                {
                    AddToken(TokenType.SLASH);
                }
                break;

            case ' ':
            case '\r':
            case '\t':
                break;     // ignoring whitespace and carry on.

            case '\n':
                this.Line++;     // update the line, and carry on.
                break;

            case '"': String(); break;

            default:
                if (Char.IsDigit(c))
                {
                    Number();
                }
                else if (IsAlpha(c))
                {
                    Identifier();
                }
                else
                {
                    CSLox.Error(this.Line, $"Unexpected Character '{c}'");
                }
                break;
            }
        }
Example #7
0
 private Exception Error(Token token, string message)
 {
     CSLox.Error(token, message);
     return(new ParserError(message));
 }