Пример #1
0
        /// 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;
        }
Пример #2
0
        // 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;
        }