public Expr Parse(TokenStream stream) { TokenType nextTokenType = stream.Peek().Type; // Variable declaration expression. if (TokenIdentifier.IsType(nextTokenType)) { return(new VarDeclareExprParser().Parse(stream)); } // Numeric expression. else if (TokenIdentifier.IsNumeric(nextTokenType)) { return(new NumericExprParser().Parse(stream)); } // Identifier expression. else if (nextTokenType == TokenType.Identifier) { return(new IdentifierExprParser().Parse(stream)); } // Parentheses expression. else if (nextTokenType == TokenType.SymbolParenthesesL) { return(new ParenthesesExprParser().Parse(stream)); } // At this point, return null. return(null); }
public Expr Parse(ParserContext context) { // Ensure current token is parentheses start. context.Stream.EnsureCurrent(TokenType.SymbolParenthesesL); // Peek at the next token. Token peek = context.Stream.Peek(); // Lambda expresion. if (TokenIdentifier.IsType(peek, context) || peek.Type == TokenType.SymbolParenthesesR) { // Delegate to the lambda expression parser. return(new LambdaExprParser().Parse(context)); } // Skip the parentheses start token. context.Stream.Skip(); // Parse the expression. Expr expr = new ExprParser().Parse(context); // Ensure current token is parentheses end. context.Stream.EnsureCurrent(TokenType.SymbolParenthesesR); // Skip the parentheses end token. context.Stream.Skip(); // Return the expression. return(expr); }
public FormalArg Parse(TokenStream stream) { // Initialize the type value. string typeValue; // Check if the next token is a type if (TokenIdentifier.IsType(stream.Peek())) { // Capture argument type value. typeValue = stream.Next().Value; } else { // TODO: Better error lol. throw new Exception("Oops you need a type!"); } // Create the argument's type. var type = new Type(typeValue); // Create the formal argument entity. var arg = new FormalArg(type); // Capture the argument's name. var name = stream.Next(TokenType.Identifier).Value; // Assign the argument's name. arg.SetName(name); return(arg); }
public Type Parse(TokenStream stream) { // Consume type token. Token type = stream.Next(); // Ensure type value is a type. if (!TokenIdentifier.IsType(type)) { throw new Exception($"Expected a type but got '{type.Type}'"); } // Create the type. return(new Type(type.Value)); }
public Expr Parse(ParserContext context) { // Capture the current token's type. Token token = context.Stream.Current; // Variable declaration expression. if (TokenIdentifier.IsType(token, context)) { return(new VarDeclareExprParser().Parse(context)); } // If expression. else if (token.Type == TokenType.KeywordIf) { return(new IfExprParser().Parse(context)); } // Otherwise, delegate to the expression parser. Expr expr = new ExprParser().Parse(context); // Return the parsed expression. return(expr); }
/// <summary> /// Process the next sequence. Returns true /// if the sequence was successfully processed. /// </summary> public bool Next() { // TODO: What if EOF token has not been processed itself? // End reached. if (stream.LastItem) { return(false); } // TODO: Finish fixing this, parsers overflowing (+1) because of this issue with the Program start (05/02/2019). TokenType type = stream.Get().Type; // Skip program start token. if (type == TokenType.ProgramStart) { stream.Skip(); // Assign type as next token type, continue execution. type = stream.Get().Type; } // Skip unknown tokens for error recovery. if (type == TokenType.Unknown) { // TODO: Use error reporting. Console.WriteLine("Warning: Skipping unknown token"); return(false); } // Function definition or global variable. else if (TokenIdentifier.IsType(type)) { // Peek the token after identifier. Token afterIdentifier = stream.Peek(2); // Function definition. if (afterIdentifier.Type == TokenType.SymbolParenthesesL) { // Invoke the function parser. Function function = new FunctionParser().Parse(stream); // Emit the function. function.Emit(Module.Source); } // Otherwise, global variable declaration. else { // Invoke the global variable parser. GlobalVar globalVariable = new GlobalVarParser().Parse(stream); // Emit the global variable. globalVariable.Emit(Module.Source); } } // External definition. else if (type == TokenType.KeywordExternal) { // Invoke the external definition parser. Extern external = new ExternParser().Parse(stream); // Emit the external definition. external.Emit(Module.Source); } // Otherwise, top-level expression. else { // Invoke the top-level expression parser. Function exprDelegate = new TopLevelExprParser().Parse(stream); // Emit the top-level expression. exprDelegate.Emit(Module.Source); } // At this point, an entity was processed. return(true); }
public Type Parse(ParserContext context) { // Capture current type token. Token token = context.Stream.Current; // Ensure current token is a type. if (!TokenIdentifier.IsType(token, context)) { throw new Exception($"Expected a type but got '{token.Type}'"); } // Skip and capture the next token. Token nextToken = context.Stream.Next(); // Create the array length (and flag), defaulting to null. uint?arrayLength = null; // Determine if type is an array. if (nextToken.Type == TokenType.SymbolBracketL) { // Skip bracket start token. context.Stream.Skip(); // TODO: Must ensure array length is integer somehow. // TODO: Invoke expression parser to capture array length. // TODO: arrayLength.Value = new ExprParser().Parse(context); // TODO: BEGIN temporary solution. // Ensure current token is an integer. context.Stream.EnsureCurrent(TokenType.LiteralInteger); // Capture the current integer token. Token integerToken = context.Stream.Current; // Assign the token value as the array length. arrayLength = uint.Parse(integerToken.Value); // Skip over the captured integer token. context.Stream.Skip(); // TODO: END temporary solution. // Ensure the current token is a closing bracket. context.Stream.EnsureCurrent(TokenType.SymbolBracketR); // Skip bracket end token. context.Stream.Skip(); } // Update the next token buffer. nextToken = context.Stream.Get(); // Create the pointer flag. bool isPointer = false; // Determine if pointer sequence exists. if (nextToken.Type == TokenType.OperatorMultiplication) { // Raise the pointer flag. isPointer = true; // Skip the pointer token. context.Stream.Skip(); } // Create the type. return(new Type(context.SymbolTable, token, isPointer, arrayLength)); }