public override List <string> ExecuteSemanticAction(Stack <SemanticRecord> semanticRecordTable, Stack <SymbolTable> symbolTable, IToken lastToken, MoonCodeResult moonCode)
        {
            SymbolTable   currentTable = symbolTable.Peek();
            List <string> errors       = new List <string>();
            string        className    = lastToken.getSemanticName();

            // Check if the class' name already exists
            foreach (Entry entry in currentTable.GetEntries())
            {
                if (entry.getName() == className)
                {
                    errors.Add(string.Format("Identifier {0} at line {1} has already been declared", className, lastToken.getLine()));
                    break;
                }
            }

            // Create a class entry
            Entry classEntry = new ClassEntry(className, currentTable);

            symbolTable.Push(classEntry.getChild());

            return(errors);
        }
        public override List <string> ExecuteSemanticAction(Stack <SemanticRecord> semanticRecordTable, Stack <SymbolTable> symbolTable, IToken lastToken, MoonCodeResult moonCode)
        {
            Stack <SemanticRecord> callChain = new Stack <SemanticRecord>();
            List <string>          errors    = new List <string>();

            if (!semanticRecordTable.Any())
            {
                errors.Add(string.Format("Grammar error at line {0}: could not verify factor for emtpy stack", lastToken.getLine()));
                return(errors);
            }

            SemanticRecord lastRecord = semanticRecordTable.Pop();

            // Accumulate semantic records until we reach the start of the factor
            while (lastRecord.recordType != RecordTypes.FactorStart)
            {
                callChain.Push(lastRecord);

                if (!semanticRecordTable.Any())
                {
                    errors.Add(string.Format("Grammar error at {0}. Could not find start for a factor", lastToken.getLine()));
                    break;
                }

                lastRecord = semanticRecordTable.Pop();
            }

            SemanticRecord currentLink    = callChain.Pop();
            Entry          linkedVariable = null;

            // The first element in the chain is a reference to a locally accessible variable or function
            // Go through symbol tables of increasing scope until we find the referenced identifier
            foreach (SymbolTable table in symbolTable)
            {
                linkedVariable = table.GetEntries().FirstOrDefault(x => (x is VarParamEntry || x is FunctionEntry) && x.getName() == currentLink.getValue());

                if (linkedVariable != null)
                {
                    break;
                }
            }

            // Verify the validity of this initial reference
            bool success = VerifyLink(currentLink, linkedVariable, lastToken, errors);

            // Go through the call chain and verify each link
            while (callChain.Any() && success)
            {
                currentLink = callChain.Pop();

                ClassEntry referredClass = ((VarParamEntry)linkedVariable).getVariable().getClass();

                if (referredClass.getChild() == null)
                {
                    errors.Add(string.Format("Identifier {0} cannot be reached at line {1}", currentLink.getValue(), lastToken.getLine()));
                    return(errors);
                }

                // Look in the referred class for the variable or function that is being referred to
                linkedVariable = referredClass.getChild().GetEntries().FirstOrDefault(x => (x is VarParamEntry || x is FunctionEntry) && x.getName() == currentLink.getValue());

                success = VerifyLink(currentLink, linkedVariable, lastToken, errors);
            }

            ClassEntry expressionType = new ClassEntry("undefined", 0);

            // Find the linked variable and create a new expression for it
            if (linkedVariable is VarParamEntry)
            {
                expressionType = ((VarParamEntry)linkedVariable).getVariable().getClass();
            }
            else if (linkedVariable is FunctionEntry)
            {
                expressionType = ((FunctionEntry)linkedVariable).GetReturnType();
            }

            if (linkedVariable == null)
            {
                errors.Add(string.Format("Grammar error: Could not link variable at line {0}", lastToken.getLine()));
            }
            else
            {
                semanticRecordTable.Push(new ExpressionRecord(expressionType, linkedVariable.getAddress()));
            }

            return(errors);
        }