Exemple #1
0
        private void _call_function(NakoNodeCallFunction node)
        {
            // push args values
            if (node.argNodes != null)
            {
                for (int i = 0; i < node.argNodes.Count; i++)
                {
                    Write_r(node.argNodes[i]);
                }
            }
            NakoILCode code = new NakoILCode();

            if (node.func.funcType == Function.NakoFuncType.SysCall)
            {
                // NakoAPIFunc f = (NakoAPIFunc)node.func;
                code.type  = NakoILType.SYSCALL;
                code.value = node.func.varNo;
                result.Add(code);
            }
            else // UserCall
            {
                NakoILCode defLabel = ((NakoNodeDefFunction)node.value).defLabel;
                code.type  = NakoILType.USRCALL;
                code.value = defLabel;
                if (code.value == null)
                {
                    //一旦ラベルを設定出来なかったユーザー関数には定義のオブジェクトそのものを入れて、FixLabel内で設定しなおす
                    code.value = node.value;
                }
                result.Add(code);
            }
        }
Exemple #2
0
        //> _arglist : '(' { _value } ')'
        //>          ;
        private bool _arglist(NakoNodeCallFunction node)
        {
            NakoToken firstT = tok.CurrentToken;
            int       nest   = 0;

            // '(' から始まるかチェック
            if (!Accept(NakoTokenType.PARENTHESES_L))
            {
                return(false);
            }
            tok.MoveNext(); // skip '('
            nest++;

            // '(' .. ')' の間を取りだして別トークンとする
            NakoTokenList par_list = new NakoTokenList();

            while (!tok.IsEOF())
            {
                if (Accept(NakoTokenType.PARENTHESES_R))
                {
                    nest--;
                    if (nest == 0)
                    {
                        tok.MoveNext();
                        break;
                    }
                }
                else if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    nest++;
                }
                par_list.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            // 現在のトークン位置を保存
            tok.Save();
            NakoTokenList tmp_list = tok;

            tok = par_list;
            tok.MoveTop();
            while (!tok.IsEOF())
            {
                if (!_value())
                {
                    throw new NakoParserException("関数の引数の配置エラー。", firstT);
                }
            }
            // トークンリストを復元
            tok = tmp_list;
            tok.Restore();
            return(true);
        }
        private void _call_function(NakoNodeCallFunction node)
        {
            // push args values
            if (node.argNodes != null)
            {
                for (int i = 0; i < node.argNodes.Count; i++)
                {
                    Write_r(node.argNodes[i]);
                }
            }
            NakoILCode code = new NakoILCode();

            if (node.func.funcType == Function.NakoFuncType.SysCall)
            {
                // NakoAPIFunc f = (NakoAPIFunc)node.func;
                code.type  = NakoILType.SYSCALL;
                code.value = node.func.varNo;
                result.Add(code);
            }
            else // UserCall
            {
                NakoILCode defLabel = ((NakoNodeDefFunction)node.value).defLabel;
                code.type  = NakoILType.USRCALL;
                code.value = defLabel;
                if (code.value == null)
                {
                    //一旦ラベルを設定出来なかったユーザー関数には定義のオブジェクトそのものを入れて、FixLabel内で設定しなおす
                    if (node.func.name != null)
                    {
                        code.value = node.value;
                    }
                    else
                    {
                        //ユーザー関数名がないもの(引数が関数定義だった場合)は、呼び出し先の情報が入った変数を取り出すILを書く
                        addNewILCode(NakoILType.LD_LOCAL, node.func.varNo);
                    }
                }
                result.Add(code);
            }
        }
Exemple #4
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);
        }