Beispiel #1
0
 private void ParseArray(Node subtree)
 {
     //ident[x] = blah;
     VariableAssignmentNode node = new VariableAssignmentNode(subtree);
     tokens.ConsumeToken(TokenType.Ident);
     SymbolTable.Lookup(tokens.LastToken.Value);
 }
Beispiel #2
0
        public void PropagateConstants_Chains()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            ast.AddChild(new VariableAssignmentNode("b", new VariableValueNode("a")));
            ast.AddChild(new VariableDeclarationNode("byte", "c"));
            ast.AddChild(new VariableAssignmentNode("c", new VariableValueNode("b")));
            ast.AddChild(new VariableDeclarationNode("byte", "c"));
            var assignment = new VariableAssignmentNode("c", new VariableValueNode("b"));

            ast.AddChild(assignment);

            var iterations = 0;

            while (PropagateConstants(ast))
            {
                iterations++;
            }

            Assert.AreEqual(1, iterations);
            Assert.IsInstanceOfType(assignment.Value, typeof(ShortValueNode));
            Assert.AreEqual(5, ((ShortValueNode)assignment.Value).GetValue());
        }
Beispiel #3
0
        private CheckedType MakeVariableAssignment(VariableAssignmentNode node, TypeCheckerVisitor checker)
        {
            if (node.Accessor.Parent != null)
            {
                var enc = node.Accessor.Parent.Visit(checker);

                /*if (enc.ITypeSymbol is Class c)
                 *  throw new System.Exception($"An instance of {c.Name} '{c.ClassName}' is required to access member '{node.Accessor.Target.Value}'");*/
            }

            var leftHandSide  = node.Accessor.Visit(checker);
            var rightHandSide = node.Right.Visit(checker);

            if (leftHandSide.Symbol.Storage == Symbols.Storage.Constant)
            {
                throw new System.Exception($"Cannot change value of constant {leftHandSide.TypeSymbol.Name} '{leftHandSide.Symbol.Name}'");
            }

            /*if (!leftHandSide.TypeSymbol.IsAssignableFrom(rightHandSide.TypeSymbol))
             *  throw new System.Exception($"Cannot convert from {rightHandSide.TypeSymbol} to {leftHandSide.TypeSymbol}");*/

            leftHandSide.Symbol = null;

            return(leftHandSide);
        }
Beispiel #4
0
        public void FlattenExpression_Assignment_MemoryValue_Both()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            var additionnode = new AdditionNode(new MemoryValueNode(100), new MemoryValueNode(100));
            var assignment   = new VariableAssignmentNode("x", additionnode);

            ast.AddChild(assignment);

            var changes = FlattenExpression(ast, 1);

            Assert.IsTrue(changes > 0);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(6, children.Count);
            Assert.IsInstanceOfType(additionnode.Left, typeof(VariableValueNode));
            Assert.IsInstanceOfType(additionnode.Right, typeof(VariableValueNode));
            Assert.IsInstanceOfType(children[0], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[1], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[2], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[3], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[4], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[5], typeof(VariableAssignmentNode));
            Assert.AreSame(children[5], assignment);
            Assert.AreNotEqual(((VariableAssignmentNode)children[2]).VariableName, ((VariableAssignmentNode)children[4]).VariableName);
        }
        private IType MakeVariableAssignment(VariableAssignmentNode node, TypeInferrerVisitor visitor)
        {
            var leftHandSide  = node.Accessor.Visit(visitor);
            var rightHandSide = node.Right.Visit(visitor);

            return(visitor.Inferrer.FindMostGeneralType(leftHandSide, rightHandSide));
        }
        private MutabilityCheckResult CheckVariableAssignment(VariableAssignmentNode node, MutabilityCheckerVisitor checker)
        {
            var leftHandSide  = node.Accessor.Visit(checker);
            var rightHandSide = node.Right.Visit(checker);

            /*if (leftHandSide.Symbol.Storage == Symbols.Storage.Immutable)
             *  throw new System.Exception($"Cannot change value of immutable variable {leftHandSide.Symbol.Name} '{leftHandSide.Symbol.Name}'");*/

            return(leftHandSide);
        }
Beispiel #7
0
        public void PropagateConstants_ResolvesExpressions()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            var expression = new VariableAssignmentNode("a", new AdditionNode(new ShortValueNode(1), new ShortValueNode(5)));

            ast.AddChild(expression);

            var changed = PropagateConstants(ast);

            Assert.IsTrue(changed);
            Assert.IsInstanceOfType(expression.Value, typeof(ConstantNode));
        }
