public void PopFrame(SymtabNode pRoutineId, ref IntermediateCode pIcode)
        {
            TFrameHeader pHeader = (TFrameHeader)stack[pFrameBase];

            //--Don't do anything if it's the bottommost stack frame.
            if (pFrameBase != 0)
            {
                //--Return to the caller's intermediate code.
                pIcode = pHeader.returnAddress.icode;
                pIcode.GoTo((int)pHeader.returnAddress.location);

                //--Cut the stack back.  Leave a function value on top.

                tos = pFrameBase;

                //if (pRoutineId.defn.how != TDefnCode.dcFunction) --tos;
                //    pFrameBase = (TStackItem)pHeader.dynamicLink.Value;
            }
        }
Beispiel #2
0
        public TType(TFormCode fc, int s, SymtabNode pId)
        {
            Form = fc;
            size = s;
            TypeId = pId;
            refCount = 0;

            switch (fc)
            {
                case TFormCode.fcSubrange:
                    SubRange.BaseType = null;
                    break;

                case TFormCode.fcArray:
                    array.pIndexType = array.pElmtType = null;
                    break;

                default:
                    break;
            }
        }
 public object GetValueAddress(SymtabNode pId)
 {
     throw new NotImplementedException();
 }
Beispiel #4
0
 public TExecutor(IntermediateCode icode)
     : base(icode)
 {
     pInputNode = SharedProperties.globalSymtab.Search("input");
     pOutputNode = SharedProperties.globalSymtab.Search("output");
 }
        private void ParseConstant(SymtabNode pConstId)
        {
            TTokenCode sign = TTokenCode.Dummy;     // Unary + or - sign, or none

            //-- Unary + or -
            if (TokenIn(token, tlUnaryOps))
            {
                if (token == TTokenCode.Minus) sign = TTokenCode.Minus;
                GetToken();
            }

            switch (token)
            {
                // -- Numeric constant: Integer or real type.
                case TTokenCode.Number:
                    if (pToken.DataType == TDataType.tyInteger)
                    {
                        pConstId.defn.constantValue.integerValue
                            = sign == TTokenCode.Minus ? -pToken.Value.integerValue
                                                        : pToken.Value.integerValue;

                        TType.SetType(ref pConstId.pType, TType.pIntegerType);
                    }
                    else
                    {
                        pConstId.defn.constantValue.realValue =
                            sign == TTokenCode.Minus ? -pToken.Value.realValue
                                                       : pToken.Value.realValue;

                        TType.SetType(ref pConstId.pType, TType.pRealType);
                    }

                    GetToken();
                    break;

                // -- Identifier constant
                case TTokenCode.Identifier:
                    ParseIdentifierConstant(pConstId, sign);
                    break;

                    // -- String constant: Character or string
                    // --                   (character array) type.
                case TTokenCode.String:
                    int length = pToken.TokenString.Length - 2; // skip quotes

                    if (sign != TTokenCode.Dummy) OnError(TErrorCode.InvalidConstant);

                    // -- Single character
                    if (length == 1)
                    {
                        pConstId.defn.constantValue.characterValue = pToken.TokenString[1];
                        TType.SetType(ref pConstId.pType, TType.pCharType);
                    }

                    // -- String (character array): Create a new unnamed
                    // --                           string type.
                    else
                    {
                        string pString = string.Empty;
                        CopyQuotedString(ref pString, pToken.TokenString);
                        pConstId.defn.constantValue.stringValue = pString;
                        TType.SetType(ref pConstId.pType, new TType(length));
                    }

                    GetToken();
                    break;
            }
        }
        private void ParseActualParmList(SymtabNode pRoutineId, bool parmCheckFlag)
        {
            SymtabNode pFormalId = pRoutineId != null ? pRoutineId.defn.routine.locals.pParmIds : null;
            // -- if there are no actual parameters, therw better not be
            // -- any formal parameters either.
            if (token != TTokenCode.LParen)
            {
                if (parmCheckFlag && pFormalId != null) OnError(TErrorCode.WrongNumberOfParms);
                return;
            }

            // -- Loop to parse acual parameter expressions
            // -- separated by commas.
            do
            {
                // -- ( or ,
                GetTokenAppend();

                ParseActualParm(pFormalId, parmCheckFlag);
                if (pFormalId != null) pFormalId = pFormalId.Next;
            } while (token == TTokenCode.Comma);

            // -- )
            CondGetTokenAppend(TTokenCode.RParen, TErrorCode.MissingRightParen);

            // There better not be any more formal paraters.
            if (parmCheckFlag && pFormalId != null) OnError(TErrorCode.WrongNumberOfParms);
        }
        protected void ParseAssignment(SymtabNode pTargetId)
        {
            TType pTargetType = ParseVariable(pTargetId);

            //-- :=
            Resync(tlColonEqual, tlExpressionStart);
            CondGetTokenAppend(TTokenCode.ColonEqual, TErrorCode.MissingColonEqual);

            //--<expr>
            TType pExprType = ParseExpression();

            //--Check for assignment compatibility.
            if (!TType.CheckAssignmentTypeCompatible(pTargetType, pExprType))
            {
                OnError(TErrorCode.IncompatibleAssignment);
            }
        }
        private void ParseVarOrFieldDecls(SymtabNode pRoutineId,
                                            TType pRecordType,
                                            int offset)
        {
            SymtabNode pId, pFirstId, pLastId;          // ptrs to symtab nodes
            SymtabNode pPrevSublistLastId = null;   // ptr to last node of
                                                    // previous sublist

            int totalSize = 0;                      // local variables

            // -- Loop to parse a list of variable or field declarations
            // -- separated by semicolons.
            while (token == TTokenCode.Identifier)
            {
                // -- <id-sublist>
                pFirstId = ParseIdSublist(pRoutineId, pRecordType, out pLastId);

                // -- :
                Resync(tlSublistFollow, tlDeclarationFollow);
                CondGetToken(TTokenCode.Colon, TErrorCode.MissingColon);

                // -- <type>
                TType pType = ParseTypeSpec();

                // -- Now loop to assign the type and offset to each
                // -- identifier in the sublist
                for (pId = pFirstId; pId != null; pId = pId.Next)
                {
                    TType.SetType(ref pId.pType, pType);

                    if (pRoutineId != null)
                    {
                        // -- Variables
                        pId.defn.dataOffset = offset++;
                        totalSize += pType.size;
                    }
                    else
                    {
                        // -- Record fields
                        pId.defn.dataOffset = offset;
                        offset += pType.size;
                    }

                }

                if (pFirstId != null)
                {
                    // -- Set the first sublist into the routine id's symtab node.
                    if (pRoutineId != null &&
                        (pRoutineId.defn.routine.locals.pVariableIds == null))
                    {
                        pRoutineId.defn.routine.locals.pVariableIds = pFirstId;
                    }

                    // -- Link this list to the previous sublist
                    if (pPrevSublistLastId != null) pPrevSublistLastId.Next = pFirstId;
                    pPrevSublistLastId = pLastId;

                }

                // -- ; for variable and record field declaraion, or
                // -- END for field declaration
                if (pRoutineId != null)
                {
                    Resync(tlDeclarationFollow, tlDeclarationStart);
                    CondGetToken(TTokenCode.Semicolon, TErrorCode.MissingSemicolon);

                    // -- Skip extra semicolons
                    while (token == TTokenCode.Semicolon) GetToken();
                    Resync(tlDeclarationFollow, tlDeclarationStart,
                        tlStatementStart);
                }
                else
                {
                    Resync(tlFieldDeclFollow);
                    if (token != TTokenCode.End)
                    {
                        CondGetToken(TTokenCode.Semicolon, TErrorCode.MissingSemicolon);

                        // -- Skip extra semicolons
                        while (token == TTokenCode.Semicolon) GetToken();
                        Resync(tlFieldDeclFollow, tlDeclarationStart, tlStatementStart);
                    }
                }
            }

            // -- Set the routine identifier node or the record type object.
            if (pRoutineId != null)
            {
                pRoutineId.defn.routine.totalLocalSize = totalSize;
            }
            else
            {
                pRecordType.size = offset;
            }
        }
        private TType ParseVariable(SymtabNode pId)
        {
            TType pResultType = pId.pType;  // ptr to result type

            //--Check how the variable identifier was defined.
            switch (pId.defn.how)
            {
                case TDefnCode.dcVariable:
                case TDefnCode.dcValueParm:
                case TDefnCode.dcVarParm:
                case TDefnCode.dcFunction:
                case TDefnCode.dcUndefined: break;  // OK

                default:
                    pResultType = TType.pDummyType;
                    OnError(TErrorCode.InvalidIdentifierUsage);
                    break;
            }

            GetTokenAppend();

            //-- [ or . : Loop to parse any subscripts and fields.
            bool doneFlag = false;
            do
            {
                switch (token)
                {

                    case TTokenCode.LBracket:
                        pResultType = ParseSubscripts(pResultType);
                        break;

                    case TTokenCode.Period:
                        pResultType = ParseField(pResultType);
                        break;

                    default:
                        doneFlag = true;
                        break;
                }
            } while (!doneFlag);

            return pResultType;
        }
        private void ParseIdentifierConstant(SymtabNode pId1, TTokenCode sign)
        {
            SymtabNode pId2 = Find(pToken.TokenString);     // ptr to <id-2>

            if (pId2.defn.how != TDefnCode.dcConstant)
            {
                OnError(TErrorCode.NotAConstantIdentifier);
                TType.SetType(ref pId1.pType, TType.pDummyType);
                GetToken();
                return;
            }

            // -- Integer identifier
            if (pId2.pType == TType.pIntegerType)
            {
                pId1.defn.constantValue.integerValue =
                    sign == TTokenCode.Minus ? -pId2.defn.constantValue.integerValue
                    : pId2.defn.constantValue.integerValue;

                TType.SetType(ref pId1.pType, TType.pIntegerType);
            }

            // -- Real identifier
            else if (pId2.pType == TType.pRealType)
            {
                pId1.defn.constantValue.realValue =
                    sign == TTokenCode.Minus ? -pId2.defn.constantValue.realValue
                    : pId2.defn.constantValue.realValue;

                TType.SetType(ref pId1.pType, TType.pRealType);
            }

            // -- Character identifier: No unary sign allowed
            else if (pId2.pType == TType.pCharType)
            {
                if (sign != TTokenCode.Dummy) OnError(TErrorCode.InvalidConstant);

                pId1.defn.constantValue.characterValue =
                    pId2.defn.constantValue.characterValue;

                TType.SetType(ref pId1.pType, TType.pCharType);
            }

            // -- Enumeration identifier: No unary sign allowed.
            else if (pId2.pType.Form == TFormCode.fcEnum)
            {
                if (sign != TTokenCode.Dummy) OnError(TErrorCode.InvalidConstant);

                pId1.defn.constantValue.integerValue =
                    pId2.defn.constantValue.integerValue;

                TType.SetType(ref pId1.pType, pId2.pType);

            }

            // -- Array identifier: Must be character array, and
            //                      no unary sign allowed.
            else if (pId2.pType.Form == TFormCode.fcArray)
            {
                if ((sign != TTokenCode.Dummy) ||
                    (pId2.pType.array.pElmtType != TType.pCharType))
                {
                    OnError(TErrorCode.InvalidConstant);
                }

                pId1.defn.constantValue.stringValue =
                    pId2.defn.constantValue.stringValue;

                TType.SetType(ref pId1.pType, pId2.pType);
            }

            GetToken();
        }
 private TType ParseDeclaredSubroutineCall(SymtabNode pRoutineId, bool parmCheckFlag)
 {
     ParseActualParmList(pRoutineId, parmCheckFlag);
     return pRoutineId.pType;
 }
        private void ParseDeclarations(SymtabNode pRoutineId)
        {
            if (token == TTokenCode.Const)
            {
                GetToken();
                ParseConstantDefinitions(pRoutineId);
            }

            if (token == TTokenCode.Type)
            {
                GetToken();
                ParseTypeDefinitions(pRoutineId);
            }

            if (token == TTokenCode.Var)
            {
                GetToken();
                ParseVariableDeclarations(pRoutineId);
            }

            if (TokenIn(token, tlProcFuncStart))
            {
                ParseSubroutineDeclarations(pRoutineId);
            }
        }
        public TToken Get()
        {
            TToken pToken = null;
            TTokenCode token;
            int code;

            //--Loop to process any line markers
            //--and extract the next token code.
            do
            {
                //--First read the token code.
                code = m_formatter.ReadInt32();
                token = (TTokenCode)code;

                if (token == TTokenCode.LineMarker)
                {
                    int number = m_formatter.ReadInt32();
                    m_currentLineNumber = number;
                }

            } while (token == TTokenCode.LineMarker);

            //--Determine the token class, based on the token code.
            switch (token)
            {
                case TTokenCode.Number: pToken = new NumberToken(); break;
                case TTokenCode.String: pToken = new StringToken(); break;

                case TTokenCode.Identifier:
                    pToken = new WordToken();
                    pToken.Code = TTokenCode.Identifier;
                    break;

                default:
                    if (code < (int)TTokenCode.And)
                    {
                        pToken = new SpecialToken();
                        pToken.Code = token;
                    }
                    else
                    {
                        pToken = new WordToken(); // reserved word
                        pToken.Code = token;
                    }
                    break;
            }

            // now get node
            //--Extract the symbol table node and set the token string.
            switch (token)
            {
                case TTokenCode.Identifier:
                case TTokenCode.Number:
                case TTokenCode.String:
                    pNode = GetNode();
                    pToken.TokenString = pNode.String;
                    break;

                default:
                    pNode = null;
                    pToken.TokenString = symbolStrings[code];
                    break;
            }

            return pToken;
        }
 public void Put(SymtabNode node)
 {
     m_formatter.Write(node.SymtabIndex);
     m_formatter.Write(node.NodeIndex);
 }
        private void ParseSubroutineDeclarations(SymtabNode pRoutineId)
        {
            SymtabNode pLastId = null;      // ptr to last routine id node
                                            // in local list

            // --Loop to parse procedure and function definitions.
            while (TokenIn(token, tlProcFuncStart))
            {
                SymtabNode pRtnId = ParseSubroutine();

                // -- Link the routine's local (nested) routine id nodes together
                if (pRoutineId.defn.routine.locals.pRoutineIds == null)
                {
                    pRoutineId.defn.routine.locals.pRoutineIds = pRtnId;
                }
                else
                {
                    pLastId.Next = pRtnId;
                }

                pLastId = pRtnId;
            }
        }
 private TType ParseIdentifierType(SymtabNode pId2)
 {
     GetToken();
     return pId2.pType;
 }
        private void ParseTypeDefinitions(SymtabNode pRoutineId)
        {
            SymtabNode pLastId = null;

            while (token == TTokenCode.Identifier)
            {
                SymtabNode pTypeId = EnterNewLocal(pToken.TokenString);

                if (pRoutineId.defn.routine.locals.pTypeIds == null)
                {
                    pRoutineId.defn.routine.locals.pTypeIds = pTypeId;
                }
                else
                {
                    pLastId.Next = pTypeId;
                }

                pLastId = pTypeId;

                GetToken();
                CondGetToken(TTokenCode.Equal, TErrorCode.MissingEqual);

                TType.SetType(ref pTypeId.pType, ParseTypeSpec());
                pTypeId.defn.how = TDefnCode.dcType;

                if (pTypeId.pType.TypeId == null)
                {
                    pTypeId.pType.TypeId = pTypeId;
                }

                Resync(tlDeclarationFollow, tlDeclarationStart,
                    tlStatementStart);
                CondGetToken(TTokenCode.Semicolon, TErrorCode.MissingSemicolon);

                while (token == TTokenCode.Semicolon) GetToken();
                Resync(tlDeclarationFollow, tlDeclarationStart, tlStatementStart);
            }
        }
        private SymtabNode ParseIdSublist(SymtabNode pRoutineId, TType pRecordType, out SymtabNode pLastId)
        {
            SymtabNode pId;
            SymtabNode pFirstId = null;

            pLastId = null;

            // -- Loop to parse each identifier in the sublist.
            while (token == TTokenCode.Identifier)
            {
                // -- Variable: Enter into local symbol table.
                // -- Field:    Enter into record symbol table.
                pId = pRoutineId != null ? EnterNewLocal(pToken.TokenString)
                    : pRecordType.record.pSymtab.EnterNew(pToken.TokenString);

                // -- Link newly-declared identifier nodes together
                // -- into a sublist.
                if (pId.defn.how == TDefnCode.dcUndefined)
                {
                    pId.defn.how = pRoutineId != null ? TDefnCode.dcVariable : TDefnCode.dcField;

                    if (pFirstId == null) pFirstId = pLastId = pId;
                    else
                    {
                        pLastId.Next = pId;
                        pLastId = pId;
                    }
                }

               // -- ,
                GetToken();
                Resync(tlIdentifierFollow);
                if (token == TTokenCode.Comma)
                {
                    // -- Saw comma.
                    // -- Skip extra commas and look for an identifier
                    do
                    {
                        GetToken();
                        Resync(tlIdentifierStart, tlIdentifierFollow);
                        if (token == TTokenCode.Comma) OnError(TErrorCode.MissingIdentifier);
                    } while (token == TTokenCode.Comma);
                }
            }

            return pFirstId;
        }
 private void ParseVariableDeclarations(SymtabNode pRoutineId)
 {
     ParseVarOrFieldDecls(pRoutineId, null, 0);
 }
        private TType ParseReadReadLnCall(SymtabNode pRoutineId)
        {
            //--Actual parameters are optional for readln.
            if (token != TTokenCode.LParen)
            {
                if (pRoutineId.defn.routine.which == TRoutineCode.rcRead)
                {
                    OnError(TErrorCode.WrongNumberOfParms);
                }
                return TType.pDummyType;
            }

            //--Loop to parse comma-separated list of actual parameters.
            do
            {
                //-- ( or ,
                GetTokenAppend();

                //--Each actual parameter must be a scalar variable,
                //--but parse an expression anyway for error recovery.
                if (token == TTokenCode.Identifier)
                {
                    SymtabNode pParmId = Find(pToken.TokenString);
                    icode.Put(pParmId);

                    if (ParseVariable(pParmId).Base.Form
                        != TFormCode.fcScalar) OnError(TErrorCode.IncompatibleTypes);
                }
                else
                {
                    ParseExpression();
                    OnError(TErrorCode.InvalidVarParm);
                }

                //-- , or )
                Resync(tlActualVarParmFollow,
                       tlStatementFollow, tlStatementStart);
            } while (token == TTokenCode.Comma);

            //-- )
            CondGetTokenAppend(TTokenCode.RParen, TErrorCode.MissingRightParen);

            return TType.pDummyType;
        }
        private TType parseWriteWritelnCall(SymtabNode pRoutineId)
        {
            //--Actual parameters are optional only for writeln.
            if (token != TTokenCode.LParen)
            {
                if (pRoutineId.defn.routine.which == TRoutineCode.rcWrite)
                {
                    OnError(TErrorCode.WrongNumberOfParms);
                }
                return TType.pDummyType;
            }

            //--Loop to parse comma-separated list of actual parameters.
            do
            {
                //-- ( or ,
                GetTokenAppend();

                //--Value <expr> : The type must be either a non-Boolean
                //--               scalar or a string.
                TType pActualType = ParseExpression().Base;
                if (((pActualType.Form != TFormCode.fcScalar) ||
                    (pActualType == TType.pBooleanType))
                    && ((pActualType.Form != TFormCode.fcArray) ||
                    (pActualType.array.pElmtType != TType.pCharType)))
                {
                    OnError(TErrorCode.IncompatibleTypes);
                }

                //--Optional field width <expr>
                if (token == TTokenCode.Colon)
                {
                    GetTokenAppend();
                    if (ParseExpression().Base != TType.pIntegerType)
                    {
                        OnError(TErrorCode.IncompatibleTypes);
                    }

                    //--Optional precision <expr>
                    if (token == TTokenCode.Colon)
                    {
                        GetTokenAppend();
                        if (ParseExpression().Base != TType.pIntegerType)
                        {
                            OnError(TErrorCode.IncompatibleTypes);
                        }
                    }
                }
            } while (token == TTokenCode.Comma);

            //-- )
            CondGetTokenAppend(TTokenCode.RParen, TErrorCode.MissingRightParen);

            return TType.pDummyType;
        }
        private TType ParseStandardSubroutineCall(SymtabNode pRoutineId)
        {
            switch (pRoutineId.defn.routine.which)
            {
                case TRoutineCode.rcRead:
                case TRoutineCode.rcReadln:
                    return ParseReadReadLnCall(pRoutineId);

                case TRoutineCode.rcWrite:
                case TRoutineCode.rcWriteln:
                    return parseWriteWritelnCall(pRoutineId);

                case TRoutineCode.rcEoln:
                case TRoutineCode.rcEof:
                    return ParseEofEolnCall();

                case TRoutineCode.rcAbs:
                case TRoutineCode.rcSqr:
                    return ParseAbsSqrCall();

                case TRoutineCode.rcArctan:
                case TRoutineCode.rcCos:
                case TRoutineCode.rcExp:
                case TRoutineCode.rcLn:
                case TRoutineCode.rcSin:
                case TRoutineCode.rcSqrt:
                    return ParseArctanCosExpLnSinSqrtCall();

                case TRoutineCode.rcPred:
                case TRoutineCode.rcSucc:
                    return ParsePredSuccCall();

                case TRoutineCode.rcChr:
                    return ParseChrCall();

                case TRoutineCode.rcOdd:
                    return ParseOddCall();

                case TRoutineCode.rcOrd:
                    return ParseOrdCall();

                case TRoutineCode.rcRound:
                case TRoutineCode.rcTrunc:
                    return ParseRoundTruncCall();

                default:
                    return TType.pDummyType;
            }
        }
        private void ParseActualParm(SymtabNode pFormalId, bool parmCheckFlag)
        {
            // -- If we're not checking the acual parameters against
            // -- the corresponding formal parameters (as during error
            // -- recovery), just parse the actual parameter.
            if (!parmCheckFlag)
            {
                ParseExpression();
                return;
            }

            // -- If we've already run out formal parmeter,
            // -- we have and error.  Go into error recovery mode and
            // -- parse the actual parameter anyway
            if (pFormalId == null)
            {
                OnError(TErrorCode.WrongNumberOfParms);
                ParseExpression();
                return;
            }

            // -- Formal value parameter: The acual parameter can be an
            // --                         arbitrary expressoin that is
            // --                         assignment type compatible with
            // --                         the formal parameter.
            if (pFormalId.defn.how == TDefnCode.dcValueParm)
            {
                if( !TType.CheckAssignmentTypeCompatible(pFormalId.pType, ParseExpression()) )
                {
                    OnError(TErrorCode.IncompatibleTypes);
                }

            }

            // -- Formal VAR parameter: The actual parameter must be a
            // --                       variable of the same type as the
            // --                       formal parameter.
            else if (token == TTokenCode.Identifier)
            {
                SymtabNode pActualId = Find(pToken.TokenString);
                icode.Put(pActualId);

                if (pFormalId.pType != ParseVariable(pActualId))
                {
                    OnError(TErrorCode.IncompatibleTypes);
                }

                Resync(tlExpressionFollow, tlStatementFollow, tlStatementStart);
            }
            else
            {
                ParseExpression();
                OnError(TErrorCode.InvalidVarParm);
            }
        }
        private TType ParseSubrangeLimit(SymtabNode pLimitId, ref int limit)
        {
            TType pType = TType.pDummyType;

            TTokenCode sign = TTokenCode.Dummy;

            limit = 0;

            if (TokenIn(token, tlUnaryOps))
            {
                if (token == TTokenCode.Minus) sign = TTokenCode.Minus;
                GetToken();
            }

            switch (token)
            {
                case TTokenCode.Number:
                    if (pToken.DataType == TDataType.tyInteger)
                    {
                        limit = (sign == TTokenCode.Minus) ? -pToken.Value.integerValue
                            : pToken.Value.integerValue;

                        pType = TType.pIntegerType;
                    }
                    else OnError(TErrorCode.InvalidSubrangeType);
                    break;

                case TTokenCode.Identifier:

                    if (pLimitId != null) pLimitId = Find(pToken.TokenString);

                    if (pLimitId.defn.how == TDefnCode.dcUndefined)
                    {
                        pLimitId.defn.how = TDefnCode.dcConstant;
                        TType.SetType(ref pLimitId.pType, TType.pDummyType);
                        pType = TType.pDummyType;
                        break;
                    }
                    else if ((pLimitId.pType == TType.pRealType) ||
                              (pLimitId.pType == TType.pDummyType) ||
                              (pLimitId.pType.Form == TFormCode.fcArray))
                    {
                        OnError(TErrorCode.InvalidSubrangeType);
                    }
                    else if (pLimitId.defn.how == TDefnCode.dcConstant)
                    {
                        if (pLimitId.pType == TType.pIntegerType)
                        {
                            limit = sign == TTokenCode.Minus ? -pLimitId.defn.constantValue.integerValue : pLimitId.defn.constantValue.integerValue;
                        }
                        else if (pLimitId.pType == TType.pCharType)
                        {
                            if (sign != TTokenCode.Dummy) OnError(TErrorCode.InvalidConstant);
                            limit = pLimitId.defn.constantValue.characterValue;
                        }
                        else if (pLimitId.pType.Form == TFormCode.fcEnum)
                        {
                            if (sign != TTokenCode.Dummy) OnError(TErrorCode.InvalidConstant);
                            limit = pLimitId.defn.constantValue.integerValue;
                        }

                        pType = pLimitId.pType;
                    }
                    else OnError(TErrorCode.NotAConstantIdentifier);
                    break;

                case TTokenCode.String:

                    if (sign != TTokenCode.Dummy) OnError(TErrorCode.InvalidConstant);

                    if (pToken.TokenString.Length != 3)
                    {
                        OnError(TErrorCode.InvalidSubrangeType);
                    }

                    limit = pToken.TokenString[1];
                    pType = TType.pCharType;
                    break;

                default:
                    OnError(TErrorCode.MissingConstant);
                    return pType;
            }

            GetHashCode();
            return pType;
        }
        private void ParseBlock(SymtabNode pRoutineId)
        {
            //--<declarations>
            ParseDeclarations(pRoutineId);

            // --<compound-statement> : Reset the icode and append BEGIN to it,
            //                          and then Parse the compound statement
            Resync(tlStatementStart);
            if (token != TTokenCode.Begin) OnError(TErrorCode.MissingBEGIN);
            icode.Reset();
            ParseCompound();

            // -- Set the program's or routine's icode.
            pRoutineId.defn.routine.pIcode = new IntermediateCode(icode);
        }
        private TType ParseSubrangeType(SymtabNode pMinId)
        {
            TType pType = new TType(TFormCode.fcSubrange, 0, null);

            TType.SetType(ref pType.SubRange.BaseType,
                            ParseSubrangeLimit(pMinId, ref pType.SubRange.min));

            Resync(tlSubrangeLimitFollow, tlDeclarationStart);
            CondGetToken(TTokenCode.DotDot, TErrorCode.MissingDotDot);

            TType pMaxType = ParseSubrangeLimit(null, ref pType.SubRange.max);

            if (pMaxType != pType.SubRange.BaseType)
            {
                OnError(TErrorCode.IncompatibleTypes);
                pType.SubRange.max = pType.SubRange.min;
            }
            else if (pType.SubRange.min > pType.SubRange.max)
            {
                OnError(TErrorCode.MinGtMax);

                int temp = pType.SubRange.min;
                pType.SubRange.min = pType.SubRange.max;
                pType.SubRange.max = temp;
            }

            pType.size = pType.SubRange.BaseType.size;
            return pType;
        }
        private void ParseConstantDefinitions(SymtabNode pRoutineId)
        {
            SymtabNode pLastId = null;      // ptr to last constant id node
                                            // in local list

            // -- Loop to parse a list of constant definitions
            // -- separated by semicolons.
            while (token == TTokenCode.Identifier)
            {   // --<id>
                SymtabNode pConstId = EnterNewLocal(pToken.TokenString);

                // -- Link the routine's local constant id nodes together.
                if (pRoutineId.defn.routine.locals.pConstantIds == null)
                {
                    pRoutineId.defn.routine.locals.pConstantIds = pConstId;
                }
                else
                {
                    pLastId.Next = pConstId;
                }

                pLastId = pConstId;

                // -- =
                GetToken();
                CondGetToken(TTokenCode.Equal, TErrorCode.MissingEqual);

                // --<constant>
                ParseConstant(pConstId);
                pConstId.defn.how = TDefnCode.dcConstant;

                // --;
                Resync(tlDeclarationFollow, tlDeclarationStart, tlStatementStart);
                CondGetToken(TTokenCode.Semicolon, TErrorCode.MissingSemicolon);

                // -- Skip extra semicolons
                while (token == TTokenCode.Semicolon) GetToken();
                Resync(tlDeclarationFollow, tlDeclarationStart, tlStatementStart);
            }
        }
        private TType ParseSubroutineCall(SymtabNode pRoutineId, bool parmCheckFlag)
        {
            GetTokenAppend();

            return pRoutineId.defn.routine.which == TRoutineCode.rcDeclared ||
                    pRoutineId.defn.routine.which == TRoutineCode.rcForward ||
                    !parmCheckFlag
                    ? ParseDeclaredSubroutineCall(pRoutineId, parmCheckFlag)
                    : ParseStandardSubroutineCall(pRoutineId);
        }
Beispiel #29
0
 protected void GetToken()
 {
     pToken = icode.Get();
     token = pToken.Code;
     pNode = icode.SymtabNode;
 }
 public void DeallocateValue(SymtabNode pId)
 {
 }