Exemple #1
0
        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);
        }
Exemple #2
0
        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()));
        }
Exemple #4
0
        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()));
        }
Exemple #5
0
        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);
        }
Exemple #6
0
            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);
            }
Exemple #7
0
            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);
            }
Exemple #8
0
        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);
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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;
                }
            }
        }
Exemple #13
0
        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));
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        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--;
        }
Exemple #16
0
 public BoundThisExpression(SyntaxNode syntax, StructSymbol instance)
     : base(syntax)
 {
     Instance = instance;
 }
 public StructMethodBinder(SharedBinderState sharedBinderState, Binder parent, StructSymbol classSymbol)
     : base(sharedBinderState, parent)
 {
     _structSymbol = classSymbol;
 }
Exemple #18
0
 public bool TryDeclareStruct(StructSymbol @struct)
 => TryDeclareSymbol(@struct);
Exemple #19
0
 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;
 }