Beispiel #8
0
        public void PropagateConstants_CopiesOver()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            var assignment = new VariableAssignmentNode("b", new VariableValueNode("a"));

            ast.AddChild(assignment);

            PropagateConstants(ast);

            Assert.IsInstanceOfType(assignment.Value, typeof(ShortValueNode));
            Assert.AreEqual(5, ((ShortValueNode)assignment.Value).GetValue());
        }
        private Operand MakeVariableAssignment(VariableAssignmentNode node, ILGenerator generator)
        {
            SymbolOperand leftHandSide  = node.Accessor.Visit(generator) as SymbolOperand;
            Operand       rightHandSide = node.Right.Visit(generator);

            // If right-hand side exists and has a type, do some type checking

            /*if (rightHandSide.Type != leftHandSide.Type)
             *  throw new AstWalkerException($"Cannot convert {rightHandSide.Type} to {leftHandSide.Type} ('{leftHandSide.Name}')");*/

            if (node.Operator.Type == TokenType.Assignment)
            {
                generator.Emmit(new StoreInstruction(leftHandSide, rightHandSide));
                return(leftHandSide);
            }


            Instruction instr = null;

            switch (node.Operator.Type)
            {
            case TokenType.IncrementAndAssign:
                instr = new AddInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.DecrementAndAssign:
                instr = new SubInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.MultAndAssign:
                instr = new MultInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.DivideAndAssign:
                instr = new DivInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            default:
                throw new InvalidInstructionException($"Unsupported operation: {node.Operator.Value} ({node.Operator.Type})");
            }

            generator.Emmit(instr);

            return(leftHandSide);
        }
        private ISymbol MakeVariableAssignment(VariableAssignmentNode node, SymbolResolverVisitor visitor)
        {
            var left  = node.Accessor.Visit(visitor);
            var right = node.Right.Visit(visitor);

            if (!left.IsAssignable())
            {
                throw new SymbolException($"'{left.Name}' is a {left.GetType().Name} and cannot be used as a left-hand side in an assignment expression");
            }

            if (!right.IsAssignable())
            {
                throw new SymbolException($"'{right.Name}' is a {right.GetType().Name} and cannot be used as a right-hand side in an assignment expression");
            }

            // On an assignment statement, we always return the left-hand side type
            return(left);
        }
Beispiel #11
0
        public void PropagateConstants_RemovesDecrement()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new DecrementNode("a"));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            var assignment = new VariableAssignmentNode("b", new VariableValueNode("a"));

            ast.AddChild(assignment);

            PropagateConstants(ast);

            Assert.IsInstanceOfType(assignment.Value, typeof(ShortValueNode));
            Assert.AreEqual(4, ((ShortValueNode)assignment.Value).GetValue());
            Assert.AreEqual(4, ast.GetChildren().Count());
        }
Beispiel #12
0
        public void PropagateConstants_Decrement_BeforeAndAfter()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            var before = new VariableAssignmentNode("b", new VariableValueNode("a"));

            ast.AddChild(before);
            ast.AddChild(new DecrementNode("a"));
            ast.AddChild(new VariableDeclarationNode("byte", "c"));
            var after = new VariableAssignmentNode("c", new VariableValueNode("a"));

            ast.AddChild(after);

            PropagateConstants(ast);

            Assert.IsInstanceOfType(before.Value, typeof(ShortValueNode));
            Assert.AreEqual(5, ((ShortValueNode)before.Value).GetValue());
            Assert.IsInstanceOfType(after.Value, typeof(ShortValueNode));
            Assert.AreEqual(4, ((ShortValueNode)after.Value).GetValue());
        }
