public void Invoke(ParserContext context) { // Retrieve the current token. Token token = context.Stream.Current; // Abstract the token's type. TokenType type = token.Type; // Skip unknown tokens for error recovery. if (type == SyntaxAnalysis.TokenType.Unknown) { // Create the warning. context.NoticeRepository.UnknownToken(token.Value); // Skip token. context.Stream.Skip(); // Return immediately. return; } // Function definition or global variable. else if (TokenIdentifier.IsPrimitiveType(type) || type == TokenType.SymbolBracketL) { // Peek the token after identifier. Token afterIdentifier = context.Stream.Peek(2); // Function definition. if (type == TokenType.SymbolBracketL || afterIdentifier.Type == SyntaxAnalysis.TokenType.SymbolParenthesesL) { // Invoke the function parser. Function function = new FunctionParser().Parse(context); // Emit the function. function.Emit(this.ModulePipeContext); } // Otherwise, global variable declaration. else { // Invoke the global variable parser. GlobalVar globalVariable = new GlobalVarParser().Parse(context); // Emit the global variable. globalVariable.Emit(this.ModulePipeContext); } } // Struct definition. else if (type == SyntaxAnalysis.TokenType.KeywordStruct) { // Invoke the struct parser. StructDef @struct = new StructDefParser().Parse(context); // Emit the struct construct. @struct.Emit(this.ModulePipeContext); } // External definition. else if (type == SyntaxAnalysis.TokenType.KeywordExternal) { // Invoke the external definition parser. Extern @extern = new ExternParser().Parse(context); // Emit the external definition. @extern.Emit(this.ModulePipeContext); } // TODO: Enforce a single namespace definition per-file. // Namespace definition. else if (type == SyntaxAnalysis.TokenType.KeywordNamespace) { // Invoke the namespace definition parser. Namespace @namespace = new NamespaceParser().Parse(context); // Process the namespace definition reaction. @namespace.Invoke(this.ModulePipeContext.Target); } // Directive. else if (type == SyntaxAnalysis.TokenType.SymbolHash) { // Invoke the directive parser. Directive directive = new DirectiveParser().Parse(context); // Invoke the directive onto the symbol table. directive.Invoke(context); } // Otherwise, throw an error. else { throw new Exception("Unexpected top-level entity"); } }
/// <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); }