public override bool VisitStmtVarDefBase([NotNull] GamaParser.StmtVarDefBaseContext context) { var name = context.Symbol().GetText(); var val = Top.FindValue(name); // Duplicate variable definition (parent frames can have same variable, it will be overriden in current frame) if (val != null) { NamespaceContext.Context.AddError(new ErrorDuplicateVariable(context)); return(false); } val = VisitExpression(context.expr()); if (val == null) { return(false); } /* LLVM */ CurrentBlock.PositionBuilderAtEnd(Builder); var alloc = Builder.BuildAlloca(val.Type.UnderlyingType, name); Builder.BuildStore(val.Value, alloc); Top.AddValue(name, new GamaValueRef(val.Type, alloc, true)); return(true); }
public override bool VisitStmtVarDefNull([NotNull] GamaParser.StmtVarDefNullContext context) { var name = context.Symbol().GetText(); var val = Top.FindValue(name); if (val != null) { NamespaceContext.Context.AddError(new ErrorDuplicateVariable(context)); return(false); } var ty = NamespaceContext.FindTypeRefGlobal(context.typeName()); if (ty == null) { NamespaceContext.Context.AddError(new ErrorTypeNotFound(context.typeName())); return(false); } if (ty == InstanceTypes.Void) { NamespaceContext.Context.AddError(new ErrorVariableVoid(context.typeName())); return(false); } /* LLVM */ CurrentBlock.PositionBuilderAtEnd(Builder); if (ty is GamaFunction) // Functionals are not allocated directly, instead a pointer is allocateds { var ptr = new GamaPointer(ty); var alloc = Builder.BuildAlloca(ptr.UnderlyingType, name); Builder.BuildStore(LLVMValueRef.CreateConstPointerNull(ptr.UnderlyingType), alloc); Top.AddValue(name, new GamaValueRef(ty, alloc, true)); } else { var alloc = Builder.BuildAlloca(ty.UnderlyingType, name); // TODO: maybe add an option to not null initialize these variable definitions // Possible speed boost Builder.BuildStore(LLVMValueRef.CreateConstNull(ty.UnderlyingType), alloc); Top.AddValue(name, new GamaValueRef(ty, alloc, true)); } return(true); }
public override bool VisitStmtVarDefFull([NotNull] GamaParser.StmtVarDefFullContext context) { var name = context.Symbol().GetText(); var val = Top.FindValue(name); if (val != null) { NamespaceContext.Context.AddError(new ErrorDuplicateVariable(context)); return(false); } var ty = NamespaceContext.FindTypeRefGlobal(context.typeName()); if (ty == null) { NamespaceContext.Context.AddError(new ErrorTypeNotFound(context.typeName())); return(false); } if (ty == InstanceTypes.Void) { NamespaceContext.Context.AddError(new ErrorVariableVoid(context.typeName())); return(false); } val = VisitExpression(ty, context.expr()); if (val == null) { return(false); } // If expression compiler returns a function then it's impossible for a type mismatch to happen // Expression compiler checks for type mismatches when evaluating function pointers // Alsp no need to check if 'ty' is a GamaFunction either, expressiom compiler already did that if (val.Type is GamaFunction valtyfn) { var tyfn = new GamaPointer(ty as GamaFunction); /* LLVM */ CurrentBlock.PositionBuilderAtEnd(Builder); var alloc = Builder.BuildAlloca(tyfn.UnderlyingType, name); Builder.BuildStore(val.Value, alloc); Top.AddValue(name, new GamaValueRef(ty, alloc, true)); return(true); } // If not function, there might be a mismatch. Check it and error if it mismatches if (val.Type != ty) { NamespaceContext.Context.AddError(new ErrorTypeMismatch(context.expr())); return(false); } /* LLVM */ // One block above to avoid dumb C# error message saying 'alloc' is already defined (SOMEHOW) { CurrentBlock.PositionBuilderAtEnd(Builder); var alloc = Builder.BuildAlloca(ty.UnderlyingType, name); Builder.BuildStore(val.Value, alloc); Top.AddValue(name, new GamaValueRef(ty, alloc, true)); } return(true); }