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; }
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); }
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); }
/// <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); } }
/// <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; }
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; }
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); }
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); }
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); }
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); }
/// <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); }
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); } } } }
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); }
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); }
//> _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); }
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); }
//> _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); }
/// <summary> /// 変数をセット /// </summary> /// <param name="varname"></param> /// <param name="value"></param> public void SetVariable(string varname, NakoVariable value) { _runner.globalVar.SetVar(varname, (NakoVariable)value); }
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)); }
//> _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); }