// Parse a statement function. // We basically save the generated expression parse tree in the symbol // to be inserted whenever a reference to the statement function is made. ParseNode KStatementFunction(IdentifierToken identToken) { string methodName = identToken.Name; Symbol method = _localSymbols.Get(methodName); if (method != null && method.Defined && method.IsMethod) { _messages.Error(MessageCode.SUBFUNCDEFINED, String.Format("Statement function {0} already defined", methodName)); SkipToEndOfLine(); return null; } // Create a special symbol table just for this statement function _stfSymbols = new SymbolCollection(_localSymbols); // Parameter list expected int altReturnCount = 0; Collection<Symbol> parameters = ParseParameterDecl(_stfSymbols, SymScope.LOCAL, out altReturnCount); if (altReturnCount > 0) { _messages.Error(MessageCode.ALTRETURNNOTALLOWED, "Alternate return not permitted for statement functions"); } if (method == null) { method = _localSymbols.Add(methodName, new SymFullType(), SymClass.FUNCTION, null, _ls.LineNumber); } method.Class = SymClass.INLINE; method.Parameters = parameters; method.Linkage = SymLinkage.BYVAL; method.Defined = true; ExpectToken(TokenID.EQUOP); method.InlineValue = Expression(); // Blow away the temporary symbol table now we're out of scope _stfSymbols = null; return null; }
// Parse an identifier from the specified token and assign the corresponding // symbol to the identifier parse node. ParseNode ParseIdentifierFromToken(IdentifierToken identToken) { IdentifierParseNode node = ParseIdentifierParseNode(); if (node != null) { Symbol sym = GetMakeSymbolForCurrentScope(identToken.Name); if (sym == null) { _messages.Error(MessageCode.UNDEFINEDVARIABLE, String.Format("Undefined identifier {0}", identToken.Name)); return null; } node.Symbol = sym; sym.IsReferenced = true; } return node; }