public LLVMTypeRef Emit() { // Create the result buffer. LLVMTypeRef result; // Use LLVM type resolver if token is a primitive type. if (TokenIdentifier.IsPrimitiveType(this.Token)) { // Delegate to primitive type construct. result = new PrimitiveType(this.Token.Value).Emit(); } // Otherwise, look it up on the structs dictionary, on the symbol table. else if (this.symbolTable.structs.Contains(this.Token.Value)) { result = this.symbolTable.structs[this.Token.Value].Value; } // At this point, provided token is not a valid type. else { throw new Exception($"Token is not a primitive nor user-defined type: '{this.Token.Value}'"); } // Convert result to an array if applicable. if (this.arrayLength.HasValue) { result = LLVM.ArrayType(result, this.arrayLength.Value); } // Convert result to a pointer if applicable. if (this.IsPointer) { result = LLVM.PointerType(result, result.GetPointerAddressSpace()); } // Return the resulting type. return(result); }
public void IsNotPrimitiveType(TokenType input) { Assert.False(TokenIdentifier.IsPrimitiveType(input)); }
public void IsPrimitiveType(TokenType input) { Assert.True(TokenIdentifier.IsPrimitiveType(input)); }
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"); } }