public static void StackCheckBinary(ValueStack check) { check.Pop(); check.Pop(); check.Push(new UnionValue(true)); }
public void Eval(Context ctx, ValueStack stack) { switch (VType) { case EValueTypes.CONST: stack.Push(_Val); break; case EValueTypes.OP_UNARY: Operator.Eval(stack, _operator); break; case EValueTypes.OP_BINARY: Operator.Eval(stack, _operator); break; case EValueTypes.GET_VAR_OR_CALL: if (ctx != null) { UnionValue val = ctx.Dispatch(_Val.AsString); stack.Push(val); } else { stack.Push(UnionValue.Error); } break; } }
public static void Eval(ValueStack stack, EOperatorType op) { if (op == EOperatorType.Unary_Negation) { Negate(stack, op); return; } if (stack.Size < 2 || op == EOperatorType.INVALID) { stack.Push(UnionValue.Error); return; } var rhs = stack.Pop(); var lhs = stack.Pop(); stack.Push(EvaluateImpl(lhs, rhs, op)); }
public static void Negate(ValueStack stack, EOperatorType op) { if (stack.Size < 1) { stack.Push(UnionValue.Error); return; } var rhs = stack.Pop(); if (!rhs.IsError && (rhs.Type == EValType.BOOL)) { stack.Push(new UnionValue(!rhs.AsBool)); } else { stack.Push(UnionValue.Error); return; } }
public void DBGStackCheck(Context ctx, ValueStack stack) { switch (VType) { case EValueTypes.CONST: stack.Push(_Val); break; case EValueTypes.OP_UNARY: var vl = stack.Pop(); if (vl.Type == EValType.BOOL) { stack.Push(!vl.AsBool); } else { stack.Push(UnionValue.Error); } break; case EValueTypes.OP_BINARY: Operator.StackCheckBinary(stack); break; // TODO improve validation case EValueTypes.GET_VAR_OR_CALL: if (null != ctx) { var val2 = ctx.Vars.Contains(_Val.AsString); stack.Push(val2); } else { stack.Push(true); } break; } }
public static ParseResult Parse( string script) { ParseResult result = default; result.DebugStr = ""; if (null == script) { result.DebugStr = "Null input"; return(result); } var currentLine = script; currentLine = currentLine.Replace("<=", "@%less_q"); currentLine = currentLine.Replace(">=", "@%gr_q"); currentLine = currentLine.Replace("!=", "@%ne_q"); var delims = new List <string> { "||", "&&", "==", "@%ne_q", // != "@%less_q", // <= "@%gr_q", // >= "<", ">", "!", "(", ")" }; currentLine = currentLine.Replace("!!", " "); RegexOptions options = RegexOptions.None; Regex regex = new Regex("[ ]{2,}", options); currentLine = regex.Replace(currentLine, " "); foreach (var dl in delims) { currentLine = currentLine.Replace(dl, "~" + dl + "~"); } var rawTokens = currentLine.Split('~', ' '). Where(x => x != " " && x.Length > 0).ToArray(); // fixing >= and > type of collisions for (int i = 0; i < rawTokens.Length; ++i) { if (rawTokens[i] == "@%ne_q") { rawTokens[i] = "!="; } else if (rawTokens[i] == "@%less_q") { rawTokens[i] = "<="; } else if (rawTokens[i] == "@%gr_q") { rawTokens[i] = ">="; } } Token[] tokens = ToTokens(rawTokens); var list = tokens.ToList(); result.Tokens = PrepareTokensRPL(list); if (null == result.Tokens) { result.DebugStr = "Could not parse token subtree, syntax error"; return(result); } result.Expressions = result.Tokens.Select(x => ToExpression(x)).ToArray(); Expression[] inst = result.Expressions; ValueStack stack = new ValueStack(); for (int i = 0; i < inst.Length; ++i) { if (inst[i].IsError) { result.DebugStr = "Expression marked as an error, could be unrecognized operator."; return(result); } inst[i].DBGStackCheck(null, stack); if (stack.Size > 0 && stack.Peek.IsError) { result.DebugStr = "Stack validation error"; return(result); } } if (stack.Size > 1 || stack.Corrupted) { result.DebugStr = "Stack validation error, error or excess values left"; return(result); } result.Success = true; return(result); }