예제 #1
0
        public static void StackCheckBinary(ValueStack check)
        {
            check.Pop();
            check.Pop();

            check.Push(new UnionValue(true));
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        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));
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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;
            }
        }
예제 #6
0
        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);
        }