public override object VisitFunctionDeclaration([NotNull] CMinusParser.FunctionDeclarationContext context)
        {
            string functionType = SymbolTable.Symbol.RemoveExtras(context.typeSpecifier().GetText());
            string functionName = context.ID().GetText();

            List <SymbolTable.Symbol> parameters = (List <SymbolTable.Symbol>) this.Visit(context.parameters()); // Visit parameters

            SymbolTable.Symbol functionSymbol = new SymbolTable.Symbol(
                id: functionName,
                type: functionType,
                construct: SymbolTable.Symbol.Construct.FUNCTION,
                size: (uint)parameters.Count,
                scope: this.internalScope,
                pointerCount: 0
                );

            functionSymbol.AddMembers(parameters);

            bool success = this.symbolTable.AddSymbol(functionSymbol);

            if (!success)
            {
                this.EmitSemanticErrorMessage($"Symbol {functionName} already in symbol table as a {this.symbolTable.GetSymbol(functionName).construct}", context);
            }

            return(null);
        }
        public override object VisitStructDeclaration([NotNull] CMinusParser.StructDeclarationContext context)
        {
            string structType = context.ID().GetText();

            bool typeSuccess = this.symbolTable.AddSymbolType(structType);

            if (!typeSuccess)
            {
                this.EmitSemanticErrorMessage($"Struct type {structType} already declared", context);
            }

            List <SymbolTable.Symbol> members = (List <SymbolTable.Symbol>) this.Visit(context.structDeclarationList());

            uint membersSize = (uint)members.Sum(member => member.size);

            SymbolTable.Symbol structSymbol = new SymbolTable.Symbol(
                id: structType,
                type: structType,
                construct: SymbolTable.Symbol.Construct.STRUCT,
                scope: 0,
                size: membersSize,
                pointerCount: 0
                );

            bool symbolSuccess = this.symbolTable.AddSymbol(structSymbol);

            if (!symbolSuccess)
            {
                this.EmitSemanticErrorMessage($"Symbol {structType} already in symbol table as a {this.symbolTable.GetSymbol(structType).construct}", context);
            }

            return(null);
        }
        public override object VisitVariableDeclaration_Array([NotNull] CMinusParser.VariableDeclaration_ArrayContext context)
        {
            string variableName = context.ID().GetText();
            string variableType = SymbolTable.Symbol.RemoveExtras(context.typeSpecifier().GetText());

            if (variableType == "void")
            {
                this.EmitSemanticErrorMessage("Variable declared as void type", context);
            }

            SymbolTable.Symbol symbol = new SymbolTable.Symbol(
                id: variableName,
                type: variableType,
                construct: SymbolTable.Symbol.Construct.ARRAY,
                scope: 0,
                size: uint.Parse(context.NUM().GetText()),
                pointerCount: SymbolTable.Symbol.CountStringAsterisks(context.typeSpecifier().GetText())
                );

            bool success = this.symbolTable.AddSymbol(symbol);

            if (!success)
            {
                this.EmitSemanticErrorMessage($"Symbol {variableName} already in symbol table as a {this.symbolTable.GetSymbol(variableName).construct}", context);
            }

            return(null);
        }
        public override object VisitFunctionCall([NotNull] CMinusParser.FunctionCallContext context)
        {
            string functionName = context.ID().GetText();

            if (!this.symbolTable.HasSymbol(functionName))
            {
                this.EmitSemanticErrorMessage($"Function {functionName} called but not declared", context);
                return(null);
            }

            SymbolTable.Symbol foundSymbol = this.symbolTable.GetSymbol(functionName);

            if (foundSymbol.construct != SymbolTable.Symbol.Construct.FUNCTION)
            {
                this.EmitSemanticErrorMessage($"{functionName} called as function but declared as a {foundSymbol.construct}", context);
                return(null);
            }

            if (this.inAssignment && foundSymbol.type == "void")
            {
                this.EmitSemanticErrorMessage($"Void returning function in assignment", context);
            }

            return(null);
        }
        public override object VisitFunctionDeclaration([NotNull] CMinusParser.FunctionDeclarationContext context)
        {
            string functionName = context.ID().GetText();

            SymbolTable.Symbol functionSymbol = this.symbolTable.GetSymbol(functionName);

            this.internalScope++;
            this.symbolTable.EnterScope();

            foreach (SymbolTable.Symbol member in functionSymbol.submembers)
            {
                bool success = this.symbolTable.AddSymbol(member);
                if (!success)
                {
                    this.EmitSemanticErrorMessage($"Symbol {member.id} already in symbol table as a {this.symbolTable.GetSymbol(member.id).construct}", context);
                }
            }

            this.Visit(context.compoundStatement());

            this.symbolTable.ExitScope();
            this.internalScope--;

            return(true);
        }
        public override object VisitStructDeclarationList_ManyDeclarations([NotNull] CMinusParser.StructDeclarationList_ManyDeclarationsContext context)
        {
            List <SymbolTable.Symbol> members = (List <SymbolTable.Symbol>) this.Visit(context.structDeclarationList());

            SymbolTable.Symbol member = (SymbolTable.Symbol) this.Visit(context.structVariableDeclaration());
            members.Add(member);
            return(members);
        }
        public override object VisitParameterList_ManyParameters([NotNull] CMinusParser.ParameterList_ManyParametersContext context)
        {
            List <SymbolTable.Symbol> parameters = (List <SymbolTable.Symbol>) this.Visit(context.parameterList());

            SymbolTable.Symbol parameter = (SymbolTable.Symbol) this.Visit(context.parameter());
            parameters.Add(parameter);
            return(parameters);
        }
        public override object VisitVariable_ID([NotNull] CMinusParser.Variable_IDContext context)
        {
            string variableName = context.ID().GetText();

            if (!this.symbolTable.HasSymbol(variableName))
            {
                this.EmitSemanticErrorMessage($"Variable {variableName} called but not declared", context);
                return("error");
            }

            SymbolTable.Symbol foundSymbol = this.symbolTable.GetSymbol(variableName);

            if (foundSymbol.construct == SymbolTable.Symbol.Construct.FUNCTION || foundSymbol.construct == SymbolTable.Symbol.Construct.ERROR)
            {
                this.EmitSemanticErrorMessage($"{variableName} used as a variable but declared as a {foundSymbol.construct}", context);
                return("error");
            }

            return(foundSymbol.type);
        }
        public override object VisitVariable_ArrayAccess([NotNull] CMinusParser.Variable_ArrayAccessContext context)
        {
            string arrayType = (string)this.Visit(context.variable());

            string arrayName = SymbolTable.Symbol.RemoveExtras(context.variable().GetText());

            if (!this.symbolTable.HasSymbol(arrayName))
            {
                this.EmitSemanticErrorMessage($"Variable {arrayName} called but not declared", context);
                return(SymbolTable.Symbol.Construct.ERROR);
            }

            SymbolTable.Symbol foundSymbol = this.symbolTable.GetSymbol(arrayName);

            if (foundSymbol.construct != SymbolTable.Symbol.Construct.ARRAY)
            {
                this.EmitSemanticErrorMessage($"{arrayName} used as an array but declared as a {foundSymbol.construct}", context);
                return(SymbolTable.Symbol.Construct.ERROR);
            }

            return(foundSymbol.type);
        }
示例#10
0
 public static bool IsValid(SymbolTable.Symbol symbol)
 {
     return(symbol <= SymbolTable.Symbol.D9);
 }