void CompileAssignment(AssignStatement assign)
 {
     for (var i = 0; i < assign.IdentifierCount; i++)
     {
         CompileAssignment(assign, assign.Identifiers [i], assign.Expressions [i]);
     }
 }
Esempio n. 2
0
        AssignStatement ParseAssignStatement()
        {
            var stmt = AssignStatement.Create(unit.Location);

            // Parse identifiers
            while (!unit.Match(LoreToken.Operator, "="))
            {
                // Parse name
                var ident = ParseName();
                var name  = NamedParameter.Create(ident);

                // Parse type
                if (unit.Accept(LoreToken.Colon))
                {
                    name.SetType(ParseName());
                }

                // Add the named parameter to the identifiers
                stmt.AddIdentifier(name);

                // Try parsing another identifier
                if (!unit.Match(LoreToken.Operator, "="))
                {
                    unit.Expect(LoreToken.Comma);
                }
            }
            unit.Expect(LoreToken.Operator, "=");

            // Parse expressions
            do
            {
                var expr = ParseExpression();
                stmt.AddExpression(expr);
            } while (unit.Accept(LoreToken.Comma));

            // Verify that all identifiers are satisfied
            var pluralizeExpression = stmt.ExpressionCount > 1 ? "s" : string.Empty;
            var pluralizeIdentifier = stmt.IdentifierCount > 1 ? "s" : string.Empty;

            if (stmt.IdentifierCount > stmt.ExpressionCount)
            {
                var count = stmt.IdentifierCount - stmt.ExpressionCount;
                var pluralizeDifference = count > 1 ? "s" : string.Empty;
                throw LoreException.Create(stmt.Location)
                      .Describe($"Attempt to assign {stmt.ExpressionCount} expression{pluralizeExpression} to {stmt.IdentifierCount} identifier{pluralizeIdentifier}.")
                      .Resolve($"Add more expressions or remove {count} identifier{pluralizeDifference}.");
            }
            if (stmt.IdentifierCount < stmt.ExpressionCount)
            {
                var count = stmt.ExpressionCount - stmt.IdentifierCount;
                var pluralizeDifference = count > 1 ? "s" : string.Empty;
                throw LoreException.Create(stmt.Location)
                      .Describe($"Attempt to assign {stmt.ExpressionCount} expression{pluralizeExpression} to {stmt.IdentifierCount} identifier{pluralizeIdentifier}.")
                      .Resolve($"Discard {count} expression{pluralizeDifference} by using the _ operator.");
            }

            return(stmt);
        }
        void CompileAssignment(AssignStatement stmt, NamedParameter identifier, AstNode expr)
        {
            // Check if the variable already exists in the parent scope
            Symbol sym;

            if (Table.TopScope.FindSymbol(identifier.Name.Name, out sym))
            {
                // The variable already exists
                throw LoreException.Create(Location)
                      .Describe($"Redefinition of variable '{identifier.Name.Name}'.")
                      .Describe($"Previous definition was at '{sym.Location}'.");
            }

            // Compile the expression
            expr.Visit(this);

            // Get the expression value and type
            var exprVal     = Stack.Pop().Value;
            var exprValType = exprVal.TypeOf();

            // Check if the identifier has a type
            if (identifier.HasType)
            {
                var identType = Helper.GetBuiltinTypeFromString(identifier.Type.Name);

                // Check if the type of the identifier is different
                // from the type of the expression
                if (!Helper.CompareType(identType, exprValType))
                {
                    // Try casting the expression value to the expected type
                    exprVal = Helper.BuildCast(Builder, exprVal, identType);
                }

                // Set the type of the expression to the type of the identifier
                exprValType = identType;
            }

            // Allocate the variable
            var ptr = LLVM.BuildAlloca(Builder, exprValType, identifier.Name.Name);

            // Store the value in the variable
            LLVM.BuildStore(Builder, exprVal, ptr);

            // Add the variable to the symbol table
            var name = identifier.Name.Name;

            sym = Symbol.CreatePtr(name, ptr, Location, stmt.Mutable);
            Table.AddSymbol(sym);
        }
Esempio n. 4
0
 public virtual void Accept(AssignStatement stmt) => Update(stmt);
Esempio n. 5
0
 public override void Accept(AssignStatement stmt)
 {
     base.Accept(stmt);
     CompileAssignment(stmt);
 }