Пример #1
0
        public void Parse(ref string[] program)
        {
            string token = ParseUtils.GetToken(ref program);
            WooScript._Log.AddMsg("Found function, target \"" + token + "\"");
            WooScript._Log.Indent();
            if (WooScript.IsFloatVariable(token))
            {
                _ReturnType = VarType.varFloat;
                _Var = token;
            }
            else if (WooScript.IsVecVariable(token))
            {
                _ReturnType = VarType.varVector;
                _Var = token;
            }
            else
            {
                throw new ParseException("Expected \"" + token + "\" to be a float or vector variable");
            }

            string assignOp = ParseUtils.GetToken(ref program);
            _AssignOp = WooScript.GetAssignOp(assignOp);

            _Expression = ExpressionBuilder.Parse(ref program);

            if (_ReturnType == VarType.varVector
                && (_Expression.GetExpressionType() != VarType.varVector))
                throw new ParseException("Target token is \"" + token + "\" which is a vector, expression isn't...");

            if (_ReturnType == VarType.varFloat
                && (_Expression.GetExpressionType() != VarType.varFloat))
                throw new ParseException("Target token is \"" + token + "\" which is a float, expression isn't...");
        }
Пример #2
0
        private static string OpName(AssignOp op)
        {
            switch (op)
            {
            case AssignOp.ASSIGN:
                return("=");

            case AssignOp.ADD:
                return("+=");

            case AssignOp.SUB:
                return("-=");

            case AssignOp.MUL:
                return("*=");

            case AssignOp.DIV:
                return("/=");

            case AssignOp.MOD:
                return("%=");

            default:
                throw new ArgumentOutOfRangeException(nameof(op), op, null);
            }
        }
Пример #3
0
    public void visit(AssignOp assignOp)
    {
        string name = assignOp.left.name;

        assignOp.right.accept(this);
        stack.pushGlobal(name, assignOp.right.output);
    }
Пример #4
0
 public LValueAssign(AssignOp op, Expression lvalue, Expression value)
 {
     Operator = op;
     LValue   = lvalue;
     Value    = value;
     Line     = lvalue.Line;
     Column   = lvalue.Column;
 }
Пример #5
0
 public void visit(AssignOp assignOp)
 {
     if (!scope.contains(assignOp.left.name))
     {
         declareSymbol(assignOp.left, assignOp.type);
     }
     assignOp.right.accept(this);
 }
Пример #6
0
        public static LinkedListNode <Lexeme> TryParse(LinkedListNode <Lexeme> lexemes, out AssignStmt resultNode, bool needSC = true)
        {
            resultNode = null;
            var nextLexeme = Var.TryParse(lexemes, out Var lhs);

            if (lhs == null)
            {
                return(lexemes);
            }
            AssignOp op = AssignOp.ASSIGN;

            if (nextLexeme.Value.Type == LT.OP_ADD || nextLexeme.Value.Type == LT.OP_SUB ||
                nextLexeme.Value.Type == LT.OP_MUL || nextLexeme.Value.Type == LT.OP_DIV ||
                nextLexeme.Value.Type == LT.OP_MOD)
            {
                op         = TypeToOp(nextLexeme.Value.Type);
                nextLexeme = nextLexeme.Next;
            }

            if (nextLexeme.Value.Type != LT.OP_ASSIGN)
            {
                return(lexemes);
            }
            Lexeme token = nextLexeme.Value;

            nextLexeme = Expr.TryParse(nextLexeme.Next, out Expr rhs);
            if (rhs == null)
            {
                throw new Exception($"Unrecognized right hand member of operator '{OpName(op)}' at {nextLexeme.Value.File}:{nextLexeme.Value.Line}");
            }

            if (needSC)
            {
                if (nextLexeme.Value.Type != LT.OP_SC)
                {
                    throw new Exception($"Missing semicolon after statement at {nextLexeme.Value.File}:{nextLexeme.Value.Line}");
                }
                nextLexeme = nextLexeme.Next;
            }

            resultNode = new AssignStmt {
                LHS = lhs, RHS = rhs, Op = op, Token = token
            };
            return(nextLexeme);
        }
