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; } }
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(); }
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); }
protected void GetToken() { pToken = icode.Get(); token = pToken.Code; pNode = icode.SymtabNode; }
public void DeallocateValue(SymtabNode pId) { }