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); }
private DustVisitor CreateChild(FunctionParameter[] predefindProperties) { DustVisitor visitor = new DustVisitor(new DustContext(visitorContext)); foreach (FunctionParameter property in predefindProperties) { // fixme visitor.visitorContext.AddProperty(property.Identifier); } return(visitor); }