void CompileAssignment(AssignStatement assign) { for (var i = 0; i < assign.IdentifierCount; i++) { CompileAssignment(assign, assign.Identifiers [i], assign.Expressions [i]); } }
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); }
public virtual void Accept(AssignStatement stmt) => Update(stmt);
public override void Accept(AssignStatement stmt) { base.Accept(stmt); CompileAssignment(stmt); }