public override Argument CreateArgument(InstructionLine line, ExpressionMediator exm) { IOperandTerm[] args = popTerms(line); string errmes = line.Function.Method.CheckArgumentType(line.Function.Name, args); if (errmes != null) throw new CodeEE(errmes); IOperandTerm mTerm = new FunctionMethodTerm(line.Function.Method, args); return new MethodArgument(mTerm.Restructure(exm)); }
public static StrForm FromWordToken(StrFormWord wt) { StrForm ret = new StrForm(); ret.strs = wt.Strs; IOperandTerm[] termArray = new IOperandTerm[wt.SubWords.Length]; for (int i = 0; i < wt.SubWords.Length; i++) { SubWord SWT = wt.SubWords[i]; TripleSymbolSubWord tSymbol = SWT as TripleSymbolSubWord; if (tSymbol != null) { switch (tSymbol.Code) { case '*': termArray[i] = NameTarget; continue; case '+': termArray[i] = CallnameMaster; continue; case '=': termArray[i] = CallnamePlayer; continue; case '/': termArray[i] = NameAssi; continue; case '$': termArray[i] = CallnameTarget; continue; } throw new ExeEE("何かおかしい"); } WordCollection wc = null; IOperandTerm operand = null; YenAtSubWord yenat = SWT as YenAtSubWord; if (yenat != null) { wc = yenat.Words; if (wc != null) { operand = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.EoL); if (!wc.EOL) throw new CodeEE("三項演算子\\@の第一オペランドが異常です"); } else operand = new SingleTerm(0); IOperandTerm left = new StrFormTerm(StrForm.FromWordToken(yenat.Left)); IOperandTerm right = null; if (yenat.Right == null) right = new SingleTerm(""); else right = new StrFormTerm(StrForm.FromWordToken(yenat.Right)); termArray[i] = new FunctionMethodTerm(formatYenAt, new IOperandTerm[] { operand, left, right }); continue; } wc = SWT.Words; operand = ExpressionParser.ReduceExpressionTerm(wc, TermEndWith.Comma); if (operand == null) { if (SWT is CurlyBraceSubWord) throw new CodeEE("{}の中に式が存在しません"); else throw new CodeEE("%%の中に式が存在しません"); } IOperandTerm second = null; SingleTerm third = null; wc.ShiftNext(); if (!wc.EOL) { second = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.Comma); wc.ShiftNext(); if (!wc.EOL) { IdentifierWord id = wc.Current as IdentifierWord; if (id == null) throw new CodeEE("','の後にRIGHT又はLEFTがありません"); if (string.Equals(id.Code, "LEFT", Config.SCVariable))//標準RIGHT third = new SingleTerm(1); else if (!string.Equals(id.Code, "RIGHT", Config.SCVariable)) throw new CodeEE("','の後にRIGHT又はLEFT以外の単語があります"); wc.ShiftNext(); } if (!wc.EOL) throw new CodeEE("RIGHT又はLEFTの後に余分な文字があります"); } if (SWT is CurlyBraceSubWord) { if (operand.GetOperandType() != typeof(Int64)) throw new CodeEE("{}の中の式が数式ではありません"); termArray[i] = new FunctionMethodTerm(formatCurlyBrace, new IOperandTerm[] { operand, second, third }); continue; } if (operand.GetOperandType() != typeof(string)) throw new CodeEE("%%の中の式が文字列式ではありません"); termArray[i] = new FunctionMethodTerm(formatPercent, new IOperandTerm[] { operand, second, third }); } ret.terms = termArray; return ret; }
/// <summary> /// 1803beta005 予め引数の数を合わせて規定値を代入しておく /// 1806+v6.99 式中関数の引数に無効な#DIM変数を与えている場合に例外になるのを修正 /// 1808beta009 REF型に対応 /// </summary> public UserDefinedFunctionArgument ConvertArg(IOperandTerm[] srcArgs, out string errMes) { errMes = null; if (TopLabel.IsError) { errMes = TopLabel.ErrMes; return null; } FunctionLabelLine func = TopLabel; IOperandTerm[] convertedArg = new IOperandTerm[func.Arg.Length]; if(convertedArg.Length < srcArgs.Length) { errMes = "引数の数が関数\"@" + func.LabelName + "\"に設定された数を超えています"; return null; } IOperandTerm term = null; VariableTerm destArg = null; bool isString = false; for (int i = 0; i < func.Arg.Length; i++) { term = (i < srcArgs.Length) ? srcArgs[i] : null; destArg = func.Arg[i]; isString = destArg.IsString; if (destArg.Identifier.IsReference)//参照渡しの場合 { if (term == null) { errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数は参照渡しのため省略できません"; return null; } VariableTerm vTerm = term as VariableTerm; if (vTerm == null|| vTerm.Identifier.Readonly || vTerm.Identifier.IsCalc) { errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数は参照渡しのための配列変数でなければなりません"; return null; } //変数の型と次元数が一致すればいい。キャラ型については後に判断 VariableCode destCodeFlag = destArg.Identifier.Code & (VariableCode.__ARRAY_1D__ | VariableCode.__ARRAY_2D__ | VariableCode.__ARRAY_3D__ | VariableCode.__INTEGER__ | VariableCode.__STRING__); VariableCode srcCodeFlag = vTerm.Identifier.Code & (VariableCode.__ARRAY_1D__ | VariableCode.__ARRAY_2D__ | VariableCode.__ARRAY_3D__ | VariableCode.__INTEGER__ | VariableCode.__STRING__); if (destCodeFlag != srcCodeFlag) { errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数の型が一致しません"; return null; } } else if (term == null)//引数が省略されたとき { term = func.Def[i];//デフォルト値を代入 //1808beta001 デフォルト値がない場合はエラーにする //一応逃がす if (term == null && !Config.CompatiFuncArgOptional) { errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数は省略できません"; return null; } } else if (term.GetOperandType() != destArg.GetOperandType()) { if (term.GetOperandType() == typeof(string)) { errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数を文字列型から整数型に変換できません"; return null; } else { if (Config.CompatiFuncArgAutoConvert) { errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数を整数型から文字列型に変換できません"; return null; } if (tostrMethod == null) tostrMethod = FunctionMethodCreator.GetMethodList()["TOSTR"]; term = new FunctionMethodTerm(tostrMethod, new IOperandTerm[] { term }); } } convertedArg[i] = term; } return new UserDefinedFunctionArgument(convertedArg, func.Arg); }
public static void Initialize() { formatCurlyBrace = new FormatCurlyBrace(); formatPercent = new FormatPercent(); formatYenAt = new FormatYenAt(); VariableToken nameID = GlobalStatic.VariableData.GetSystemVariableToken("NAME"); VariableToken callnameID = GlobalStatic.VariableData.GetSystemVariableToken("CALLNAME"); IOperandTerm[] zeroArg = new IOperandTerm[] { new SingleTerm(0) }; VariableTerm target = new VariableTerm(GlobalStatic.VariableData.GetSystemVariableToken("TARGET"), zeroArg); VariableTerm master = new VariableTerm(GlobalStatic.VariableData.GetSystemVariableToken("MASTER"), zeroArg); VariableTerm player = new VariableTerm(GlobalStatic.VariableData.GetSystemVariableToken("PLAYER"), zeroArg); VariableTerm assi = new VariableTerm(GlobalStatic.VariableData.GetSystemVariableToken("ASSI"), zeroArg); VariableTerm nametarget = new VariableTerm(nameID, new IOperandTerm[] { target }); VariableTerm callnamemaster = new VariableTerm(callnameID, new IOperandTerm[] { master }); VariableTerm callnameplayer = new VariableTerm(callnameID, new IOperandTerm[] { player }); VariableTerm nameassi = new VariableTerm(nameID, new IOperandTerm[] { assi }); VariableTerm callnametarget = new VariableTerm(callnameID, new IOperandTerm[] { target }); NameTarget = new FunctionMethodTerm(formatPercent, new IOperandTerm[] { nametarget, null, null }); CallnameMaster = new FunctionMethodTerm(formatPercent, new IOperandTerm[] { callnamemaster, null, null }); CallnamePlayer = new FunctionMethodTerm(formatPercent, new IOperandTerm[] { callnameplayer, null, null }); NameAssi = new FunctionMethodTerm(formatPercent, new IOperandTerm[] { nameassi, null, null }); CallnameTarget = new FunctionMethodTerm(formatPercent, new IOperandTerm[] { callnametarget, null, null }); }