/// CALL keyword /// Call a subroutine/function with specified parameters ParseNode KCall() { IdentifierToken identToken = ExpectIdentifierToken(); if (identToken == null) { SkipToEndOfLine(); return null; } Symbol sym = GetSymbolForCurrentScope(identToken.Name); if (sym == null) { sym = _globalSymbols.Add(identToken.Name, new SymFullType(SymType.NONE), SymClass.SUBROUTINE, null, _ls.LineNumber); } // If this was a parameter now being used as a function, change its // class and type. if (sym.Class != SymClass.SUBROUTINE) { sym.Class = SymClass.SUBROUTINE; sym.Defined = true; sym.Linkage = SymLinkage.BYVAL; } sym.IsReferenced = true; CallParseNode node = new CallParseNode(); node.ProcName = new IdentifierParseNode(sym); node.Parameters = new ParametersParseNode(); bool hasAlternateReturn = false; if (!IsAtEndOfLine()) { ExpectToken(TokenID.LPAREN); if (_ls.PeekToken().ID != TokenID.RPAREN) { SimpleToken token; do { if (_ls.PeekToken().ID == TokenID.STAR) { // Alternate return label. SkipToken(TokenID.STAR); token = ExpectToken(TokenID.INTEGER); if (token != null) { IntegerToken intToken = (IntegerToken)token; Symbol altLabel = GetMakeLabel(intToken.Value.ToString(), false); node.AlternateReturnLabels.Add(altLabel); hasAlternateReturn = true; } } else { if (hasAlternateReturn) { _messages.Error(MessageCode.ALTRETURNORDER, "Alternate return labels must be at the end"); } ParseNode exprNode = Expression(); if (exprNode != null) { node.Parameters.Add(exprNode, true); } } token = _ls.GetToken(); } while (token.ID == TokenID.COMMA); _ls.BackToken(); } ExpectToken(TokenID.RPAREN); } return node; }
// Parse a function call operand ParseNode FunctionOperand(string name, IdentifierParseNode identNode) { Symbol sym = GetSymbolForCurrentScope(name); SymType type = SymType.NONE; // Look for this symbol name in the local table which means its type // was predefined. Symbol symLocal = _localSymbols.Get(name); if (symLocal != null && symLocal.Scope != SymScope.PARAMETER && symLocal.Class != SymClass.FUNCTION && !symLocal.IsIntrinsic) { type = symLocal.Type; _localSymbols.Remove(symLocal); sym = _globalSymbols.Get(name); } if (sym == null) { sym = _globalSymbols.Add(name, new SymFullType(type), SymClass.FUNCTION, null, _ls.LineNumber); } // If this was a parameter now being used as a function, change its // class and type. if (sym.Class != SymClass.FUNCTION) { sym.Class = SymClass.FUNCTION; sym.Defined = true; sym.Linkage = SymLinkage.BYVAL; } sym.IsReferenced = true; CallParseNode node = new CallParseNode(); node.ProcName = new IdentifierParseNode(sym); node.Parameters = new ParametersParseNode(); node.Type = sym.Type; foreach (ParseNode t in identNode.Indexes) { node.Parameters.Add(t, true); } return node; }