Пример #7
0
        private string GetValue(AssignOp op)
        {
            switch (op)
            {
            case AssignOp.Assign:
                return("=");

            case AssignOp.AddAssign:
                return("+=");

            case AssignOp.SubAssign:
                return("-=");

            case AssignOp.MulAssign:
                return("*=");

            case AssignOp.DivAssign:
                return("/=");
            }
            return(null);
        }
Пример #8
0
        public void Parse(ref string[] program)
        {
            string token = ParseUtils.GetToken(ref program);

            WooScript._Log.AddMsg("Found function, target \"" + token + "\"");
            WooScript._Log.Indent();
            if (WooScript.IsFloatVariable(token))
            {
                _ReturnType = VarType.varFloat;
                _Var        = token;
            }
            else if (WooScript.IsVecVariable(token))
            {
                _ReturnType = VarType.varVector;
                _Var        = token;
            }
            else
            {
                throw new ParseException("Expected \"" + token + "\" to be a float or vector variable");
            }

            string assignOp = ParseUtils.GetToken(ref program);

            _AssignOp = WooScript.GetAssignOp(assignOp);

            _Expression = ExpressionBuilder.Parse(ref program);

            if (_ReturnType == VarType.varVector &&
                (_Expression.GetExpressionType() != VarType.varVector))
            {
                throw new ParseException("Target token is \"" + token + "\" which is a vector, expression isn't...");
            }

            if (_ReturnType == VarType.varFloat &&
                (_Expression.GetExpressionType() != VarType.varFloat))
            {
                throw new ParseException("Target token is \"" + token + "\" which is a float, expression isn't...");
            }
        }
Пример #9
0
        /// <summary>
        /// Optimization #6:
        /// Constant substitution
        ///
        /// TODO: This method has some inconsistencies when setting the offset with the new memory operations.
        ///       For some memory operations, I'm using "new {Op}(ptr + {op}.Offset)"
        ///       and for others I'm just using "new {Op}({op}.Offset)".
        ///       I'm pretty sure this inconsistency is causing some problems.
        /// </summary>
        /// <param name="operations"></param>
        private bool SubstituteConstants(ref DILOperationSet operations)
        {
            if (WereConstantsSubstituted)
            {
                return(false);
            }

            var ptr = 0;
            var arr = operations.ToArray();
            var didAnysubstitutions = false;

            for (int i = 0; i < arr.Length; i++)
            {
                var operation = arr[i];
                if (operation is AdditionMemoryOp)
                {
                    var add = (AdditionMemoryOp)operation;
                    if (add.Constant == null)
                    {
                        arr[i] = new AdditionMemoryOp(ptr + add.Offset, add.Scalar, new ConstantValue(ptr + add.Offset));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is MultiplicationMemoryOp)
                {
                    var mul = (MultiplicationMemoryOp)operation;
                    if (mul.Constant == null)
                    {
                        arr[i] = new MultiplicationMemoryOp(ptr + mul.Offset, mul.Scalar, new ConstantValue(ptr + mul.Offset), new ConstantValue(ptr));
                    }
                }
                else if (operation is AssignOp)
                {
                    var ass = arr[i] as AssignOp;
                    if (ass.Constant == null)
                    {
                        arr[i] = new AssignOp(ptr + ass.Offset, ass.Value, new ConstantValue(ptr + ass.Offset));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is PtrOp)
                {
                    arr[i] = null; // if we're using constants, then we don't need pointer movements
                    var ptrOp = (PtrOp)operation;
                    ptr += ptrOp.Delta;
                    //didAnysubstitutions = true;
                }
                else if (operation is WriteOp)
                {
                    var write = ((WriteOp)arr[i]);
                    if (write.Constant == null)
                    {
                        arr[i] = new WriteOp(write.Offset, write.Repeated, new ConstantValue(ptr));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is ReadOp)
                {
                    var read = ((ReadOp)arr[i]);
                    if (read.Constant == null)
                    {
                        arr[i] = new ReadOp(read.Offset, read.Repeated, new ConstantValue(ptr));
                        didAnysubstitutions = true;
                    }
                }
            }

            var list = arr.ToList();

            list.RemoveAll(l => l == null);

            operations = new DILOperationSet(list);

            operations.WereConstantsSubstituted = true;

            return(didAnysubstitutions);
        }