public override LLVMValueRef Emit(PipeContext <LLVMBuilderRef> context) { // Ensure target struct exists on the symbol table. if (!context.SymbolTable.structs.Contains(this.TargetIdentifier)) { throw new Exception($"Reference to undefined struct named '${this.TargetIdentifier}'"); } // Retrieve the symbol from the symbol table. StructSymbol symbol = context.SymbolTable.structs[this.TargetIdentifier]; // Retrieve the target struct's LLVM reference value from the symbol. LLVMTypeRef structDef = symbol.Value; // Create a value buffer list. List <LLVMValueRef> values = new List <LLVMValueRef>(); // Populate body properties. foreach (StructProperty property in this.Body) { // Emit and append the value to the buffer list. values.Add(property.Value.Emit(context)); } // Create the resulting struct assignment value. LLVMValueRef assignment = LLVM.ConstNamedStruct(structDef, values.ToArray()); // Return the resulting struct assignment instruction. return(assignment); }
public Construct VisitStruct(Struct node) { // Ensure target struct exists on the symbol table. if (!context.SymbolTable.structs.Contains(node.TargetIdentifier)) { throw new Exception($"Reference to undefined struct named '${node.TargetIdentifier}'"); } // Retrieve the symbol from the symbol table. StructSymbol symbol = context.SymbolTable.structs[this.TargetIdentifier]; // Retrieve the target struct's LLVM reference value from the symbol. LLVMTypeRef structDef = symbol.Value; // Create a value buffer list. List <LLVMValueRef> values = new List <LLVMValueRef>(); // Populate body properties. foreach (StructProperty property in node.Body) { // Emit and append the value to the buffer list. values.Add(property.Value.Emit(context)); } // Create the resulting struct assignment value. LlvmValue assignment = LLVM.ConstNamedStruct(structDef, values.ToArray()).Wrap(); // Append the assignment value onto the stack. this.valueStack.Push(assignment); // Return the node. return(node); }
private BoundStructType BindStructDeclaration(StructTypeSyntax declaration, Symbol parent) { ClassOrStructSymbol baseType; List <InterfaceSymbol> baseInterfaces; BindBaseList(declaration.BaseList, parent, out baseType, out baseInterfaces); var structSymbol = new StructSymbol(declaration, parent, baseType, baseInterfaces.ToImmutableArray()); AddSymbol(structSymbol, declaration.Name?.SourceRange ?? declaration.SourceRange); var variables = new List <BoundMultipleVariableDeclarations>(); var structBinder = new Binder(_sharedBinderState, this); foreach (var variableDeclarationStatement in declaration.Fields) { variables.Add(structBinder.Bind(variableDeclarationStatement, x => structBinder.BindField(x, structSymbol))); } foreach (var member in structBinder.LocalSymbols.Values.SelectMany(x => x)) { structSymbol.AddMember(member); } return(new BoundStructType(structSymbol, variables.ToImmutableArray())); }
private BoundStructType BindStructDeclaration(StructTypeSyntax declaration, Symbol parent) { StructSymbol baseType; List <InterfaceSymbol> baseInterfaces; BindBaseList(declaration.BaseList, parent, out baseType, out baseInterfaces); var structBinder = new Binder(_sharedBinderState, this); var structSymbol = new StructSymbol(declaration, parent, baseType, baseInterfaces.ToImmutableArray(), structBinder); if (!structSymbol.IsAnonymous) { AddSymbol(structSymbol, declaration.Name?.SourceRange ?? declaration.SourceRange); } var members = new List <BoundNode>(); // Bit of a hack - need to add member symbols to structSymbol as we go, otherwise (for example) // static methods defined inline in a struct won't be able to see struct members. var alreadyAddedMemberSymbols = new List <Symbol>(); Action addMemberSymbols = () => { var newMemberSymbols = structBinder.LocalSymbols.Values .SelectMany(x => x) .Except(alreadyAddedMemberSymbols) .ToList(); foreach (var member in newMemberSymbols) { structSymbol.AddMember(member); alreadyAddedMemberSymbols.Add(member); } }; foreach (var memberSyntax in declaration.Members) { switch (memberSyntax.Kind) { case SyntaxKind.VariableDeclarationStatement: members.Add(structBinder.Bind((VariableDeclarationStatementSyntax)memberSyntax, x => structBinder.BindField(x, structSymbol))); addMemberSymbols(); break; case SyntaxKind.FunctionDeclaration: members.Add(structBinder.Bind((FunctionDeclarationSyntax)memberSyntax, x => structBinder.BindFunctionDeclaration(x, structSymbol))); addMemberSymbols(); break; case SyntaxKind.FunctionDefinition: members.Add(structBinder.Bind((FunctionDefinitionSyntax)memberSyntax, x => structBinder.BindFunctionDefinition(x, structSymbol))); addMemberSymbols(); break; } } return(new BoundStructType(structSymbol, members.ToImmutableArray())); }
public bool checkUnique(DiagnosticPosition pos, StructSymbol ssym, WritableScope scope) { bool contains = scope.getSymbolsByName(ssym.name, LookupKind.NON_RECURSIVE).Any(); if (contains) { log.error(pos, messages.duplicateStructName, ssym.name); } return(!contains); }
private StructSymbol makeStructSymbol(StructDef structDef, Symbol owner) { StructSymbol ssym = new StructSymbol(structDef.name, owner, null); ssym.type = new StructType(ssym); structDef.symbol = ssym; return(ssym); }
public override object visitStructDef(StructDef structDef, WritableScope enclScope) { StructSymbol ssym = makeStructSymbol(structDef, enclScope.owner); if (check.checkUnique(structDef.Pos, ssym, enclScope)) { enclScope.enter(ssym); } return(null); }
public override Type visitNewStruct(NewStruct newStruct, Environment env) { String name = newStruct.structName; StructSymbol ssym = (StructSymbol)env.scope.findFirst(name, s => (s.kind & Kind.STRUCT) != 0); if (ssym == null) { log.error(newStruct.Pos, messages.undefinedStruct, newStruct.structName); return(symtab.errorType); } newStruct.symbol = ssym; newStruct.type = ssym.type; return(ssym.type); }
private void BindStructDeclaration(StructTypeSyntax declaration) { Func <TypeSymbol, IEnumerable <FieldSymbol> > lazyMemberSymbols = cd => { var memberSymbols = new List <FieldSymbol>(); foreach (var memberSyntax in declaration.Fields) { memberSymbols.AddRange(BindFields(memberSyntax, cd)); } return(memberSymbols); }; var symbol = new StructSymbol(declaration, null, lazyMemberSymbols); _bindingResult.AddSymbol(declaration, symbol); _symbolSet.AddGlobal(symbol); }
public override Type visitSelect(Select select, Environment env) { Type leftType = analyzeExpr(select.selectBase, env); if (leftType.IsError) { select.symbol = symtab.errorVarSymbol; return(symtab.errorType); } if (leftType.IsPrimitive) { log.error(select.Pos, messages.selectOnPrimitive); select.symbol = symtab.errorVarSymbol; return(symtab.errorType); } if (leftType.IsArray) { if (select.name != "length") { log.error(select.Pos, "Arrays only have a \"length\" field"); return(symtab.errorType); } select.symbol = symtab.arrayLengthField; select.type = symtab.arrayLengthField.type; return(select.type); } StructSymbol ssym = ((StructType)leftType).symbol; VarSymbol field = (VarSymbol)ssym.membersScope.findFirst(select.name); if (field == null) { log.error(select.Pos, messages.unknownField, select.name, ssym.name); select.symbol = symtab.errorVarSymbol; return(symtab.errorType); } select.symbol = field; select.type = field.type; return(field.type); }
private BoundStructType BindStructDeclaration(StructTypeSyntax declaration, Symbol parent) { var structSymbol = new StructSymbol(declaration, parent); AddSymbol(structSymbol, declaration.Name?.Span ?? declaration.GetTextSpanSafe()); var variables = new List <BoundMultipleVariableDeclarations>(); var structBinder = new Binder(_sharedBinderState, this); foreach (var variableDeclarationStatement in declaration.Fields) { variables.Add(structBinder.Bind(variableDeclarationStatement, x => structBinder.BindField(x, structSymbol))); } foreach (var member in structBinder.LocalSymbols.Values.SelectMany(x => x)) { structSymbol.AddMember(member); } return(new BoundStructType(structSymbol, variables.ToImmutableArray())); }
private void BindBaseList(BaseListSyntax baseList, Symbol parent, out StructSymbol baseType, out List <InterfaceSymbol> baseInterfaces) { baseType = null; baseInterfaces = new List <InterfaceSymbol>(); if (baseList != null) { var baseTypeTemp = Bind(baseList.BaseType, x => BindType(x, parent)); switch (baseTypeTemp.TypeSymbol.Kind) { case SymbolKind.Class: case SymbolKind.Struct: baseType = (StructSymbol)baseTypeTemp.TypeSymbol; break; case SymbolKind.Interface: baseInterfaces.Add((InterfaceSymbol)baseTypeTemp.TypeSymbol); break; } } }
public override Type visitMethodInvoke(MethodInvocation invocation, Environment env) { Type receiverType = analyzeExpr(invocation.receiver, env); string name = invocation.funcName; if (receiverType.Tag == TypeTag.ERROR) { invocation.type = symtab.errorType; return(symtab.errorType); // No need for parameter type validation } if (receiverType.Tag != TypeTag.STRUCT) { log.error(invocation.Pos, messages.receiverNotStruct); invocation.type = symtab.errorType; return(symtab.errorType); // No need for parameter type validation } // resolve func StructSymbol ssym = ((StructType)receiverType).symbol; Symbol sym = ssym.membersScope.findFirst(name, s => s.kind == Kind.FUNC); if (sym == null) { log.error(invocation.Pos, messages.methodNotFound, name, ssym.name); invocation.type = symtab.errorType; return(symtab.errorType); } if (sym.kind != Kind.FUNC) { log.error(invocation.Pos, messages.notAMethod, name, ssym.name); invocation.type = symtab.errorType; return(symtab.errorType); } return(analyzeInvocation(invocation, (FuncSymbol)sym, env)); }
public LLVMTypeRef Emit(PipeContext <Module> context) { // Create the struct construct. LLVMTypeRef @struct = LLVM.StructCreateNamed(context.Target.GetContext(), this.Identifier); // Create the body buffer list. List <LLVMTypeRef> body = new List <LLVMTypeRef>(); // Create a buffer dictionary for the symbol. Dictionary <string, LLVMTypeRef> symbolProperties = new Dictionary <string, LLVMTypeRef>(); // Map the body's properties onto the body. foreach (StructDefProperty property in this.Body.Properties) { // Emit the property's type. LLVMTypeRef type = property.Type.Emit(); // Append it to the body. body.Add(type); // Append it to the symbol's properties dictionary. symbolProperties.Add(property.Identifier, type); } // Set the struct's body. LLVM.StructSetBody(@struct, body.ToArray(), true); // Create the struct symbol. StructSymbol symbol = new StructSymbol(this.Identifier, @struct, symbolProperties); // TODO: Ensure it does not already exist on the symbol table? Or automatically does it? // Register struct as a symbol in the symbol table. context.SymbolTable.structs.Add(symbol); // Return the resulting struct. return(@struct); }
private void PrintStructSymbol(StructSymbol symbol) { PrintStart("Class: " + symbol.Syntax.Identifier.Value, ConsoleColor.Green); if (symbol.AllChecked.Count > 1) { foreach (var checkedClass in symbol.AllChecked) { PrintMiddle(checkedClass.FullName, ConsoleColor.Cyan); foreach (var memberFunction in checkedClass.Body !.Environment.Functions) { var checkedFunction = checkedClass.GetFunction(memberFunction.Syntax.FullName); if (checkedFunction != null) { _indentationLevel++; PrintCheckedFunction(checkedFunction, ConsoleColor.Gray); _indentationLevel--; } } } } _indentationLevel--; }
public BoundThisExpression(SyntaxNode syntax, StructSymbol instance) : base(syntax) { Instance = instance; }
public StructMethodBinder(SharedBinderState sharedBinderState, Binder parent, StructSymbol classSymbol) : base(sharedBinderState, parent) { _structSymbol = classSymbol; }
public bool TryDeclareStruct(StructSymbol @struct) => TryDeclareSymbol(@struct);
public BoundStructType(StructSymbol structSymbol, ImmutableArray <BoundMultipleVariableDeclarations> variables) : base(BoundNodeKind.StructType, structSymbol) { StructSymbol = structSymbol; Variables = variables; }
public BoundStructType(StructSymbol structSymbol, ImmutableArray <BoundNode> members) : base(BoundNodeKind.StructType, structSymbol) { StructSymbol = structSymbol; Members = members; }
public BoundLocalFieldAccessExpression(SyntaxNode syntax, StructSymbol instance, VariableSymbol structMember) : base(syntax) { Instance = instance; StructMember = structMember; }