public override object VisitFieldDeclaration([NotNull] DoshikParser.FieldDeclarationContext context) { _compilationContext.SetParsingAntlrContext(context); var scope = _compilationContext.CompilationUnit.Scope; var variable = new CompilationUnitVariable(_compilationContext.CompilationUnit); variable.IsPublic = context.PUBLIC() != null; var foundType = GetTypeNameVisitor.Apply(_compilationContext, context.typeType()); foundType.ThrowIfNotFound(_compilationContext); variable.Type = foundType.DataType; (var variableName, var variableInitializer) = ((string, DoshikParser.VariableInitializerContext))Visit(context.variableDeclarator()); variable.Name = variableName; if (variableInitializer != null) { // ToDo: потом можно сделать инициализаторы полей. Прикол тут в том что их нельзя инициализировать также // как локальные переменные в statement-ах, потому что тут нет порядка выполнения операций, а значит // в инициализирующем выражении первой переменной может быть зареференшена вторвая переменная а в инициализации второй переменной референс на первую // таким образом будет circular reference. И такие вещи нужно определять, для этого нужно сортировать эти определения переменных и инициализировать их // в порядке начиная от меньшего количества референсов на другие переменные в инициализаторе до больших + трекать как то circular референсы. // Из-за того что тут такой гимор, я решил пока не делать инициализаторы (инициализировать переменные все равно можно будет вручную на событии Start или как там его) throw _compilationContext.ThrowCompilationError($"field initializer is not supported yet"); } if (scope.FindVariableByName(variable.Name, true) != null) { throw _compilationContext.ThrowCompilationError($"variable { variable.Name } is already defined"); } scope.Variables[variable.Name] = variable; return(null); }
/// <summary> /// Visit a parse tree produced by <see cref="DoshikParser.fieldDeclaration"/>. /// <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 VisitFieldDeclaration([NotNull] DoshikParser.FieldDeclarationContext context) { return(VisitChildren(context)); }
/// <summary> /// Exit a parse tree produced by <see cref="DoshikParser.fieldDeclaration"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitFieldDeclaration([NotNull] DoshikParser.FieldDeclarationContext context) { }