private void AnalyzeVariableDeclaration(VariableDeclarationStatementNode variableDeclaration) { CobaltType variableType; if (variableDeclaration.TypeKeyword != null && variableDeclaration.Expression != null) { CobaltType expressionType = AnalyzeExpression(variableDeclaration.Expression); if (expressionType != variableDeclaration.TypeKeyword.Type) { throw new CobaltTypeError($"Type mismatch between explicitely declared type of variable `{variableDeclaration.Identifier.IdentifierName}` ({variableDeclaration.TypeKeyword.Type}) and type of expression ({expressionType}).", variableDeclaration.Expression.SourceLine); } variableType = expressionType; } else if (variableDeclaration.TypeKeyword == null && variableDeclaration.Expression != null) { variableType = AnalyzeExpression(variableDeclaration.Expression); } else if (variableDeclaration.TypeKeyword != null && variableDeclaration.Expression == null) { variableType = variableDeclaration.TypeKeyword.Type; } else { throw new CompilerException($"`{MethodBase.GetCurrentMethod().Name}` called with bad AST stucture in variable declaration from line {variableDeclaration.SourceLine}."); } Symbol variable = new Symbol(variableDeclaration.Identifier.IdentifierName, new VariableTypeSignature(variableType), variableDeclaration.Expression != null, variableDeclaration.SourceLine); variableDeclaration.Parent.RegisterSymbol(variable); }
private void GenerateVariableDeclarationCode(StringBuilder builder, VariableDeclarationStatementNode variableDeclaration) { builder.Append($"let {variableDeclaration.Identifier.IdentifierName}"); if (variableDeclaration.Expression != null) { builder.Append("="); GenerateExpressionCode(builder, variableDeclaration.Expression); } builder.Append(";"); }
public StatementNode ParseVariableDeclarationStatement(List <Token> tokens) { if (tokens.Count <= 3 || tokens.ElementAt(0).Type != TokenType.Declaration || tokens.ElementAt(1).Type != TokenType.Identifier || tokens.ElementAt(2).Type != TokenType.Colon || (tokens.ElementAt(3).Type != TokenType.Equal && tokens.ElementAt(3).Type != TokenType.TypeKeyword)) { throw new CobaltSyntaxError($"Ivalid variable declaration statement.", tokens.First().SourceLine, tokens.First().PositionOnLine); } // Parse identifier IdentifierNode identifier = ParseIdentifier(tokens.ElementAt(1)); // Parse type, if applicable TypeKeywordNode type = null; if (tokens.ElementAt(3).Type == TokenType.TypeKeyword) { type = ParseTypeKeyword(tokens.ElementAt(3)); } // Parse expression ExpressionNode expression = null; if (tokens.Count > 4 && tokens.ElementAt(3).Type == TokenType.Equal) { expression = ParseExpression(tokens.GetRange(4, tokens.Count - 4)); } else if (tokens.Count > 5 && tokens.ElementAt(4).Type == TokenType.Equal) { expression = ParseExpression(tokens.GetRange(5, tokens.Count - 5)); } // Validate syntax if (type == null && expression == null) { throw new CobaltSyntaxError("Variable declaration has no explicit type and no expression to infer a type from.", tokens.First().SourceLine, tokens.First().PositionOnLine); } // Create and return output statement node VariableDeclarationStatementNode statement = new VariableDeclarationStatementNode(tokens.First().SourceLine); statement.Identifier = identifier; if (type != null) { statement.TypeKeyword = type; } if (expression != null) { statement.Expression = expression; } return(statement); }
private void EmitVariableDeclaration(VariableDeclarationStatementNode variableDeclaration) { output.Append("let "); output.Append(variableDeclaration.VariableIdentifier); if (variableDeclaration.AssignedExpressionNode != null) { output.Append('='); EmitExpression(variableDeclaration.AssignedExpressionNode); } output.Append(';'); }
private bool BindInVariableDeclaration(VariableDeclarationStatementNode variableDeclaration, VariableIdentifierMap variableIdentifierMap) { if (variableIdentifierMap.TryGet(variableDeclaration.VariableIdentifier, out VariableSymbolNode? _)) { ErrorProvider.ReportError(ErrorCode.CantRedeclareVariable, Compilation, variableDeclaration.VariableIdentifierNode); return(false); } VariableSymbolNode variable; if (variableDeclaration.AssignedExpressionNode != null) { TypeSymbolNode?assignedType = BindInExpression(variableDeclaration.AssignedExpressionNode, variableIdentifierMap); if (assignedType == null) { return(false); } if (variableDeclaration.TypeSpecNode == null) { variable = variableDeclaration.CreateVariable(typeSymbol: assignedType); } else { if (!typeManager.TryGetTypeSymbol(variableDeclaration.TypeSpecNode, out TypeSymbolNode? variableType)) { return(false); } else if (!TypeIsCompatibleWith(assignedType, variableType, variableDeclaration.AssignedExpressionNode, out ImplicitConversionSymbolNode? conversion)) { return(false); } else { if (conversion != null) { variableDeclaration.AssignedExpressionNode.SpecifyImplicitConversion(conversion); } variable = variableDeclaration.CreateVariable(variableType); } } } else { if (typeManager.TryGetTypeSymbol(variableDeclaration.TypeSpecNode, out TypeSymbolNode? variableType)) { variable = variableDeclaration.CreateVariable(variableType); } else { return(false); } } variableIdentifierMap.AddSymbol(variableDeclaration.VariableIdentifier, variable); return(true); }