public VariableStrArgTerm(VariableCode code, IOperandTerm strTerm, int index) : base(typeof(Int64)) { this.strTerm = strTerm; parentCode = code; this.index = index; }
/// <summary> /// エラーならnullを返す。 /// </summary> public static UserDefinedMethodTerm Create(IOperandTerm[] srcArgs, CalledFunction call, out string errMes) { UserDefinedFunctionArgument arg = call.ConvertArg(srcArgs, out errMes); if (arg == null) return null; return new UserDefinedMethodTerm(arg, call.TopLabel.MethodType, call); }
public IOperandTerm ReduceAll() { if (stack.Count == 0) { return(null); } if (state != 1) { throw new CodeEE("式が異常です"); } //単項演算子の待ちが未解決の時はここで解決 if (waitAfter) { reduceUnary(); } waitAfter = false; hasBefore = false; hasAfter = false; while (stack.Count > 1) { reduceLastThree(); } IOperandTerm retTerm = (IOperandTerm)stack.Pop(); return(retTerm); }
public virtual SingleTerm GetReturnValue(ExpressionMediator exm, IOperandTerm[] arguments) { if (ReturnType == typeof(Int64)) return new SingleTerm(GetIntValue(exm, arguments)); else return new SingleTerm(GetStrValue(exm, arguments)); }
public static IOperandTerm ReduceBinaryTerm(OperatorCode op, IOperandTerm left, IOperandTerm right) { OperatorMethod method = null; if ((left.GetOperandType() == typeof(Int64)) && (right.GetOperandType() == typeof(Int64))) { if (binaryIntIntDic.ContainsKey(op)) { method = binaryIntIntDic[op]; } } else if ((left.GetOperandType() == typeof(string)) && (right.GetOperandType() == typeof(string))) { if (binaryStrStrDic.ContainsKey(op)) { method = binaryStrStrDic[op]; } } else if (((left.GetOperandType() == typeof(Int64)) && (right.GetOperandType() == typeof(string))) || ((left.GetOperandType() == typeof(string)) && (right.GetOperandType() == typeof(Int64)))) { if (op == OperatorCode.Mult) { method = binaryMultIntStr; } } if (method != null) { return(new FunctionMethodTerm(method, new IOperandTerm[] { left, right })); } string errMes = ""; if (left.GetOperandType() == typeof(Int64)) { errMes += "数値型と"; } else if (left.GetOperandType() == typeof(string)) { errMes += "文字列型と"; } else { errMes += "不定型と"; } if (right.GetOperandType() == typeof(Int64)) { errMes += "数値型の"; } else if (right.GetOperandType() == typeof(string)) { errMes += "文字列型の"; } else { errMes += "不定型の"; } errMes += "演算に二項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません"; throw new CodeEE(errMes); }
public override string GetStrValue(ExpressionMediator exm, IOperandTerm[] arguments) { string str = arguments[0].GetStrValue(exm); Int64 pos = arguments[1].GetIntValue(exm); if (pos < 0 || pos >= str.Length) return ""; return str[(int)pos].ToString(); }
public void Reduce(ExpressionMediator exm) { LeftTerm = LeftTerm.Restructure(exm); if (CaseType == CaseExpressionType.To) { RightTerm = RightTerm.Restructure(exm); } }
public override IOperandTerm Restructure(ExpressionMediator exm) { if (dic == null) dic = exm.VEvaluator.Constant.GetKeywordDictionary(out errPos, parentCode, index); strTerm = strTerm.Restructure(exm); if (!(strTerm is SingleTerm)) return this; return new SingleTerm(this.GetIntValue(exm)); }
private void reduceTernary(IOperandTerm left, IOperandTerm right, OperatorCode op) { OperatorCode newOp = (OperatorCode)stack.Pop(); IOperandTerm newLeft = (IOperandTerm)stack.Pop(); IOperandTerm newTerm = OperatorMethodManager.ReduceTernaryTerm(newOp, newLeft, left, right); stack.Push(newTerm); }
private void reduceUnary() { //if (stack.Count < 2) // throw new ExeEE("不正な時期の呼び出し"); IOperandTerm operand = (IOperandTerm)stack.Pop(); OperatorCode op = (OperatorCode)stack.Pop(); IOperandTerm newTerm = OperatorMethodManager.ReduceUnaryTerm(op, operand); stack.Push(newTerm); }
public static IOperandTerm ReduceVariableArgument(WordCollection wc, VariableCode varCode) { IOperandTerm ret = reduceTerm(wc, false, TermEndWith.EoL, varCode); if (ret == null) { throw new CodeEE("変数の:の後に引数がありません"); } return(ret); }
public bool GetBool(Int64 Is, ExpressionMediator exm) { if (CaseType == CaseExpressionType.To) { return(LeftTerm.GetIntValue(exm) <= Is && Is <= RightTerm.GetIntValue(exm)); } if (CaseType == CaseExpressionType.Is) { IOperandTerm term = OperatorMethodManager.ReduceBinaryTerm(Operator, new SingleTerm(Is), LeftTerm); return(term.GetIntValue(exm) != 0); } return(LeftTerm.GetIntValue(exm) == Is); }
//引数の数・型が一致するかどうかのテスト //正しくない場合はエラーメッセージを返す。 //引数の数が不定である場合や引数の省略を許す場合にはoverrideすること。 public virtual string CheckArgumentType(string name, IOperandTerm[] arguments) { if (arguments.Length != argumentTypeArray.Length) return name + "関数の引数の数が正しくありません"; for (int i = 0; i < argumentTypeArray.Length; i++) { if (arguments[i] == null) return name + "関数の" + (i + 1).ToString() + "番目の引数は省略できません"; if (argumentTypeArray[i] != arguments[i].GetOperandType()) return name + "関数の" +(i+1).ToString()+ "番目の引数の型が正しくありません"; } return null; }
public bool GetBool(string Is, ExpressionMediator exm) { if (CaseType == CaseExpressionType.To) { return(string.Compare(LeftTerm.GetStrValue(exm), Is, Config.SCExpression) <= 0 && string.Compare(Is, RightTerm.GetStrValue(exm), Config.SCExpression) <= 0); } if (CaseType == CaseExpressionType.Is) { IOperandTerm term = OperatorMethodManager.ReduceBinaryTerm(Operator, new SingleTerm(Is), LeftTerm); return(term.GetIntValue(exm) != 0); } return(LeftTerm.GetStrValue(exm) == Is); }
///// <summary> ///// 単純文字列、書式付文字列、文字列式のうち、文字列式を取り扱う。 ///// 終端記号が正しいかどうかは呼び出し元で調べること ///// </summary> ///// <param name="st"></param> ///// <returns></returns> //public static IOperandTerm ReduceStringTerm(WordCollection wc, TermEndWith endWith) //{ // IOperandTerm term = reduceTerm(wc, false, endWith, VariableCode.__NULL__); // if (term.GetOperandType() != typeof(string)) // throw new CodeEE("式の結果が文字列ではありません"); // return term; //} public static IOperandTerm ReduceIntegerTerm(WordCollection wc, TermEndWith endwith) { IOperandTerm term = reduceTerm(wc, false, endwith, VariableCode.__NULL__); if (term == null) { throw new CodeEE("構文を式として解釈できません"); } if (term.GetOperandType() != typeof(Int64)) { throw new CodeEE("式の結果が数値ではありません"); } return(term); }
protected bool checkArgumentType(InstructionLine line, ExpressionMediator exm, IOperandTerm[] arguments) { if (arguments == null) { warn("引数がありません", line, 2, false); return false; } if ( arguments.Length < minArg || ((arguments.Length < argumentTypeArray.Length) && (minArg < 0)) ) { warn("引数が足りません", line, 2, false); return false; } int length = arguments.Length; if ((arguments.Length > argumentTypeArray.Length)&&(!argAny)) { warn("引数が多すぎます", line, 1, false); length = argumentTypeArray.Length; } for (int i = 0; i < length; i++) { Type allowType; if ((!argAny) && (argumentTypeArray[i] == null)) continue; else if (argAny && i >= argumentTypeArray.Length) allowType = argumentTypeArray[argumentTypeArray.Length - 1]; else allowType = argumentTypeArray[i]; if (arguments[i] == null) { if (allowType == null) continue; warn("第" + (i + 1).ToString() + "引数を認識できません", line, 2, false); return false; } if ((allowType != typeof(void)) && (allowType != arguments[i].GetOperandType())) { warn("第" + (i + 1).ToString() + "引数の型が正しくありません", line, 2, false); return false; } } length = arguments.Length; for (int i = 0; i < length; i++) { if (arguments[i] == null) continue; arguments[i] = arguments[i].Restructure(exm); } return true; }
public static IOperandTerm ReduceUnaryTerm(OperatorCode op, IOperandTerm o1) { OperatorMethod method = null; if (op == OperatorCode.Increment || op == OperatorCode.Decrement) { VariableTerm var = o1 as VariableTerm; if (var == null) { throw new CodeEE("変数以外をインクリメントすることはできません"); } if (var.Identifier.IsConst) { throw new CodeEE("変更できない変数をインクリメントすることはできません"); } } if (o1.GetOperandType() == typeof(Int64)) { if (op == OperatorCode.Plus) { return(o1); } OperatorMethod operator_method = null; if (unaryDic.TryGetValue(op, out operator_method)) { method = operator_method; } } if (method != null) { return(new FunctionMethodTerm(method, new IOperandTerm[] { o1 })); } string errMes = ""; if (o1.GetOperandType() == typeof(Int64)) { errMes += "数値型"; } else if (o1.GetOperandType() == typeof(string)) { errMes += "文字列型"; } else { errMes += "不定型"; } errMes += "に単項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません"; throw new CodeEE(errMes); }
public override IOperandTerm Restructure(ExpressionMediator exm) { sfValue.Restructure(exm); if (sfValue.IsConst) { return(new SingleTerm(sfValue.GetString(exm))); } IOperandTerm term = sfValue.GetIOperandTerm(); if (term != null) { return(term); } return(this); }
public void Add(IOperandTerm term) { stack.Push(term); if (state == 1) { throw new CodeEE("式が異常です"); } if (state == 2) { waitAfter = true; } if (state == 3) { reduceUnary(); hasBefore = true; } state = 1; }
public static IOperandTerm ReduceTernaryTerm(OperatorCode op, IOperandTerm o1, IOperandTerm o2, IOperandTerm o3) { OperatorMethod method = null; if ((o1.GetOperandType() == typeof(Int64)) && (o2.GetOperandType() == typeof(Int64)) && (o3.GetOperandType() == typeof(Int64))) { method = ternaryIntIntInt; } else if ((o1.GetOperandType() == typeof(Int64)) && (o2.GetOperandType() == typeof(string)) && (o3.GetOperandType() == typeof(string))) { method = ternaryIntStrStr; } if (method != null) { return(new FunctionMethodTerm(method, new IOperandTerm[] { o1, o2, o3 })); } throw new CodeEE("三項演算子の使用法が不正です"); }
public static IOperandTerm ReduceUnaryAfterTerm(OperatorCode op, IOperandTerm o1) { OperatorMethod method = null; if (op == OperatorCode.Increment || op == OperatorCode.Decrement) { var var = o1 as VariableTerm; if (var == null) { throw new CodeEE("変数以外をインクリメントすることはできません"); } if (var.Identifier.IsConst) { throw new CodeEE("変更できない変数をインクリメントすることはできません"); } } if (o1.GetOperandType() == typeof(long)) { if (unaryAfterDic.ContainsKey(op)) { method = unaryAfterDic[op]; } } if (method != null) { return(new FunctionMethodTerm(method, new[] { o1 })); } var errMes = ""; if (o1.GetOperandType() == typeof(long)) { errMes += "数値型"; } else if (o1.GetOperandType() == typeof(string)) { errMes += "文字列型"; } else { errMes += "不定型"; } errMes += "に後置単項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません"; throw new CodeEE(errMes); }
private void reduceLastThree() { //if (stack.Count < 2) // throw new ExeEE("不正な時期の呼び出し"); IOperandTerm right = (IOperandTerm)stack.Pop();//後から入れたほうが右側 OperatorCode op = (OperatorCode)stack.Pop(); IOperandTerm left = (IOperandTerm)stack.Pop(); if (OperatorManager.IsTernary(op)) { if (stack.Count > 1) { reduceTernary(left, right, op); return; } throw new CodeEE("式の数が不足しています"); } IOperandTerm newTerm = OperatorMethodManager.ReduceBinaryTerm(op, left, right); stack.Push(newTerm); }
public override Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { Int64 integer = arguments[0].GetIntValue(exm); Int64 chara = -1L; bool CheckSp = false; if ((arguments.Length > 1) && (arguments[1] != null) && (arguments[1].GetIntValue(exm) != 0)) CheckSp = true; if (CheckSp) { chara = exm.VEvaluator.GetChara(integer, false); if (chara != -1) return chara; else return exm.VEvaluator.GetChara(integer, true); } else return exm.VEvaluator.GetChara(integer, false); }
public override string GetStrValue(ExpressionMediator exm, IOperandTerm[] arguments) { return Regex.Escape(arguments[0].GetStrValue(exm)); }
public override string CheckArgumentType(string name, IOperandTerm[] arguments) { if (arguments.Length < 1) return name + "関数には少なくとも1つの引数が必要です"; if (arguments.Length > 2) return name + "関数の引数が多すぎます"; if (arguments[0] == null) return name + "関数の1番目の引数は省略できません"; if (!arguments[0].IsInteger) return name + "関数の1番目の引数が数値ではありません"; if (arguments.Length == 1) return null; if ((arguments[1] != null) && (arguments[1].GetOperandType() != typeof(Int64))) return name + "関数の2番目の変数が数値ではありません"; return null; }
/// <summary> /// カンマで区切られた引数を一括して取得。 /// return時にはendWithの次の文字がCurrentになっているはず。終端の適切さの検証はExpressionParserがが行う。 /// 呼び出し元はCodeEEを適切に処理すること /// </summary> /// <returns></returns> public static IOperandTerm[] ReduceArguments(WordCollection wc, ArgsEndWith endWith, bool isDefine) { if (wc == null) { throw new ExeEE("空のストリームを渡された"); } List <IOperandTerm> terms = new List <IOperandTerm>(); TermEndWith termEndWith = TermEndWith.EoL; switch (endWith) { case ArgsEndWith.EoL: termEndWith = TermEndWith.Comma; break; //case ArgsEndWith.RightBracket: // termEndWith = TermEndWith.RightBracket_Comma; // break; case ArgsEndWith.RightParenthesis: termEndWith = TermEndWith.RightParenthesis_Comma; break; } TermEndWith termEndWith_Assignment = termEndWith | TermEndWith.Assignment; while (true) { Word word = wc.Current; switch (word.Type) { case '\0': if (endWith == ArgsEndWith.RightBracket) { throw new CodeEE("'['に対応する']'が見つかりません"); } if (endWith == ArgsEndWith.RightParenthesis) { throw new CodeEE("'('に対応する')'が見つかりません"); } goto end; case ')': if (endWith == ArgsEndWith.RightParenthesis) { wc.ShiftNext(); goto end; } throw new CodeEE("構文解析中に予期しない')'を発見しました"); case ']': if (endWith == ArgsEndWith.RightBracket) { wc.ShiftNext(); goto end; } throw new CodeEE("構文解析中に予期しない']'を発見しました"); } if (!isDefine) { terms.Add(ReduceExpressionTerm(wc, termEndWith)); } else { terms.Add(ReduceExpressionTerm(wc, termEndWith_Assignment)); if (terms[terms.Count - 1] == null) { throw new CodeEE("関数定義の引数は省略できません"); } if (wc.Current is OperatorWord) { //=がある wc.ShiftNext(); IOperandTerm term = reduceTerm(wc, false, termEndWith, VariableCode.__NULL__); if (term == null) { throw new CodeEE("'='の後に式がありません"); } if (term.GetOperandType() != terms[terms.Count - 1].GetOperandType()) { throw new CodeEE("'='の前後で型が一致しません"); } terms.Add(term); } else { if (terms[terms.Count - 1].GetOperandType() == typeof(Int64)) { terms.Add(new NullTerm(0)); } else { terms.Add(new NullTerm("")); } } } if (wc.Current.Type == ',') { wc.ShiftNext(); } } end: IOperandTerm[] ret = new IOperandTerm[terms.Count]; terms.CopyTo(ret); return(ret); }
/// <summary> /// 識別子一つを解決 /// </summary> /// <param name="wc"></param> /// <param name="idStr">識別子文字列</param> /// <param name="varCode">変数の引数の場合はその変数のCode。連想配列的につかう</param> /// <returns></returns> private static IOperandTerm reduceIdentifier(WordCollection wc, string idStr, VariableCode varCode) { wc.ShiftNext(); SymbolWord symbol = wc.Current as SymbolWord; if (symbol != null && symbol.Type == '.') { //名前空間 throw new NotImplCodeEE(); } else if (symbol != null && (symbol.Type == '(' || symbol.Type == '[')) { //関数 wc.ShiftNext(); if (symbol.Type == '[') //1810 多分永久に実装されない { throw new CodeEE("[]を使った機能はまだ実装されていません"); } //引数を処理 IOperandTerm[] args = ReduceArguments(wc, ArgsEndWith.RightParenthesis, false); IOperandTerm mToken = GlobalStatic.IdentifierDictionary.GetFunctionMethod(GlobalStatic.LabelDictionary, idStr, args, false); if (mToken == null) { if (!Program.AnalysisMode) { GlobalStatic.IdentifierDictionary.ThrowException(idStr, true); } else { if (GlobalStatic.tempDic.ContainsKey(idStr)) { GlobalStatic.tempDic[idStr]++; } else { GlobalStatic.tempDic.Add(idStr, 1); } return(new NullTerm(0)); } } return(mToken); } else { //変数 or キーワード VariableToken id = ReduceVariableIdentifier(wc, idStr); if (id != null) //idStrが変数名の場合、 { if (varCode != VariableCode.__NULL__) //変数の引数が引数を持つことはない { return(VariableParser.ReduceVariable(id, null, null, null)); } else { return(VariableParser.ReduceVariable(id, wc)); } } //idStrが変数名でない場合、 IOperandTerm refToken = GlobalStatic.IdentifierDictionary.GetFunctionMethod(GlobalStatic.LabelDictionary, idStr, null, false); if (refToken != null) //関数参照と名前が一致したらそれを返す。実際に使うとエラー { return(refToken); } if (varCode != VariableCode.__NULL__ && GlobalStatic.ConstantData.isDefined(varCode, idStr)) //連想配列的な可能性アリ { return(new SingleTerm(idStr)); } GlobalStatic.IdentifierDictionary.ThrowException(idStr, false); } throw new ExeEE("エラー投げ損ねた"); //ここまででthrowかreturnのどちらかをするはず。 }
public override string CheckArgumentType(string name, IOperandTerm[] arguments) { //通常3つ、1つ省略可能で2~3の引数が必要。 if (arguments.Length < 2) return name + "関数には少なくとも2つの引数が必要です"; if (arguments.Length > 4) return name + "関数の引数が多すぎます"; if (arguments[0] == null) return name + "関数の1番目の引数は省略できません"; if (!(arguments[0] is VariableTerm)) return name + "関数の1番目の引数の型が正しくありません"; if (!(((VariableTerm)arguments[0]).Identifier.IsCharacterData)) return name + "関数の1番目の引数の変数がキャラクタ変数ではありません"; if (arguments[1] == null) return name + "関数の2番目の引数は省略できません"; if (arguments[1].GetOperandType() != arguments[0].GetOperandType()) return name + "関数の2番目の引数の型が正しくありません"; //3番目は省略可能 if ((arguments.Length >= 3) && (arguments[2] != null) && (arguments[2].GetOperandType() != typeof(Int64))) return name + "関数の3番目の引数の型が正しくありません"; //4番目は省略可能 if ((arguments.Length >= 4) && (arguments[3] != null) && (arguments[3].GetOperandType() != typeof(Int64))) return name + "関数の4番目の引数の型が正しくありません"; return null; }
public TermWord(IOperandTerm term) { this.term = term; }
public override string CheckArgumentType(string name, IOperandTerm[] arguments) { if (arguments.Length < 2) return name + "関数には少なくとも2つの引数が必要です"; if (arguments.Length > 5) return name + "関数の引数が多すぎます"; if (arguments[0] == null) return name + "関数の1番目の引数は省略できません"; VariableTerm varToken = arguments[0] as VariableTerm; if (varToken == null) return name + "関数の1番目の引数が変数ではありません"; if (varToken.Identifier.IsArray2D || varToken.Identifier.IsArray3D) return name + "関数は二重配列・三重配列には対応していません"; if (!varToken.Identifier.IsArray1D) return name + "関数の1番目の引数が配列変数ではありません"; Type baseType = arguments[0].GetOperandType(); if (arguments[1] == null) return name + "関数の2番目の引数は省略できません"; if (arguments[1].GetOperandType() != baseType) return name + "関数の2番目の引数の型が正しくありません"; if ((arguments.Length >= 3) && (arguments[2] != null) && (arguments[2].GetOperandType() != typeof(Int64))) return name + "関数の3番目の引数の型が正しくありません"; if ((arguments.Length >= 4) && (arguments[3] != null) && (arguments[3].GetOperandType() != typeof(Int64))) return name + "関数の4番目の引数の型が正しくありません"; if ((arguments.Length >= 5) && (arguments[4] != null) && (arguments[4].GetOperandType() != typeof(Int64))) return name + "関数の5番目の引数の型が正しくありません"; return null; }
//実際の計算。 public virtual Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { throw new ExeEE("戻り値の型が違う or 未実装"); }
public override Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { bool isExact = false; VariableTerm varTerm = (VariableTerm)arguments[0]; Int64 start = (arguments.Length > 2 && arguments[2] != null) ? arguments[2].GetIntValue(exm) : 0; Int64 end = (arguments.Length > 3 && arguments[3] != null) ? arguments[3].GetIntValue(exm) : varTerm.GetLength(); if (arguments.Length > 4 && arguments[4] != null) isExact = (arguments[4].GetIntValue(exm) != 0); FixedVariableTerm p = varTerm.GetFixedVariableTerm(exm); p.IsArrayRangeValid(start, end, "FINDELEMENT", 3L, 4L); if (arguments[0].GetOperandType() == typeof(Int64)) { Int64 targetValue = arguments[1].GetIntValue(exm); return exm.VEvaluator.FindElement(p, targetValue, start, end, isExact, isLast); } else { Regex targetString = null; try { targetString = new Regex(arguments[1].GetStrValue(exm)); } catch (ArgumentException) { throw new CodeEE("第2引数が正規表現として不正です"); } return exm.VEvaluator.FindElement(p, targetString, start, end, isExact, isLast); } }
public override bool UniqueRestructure(ExpressionMediator exm, IOperandTerm[] arguments) { arguments[0].Restructure(exm); for (int i = 1; i < arguments.Length; i++) { if (arguments[i] == null) continue; arguments[i] = arguments[i].Restructure(exm); } return false; }
public override Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { Color color = (defaultColor) ? Config.BackColor : GlobalStatic.Console.bgColor; return (color.ToArgb() & 0xFFFFFF); }
public override Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { Int64 n = arguments[0].GetIntValue(exm); Int64 m = arguments[1].GetIntValue(exm); if ((m < 0) || (m > 63)) throw new CodeEE("GETBIT関数の第2引数に範囲外の値(" + m.ToString() + ")が渡されました"); int mi = (int)m; return ((n >> mi) & 1); }
public static VariableTerm ReduceVariable(VariableToken id, IOperandTerm p1, IOperandTerm p2, IOperandTerm p3) { IOperandTerm[] terms = null; IOperandTerm op1 = p1; IOperandTerm op2 = p2; IOperandTerm op3 = p3; //引数の推測 if (id.IsCharacterData) { if (id.IsArray2D) { if ((op1 == null) || (op2 == null) || (op3 == null)) throw new CodeEE("キャラクタ二次元配列変数" + id.Name + "の引数は省略できません"); terms = new IOperandTerm[3]; terms[0] = op1; terms[1] = op2; terms[2] = op3; } else if (id.IsArray1D) { if (op3 != null) throw new CodeEE("キャラクタ変数" + id.Name + "の引数が多すぎます"); if (op2 == null) { if (op1 == null) op1 = ZeroTerm; op2 = op1; op1 = TARGET; } terms = new IOperandTerm[2]; terms[0] = op1; terms[1] = op2; } else { if (op2 != null) throw new CodeEE("一次元配列変数" + id.Name + "の引数が多すぎます"); if (op1 == null) op1 = TARGET; terms = new IOperandTerm[1]; terms[0] = op1; } } else if (id.IsArray3D) { if ((op1 == null) || (op2 == null) || (op3 == null)) throw new CodeEE("三次元配列変数" + id.Name + "の引数は省略できません"); terms = new IOperandTerm[3]; terms[0] = op1; terms[1] = op2; terms[2] = op3; } else if (id.IsArray2D) { if ((op1 == null) || (op2 == null)) throw new CodeEE("二次元配列変数" + id.Name + "の引数は省略できません"); if (op3 != null) throw new CodeEE("二次元配列" + id.Name + "の引数が多すぎます"); terms = new IOperandTerm[2]; terms[0] = op1; terms[1] = op2; } else if (id.IsArray1D) { if (op2 != null) throw new CodeEE("一次元配列変数" + id.Name + "の引数が多すぎます"); if (op1 == null) op1 = ZeroTerm; terms = new IOperandTerm[1]; terms[0] = op1; } else if (op1 != null) { throw new CodeEE("配列でない変数" + id.Name + "を引数付きで呼び出しています"); } else terms = new IOperandTerm[0]; for (int i = 0; i < terms.Length; i++) if (terms[i].IsString) terms[i] = new VariableStrArgTerm(id.Code, terms[i], i); return new VariableTerm(id, terms); }
public void Reduce(ExpressionMediator exm) { LeftTerm = LeftTerm.Restructure(exm); if (CaseType == CaseExpressionType.To) RightTerm = RightTerm.Restructure(exm); }
public virtual string GetStrValue(ExpressionMediator exm, IOperandTerm[] arguments) { throw new ExeEE("戻り値の型が違う or 未実装"); }
/// <summary> /// 数式または文字列式。CALLの引数などを扱う。nullを返すことがある。 /// return時にはendWithの文字がCurrentになっているはず。終端の適切さの検証は呼び出し元が行う。 /// </summary> /// <param name="st"></param> /// <returns></returns> public static IOperandTerm ReduceExpressionTerm(WordCollection wc, TermEndWith endWith) { IOperandTerm term = reduceTerm(wc, false, endWith, VariableCode.__NULL__); return(term); }
/// <summary> /// 戻り値は全体をRestructureできるかどうか /// </summary> /// <param name="exm"></param> /// <param name="arguments"></param> /// <returns></returns> public virtual bool UniqueRestructure(ExpressionMediator exm, IOperandTerm[] arguments) { throw new ExeEE("未実装?"); }
public override Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { Int64 ret = arguments[0].GetIntValue(exm); double dret = Math.Exp((double)ret); if (double.IsNaN(dret)) throw new CodeEE("計算値が非数値です"); else if (double.IsInfinity(dret)) throw new CodeEE("計算値が無限大です"); else if ((dret >= Int64.MaxValue) || (dret <= Int64.MinValue)) throw new CodeEE("計算結果(" + dret.ToString() + ")が64ビット符号付き整数の範囲外です"); return ((Int64)dret); }
public VariableTerm(VariableToken token, IOperandTerm[] args) : base(token.VariableType) { this.Identifier = token; arguments = args; transporter = new Int64[arguments.Length]; allArgIsConst = false; for (int i = 0; i < arguments.Length; i++) { if (!(arguments[i] is SingleTerm)) return; transporter[i] = ((SingleTerm)arguments[i]).Int; } allArgIsConst = true; }
/// <summary> /// 解析器の本体 /// </summary> /// <param name="wc"></param> /// <param name="allowKeywordTo">TOキーワードが見つかっても良いか</param> /// <param name="endWith">終端記号</param> /// <returns></returns> private static IOperandTerm reduceTerm(WordCollection wc, bool allowKeywordTo, TermEndWith endWith, VariableCode varCode) { TermStack stack = new TermStack(); //int termCount = 0; int ternaryCount = 0; OperatorCode formerOp = OperatorCode.NULL; bool varArg = varCode != VariableCode.__NULL__; do { Word token = wc.Current; switch (token.Type) { case '\0': goto end; case '"': //LiteralStringWT stack.Add(((LiteralStringWord)token).Str); break; case '0': //LiteralIntegerWT stack.Add(((LiteralIntegerWord)token).Int); break; case 'F': //FormattedStringWT stack.Add(ToStrFormTerm((StrFormWord)token)); break; case 'A': //IdentifierWT { string idStr = (((IdentifierWord)token).Code); if (idStr.Equals("TO", Config.SCVariable)) { if (allowKeywordTo) { goto end; } else { throw new CodeEE("TOキーワードはここでは使用できません"); } } else if (idStr.Equals("IS", Config.SCVariable)) { throw new CodeEE("ISキーワードはここでは使用できません"); } stack.Add(reduceIdentifier(wc, idStr, varCode)); continue; } case '=': //OperatorWT { if (varArg) { throw new CodeEE("変数の引数の読み取り中に予期しない演算子を発見しました"); } OperatorCode op = ((OperatorWord)token).Code; if (op == OperatorCode.Assignment) { if ((endWith & TermEndWith.Assignment) == TermEndWith.Assignment) { goto end; } throw new CodeEE("式中で代入演算子'='が使われています(等価比較には'=='を使用してください)"); } if (formerOp == OperatorCode.Equal || formerOp == OperatorCode.Greater || formerOp == OperatorCode.Less || formerOp == OperatorCode.GreaterEqual || formerOp == OperatorCode.LessEqual || formerOp == OperatorCode.NotEqual) { if (op == OperatorCode.Equal || op == OperatorCode.Greater || op == OperatorCode.Less || op == OperatorCode.GreaterEqual || op == OperatorCode.LessEqual || op == OperatorCode.NotEqual) { ParserMediator.Warn("(構文上の注意)比較演算子が連続しています。", GlobalStatic.Process.GetScaningLine(), 0, false, false); } } stack.Add(op); formerOp = op; if (op == OperatorCode.Ternary_a) { ternaryCount++; } else if (op == OperatorCode.Ternary_b) { if (ternaryCount > 0) { ternaryCount--; } else { throw new CodeEE("対応する'?'のない'#'です"); } } break; } case '(': wc.ShiftNext(); IOperandTerm inTerm = reduceTerm(wc, false, TermEndWith.RightParenthesis, VariableCode.__NULL__); if (inTerm == null) { throw new CodeEE("かっこ\"(\"~\")\"の中に式が含まれていません"); } stack.Add(inTerm); if (wc.Current.Type != ')') { throw new CodeEE("対応する')'のない'('です"); } //termCount++; wc.ShiftNext(); continue; case ')': if ((endWith & TermEndWith.RightParenthesis) == TermEndWith.RightParenthesis) { goto end; } throw new CodeEE("構文解釈中に予期しない記号'" + token.Type + "'を発見しました"); case ']': if ((endWith & TermEndWith.RightBracket) == TermEndWith.RightBracket) { goto end; } throw new CodeEE("構文解釈中に予期しない記号'" + token.Type + "'を発見しました"); case ',': if ((endWith & TermEndWith.Comma) == TermEndWith.Comma) { goto end; } throw new CodeEE("構文解釈中に予期しない記号'" + token.Type + "'を発見しました"); case 'M': throw new ExeEE("マクロ解決失敗"); default: throw new CodeEE("構文解釈中に予期しない記号'" + token.Type + "'を発見しました"); } //termCount++; wc.ShiftNext(); } while (!varArg); end: if (ternaryCount > 0) { throw new CodeEE("'?'と'#'の数が正しく対応していません"); } return(stack.ReduceAll()); }
public void SetValue(IOperandTerm value, ExpressionMediator exm) { if (Identifier.VariableType == typeof(Int64)) SetValue(value.GetIntValue(exm), exm); else SetValue(value.GetStrValue(exm), exm); }
public override Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { Int64 no = arguments[0].GetIntValue(exm); bool isSp =(arguments.Length == 2 && arguments[1] != null) ? (arguments[1].GetIntValue(exm) != 0) : false; return (exm.VEvaluator.ExistCsv(no, isSp)); }
public override string GetStrValue(ExpressionMediator exm, IOperandTerm[] arguments) { string str = arguments[0].GetStrValue(exm); return exm.Console.getStBar(str); }
public override Int64 GetIntValue(ExpressionMediator exm, IOperandTerm[] arguments) { VariableTerm vTerm = (VariableTerm)arguments[0]; VariableToken varID = vTerm.Identifier; Int64 elem = 0; if (vTerm.Identifier.IsArray1D) elem = vTerm.GetElementInt(1, exm); else if (vTerm.Identifier.IsArray2D) { elem = vTerm.GetElementInt(1, exm) << 32; elem += vTerm.GetElementInt(2, exm); } Int64 startindex = 0; Int64 lastindex = exm.VEvaluator.CHARANUM; if (arguments.Length >= 3 && arguments[2] != null) startindex = arguments[2].GetIntValue(exm); if (arguments.Length >= 4 && arguments[3] != null) lastindex = arguments[3].GetIntValue(exm); Int64 ret = -1; if (startindex < 0 || startindex >= exm.VEvaluator.CHARANUM) throw new CodeEE((isLast ? "" : "") + "関数の第3引数(" + startindex.ToString() + ")はキャラクタ位置の範囲外です"); if (lastindex < 0 || lastindex > exm.VEvaluator.CHARANUM) throw new CodeEE((isLast ? "" : "") + "関数の第4引数(" + lastindex.ToString() + ")はキャラクタ位置の範囲外です"); if (varID.IsString) { string word = arguments[1].GetStrValue(exm); ret = exm.VEvaluator.FindChara(varID, elem, word, startindex, lastindex, isLast); } else { Int64 word = arguments[1].GetIntValue(exm); ret = exm.VEvaluator.FindChara(varID, elem, word, startindex, lastindex, isLast); } return (ret); }
public static void Initialize() { ZeroTerm = new SingleTerm(0); IOperandTerm[] zeroArgs = new IOperandTerm[] { ZeroTerm }; TARGET = new VariableTerm(GlobalStatic.VariableData.GetSystemVariableToken("TARGET"), zeroArgs); }
SingleTerm GetSingle(IOperandTerm oprand) { return((SingleTerm)oprand); }
public override string CheckArgumentType(string name, IOperandTerm[] arguments) { //通常2つ、1つ省略可能で1~2の引数が必要。 if (arguments.Length < 1) return name + "関数には少なくとも1つの引数が必要です"; if (arguments.Length > 2) return name + "関数の引数が多すぎます"; if (arguments[0] == null) return name + "関数の1番目の引数は省略できません"; if (arguments[0].GetOperandType() != typeof(Int64)) return name + "関数の1番目の引数の型が正しくありません"; //2は省略可能 if ((arguments.Length == 2) && (arguments[1] != null) && (arguments[1].GetOperandType() != typeof(Int64))) return name + "関数の2番目の引数の型が正しくありません"; return null; }