Beispiel #1
0
        private void arr_length()
        {
            object value = StackPop();

            // 配列要素を取り出す
            NakoVarArray arr = null;

            if (value is NakoVarArray)
            {
                arr = (NakoVarArray)value;
            }
            else if (value is NakoVariable)
            {
                NakoVariable v = (NakoVariable)value;
                if (v.Type == NakoVarType.Array)
                {
                    arr = (NakoVarArray)v.Body;
                }
            }
            if (arr != null)
            {
                StackPush(arr.Count);
            }
            else
            {
                StackPush(0L);
            }
            return;
        }
Beispiel #2
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 #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
        /// <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);
        }
 /// <summary>
 /// 変数をセット
 /// </summary>
 /// <param name="index"></param>
 /// <param name="v"></param>
 public void SetVar(int index, NakoVariable v)
 {
     // Create Var
     while (index >= list.Count)
     {
         list.Add(null);
     }
     list[index] = v;
 }
Beispiel #7
0
        private object _getFunctionFurigana(INakoFuncCallInfo info)
        {
            string       funcName = info.StackPopAsString();
            NakoVariable v        = new NakoVariable();
            NakoAPIFunc  f        = NakoAPIFuncBank.Instance.FuncList.Find((obj) => (obj.name == funcName));

            v.SetBodyAutoType(f.kana);
            return(v);
        }
        /// <summary>
        /// 変数をセット
        /// </summary>
        /// <param name="name"></param>
        /// <param name="v"></param>
        public void SetVar(string name, NakoVariable v)
        {
            int i = GetIndex(name);

            if (i < 0)
            {
                i = CreateVar(name, v);
            }
            list[i] = v;
        }
Beispiel #9
0
        private void ld_local_ref(int no)
        {
            NakoVariable v = localVar.GetVar(no);

            if (v == null)
            {
                v = new NakoVariable();
                localVar.SetVar(no, v);
            }
            StackPush(v);
        }
        /// <summary>
        /// 変数に値を設定
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public void SetValue(int index, object value)
        {
            NakoVariable v = GetVar(index);

            if (v == null)
            {
                v = new NakoVariable();
                SetVar(index, v);
            }
            v.SetBodyAutoType(value);
        }
        /// <summary>
        /// 変数を作成
        /// </summary>
        /// <param name="name"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public int CreateVar(string name, NakoVariable v)
        {
            if (v == null)
            {
                v = new NakoVariable();
            }
            list.Add(v);
            int i = list.Count - 1;

            names[name] = i;
            return(i);
        }
Beispiel #12
0
        private object _getFunctionNames(INakoFuncCallInfo info)
        {
            NakoVarArray a = info.CreateArray();

            foreach (NakoAPIFunc f in NakoAPIFuncBank.Instance.FuncList)
            {
                NakoVariable v = new NakoVariable();
                v.SetBodyAutoType(f.name);
                a.Add(v);
            }
            return(a);
        }
Beispiel #13
0
        private object _getPlugins(INakoFuncCallInfo info)
        {
            NakoVarArray a = info.CreateArray();

            foreach (KeyValuePair <string, INakoPlugin> pair in NakoAPIFuncBank.Instance.PluginList)
            {
                NakoVariable v = new NakoVariable();
                v.SetBodyAutoType(pair.Key);
                a.Add(v);
            }
            return(a);
        }
Beispiel #14
0
        private void ld_global_ref(int no)
        {
            NakoVariable v = globalVar.GetVar(no);

            if (v == null)
            {
                v       = new NakoVariable();
                v.varNo = no;
                globalVar.SetVar(no, v);
            }
            StackPush(v);
        }
