Ejemplo n.º 1
0
        public override int VisitBlock([NotNull] CBluntParser.BlockContext context)
        {
#if DEBUG
            Console.WriteLine("VisitBlock");
#endif
            AddText("{\n");
            for (int count = 0; count < context.ChildCount; ++count)
            {
                Visit(context.GetChild(count));
            }
            AddText("}\n");
            return(0);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="CBluntParser.block"/>.
 /// <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 VisitBlock([NotNull] CBluntParser.BlockContext context)
 {
     return(VisitChildren(context));
 }
Ejemplo n.º 3
0
        public override int VisitBlock([NotNull] CBluntParser.BlockContext context)
        {
#if DEBUG
            Console.WriteLine("VisitBlock");
#endif

            if (context.Parent.RuleIndex != CBluntParser.RULE_function)
            {
                SymbolTable.MethodScopeLinkedList.AddLast(new Dictionary <string, VariableProperties>());
            }

            // In the initial scope of the method, check whether there exists at least one return. Error if there exists multiple
            int returnCount = 0;

            for (int i = 0; i < context.statement().Count(); ++i)
            {
                // Skip non-function returns
                if (context.statement(i).functionreturn() == null)
                {
                    Visit(context.statement(i));
                    continue;
                }

                // Cannot break here as there MAY exist multiple returns
                ++returnCount;

                // Check for void: it cannot return anything
                if (context.statement(i).functionreturn().expression() != null && SymbolTable.CurrentMethodType == "void")
                {
                    SyntaxError(context, "Void methods cannot return values");
                    return(1);
                }

                // Check for non-void: it MUST return something
                if (context.statement(i).functionreturn().expression() == null && SymbolTable.CurrentMethodType != "void")
                {
                    SyntaxError(context, "Method " + SymbolTable.CurrentMethodType + " with type " + SymbolTable.CurrentMethodType + " must return a value");
                    return(1);
                }

                // If there exists multiple returns, there is a problem. This accounts for both void and other types
                if (returnCount > 1)
                {
                    SyntaxError(context, "Method " + SymbolTable.CurrentMethodType + " with type " + SymbolTable.CurrentMethodType + " cannot return multiple times in its method scope");
                    return(1);
                }

                // Initial checks done, now expression has to be visited to determine the return type according to method type
                // void can of course be skipped
                if (SymbolTable.CurrentMethodType == "void")
                {
                    continue;
                }

                // Add to the expression store
                SymbolTable.ExpressionStoreLinkedList.AddLast(new ExpressionStore());

                // Get the type returned
                Visit(context.statement(i).functionreturn().expression());

                var returnType = SymbolTable.ExpressionStoreLinkedList.Last.Value.Type;

                if (SymbolTable.CurrentMethodType != returnType)
                {
                    SyntaxError(context, "A type " + returnType + " is returned, a type " + SymbolTable.CurrentMethodType + " was expected to be returned instead");
                    return(1);
                }

                SymbolTable.ExpressionStoreLinkedList.RemoveLast();
            }

            // If there exists no return and it is NOT a method of type void, output an error
            if (returnCount == 0 && SymbolTable.CurrentMethodType != "void" && SymbolTable.MethodScopeLinkedList.Count == 1)
            {
                SyntaxError(context, "Method " + SymbolTable.CurrentMethodType + " with type " + SymbolTable.CurrentMethodType + " does not return a type " + SymbolTable.CurrentMethodType);
                return(1);
            }

            if (context.Parent.RuleIndex != CBluntParser.RULE_function)
            {
                SymbolTable.MethodScopeLinkedList.RemoveLast();
            }

            return(0);
        }
Ejemplo n.º 4
0
 public override int VisitBlock([NotNull] CBluntParser.BlockContext context)
 {
     return(base.VisitBlock(context));
 }