private void ParseArray(Node subtree) { //ident[x] = blah; VariableAssignmentNode node = new VariableAssignmentNode(subtree); tokens.ConsumeToken(TokenType.Ident); SymbolTable.Lookup(tokens.LastToken.Value); }
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()); }
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); }
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); }
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)); }
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); }
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()); }
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()); }
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); }
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); }