Beispiel #13
0
        protected Node RETURN()
        {
            Accept(TT.TT_IdentRETURN);

            Node rval = null;

            switch (Current.TokenType)
            {
            case TT.TT_IdentTRUEFALSE:
            case TT.TT_Minus:
            case TT.TT_Plus:
            case TT.TT_ParenLeft:
            case TT.TT_IntNumber:
            case TT.TT_DoubleNumber:
            case TT.TT_Dollar:
            case TT.TT_String:
            case TT.TT_IdentCast:
                rval = Addition();
                break;

            case TT.TT_IdentCALLC:
                rval = CALLC();
                break;

            case TT.TT_IdentCALLO:
                rval = CALLO();
                break;

            case TT.TT_Semicolon:
                rval = null;
                break;

            default:
#warning Script Implement Error Handling
                Console.WriteLine("Error - 101");
                break;
            }

            if (rval != null && rval.IsContentNode)
            {
                Node varNode = GetVariableAsNode("RETURN");
                if (varNode != null && rval.ContentType != varNode.ContentType)
                {
#warning Script Implement Error Handling
                    //need to cast
                    Console.WriteLine("Error - 103");
                }

                if (rval.ContentType == typeof(int))
                {
                    rval = new VariableAssignmentNode <int>(GetVaraible <int>("RETURN"), rval);
                }
                else if (rval.ContentType == typeof(double))
                {
                    rval = new VariableAssignmentNode <double>(GetVaraible <double>("RETURN"), rval);
                }
                else if (rval.ContentType == typeof(bool))
                {
                    rval = new VariableAssignmentNode <bool>(GetVaraible <bool>("RETURN"), rval);
                }
                else if (rval.ContentType == typeof(string))
                {
                    rval = new VariableAssignmentNode <string>(GetVaraible <string>("RETURN"), rval);
                }
            }

            /*
             * Node retNode = GetVariableAsNode("RETURN");
             *
             * if (retNode != null && rval != null && rval.IsContentNode && rval.ContentType == retNode.ContentType)
             * {
             *
             * }
             *
             * /*
             * if (a != null && a.IsContentNode)
             * {
             *  if (a.ContentType == typeof(int))
             *      return new VariableAssignmentNode<int>(GetVaraible<int>(varName), a);
             *  else if (a.ContentType == typeof(double))
             *      return new VariableAssignmentNode<double>(GetVaraible<double>(varName), a);
             *  else if (a.ContentType == typeof(bool))
             *      return new VariableAssignmentNode<bool>(GetVaraible<bool>(varName), a);
             * }*/
            Node exe = NodeFactory.GenCallNodeStatic("LaserControl.ScriptV2.Exceptions.ExceptionRaiser", "RaiseReturn", new List <Node>());
            if (rval != null)
            {
                NodeCollection nc = new NodeCollection();
                nc.Add(rval);
                nc.Add(exe);
                return(nc);
            }
            return(exe);
        }
Beispiel #14
0
 private void ParseVariableAssignment(Node subtree)
 {
     //ident assign expr delim
     //does not include ident ident = expr
     VariableAssignmentNode node = new VariableAssignmentNode(subtree);
     tokens.ConsumeToken(TokenType.Ident);
     VariableNode var = new VariableNode(node);
     var.Ident = tokens.LastToken.Value;
     var.Type = SymbolTable.Lookup(tokens.LastToken.Value).ToString();
     if (tokens.CurrentToken == TokenType.LeftSquare)
     {
         tokens.Next();
         var.IsArray = true;
     }
     //assign expr
     if (!OpTable.Assignment.Contains(tokens.CurrentToken.Type))
         ErrorHandler.RaiseError(new UnexpectedTokenError(tokens.CurrentToken, "assignment operator",
             tokens.CurrentToken.LineNo));
     OperatorNode opNode = new OperatorNode(node);
     opNode.Op = tokens.CurrentToken.Type;
     tokens.Next();
     //expr
     ParseExpression(node);
 }
 private void ReportUndeclaredVariable(VariableAssignmentNode node)
 {
     var name = node.Name;
     ReportUndeclaredVariable(node, node.Name);
 }
        public void Visit(VariableAssignmentNode node)
        {
            if (node.Children.Count != 1)
            {
                throw new InternalCompilerError("Variable assignment node has no children");
            }

            if (!SymbolTable.ContainsKey(node.Name))
            {
                ReportUndeclaredVariable(node);
                return;
            }

            node.Children[0].Accept(this);

            var variableNode = SymbolTable[node.Name].node;
            TypeCheckVariableAssignment(node, variableNode);

            // warn on self assignment. This could be improved by also warning, if there are operations
            // that do not change the outcome (like c := c + 0;) but for now we just warn on the specific
            // case of var c := c;

            if (node.Children[0] is IdentifierNode && ((IdentifierNode)node.Children[0]).Name == node.Name)
            {
                reporter.ReportError(
                    Error.WARNING,
                    "Self assignment has no effect",
                    node.Children[0].Line,
                    node.Children[0].Column);
            }
        }
 public void Visit(VariableAssignmentNode node)
 {
     node.Children[0].Accept(this);
     Emit(Bytecode.STORE_VARIABLE);
     Emit(symbolTable[node.Name].id);
 }