public override bool VisitStructLevelMethod([NotNull] GamaParser.StructLevelMethodContext context) { var fndef = context.topLevelFuncDef(); var name = fndef.Symbol().GetText(); GamaFunctionList fnlist = null; if (name == "new") { fnlist = StructType.Meta.Constructors; } else { fnlist = StructType.Meta.GetMethod(name); } if (fnlist == null) { fnlist = new GamaFunctionList(name); StructType.Meta.Methods.Add(fnlist); } var retty = InstanceTypes.Void; var tyname = fndef.typeName(); if (tyname != null) { retty = Parent.NamespaceContext.FindTypeRefGlobal(tyname); if (retty == null) { Parent.GlobalContext.AddError(new ErrorTypeNotFound(tyname)); return(false); } } var stplist = fndef.symbolTypePairList(); var paramlist = new GamaParamList(); paramlist.Add("this", new GamaPointer(StructType)); // add self as a pointer since this is a method if (stplist != null) { var pairs = stplist.symbolTypePair(); foreach (var p in pairs) { var ty = Parent.NamespaceContext.FindTypeRefGlobal(p.typeName()); if (ty == null) { Parent.GlobalContext.AddError(new ErrorTypeNotFound(p.typeName())); return(false); } if (!paramlist.Add(p.Symbol().GetText(), ty)) { Parent.GlobalContext.AddError(new ErrorDuplicateParameter(p)); return(false); } } } if (fnlist.FindFunction(paramlist) != null) { Parent.GlobalContext.AddError(new ErrorDuplicateMethod(fndef)); return(false); } var modty = new GamaFunction(retty, paramlist.Parameters.Select(p => p.Type).ToArray(), LLVMTypeRef.CreateFunction(retty.UnderlyingType, paramlist.Parameters.Select(p => p.Type.UnderlyingType).ToArray())); var modfn = Parent.GlobalContext.Module.AddFunction($"{ StructType.Name }.{ name }", modty.UnderlyingType); var fn = new GamaFunctionRef(retty, paramlist, modty, modfn, true); /* Parameters are added to top frame of the target function, but they are not treated as conventional variables */ var unit = new GamaFunctionCompiler(Parent.NamespaceContext, fn); foreach (var p in paramlist.Parameters) { unit.Top.AddValue(p.Name, new GamaValueRef(p.Type, modfn.GetParam(p.Index), false)); } unit.Visit(fndef.block()); if (unit.Finish() == 0) { // TODO: handle type method attributes fnlist.AddFunction(fn); } else { ; } return(true); }
/// <summary> /// Visit a parse tree produced by the <c>StructLevelMethod</c> /// labeled alternative in <see cref="GamaParser.structLevelStatement"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitStructLevelMethod([NotNull] GamaParser.StructLevelMethodContext context) { return(VisitChildren(context)); }
/// <summary> /// Exit a parse tree produced by the <c>StructLevelMethod</c> /// labeled alternative in <see cref="GamaParser.structLevelStatement"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitStructLevelMethod([NotNull] GamaParser.StructLevelMethodContext context) { }