/// <summary> /// 引数をローカル変数として定義する /// </summary> public void RegistArgsToLocalVar(NakoVariableManager globalVar) { for (int i = 0; i < func.args.Count; i++) { NakoFuncArg arg = func.args[i]; NakoPlugin.NakoVariable var = new NakoPlugin.NakoVariable(); if (arg.type != null) { //引数が関数定義の場合 if (arg.type == NakoFuncType.UserCall.ToString()) { NakoFunc userFunc = new NakoFunc(); userFunc.funcType = NakoFuncType.UserCall; for (int j = 0; j < (int)arg.defaultValue; j++) { userFunc.args.Add(new NakoFuncArg()); } NakoNodeDefFunction funcNode = new NakoNodeDefFunction(); funcNode.func = userFunc; funcNode.funcBody = new NakoNode(); var.SetBody(funcNode, NakoPlugin.NakoVarType.UserFunc); } else { //引数がインスタンスの場合 var.SetBody(null, NakoPlugin.NakoVarType.Instance); var.InstanceType = arg.type; } } localVar.CreateVar(arg.name, var); } }
/// <summary> /// 助詞つきでポップ /// </summary> /// <param name="arg"></param> /// <returns></returns> public NakoNode Pop(NakoFuncArg arg) { // 助詞リストをチェックする if (arg != null) { foreach (string josi in arg.josiList) { for (int i = 0; i < this.Count; i++) { int bi = Count - i - 1; NakoNode cn = this[bi]; if (cn.josi == josi) { this.RemoveAt(bi); return(cn); } } } } // 普通にPOP if (this.Count > 0) { NakoNode n = this[this.Count - 1]; this.RemoveAt(this.Count - 1); return(n); } else { return(null); } }
private void _def_function(NakoNodeDefFunction node) { // 必要なラベルを定義 NakoILCode end_of_def_func = createLABEL("END_OF_DEF_FUNC_" + node.func.name); NakoILCode ret_of_def_func = createLABEL("RETURN_OF_DEF_FUNC_" + node.func.name); NakoILCode begin_def_func = createLABEL("FUNC_" + node.func.name); node.defLabel = begin_def_func; // 関数の定義は実行しないので、end_of_def_func へ飛ぶ result.Add(createJUMP(end_of_def_func)); // 関数の始まりラベルを定義 result.Add(begin_def_func); // 引数をPOPする処理 NakoFunc func = node.func; for (int i = 0; i < func.ArgCount; i++) { NakoFuncArg arg = func.args[i]; NakoILCode c = new NakoILCode(NakoILType.ST_LOCAL, i); result.Add(c); } // 本文を定義 _func_check_return(node.funcBody, ret_of_def_func); Write_r(node.funcBody); // 戻り値(変数「それ」)をスタックに載せる result.Add(ret_of_def_func); result.Add(new NakoILCode(NakoILType.LD_GLOBAL, (int)0)); result.Add(new NakoILCode(NakoILType.RET, func.updateSore)); // 関数の終わりを定義 result.Add(end_of_def_func); }
/// <summary> /// 引数をローカル変数として定義する /// </summary> public void RegistArgsToLocalVar() { for (int i = 0; i < func.args.Count; i++) { NakoFuncArg arg = func.args[i]; localVar.CreateVar(arg.name); } }
/// <summary> /// 引数をローカル変数として定義する /// </summary> public void RegistArgsToLocalVar(NakoVariableManager globalVar) { for (int i = 0; i < func.args.Count; i++) { NakoFuncArg arg = func.args[i]; NakoPlugin.NakoVariable var = new NakoPlugin.NakoVariable(); if (arg.type != null) { var.SetBody(null, NakoPlugin.NakoVarType.Instance); var.InstanceType = arg.type; } localVar.CreateVar(arg.name, var); } }
//> _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); }