Beispiel #15
0
        /// <summary>
        /// 配列要素をスタックに乗せるが、その時、配列オブジェクトへのリンクを乗せる
        /// </summary>
        private void ld_elem_ref()
        {
            object       idx = StackPop();
            object       var = StackPop();
            NakoVarArray var_ary;

            // var が不正なら null を乗せて帰る
            if (!(var is NakoVariable))
            {
                StackPush(null);
                return;
            }
            if (var is NakoVarArray)
            {
                NakoVarArray a    = (NakoVarArray)var;
                NakoVariable elem = a.GetVarFromObj(idx);
                StackPush(elem);
                return;
            }
            if (((NakoVariable)var).Body is NakoVarArray)
            {
                var_ary = (NakoVarArray)((NakoVariable)var).Body;
                NakoVariable elem = var_ary.GetVarFromObj(idx);
                if (elem == null)
                {
                    elem = new NakoVariable();
                    var_ary.SetVarFromObj(idx, elem);
                }
                StackPush(elem);
            }

            if (((NakoVariable)var).Body == null)
            {
                ((NakoVariable)var).SetBody(new NakoVarArray(), NakoVarType.Array);
            }

            if (((NakoVariable)var).Body is NakoVarArray)
            {
                var_ary = (NakoVarArray)((NakoVariable)var).Body;
                NakoVariable elem = var_ary.GetVarFromObj(idx);
                if (elem == null)
                {
                    elem = new NakoVariable();
                    var_ary.SetVarFromObj(idx, elem);
                }
                StackPush(elem);
            }
            else
            {
                StackPush(null);
            }
        }
        /// <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;
            }
        }
        /// <summary>
        /// 変数の値を取得
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public object GetValue(int index)
        {
            NakoVariable v = GetVar(index);

            if (v == null)
            {
                v = new NakoVariable();
                while (index >= list.Count)
                {
                    list.Add(new NakoVariable());
                }
                SetVar(index, v);
            }
            return(v.Body);
        }
Beispiel #18
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);
                    }
                }
            }
        }
Beispiel #19
0
        protected static object NakoVarArrayToArray(NakoVarArray array)
        {
            bool is_dictionary = false;

            if (array.Count > 0)
            {
                NakoVariable check = array.GetVar(0);
                if (check.key != null)
                {
                    is_dictionary = true;
                }
                if (is_dictionary)
                {
                    var result = new Dictionary <string, object>();
                    foreach (NakoVariable variable in array)
                    {
                        if (variable.Body is NakoVarArray)
                        {
                            result.Add(variable.key, NakoVarArrayToArray((NakoVarArray)variable.Body));
                        }
                        else
                        {
                            result.Add(variable.key, variable.Body);
                        }
                    }
                    return(result);
                }
                else
                {
                    var result = new List <object>();
                    foreach (NakoVariable variable in array)
                    {
                        if (variable.Body is NakoVarArray)
                        {
                            result.Add(NakoVarArrayToArray((NakoVarArray)variable.Body));
                        }
                        else
                        {
                            result.Add(variable.Body);
                        }
                    }
                    return(result);
                }
            }
            return(null);
        }
Beispiel #20
0
        private object _pop(INakoFuncCallInfo info)
        {
            object ary = 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;
                return(arr.Pop());
            }
            // 結果をセット
            return(null);
        }
Beispiel #21
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 #22
0
        private object _insertArray(INakoFuncCallInfo info)
        {
            object obj_base   = info.StackPop(); // 参照渡しなので変数への参照が得られる
            int    i          = (int)info.StackPopAsInt();
            object obj_insert = info.StackPop();

            if (!(obj_base is NakoVariable))
            {
                throw new NakoPluginRuntimeException("『配列一括挿入』の元配列がvariableではありません");
            }
            NakoVarArray array_insert = new NakoVarArray();

            if (obj_insert is NakoVariable)
            {
                NakoVariable var_insert = (NakoVariable)obj_insert;
                if (var_insert.Body is NakoVarArray)
                {
                    array_insert = (NakoVarArray)var_insert.Body;
                }
            }
            else if (obj_insert is string)
            {
                array_insert.SetValuesFromString((string)obj_insert);
            }
            else
            {
                throw new NakoPluginRuntimeException("『配列一括挿入』の挿入配列がvariableではありません");
            }
            NakoVariable var_base = (NakoVariable)obj_base;

            if (var_base.Body is NakoVarArray)
            {
                NakoVarArray array_base = (NakoVarArray)var_base.Body;
                while (array_insert.Count > 0)
                {
                    NakoVariable variable = array_insert.Pop();
                    array_base.Insert(i, variable);
                }
            }
            return(null);
        }
Beispiel #23
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);
        }
Beispiel #24
0
 /// <summary>
 /// 変数をセット
 /// </summary>
 /// <param name="varname"></param>
 /// <param name="value"></param>
 public void SetVariable(string varname, NakoVariable value)
 {
     _runner.globalVar.SetVar(varname, (NakoVariable)value);
 }
Beispiel #25
0
        private void dec_local(NakoILCode code)
        {
            NakoVariable v = localVar.GetVar((int)code.value);

            v.AsInt--;
        }
        /// <summary>
        /// 名前のない変数を作成
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public int CreateVarNameless(NakoVariable v)
        {
            string name = ";nameless_" + list.Count; // あり得ない変数名を作る

            return(CreateVar(name, v));
        }
Beispiel #27
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);
        }