public override ParseResult VisitFunctionDefinitionStatement(MelonParser.FunctionDefinitionStatementContext context) { string name = context.Name.GetText(); LexicalEnvironment functionEnvironment = new LexicalEnvironment(parseContext.LexicalEnvironment, true); var functionParameters = new List <FunctionParameter>(); if (context.Parameters != null) { for (var i = 0; i < context.Parameters.parameter().Length; i++) { var parameter = context.Parameters.parameter(i); bool isVarargs = parameter.VARARGS() != null; if (isVarargs && i < context.Parameters.parameter().Length - 1) { throw new MelonException("Varargs parameter can only appear once and has to be the last parameter"); } MelonType type = _engine.anyType; if (parameter.Type != null) { var typeName = parameter.Type.name().value; var typeKv = _engine.Types.FirstOrDefault(x => x.Value.Name == typeName); if (typeKv.Value == null) { throw new MelonException($"Could not find type '{typeName}'"); } type = typeKv.Value; } var typeRef = new TypeReference(_engine, type); functionEnvironment.AddVariable(parameter.Name.value, null, typeRef); functionParameters.Add(new FunctionParameter(parameter.Name.value, typeRef, isVarargs)); } } var function = new ScriptFunctionInstance(name, _engine) { ParameterTypes = functionParameters.ToArray() }; var variable = parseContext.LexicalEnvironment.AddVariable(name, function, new TypeReference(_engine, _engine.functionType)); parseContext.AddVariableReference(variable, VariableReferenceType.Local); if (context.ReturnType != null) { var typeName = context.ReturnType.value; var typeKv = _engine.Types.FirstOrDefault(x => x.Value.Name == typeName); if (typeKv.Value == null) { throw new MelonException($"Could not find type '{typeName}'"); } function.ReturnType = new TypeReference(_engine, typeKv.Value); } MelonVisitor visitor = new MelonVisitor(_engine, function); ParseContext functionParseContext = visitor.Parse(context.Block, functionEnvironment); function.SetContext(functionEnvironment, functionParseContext); return(DefaultResult); }