Beispiel #1
0
        private object _removeAt(INakoFuncCallInfo info)
        {
            object a = info.StackPop();
            long   i = info.StackPopAsInt();

            if (!(a is NakoVariable))
            {
                throw new NakoPluginRuntimeException("『削除』の引数が変数ではありません");
            }

            NakoVariable av     = (NakoVariable)a;
            NakoVarArray a_body = null;

            // 配列でなければ配列に強制変換する
            if (!(av.Body is NakoVarArray))
            {
                a_body = info.CreateArray();
                a_body.SetValuesFromString(av.Body.ToString());
                av.SetBody(a_body, NakoVarType.Array);
            }
            else
            {
                a_body = (NakoVarArray)av.Body;
            }
            // 要素を削除する
            a_body.RemoveAt((int)i);

            // 結果をセット
            return(null);
        }
Beispiel #2
0
        /// <summary>
        /// 構文解析の行われた TopNode に対して、ILコードの発行を行う
        /// 結果は、Codes に得られる
        /// </summary>
        public NakoILCodeList WriteIL()
        {
            var writer = new NakoILWriter();

            writer.Write(this.topNode);
            codes = writer.Result;
            for (int i = 0; i < this.GlobalVar.Count(); i++)  //interpreterで使えるように関数定義が保存されている変数をアドレスに変換
            {
                NakoVariable v = this.GlobalVar.GetVar(i);
                if (v.Body is NakoNodeDefFunction)
                {
                    NakoVariable   setVar = new NakoVariable();
                    string         label  = "FUNC_" + ((NakoNodeDefFunction)v.Body).func.name;
                    NakoILCodeList cl     = writer.Result;
                    for (int j = 0; j < cl.Count; j++)
                    {
                        NakoILCode c = cl [j];
                        if (c.value is string && (string)c.value == label)
                        {
                            setVar.SetBody(j, NakoVarType.Int);
                            break;
                        }
                    }
                    this.GlobalVar.SetVar(i, setVar);
                }
            }
            codes.globalVar = this.GlobalVar;
            return(Codes);
        }
Beispiel #3
0
        private object _append(INakoFuncCallInfo info)
        {
            object ary = info.StackPop(); // 参照渡しなので変数への参照が得られる
            object s   = info.StackPop();

            if (!(ary is NakoVariable))
            {
                throw new NakoPluginRuntimeException("『追加』の引数がvariableではありません");
            }
            NakoVariable ary_link = (NakoVariable)ary;

            if (ary_link.Body is NakoVarArray)
            {
                NakoVarArray arr      = (NakoVarArray)ary_link.Body;
                NakoVariable new_item = new NakoVariable();
                new_item.SetBodyAutoType(s);
                arr.Add(new_item);
            }
            else if (ary_link.Body is string && (string)ary_link.Body == "")
            {
                NakoVarArray arr      = new NakoVarArray();
                NakoVariable new_item = new NakoVariable();
                new_item.SetBodyAutoType(s);
                arr.Add(new_item);
                ary_link.SetBody(arr, NakoVarType.Array);
            }
            // 結果をセット
            return(null);
        }
Beispiel #4
0
        /// <summary>
        /// システムに登録する
        /// </summary>
        /// <param name="dic"></param>
        /// <param name="globalVar"></param>
        public void RegisterToSystem(NakoTokenDic dic, NakoVariableManager globalVar)
        {
            // --- 関数
            // Tokenizer に登録
            for (int i = 0; i < FuncList.Count; i++)
            {
                NakoAPIFunc call = FuncList[i];
                if (!dic.ContainsKey(call.name))
                {
                    dic.Add(call.name, NakoTokenType.FUNCTION_NAME);
                }
                else
                {
                    dic[call.name] = NakoTokenType.FUNCTION_NAME;
                }
            }

            // NakoVariables に登録
            for (int i = 0; i < FuncList.Count; i++)
            {
                NakoVariable var = new NakoVariable();
                var.SetBody(i, NakoVarType.SystemFunc);
                NakoAPIFunc call = FuncList[i];
                globalVar.SetVar(call.name, var);
            }

            // --- 変数
            foreach (string name in VarList.Keys)
            {
                NakoVariable var = new NakoVariable();
                var.SetBodyAutoType(VarList[name]);
                globalVar.SetVar(name, var);
            }
        }
Beispiel #5
0
        private void st_elem()
        {
            object value = StackPop();
            object index = StackPop();
            object var   = StackPop();

            if (var is NakoVariable)
            {
                NakoVariable var2 = (NakoVariable)var;
                // null か空の文字列なら NakoArray として生成
                if (var2.Body == null || (var2.Type == NakoVarType.String && (string)var2.Body == ""))
                {
                    var2.SetBody(new NakoVarArray(), NakoVarType.Array);
                }
                if (!(var2.Body is NakoVarArray))
                {
                    string s = "";
                    if (var2.Body != null)
                    {
                        s = var2.Body.ToString();
                    }
                    var2.SetBody(new NakoVarArray(), NakoVarType.Array);
                    ((NakoVarArray)var2.Body).SetValuesFromString(s);
                }
                // NakoArray なら 要素にセット
                if (var2.Body is NakoVarArray)
                {
                    NakoVarArray var3 = (NakoVarArray)(var2.Body);
                    NakoVariable elem = var3.GetVarFromObj(index);
                    if (elem == null)
                    {
                        elem = new NakoVariable();
                        elem.SetBodyAutoType(value);
                        if (index is long)
                        {
                            elem.varNo = Convert.ToInt32(index);
                        }
                        var3.SetVarFromObj(index, elem);
                    }
                    else
                    {
                        elem.SetBodyAutoType(value);
                    }
                }
            }
        }
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="scope"></param>
        public NakoVariableManager(NakoVariableScope scope)
        {
            list  = new List <NakoVariable>();
            names = new Dictionary <string, int>();

            if (scope == NakoVariableScope.Global)
            {
                // 変数「それ」を登録
                NakoVariable sore = new NakoVariable();
                sore.SetBody(0, NakoVarType.Int);
                list.Add(sore);
                names[NakoReservedWord.SORE] = 0;
            }
        }
Beispiel #7
0
        //> _def_function : DEF_FUNCTION _def_function_args _scope
        //>               ;
        private bool _def_function()
        {
            if (!Accept(NakoTokenType.DEF_FUNCTION))
            {
                return(false);
            }
            NakoToken t = tok.CurrentToken;

            tok.MoveNext(); // '*'

            NakoFunc userFunc = new NakoFunc();

            userFunc.funcType = NakoFuncType.UserCall;

            // 引数 + 関数名の取得
            _def_function_args(userFunc);

            // ブロックの取得
            PushFrame();
            NakoNodeDefFunction funcNode = new NakoNodeDefFunction();

            funcNode.func = userFunc;
            parentNode    = funcNode.funcBody = new NakoNode();
            funcNode.RegistArgsToLocalVar();
            localVar = funcNode.localVar;
            if (!_scope())
            {
                throw new NakoParserException("関数定義中のエラー。", t);
            }
            PopFrame();
            // グローバル変数に登録
            NakoVariable v = new NakoVariable();

            v.SetBody(funcNode, NakoVarType.UserFunc);
            globalVar.CreateVar(userFunc.name, v);
            // 関数の宣言は、ノードのトップ直下に追加する
            if (!this.topNode.hasChildren())
            {
                this.topNode.AddChild(new NakoNode());
            }
            this.topNode.Children.Insert(0, funcNode);
            return(true);
        }
Beispiel #8
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);
        }