private void btnEvaluate_Click(object sender, System.EventArgs e) { opCode lCode = null; try { TextBox2.AppendText((tbExpression.Text + "\r\n")); //Timer t = new Timer(); lCode = ev.Parse(tbExpression.Text); //TextBox2.AppendText(("Parsed in " // + (t.ms() + (" ms" + "\r\n")))); } catch (Exception ex) { TextBox2.AppendText((ex.Message + "\r\n")); return; } try { //Timer t = new Timer(); object res = lCode.value; //TextBox2.AppendText(("Run in " // + (t.ms() + (" ms" + "\r\n")))); if ((res == null)) { TextBox2.AppendText(("Result=" + "\r\n")); } else { TextBox2.AppendText(("Result=" + (Evaluator.ConvertToString(res) + (" (" + (res.GetType().Name + (")" + "\r\n")))))); } } catch (Exception ex) { TextBox2.AppendText((ex.Message + "\r\n")); } TextBox2.AppendText("\r\n"); }
public opCodeUnary(eTokenType tt, opCode param1) { mParam1 = param1; EvalType v1Type = mParam1.EvalType; switch (tt) { case eTokenType.operator_not: if (v1Type == EvalType.Boolean) { mValueDelegate = BOOLEAN_NOT; mEvalType = EvalType.Boolean; } break; case eTokenType.operator_minus: if (v1Type == EvalType.Number) { mValueDelegate = NUM_CHGSIGN; mEvalType = EvalType.Number; } break; } }
protected void SwapParams(ref opCode Param1, ref opCode Param2) { opCode swp = Param1; Param1 = Param2; Param2 = swp; }
protected internal void Convert(tokenizer tokenizer, ref opCode param1, EvalType EvalType) { if (param1.EvalType != EvalType) { if (param1.CanReturn(EvalType)) { param1 = new opCodeConvert(tokenizer, param1, EvalType); } else { tokenizer.RaiseError("Cannot convert " + param1.Name + " into " + EvalType); } } }
private void ParseIdentifier(ref opCode ValueLeft) { // first check functions List<object> parameters; // parameters... //Dim types As New List<object> string func = mTokenizer.value.ToString(); mTokenizer.NextToken(); bool isBrackets; parameters = ParseParameters(ref isBrackets); if ((parameters != null)) { List<object> EmptyParameters = new List<object>(); bool ParamsNotUsed; if (mEvaluator.Syntax == eParserSyntax.Vb) { // in vb we don't know if it is array or not as we have only parenthesis // so we try with parameters first if (!EmitCallFunction(ValueLeft, func, parameters, eCallType.all, ErrorIfNotFound = false)) { // and if not found we try as array or default member EmitCallFunction(ValueLeft, func, EmptyParameters, eCallType.all, ErrorIfNotFound = true); ParamsNotUsed = true; } } else { if (isBrackets) { if (!EmitCallFunction(ValueLeft, func, parameters, eCallType.property, ErrorIfNotFound = false)) { EmitCallFunction(ValueLeft, func, EmptyParameters, eCallType.all, ErrorIfNotFound = true); ParamsNotUsed = true; } } else { if (!EmitCallFunction(ValueLeft, func, parameters, eCallType.field | eCallType.method, ErrorIfNotFound = false)) { EmitCallFunction(ValueLeft, func, EmptyParameters, eCallType.all, ErrorIfNotFound = true); ParamsNotUsed = true; } } } // we found a function without parameters // so our parameters must be default property or an array Type t = ValueLeft.SystemType; if (ParamsNotUsed) { if (t.IsArray) { if (parameters.Count == t.GetArrayRank()) { ValueLeft = new opCodeGetArrayEntry(ValueLeft, parameters); } else { mTokenizer.RaiseError("This array has " + t.GetArrayRank() + " dimensions"); } } else { MemberInfo mi; mi = GetMemberInfo(t, null, parameters); if ((mi != null)) { ValueLeft = opCodeCallMethod.GetNew(mTokenizer, ValueLeft, mi, parameters); } else { mTokenizer.RaiseError("Parameters not supported here"); } } } } else { EmitCallFunction(ValueLeft, func, parameters, eCallType.all, ErrorIfNotFound = true); } }
private void ParseDot(ref opCode ValueLeft) { do { switch (mTokenizer.type) { case eTokenType.dot: mTokenizer.NextToken(); break; case eTokenType.open_parenthesis: break; // fine this is either an array or a default property default: return; } ParseIdentifier(ref ValueLeft); } while (true); }
private bool EmitCallFunction(ref opCode valueLeft, string funcName, List<object> parameters, eCallType CallType, bool ErrorIfNotFound) { opCode newOpcode; if (valueLeft == null) { foreach (object functions in mEvaluator.mEnvironmentFunctionsList) { while ((functions != null)) { newOpcode = GetLocalFunction(functions, functions.GetType(), funcName, parameters, CallType); if ((newOpcode != null)) break; // TODO: might not be correct. Was : Exit For if (functions is iEvalFunctions) { functions = ((iEvalFunctions)functions).InheritedFunctions; } else { break; // TODO: might not be correct. Was : Exit Do } } } } else { newOpcode = GetLocalFunction(valueLeft, valueLeft.SystemType, funcName, parameters, CallType); } if ((newOpcode != null)) { valueLeft = newOpcode; return true; } else { if (ErrorIfNotFound) mTokenizer.RaiseError("Variable or method " + funcName + " was not found"); return false; } }
'1' => HandleOperation(opCode, add), '2' => HandleOperation(opCode, multiply),
private void btnEvaluate2_Click(object sender, System.EventArgs e) { opCode lCodeR = null; opCode lCodeG = null; opCode lCodeB = null; try { ev.AddEnvironmentFunctions(this); ev.AddEnvironmentFunctions(new EvalFunctions()); lCodeR = ev.Parse(tbExpressionRed.Text); lCodeG = ev.Parse(tbExpressionGreen.Text); lCodeB = ev.Parse(tbExpressionBlue.Text); } catch (Exception ex) { Label1.Text = ex.Message; return; } try { Timer t = new Timer(); Bitmap bm = (Bitmap)PictureBox1.Image; if ((bm == null)) { bm = new Bitmap(256, 256); PictureBox1.Image = bm; } double mult = (2 * (Math.PI / 256)); double r = 0; double g = 0; double b = 0; for (int Xi = 0; (Xi <= 255); Xi++) { X = ((Xi - 128) * mult); for (int Yi = 0; (Yi <= 255); Yi++) { Y = ((Yi - 128) * mult); try { r = (double)lCodeR.value; g = (double)lCodeG.value; b = (double)lCodeB.value; if (((r < 0) || double.IsNaN(r))) { r = 0; } else if ((r > 1)) { r = 1; } if (((g < 0) || double.IsNaN(g))) { g = 0; } else if ((g > 1)) { g = 1; } if (((b < 0) || double.IsNaN(b))) { b = 0; } else if ((b > 1)) { b = 1; } } catch { // ignore (same as previous pixel) } bm.SetPixel(Xi, Yi, Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255))); } if ((Xi & 7) == 7) { PictureBox1.Refresh(); } } Label1.Text = ("196,608 evaluations run in " + (t.ms() + " ms")); } catch (Exception ex) { Label1.Text = ex.Message; } }
'7' => HandleOperation(opCode, lessThan), '8' => HandleOperation(opCode, equals),
'8' => HandleOperation(opCode, equals),
'6' => HandleJumpIfCondition(opCode, jumpIfZero), '7' => HandleOperation(opCode, lessThan),
'5' => HandleJumpIfCondition(opCode, jumpIfNotZero), '6' => HandleJumpIfCondition(opCode, jumpIfZero),
'2' => HandleOperation(opCode, multiply), '3' => HandleInput(),
public opCodeBinary(tokenizer tokenizer, opCode param1, eTokenType tt, opCode param2) { mParam1 = param1; mParam2 = param2; EvalType v1Type = mParam1.EvalType; EvalType v2Type = mParam2.EvalType; switch (tt) { case eTokenType.operator_plus: if (v1Type == EvalType.Number & v2Type == EvalType.Number) { mValueDelegate = NUM_PLUS_NUM; mEvalType = EvalType.Number; } else if (v1Type == EvalType.Number & v2Type == EvalType.Date) { SwapParams(ref mParam1, mParam2); mValueDelegate = DATE_PLUS_NUM; mEvalType = EvalType.Date; } else if (v1Type == EvalType.Date & v2Type == EvalType.Number) { mValueDelegate = DATE_PLUS_NUM; mEvalType = EvalType.Date; } else if (mParam1.CanReturn(EvalType.String) & mParam2.CanReturn(EvalType.String)) { Convert(tokenizer, param1, ref EvalType.String); mValueDelegate = STR_CONCAT_STR; mEvalType = EvalType.String; } break; case eTokenType.operator_minus: if (v1Type == EvalType.Number & v2Type == EvalType.Number) { mValueDelegate = NUM_MINUS_NUM; mEvalType = EvalType.Number; } else if (v1Type == EvalType.Date & v2Type == EvalType.Number) { mValueDelegate = DATE_MINUS_NUM; mEvalType = EvalType.Date; } else if (v1Type == EvalType.Date & v2Type == EvalType.Date) { mValueDelegate = DATE_MINUS_DATE; mEvalType = EvalType.Number; } break; case eTokenType.operator_mul: if (v1Type == EvalType.Number & v2Type == EvalType.Number) { mValueDelegate = NUM_MUL_NUM; mEvalType = EvalType.Number; } break; case eTokenType.operator_div: if (v1Type == EvalType.Number & v2Type == EvalType.Number) { mValueDelegate = NUM_DIV_NUM; mEvalType = EvalType.Number; } break; case eTokenType.operator_percent: if (v1Type == EvalType.Number & v2Type == EvalType.Number) { mValueDelegate = NUM_PERCENT_NUM; mEvalType = EvalType.Number; } break; case eTokenType.operator_and: case eTokenType.operator_or: Convert(tokenizer, mParam1, ref EvalType.Boolean); Convert(tokenizer, mParam2, ref EvalType.Boolean); switch (tt) { case eTokenType.operator_or: mValueDelegate = BOOL_OR_BOOL; mEvalType = EvalType.Boolean; break; case eTokenType.operator_and: mValueDelegate = BOOL_AND_BOOL; mEvalType = EvalType.Boolean; break; } break; } if (mValueDelegate == null) { tokenizer.RaiseError("Cannot apply the operator " + tt.ToString().Replace("operator_", "") + " on " + v1Type.ToString() + " and " + v2Type.ToString()); } }
private opCode ParseExpr(opCode Acc, ePriority priority) { opCode ValueLeft = null; opCode valueRight = null; do { switch (mTokenizer.type) { case eTokenType.operator_minus: // unary minus operator mTokenizer.NextToken(); ValueLeft = ParseExpr(null, ePriority.unaryminus); ValueLeft = new opCodeUnary(eTokenType.operator_minus, ValueLeft); break; // TODO: might not be correct. Was : Exit Do case eTokenType.operator_plus: // unary minus operator mTokenizer.NextToken(); break; case eTokenType.operator_not: mTokenizer.NextToken(); ValueLeft = ParseExpr(null, ePriority.not); ValueLeft = new opCodeUnary(eTokenType.operator_not, ValueLeft); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_identifier: ParseIdentifier(ref ValueLeft); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_true: ValueLeft = new opCodeImmediate(EvalType.Boolean, true); mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_false: ValueLeft = new opCodeImmediate(EvalType.Boolean, false); mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_string: ValueLeft = new opCodeImmediate(EvalType.String, mTokenizer.value.ToString()); mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_number: try { ValueLeft = new opCodeImmediate(EvalType.Number, double.Parse(mTokenizer.value.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture)); } catch (Exception) { mTokenizer.RaiseError(string.Format("Invalid number {0}", mTokenizer.value.ToString())); } mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.value_date: try { ValueLeft = new opCodeImmediate(EvalType.Date, mTokenizer.value.ToString()); } catch (Exception) { mTokenizer.RaiseError(string.Format("Invalid date {0}, it should be #DD/MM/YYYY hh:mm:ss#", mTokenizer.value.ToString())); } mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do case eTokenType.open_parenthesis: mTokenizer.NextToken(); ValueLeft = ParseExpr(null, ePriority.none); if (mTokenizer.type == eTokenType.close_parenthesis) { // good we eat the end parenthesis and continue ... mTokenizer.NextToken(); break; // TODO: might not be correct. Was : Exit Do } else { mTokenizer.RaiseUnexpectedToken("End parenthesis not found"); } break; case eTokenType.operator_if: // first check functions List<object> parameters = new List<object>(); // parameters... mTokenizer.NextToken(); bool brackets = false; parameters = ParseParameters(ref brackets); break; // TODO: might not be correct. Was : Exit Do default: break; // TODO: might not be correct. Was : Exit Do } } while (true); if (ValueLeft == null) { mTokenizer.RaiseUnexpectedToken("No Expression found"); } ParseDot(ref ValueLeft); do { eTokenType tt; tt = mTokenizer.type; switch (tt) { case eTokenType.end_of_formula: // end of line return ValueLeft; case eTokenType.value_number: mTokenizer.RaiseUnexpectedToken("Unexpected number without previous opterator"); break; case eTokenType.operator_plus: if (priority < ePriority.plusminus) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.plusminus); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_minus: if (priority < ePriority.plusminus) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.plusminus); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_concat: if (priority < ePriority.concat) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.concat); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_mul: case eTokenType.operator_div: if (priority < ePriority.muldiv) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.muldiv); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_percent: if (priority < ePriority.percent) { mTokenizer.NextToken(); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, Acc); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_or: if (priority < ePriority.or) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.or); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_and: if (priority < ePriority.and) { mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.and); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; case eTokenType.operator_ne: case eTokenType.operator_gt: case eTokenType.operator_ge: case eTokenType.operator_eq: case eTokenType.operator_le: case eTokenType.operator_lt: if (priority < ePriority.equality) { tt = mTokenizer.type; mTokenizer.NextToken(); valueRight = ParseExpr(ValueLeft, ePriority.equality); ValueLeft = new opCodeBinary(mTokenizer, ValueLeft, tt, valueRight); } else { break; // TODO: might not be correct. Was : Exit Do } break; default: break; // TODO: might not be correct. Was : Exit Do break; } } while (true); return ValueLeft; }
public opCodeGetArrayEntry(opCode array, IList @params) { iEvalTypedValue[] newParams = new iEvalTypedValue[@params.Count]; int[] newValues = new int[@params.Count]; @params.CopyTo(newParams, 0); mArray = array; mParams = newParams; mValues = newValues; mResultSystemType = array.SystemType.GetElementType; mResultEvalType = Globals.GetEvalType(mResultSystemType); }
public static Cut Write(this in Cut pc, OpCode opCode, object operand) => pc.Write(pc.Emit(opCode, operand));