public Stmt VisitDeclarationStatement(Stmt.VariableDeclaration statement) { var function = LLVM.GetBasicBlockParent(LLVM.GetInsertBlock(_builder)); var type = statement.TypeSpecifier; var name = statement.Identifier.Source; if (_namedValues.ContainsKey(name)) { throw new Exception("Variable name already declared"); } LLVMValueRef alloca; if (type.Dimensions == 0) { alloca = EntryAllocation(function, type, name); } else { Expr.ArrayInitializer init = (Expr.ArrayInitializer)statement.Initializer; alloca = AllocateArray(function, type, name, init.DimensionSizes); } _namedValues.Add(name, new LLVMSymbol { Binding = statement.Binding, IsDecayed = false, KtsType = type, Value = alloca }); if (statement.Initializer == null) { if (type.Dimensions == 0) { if (type.IsFloat()) { LLVM.BuildStore(_builder, LLVM.ConstReal(LLVMPrimitiveType(type.Type), 0), alloca); } else { LLVM.BuildStore(_builder, LLVM.ConstInt(LLVMPrimitiveType(type.Type), 0, _lFalse), alloca); } } else { throw new Exception("Uninitialized array"); } } else { if (type.Dimensions == 0) { var initType = Visit(statement.Initializer); var initValue = _valueStack.Pop(); var casted = CheckedCast(initValue, initType, type); LLVM.BuildStore(_builder, casted, alloca); } } return(null); }
public bool VisitDeclarationStatement(Stmt.VariableDeclaration statement) { bool result = true; if (LocalTypes.ContainsKey(statement.Identifier.Source)) { result = false; Console.WriteLine($"'{statement.Identifier.Source}' variable name already used"); } LocalTypes.Add(statement.Identifier.Source, statement.TypeSpecifier); if (statement.Binding != null) { foreach (var functionName in statement.Binding.Identifiers) { if (!FunctionTable.ContainsKey(functionName)) { Console.WriteLine($"Undeclared function '{functionName}' used in binding on line: {statement.Identifier.Line}"); result = false; } else { FunctionSymbol fs = FunctionTable[functionName]; if (fs.Parameters.Count > 1 || (fs.Parameters.Count == 1 && fs.Parameters[0].Type != statement.TypeSpecifier)) { Console.WriteLine($"Mismatched function parameters and binding variable on line: {statement.Binding.Type.Line}"); result = false; } } } } if (statement.Initializer != null) { TypeSpecifier ts = Examine(statement.Initializer); if (ts.ImplicitCastableTo(statement.TypeSpecifier)) { return(result); } if (ts != statement.TypeSpecifier) { Console.WriteLine($"Trying to assign type '{ts}' to a variable of type '{statement.TypeSpecifier}'"); result = false; } } return(result); }