Esempio n. 1
0
        //> _def_function_args : empty
        //>                    | '(' { WORD } ')' FUNCTION_NAME
        //>                    | { WORD } FUNCTION_NAME
        //>                    | FUNCTION_NAME '(' { WORD } ')'
        //>                    ;
        private bool _def_function_args(NakoFunc func)
        {
            NakoToken     firstT    = tok.CurrentToken;
            NakoTokenList argTokens = new NakoTokenList();
            bool          argMode   = false;
            NakoToken     funcName  = null;

            // 関数の引数宣言を取得する
            while (!tok.IsEOF())
            {
                // '(' .. ')' の中は全部、関数の引数です
                if (argMode)
                {
                    if (Accept(NakoTokenType.PARENTHESES_R))
                    {
                        argMode = false;
                        tok.MoveNext();
                        continue;
                    }
                    argTokens.Add(tok.CurrentToken);
                    tok.MoveNext();
                    continue;
                }
                if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    tok.MoveNext();
                    argMode = true;
                    continue;
                }
                if (Accept(NakoTokenType.SCOPE_BEGIN))
                {
                    break;
                }
                if (Accept(NakoTokenType.FUNCTION_NAME))
                {
                    funcName = tok.CurrentToken;
                    tok.MoveNext();
                    continue;
                }
                argTokens.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            if (funcName == null)
            {
                throw new NakoParserException("関数名がありません。", firstT);
            }
            func.name = funcName.GetValueAsName();            //TODO: check namespace and class name
            func.args.analizeArgTokens(argTokens);
            return(true);
        }
Esempio n. 2
0
        //> _callfunc : FUNCTION_NAME
        //>           | FUNCTION_NAME _arglist
        //>           ;
        private bool _callfunc()
        {
            NakoToken t = tok.CurrentToken;

            if (!Accept(NakoTokenType.FUNCTION_NAME))
            {
                return(false);
            }
            tok.MoveNext(); // skip FUNCTION_NAME

            string       fname = t.GetValueAsName();
            NakoVariable var   = globalVar.GetVar(fname);

            if (var == null)
            {
                throw new NakoParserException("関数『" + fname + "』が見あたりません。", t);
            }

            //
            NakoNodeCallFunction callNode = new NakoNodeCallFunction();
            NakoFunc             func     = null;

            callNode.Token = t;

            if (var.Type == NakoVarType.SystemFunc)
            {
                int funcNo = (int)var.Body;
                func          = NakoAPIFuncBank.Instance.FuncList[funcNo];
                callNode.func = func;
            }
            else
            {
                NakoNodeDefFunction defNode = (NakoNodeDefFunction)var.Body;
                func           = callNode.func = defNode.func;
                callNode.value = defNode;
            }

            // ---------------------------------
            if (Accept(NakoTokenType.PARENTHESES_L))
            {
                _arglist(callNode);
                // TODO ここで引数の数をチェックする処理
            }
            // 引数の数だけノードを取得
            for (int i = 0; i < func.ArgCount; i++)
            {
                NakoFuncArg arg = func.args[func.ArgCount - i - 1];
                NakoNode    argNode;
                if (arg.defaultValue != null && calcStack.Count < (func.ArgCount - i))                  //初期値があって引数が無い場合に引数に初期値を与える
                {
                    argNode       = new NakoNodeConst();
                    argNode.value = arg.defaultValue;
                    if (arg.defaultValue is int)
                    {
                        argNode.type  = NakoNodeType.INT;
                        argNode.Token = new NakoToken(NakoTokenType.INT);
                    }
                    else if (arg.defaultValue is string)
                    {
                        argNode.type  = NakoNodeType.STRING;
                        argNode.Token = new NakoToken(NakoTokenType.STRING);
                    }
                }
                else
                {
                    argNode = calcStack.Pop(arg);
                }
                if (arg.varBy == VarByType.ByRef)
                {
                    if (argNode.type == NakoNodeType.LD_VARIABLE)
                    {
                        ((NakoNodeVariable)argNode).varBy = VarByType.ByRef;
                    }
                }
                callNode.AddChild(argNode);
            }

            // ---------------------------------
            // 計算スタックに関数の呼び出しを追加
            calcStack.Push(callNode);
            this.lastNode = callNode;

            return(true);
        }
Esempio n. 3
0
        //> _def_variable : WORD (DIM_VARIABLE|DIM_NUMBER|DIM_INT|DIM_STRING|DIM_ARRAY) [=_value]
        //>               ;
        private bool _def_variable()
        {
            if (!Accept(NakoTokenType.WORD))
            {
                return(false);
            }
            NakoVarType st = NakoVarType.Object;

            switch (tok.NextTokenType)
            {
            case NakoTokenType.DIM_VARIABLE:
                st = NakoVarType.Object;
                break;

            case NakoTokenType.DIM_NUMBER:
                st = NakoVarType.Double;
                break;

            case NakoTokenType.DIM_INT:
                st = NakoVarType.Int;
                break;

            case NakoTokenType.DIM_STRING:
                st = NakoVarType.String;
                break;

            case NakoTokenType.DIM_ARRAY:
                st = NakoVarType.Array;
                break;

            default:
                return(false);
            }
            NakoToken    t     = tok.CurrentToken;
            int          varNo = localVar.CreateVar(t.GetValueAsName());
            NakoVariable v     = localVar.GetVar(varNo);

            v.SetBody(null, st);
            tok.MoveNext(); // skip WORD
            tok.MoveNext(); // skip DIM_xxx

            // 変数の初期化があるか?
            if (!Accept(NakoTokenType.EQ))
            {
                return(true); // なければ正常値として戻る
            }
            tok.MoveNext();   // skip EQ

            if (!_value())
            {
                throw new NakoParserException("変数の初期化文でエラー。", t);
            }
            // 代入文を作る
            NakoNodeLet let = new NakoNodeLet();

            let.VarNode       = new NakoNodeVariable();
            let.VarNode.varNo = varNo;
            let.VarNode.scope = NakoVariableScope.Local;
            let.ValueNode.AddChild(calcStack.Pop());
            this.parentNode.AddChild(let);
            return(true);
        }