public override Node VisitFunctionDeclaration(DustParser.FunctionDeclarationContext context) { string name = context.functionDeclarationBase().functionName().identifierName().GetText(); FunctionModifier[] modifiers = context.functionDeclarationBase().functionModifier().Select(modifierContext => FunctionModifier.Parse(modifierContext.GetText())).ToArray(); FunctionParameter[] parameters = context.functionParameterList()?.functionParameter().Select(Visit).Cast <FunctionParameter>().ToArray(); if (visitorContext.ContainsPropety(name)) { visitorContext.ErrorHandler.ThrowError(new SyntaxError($"Identifier '{name}' is already defined", context.functionDeclarationBase().functionName().GetRange())); return(null); } for (int i = 0; i < parameters?.Length; i++) { if (visitorContext.ContainsPropety(parameters[i].Identifier.Name)) { visitorContext.ErrorHandler.ThrowError(new SyntaxError($"Identifier '{name}' is already defined", context.functionParameterList().functionParameter(i).GetRange())); return(null); } } DustVisitor child = CreateChild(parameters ?? new FunctionParameter[0]); List <Statement> statements = new List <Statement>(); DustType returnType = null; if (context.statementBlock() != null) { foreach (DustParser.StatementContext statementContext in context.statementBlock().statement()) { Statement statement = (Statement)child.Visit(statementContext); if (statement is ReturnStatement) { // TODO: Fix the temporary HACK by creating a Type System. returnType = DustType.Number; } statements.Add(statement); } } FunctionDeclaration declaration = new FunctionDeclaration(name, modifiers, parameters ?? new FunctionParameter[0], statements.ToArray(), returnType, child.visitorContext, new Range { Start = context.GetRange().Start, End = context.functionDeclarationBase().functionName().GetRange().End }); visitorContext.AddFunction(declaration.Function); return(declaration); }
/// <summary> /// Visit a parse tree produced by <see cref="DustParser.functionDeclaration"/>. /// <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 VisitFunctionDeclaration([NotNull] DustParser.FunctionDeclarationContext context) { return(VisitChildren(context)); }
/// <summary> /// Exit a parse tree produced by <see cref="DustParser.functionDeclaration"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitFunctionDeclaration([NotNull] DustParser.FunctionDeclarationContext context) { }