Exemplo n.º 1
0
            protected override BaseExpression Visit(Decrement dec)
            {
                var t = _types.TypeOf(dec.Name);

                if (t != Execution.Type.Number)
                {
                    return(base.Visit(dec));
                }
                else
                {
                    return(new Subtract(new Variable(dec.Name), new ConstantNumber((Number)1)));
                }
            }
Exemplo n.º 2
0
        private Type VariableRead(VariableName name)
        {
            var t = _types.TypeOf(name);

            if (t.HasValue)
            {
                return(t.Value);
            }

            if (name.IsExternal)
            {
                return(Type.String | Type.Number);
            }
            else
            {
                return(_types.TypeOf(name) ?? Type.Unassigned);
            }
        }
Exemplo n.º 3
0
        protected override BaseStatement Visit(CompoundAssignment compAss)
        {
            if (compAss.Op != Grammar.YololBinaryOp.Add && compAss.Op != Grammar.YololBinaryOp.Subtract)
            {
                return(base.Visit(compAss));
            }

            if (!compAss.Expression.IsConstant)
            {
                return(base.Visit(compAss));
            }

            // if right side cannot be evaluated then we can't compress it
            var right = compAss.Expression.TryStaticEvaluate();

            if (!right.HasValue)
            {
                return(base.Visit(compAss));
            }

            var type = _types.TypeOf(compAss.Left);

            switch (type)
            {
            default:
            case null:
            case Type.Error:
            case Type.Unassigned:
                return(base.Visit(compAss));

            case Type.Number: {
                if (right != 1)
                {
                    return(base.Visit(compAss));
                }

                if (compAss.Op == Grammar.YololBinaryOp.Add)
                {
                    return(new Assignment(compAss.Left, new Increment(compAss.Left)));
                }
                else
                {
                    return(new Assignment(compAss.Left, new Decrement(compAss.Left)));
                }
            }

            case Type.String: {
                if (right != " " || compAss.Op != Grammar.YololBinaryOp.Add)
                {
                    return(base.Visit(compAss));
                }

                return(new Assignment(compAss.Left, new Increment(compAss.Left)));
            }
            }
        }
Exemplo n.º 4
0
        private Type DiscoverType(BaseExpression expr)
        {
            if (expr is ConstantNumber)
            {
                return(Type.Number);
            }

            if (expr is ConstantString)
            {
                return(Type.String);
            }

            if (expr is Variable var)
            {
                return(_types.TypeOf(var.Name) ?? Type.Unassigned);
            }

            return(Type.Unassigned);
        }
Exemplo n.º 5
0
        protected override BaseStatement Visit(If @if)
        {
            // Make sure true branch contains:
            // - A statement
            // - Which is an assignment
            // - To a number typed variable
            // - Variable is not external
            if (@if.TrueBranch.Statements.Count > 1)
            {
                return(base.Visit(@if));
            }
            if (!(@if.TrueBranch.Statements.SingleOrDefault() is Assignment trueAss))
            {
                return(base.Visit(@if));
            }
            if (_types.TypeOf(trueAss.Left) != Execution.Type.Number)
            {
                return(base.Visit(@if));
            }
            if (trueAss.Left.IsExternal)
            {
                return(base.Visit(@if));
            }

            // Make sure the condition is something that returns `0` or `1`
            // If the `condition` is not in this form already then replace it with `condition != 0`
            var condition = @if.Condition.IsBoolean
                ? new Bracketed(@if.Condition)
                : new Bracketed(new NotEqualTo(new Bracketed(@if.Condition), new ConstantNumber(0)));

            if (@if.FalseBranch.Statements.Count == 0)
            {
                // Replace:
                //      `if cond then a = v1 end`
                // With
                //      `a += (v1 - a) * cond
                return(new CompoundAssignment(trueAss.Left, Grammar.YololBinaryOp.Add, new Multiply(new Bracketed(new Subtract(new Bracketed(trueAss.Right), new Variable(trueAss.Left))), condition)));
            }
            else
            {
                // todo: implement false branch
                throw new NotImplementedException();

                //if (@if.FalseBranch.Statements.Count != 1)
                //    return base.Visit(@if);

                //if (!(@if.FalseBranch.Statements.Single() is Assignment falseAss))
                //    return base.Visit(@if);

                //if (trueAss.Left.Name != falseAss.Left.Name)
                //    return base.Visit(@if);

                //var falseRight = falseAss.Right.StaticEvaluate();
                //if (falseRight.Type != Execution.Type.Number)
                //    return base.Visit(@if);

                //// Replace:
                ////      `if cond then a = v1 else a = v2 end`
                //// With
                ////      `a = v2 + (v1 - v2) * cond

                ////b = 3 if a == 0 then b = 5 else b = 10 end

                //var diff = new Subtract(new ConstantNumber(trueRight.Number), new ConstantNumber(falseRight.Number));
                //var diffEval = diff.StaticEvaluate();
                //var finalRight = diffEval.Number == 1 ? (BaseExpression)condition : new Bracketed(new Multiply(new ConstantNumber(diffEval.Number), condition));

                //return new Assignment(trueAss.Left, new Add(new ConstantNumber(falseRight.Number), finalRight));
            }
        }