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); }
/// <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); }
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); } }
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; } }
//> _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); }
//> _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); }