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 Type GetOperandType() { if (LeftTerm != null) { return(LeftTerm.GetOperandType()); } return(typeof(void)); }
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); }
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); }
///// <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); }
/// <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); }
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.Readonly) throw new CodeEE("変更できない変数をインクリメントすることはできません"); } if (o1.GetOperandType() == typeof(Int64)) { if (op == OperatorCode.Plus) return o1; if (unaryDic.ContainsKey(op)) method = unaryDic[op]; } 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 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 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); }