public void InitExpressionBind() { String contents = "@x:int, @y:long, @z:int = 1,2 \r\n" + ""; SourceUnit unit = container.ParserService.Parse(contents); AssertNoErrorOrWarnings(); Assert.IsNotNull(unit); Assert.AreEqual(1, unit.Statements.Count); DeclarationBinding sb = container[typeof(DeclarationBinding)] as DeclarationBinding; sb.ExecutePass(unit.CompilationUnit); AssertNoErrorOrWarnings(); SingleVariableDeclarationStatement decl1 = unit.Statements[0] as SingleVariableDeclarationStatement; SingleVariableDeclarationStatement decl2 = unit.Statements[1] as SingleVariableDeclarationStatement; SingleVariableDeclarationStatement decl3 = unit.Statements[2] as SingleVariableDeclarationStatement; Assert.IsNotNull(decl1.InitExp); Assert.IsNotNull(decl2.InitExp); Assert.IsNull(decl3.InitExp); Assert.AreEqual(typeof(LiteralReferenceExpression), decl1.InitExp.GetType()); Assert.AreEqual(typeof(LiteralReferenceExpression), decl2.InitExp.GetType()); Assert.AreEqual("1", (decl1.InitExp as LiteralReferenceExpression).Content); Assert.AreEqual("2", (decl2.InitExp as LiteralReferenceExpression).Content); }
private IList ConvertToSingleDeclarationStatements(MultipleVariableDeclarationStatement varDecl) { IList newStmts = new ArrayList(); int index = 0; ExpressionCollection initExps = varDecl.InitExpressions; foreach (Identifier ident in varDecl.Identifiers) { // Here we are converting expression from // x:int, y:long = 1, 2L // to an AST representation equivalent to // x:int = 1; y:long = 2L SingleVariableDeclarationStatement svStmt = new SingleVariableDeclarationStatement(ident); if (index < initExps.Count) { svStmt.InitExp = initExps[index]; EnsureNoPostFixStatement(svStmt.InitExp); } index++; newStmts.Add(svStmt); } // We don't need them anymore initExps.Clear(); return(newStmts); }
public void SimplestCase() { // @x = @y + 1 // @y = @x + 1 Identifier xident = new Identifier(IdentifierType.InstanceField, "x", null); Identifier yident = new Identifier(IdentifierType.InstanceField, "y", null); SingleVariableDeclarationStatement xdecl = new SingleVariableDeclarationStatement(xident); SingleVariableDeclarationStatement ydecl = new SingleVariableDeclarationStatement(yident); VariableReferenceExpression xref = new VariableReferenceExpression(xident); VariableReferenceExpression yref = new VariableReferenceExpression(yident); BinaryExpression exp1 = new BinaryExpression(yref, new LiteralReferenceExpression("1", LiteralReferenceType.IntLiteral), BinaryOp.Plus); xdecl.DependencyExpression = exp1; BinaryExpression exp2 = new BinaryExpression(xref, new LiteralReferenceExpression("1", LiteralReferenceType.IntLiteral), BinaryOp.Plus); ydecl.DependencyExpression = exp2; Assert.IsTrue(ASTUtils.IsCycled(xdecl)); }
public override bool VisitSingleVariableDeclarationStatement(SingleVariableDeclarationStatement varDecl) { PerformSanityCheck(varDecl); CreateField(varDecl); return(base.VisitSingleVariableDeclarationStatement(varDecl)); }
public virtual bool VisitSingleVariableDeclarationStatement(SingleVariableDeclarationStatement varDecl) { VisitNode(varDecl.InitExp); VisitNode(varDecl.DependencyExpression); VisitNode(varDecl.Identifier); return(true); }
private void PerformSanityCheck(SingleVariableDeclarationStatement decl) { // TODO: Ensure that the symbol table are capable of holding a var declaration if (!decl.SymbolTable.IsDefined(decl.Identifier.Name)) { throw new CompilerException("Found single var declaration node that was not on the symbol table: " + decl.Identifier.Name); } }
private AssignmentExpression CreateAssignmentFromTypeDecl(SingleVariableDeclarationStatement decl) { if (decl.InitExp == null) { return(null); } return(new AssignmentExpression(new VariableReferenceExpression(decl.Identifier), decl.InitExp)); }
public void NestedDefinitionOfInstanceVars() { String contents = " \r\n" + "def some() \r\n" + " @x:int = 1 \r\n" + "end \r\n" + " \r\n" + "def some2() \r\n" + " @y += 2 \r\n" + "end \r\n" + " \r\n" + "@y:int = 1 \r\n" + ""; SourceUnit unit = container.ParserService.Parse(contents); AssertNoErrorOrWarnings(); Assert.IsNotNull(unit); Assert.AreEqual(3, unit.Statements.Count); DeclarationBinding sb = container[typeof(DeclarationBinding)] as DeclarationBinding; sb.ExecutePass(unit.CompilationUnit); Assert.IsNotNull(unit); Assert.AreEqual(4, unit.Statements.Count); AssertNoErrorOrWarnings(); MethodDefinitionStatement m1Stmt = unit.Statements[0] as MethodDefinitionStatement; MethodDefinitionStatement m2Stmt = unit.Statements[1] as MethodDefinitionStatement; SingleVariableDeclarationStatement varDecl1 = unit.Statements[2] as SingleVariableDeclarationStatement; SingleVariableDeclarationStatement varDecl2 = unit.Statements[3] as SingleVariableDeclarationStatement; Assert.IsNotNull(m1Stmt); Assert.IsNotNull(m2Stmt); Assert.IsNotNull(varDecl1); Assert.IsNotNull(varDecl2); Assert.AreEqual("some", m1Stmt.FullName); ExpressionStatement expStmt = m1Stmt.Statements[0] as ExpressionStatement; AssignmentExpression assignExp = expStmt.Expression as AssignmentExpression; Assert.AreEqual("@x", (assignExp.Target as VariableReferenceExpression).Identifier.Name); Assert.AreEqual("1", (assignExp.Value as LiteralReferenceExpression).Content); Assert.AreEqual("some2", m2Stmt.FullName); expStmt = m2Stmt.Statements[0] as ExpressionStatement; AugAssignmentExpression augExp = expStmt.Expression as AugAssignmentExpression; Assert.AreEqual("@y", (augExp.Target as VariableReferenceExpression).Identifier.Name); Assert.AreEqual("2", (augExp.Value as LiteralReferenceExpression).Content); }
public override bool VisitSingleVariableDeclarationStatement(SingleVariableDeclarationStatement varDecl) { nodeStack.Push(CurrentNode.Nodes.Add("SingleVariableDeclarationStatement")); CurrentNode.Tag = varDecl; CurrentNode.EnsureVisible(); base.VisitSingleVariableDeclarationStatement(varDecl); nodeStack.Pop(); return(true); }
private void CreateField(SingleVariableDeclarationStatement decl) { if (decl.Identifier.Type == IdentifierType.Local) { return; } TransientType type = decl.SymbolTable.CurrentTypeDefinition; System.Diagnostics.Debug.Assert(type != null); type.AddField(decl); }
public override bool VisitAssignmentExpression(AssignmentExpression assignExp) { if (assignExp.Target.NodeType == NodeType.VariableRefExpression) { // Convert to declaration if not found on the scope VariableReferenceExpression varRef = (VariableReferenceExpression)assignExp.Target; ISymbolTable scope = varRef.SymbolTable; System.Diagnostics.Debug.Assert(scope != null); String name = varRef.Identifier.Name; if (!scope.IsDefined(name)) // TODO: The rules are slighly more complicated than that. { errorReport.Disable(); SingleVariableDeclarationStatement varDecl = new SingleVariableDeclarationStatement(varRef.Identifier); IStatement stmt = ASTUtils.GetParentStatement(varRef); System.Diagnostics.Debug.Assert(stmt != null); IStatementContainer stmts = stmt.Parent as IStatementContainer; int index = stmts.Statements.IndexOf(stmt); varDecl.InitExp = assignExp.Value; // stmts.Statements.Insert(index, varDecl); stmts.Statements.Replace(stmt, varDecl); if (!ApplyDeclarationRules(varRef.Identifier, scope, varDecl, stmt)) { stmts.Statements.Remove(varDecl); } errorReport.Enable(); } } return(base.VisitAssignmentExpression(assignExp)); }
public void AddField(SingleVariableDeclarationStatement singleVarDecl) { HybridDictionary dict = null; if (singleVarDecl.Identifier.Type == IdentifierType.Local) { // Pardon? throw new ArgumentException("A local var declaration should get here"); } else if (singleVarDecl.Identifier.Type == IdentifierType.InstanceField) { dict = fields; } else if (singleVarDecl.Identifier.Type == IdentifierType.StaticField) { dict = sfields; } dict.Add(singleVarDecl.Identifier.Name, singleVarDecl); }
public void AssignConvertedToDeclaration2() { String contents = " \r\n" + "def some() \r\n" + " @x = 1 \r\n" + "end \r\n" + " \r\n" + ""; SourceUnit unit = container.ParserService.Parse(contents); AssertNoErrorOrWarnings(); Assert.IsNotNull(unit); Assert.AreEqual(1, unit.Statements.Count); DeclarationBinding sb = container[typeof(DeclarationBinding)] as DeclarationBinding; sb.ExecutePass(unit.CompilationUnit); AssertNoErrorOrWarnings(); Assert.AreEqual(2, unit.Statements.Count); MethodDefinitionStatement m1Stmt = unit.Statements[0] as MethodDefinitionStatement; SingleVariableDeclarationStatement varDecl1 = unit.Statements[1] as SingleVariableDeclarationStatement; ExpressionStatement assignStmt = m1Stmt.Statements[0] as ExpressionStatement; Assert.IsNotNull(m1Stmt); Assert.IsNotNull(varDecl1); Assert.IsNotNull(assignStmt); AssignmentExpression assignExp = assignStmt.Expression as AssignmentExpression; Assert.AreEqual("@x", (assignExp.Target as VariableReferenceExpression).Identifier.Name); Assert.AreEqual("1", (assignExp.Value as LiteralReferenceExpression).Content); Assert.AreEqual("@x", varDecl1.Identifier.Name); }
public override bool VisitSingleVariableDeclarationStatement(SingleVariableDeclarationStatement varDecl) { PerformSanityCheck(varDecl); CreateField(varDecl); return base.VisitSingleVariableDeclarationStatement(varDecl); }
private AssignmentExpression CreateAssignmentFromTypeDecl(SingleVariableDeclarationStatement decl) { if (decl.InitExp == null) return null; return new AssignmentExpression( new VariableReferenceExpression(decl.Identifier), decl.InitExp ); }
private IList ConvertToSingleDeclarationStatements(MultipleVariableDeclarationStatement varDecl) { IList newStmts = new ArrayList(); int index = 0; ExpressionCollection initExps = varDecl.InitExpressions; foreach(Identifier ident in varDecl.Identifiers) { // Here we are converting expression from // x:int, y:long = 1, 2L // to an AST representation equivalent to // x:int = 1; y:long = 2L SingleVariableDeclarationStatement svStmt = new SingleVariableDeclarationStatement(ident); if (index < initExps.Count) { svStmt.InitExp = initExps[index]; EnsureNoPostFixStatement(svStmt.InitExp); } index++; newStmts.Add(svStmt); } // We don't need them anymore initExps.Clear(); return newStmts; }
private bool ApplyDeclarationRules(Identifier ident, ISymbolTable namescope, SingleVariableDeclarationStatement typeDecl, IStatement statem) { // Second simple case: a local var and we are on the right place to // declare it if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { namescope.AddVariable(ident); return true; } // More complex: a block or compound tries to redefine a variable if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { if (namescope.Parent.IsDefined(ident.Name)) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined in a parent scope.", ident.Name ); return false; } } // Local variables at class level? // We will support that as a type initializer, but not now. if (ident.Type == IdentifierType.Local && namescope.ScopeType == ScopeType.Type) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "At type level, just instance or static fields are allowed (yet)" ); return false; } // Static or instance in a method/block/compound are moved // to the parent class or source unit level if (ident.Type == IdentifierType.InstanceField || ident.Type == IdentifierType.StaticField) { if (namescope.ScopeType == ScopeType.SourceUnit || namescope.ScopeType == ScopeType.Type) { namescope.AddVariable(ident); } else if (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block) { IASTNode node = statem.Parent; while(node != null && node.NodeType != NodeType.TypeDefinition && node.NodeType != NodeType.SourceUnit) { node = node.Parent; } if (node == null || node.SymbolTable == null) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "Compiler error: The instance of static declaration '{0}' could not be mapped to a parent type", ident.Name ); return false; } ISymbolTable parentScope = node.SymbolTable; IStatementContainer typeStmtsContainer = node as IStatementContainer; System.Diagnostics.Debug.Assert( parentScope != null ); System.Diagnostics.Debug.Assert( typeStmtsContainer != null ); if (parentScope.IsDefined(ident.Name)) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined.", ident.Name ); return false; } else { parentScope.AddVariable(ident); // We can replace the declaration on the method // body with an assignment if and only if this type decl has // an init expression, so CreateAssignmentFromTypeDecl can return null AssignmentExpression assignExp = CreateAssignmentFromTypeDecl(typeDecl); ExpressionStatement assignExpStmt = new ExpressionStatement(assignExp); typeDecl.ConvertInitExpressionToDependency(); // Replace the declaration with an assignment (statem.Parent as IStatementContainer).Statements.Replace(typeDecl, assignExpStmt); // Add the member/field declaration to the parent typeStmtsContainer.Statements.Add( typeDecl ); // TODO: Link assignment expression and typeDecl to help // find out the type of the field later return true; } } } return false; }
public override bool VisitAssignmentExpression(AssignmentExpression assignExp) { if (assignExp.Target.NodeType == NodeType.VariableRefExpression) { // Convert to declaration if not found on the scope VariableReferenceExpression varRef = (VariableReferenceExpression) assignExp.Target; ISymbolTable scope = varRef.SymbolTable; System.Diagnostics.Debug.Assert( scope != null ); String name = varRef.Identifier.Name; if (!scope.IsDefined(name)) // TODO: The rules are slighly more complicated than that. { errorReport.Disable(); SingleVariableDeclarationStatement varDecl = new SingleVariableDeclarationStatement(varRef.Identifier); IStatement stmt = ASTUtils.GetParentStatement(varRef); System.Diagnostics.Debug.Assert( stmt != null ); IStatementContainer stmts = stmt.Parent as IStatementContainer; int index = stmts.Statements.IndexOf(stmt); varDecl.InitExp = assignExp.Value; // stmts.Statements.Insert(index, varDecl); stmts.Statements.Replace(stmt, varDecl); if (!ApplyDeclarationRules(varRef.Identifier, scope, varDecl, stmt)) { stmts.Statements.Remove(varDecl); } errorReport.Enable(); } } return base.VisitAssignmentExpression(assignExp); }
private bool ApplyDeclarationRules(Identifier ident, ISymbolTable namescope, SingleVariableDeclarationStatement typeDecl, IStatement statem) { // Second simple case: a local var and we are on the right place to // declare it if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { namescope.AddVariable(ident); return(true); } // More complex: a block or compound tries to redefine a variable if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { if (namescope.Parent.IsDefined(ident.Name)) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined in a parent scope.", ident.Name); return(false); } } // Local variables at class level? // We will support that as a type initializer, but not now. if (ident.Type == IdentifierType.Local && namescope.ScopeType == ScopeType.Type) { errorReport.Error("TODOFILENAME", typeDecl.Position, "At type level, just instance or static fields are allowed (yet)"); return(false); } // Static or instance in a method/block/compound are moved // to the parent class or source unit level if (ident.Type == IdentifierType.InstanceField || ident.Type == IdentifierType.StaticField) { if (namescope.ScopeType == ScopeType.SourceUnit || namescope.ScopeType == ScopeType.Type) { namescope.AddVariable(ident); } else if (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block) { IASTNode node = statem.Parent; while (node != null && node.NodeType != NodeType.TypeDefinition && node.NodeType != NodeType.SourceUnit) { node = node.Parent; } if (node == null || node.SymbolTable == null) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Compiler error: The instance of static declaration '{0}' could not be mapped to a parent type", ident.Name); return(false); } ISymbolTable parentScope = node.SymbolTable; IStatementContainer typeStmtsContainer = node as IStatementContainer; System.Diagnostics.Debug.Assert(parentScope != null); System.Diagnostics.Debug.Assert(typeStmtsContainer != null); if (parentScope.IsDefined(ident.Name)) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined.", ident.Name); return(false); } else { parentScope.AddVariable(ident); // We can replace the declaration on the method // body with an assignment if and only if this type decl has // an init expression, so CreateAssignmentFromTypeDecl can return null AssignmentExpression assignExp = CreateAssignmentFromTypeDecl(typeDecl); ExpressionStatement assignExpStmt = new ExpressionStatement(assignExp); typeDecl.ConvertInitExpressionToDependency(); // Replace the declaration with an assignment (statem.Parent as IStatementContainer).Statements.Replace(typeDecl, assignExpStmt); // Add the member/field declaration to the parent typeStmtsContainer.Statements.Add(typeDecl); // TODO: Link assignment expression and typeDecl to help // find out the type of the field later return(true); } } } return(false); }
private void CreateField(SingleVariableDeclarationStatement decl) { if (decl.Identifier.Type == IdentifierType.Local) return; TransientType type = decl.SymbolTable.CurrentTypeDefinition; System.Diagnostics.Debug.Assert( type != null ); type.AddField( decl ); }
private void PerformSanityCheck(SingleVariableDeclarationStatement decl) { // TODO: Ensure that the symbol table are capable of holding a var declaration if (!decl.SymbolTable.IsDefined( decl.Identifier.Name )) { throw new CompilerException("Found single var declaration node that was not on the symbol table: " + decl.Identifier.Name); } }
public void AssignConvertedToDeclaration4() { String contents = "namespace Family::Guy \r\n"+ " \r\n"+ " class Boat \r\n"+ " \r\n"+ " def initialize \r\n"+ " @x = 1 \r\n"+ " end \r\n"+ " \r\n"+ " end \r\n"+ " \r\n"+ " class Song \r\n"+ " \r\n"+ " def save \r\n"+ " @name = 1 \r\n"+ " end \r\n"+ " \r\n"+ " end \r\n"+ " \r\n"+ "end \r\n"+ ""; SourceUnit unit = container.ParserService.Parse(contents); AssertNoErrorOrWarnings(); Assert.IsNotNull(unit); DeclarationBinding sb = container[typeof(DeclarationBinding)] as DeclarationBinding; sb.ExecutePass(unit.CompilationUnit); AssertNoErrorOrWarnings(); Assert.AreEqual(1, unit.Namespaces.Count); NamespaceDeclaration nsDecl = unit.Namespaces[0] as NamespaceDeclaration; Assert.AreEqual(2, nsDecl.TypeDeclarations.Count); TypeDefinitionStatement boatType = nsDecl.TypeDeclarations[0] as TypeDefinitionStatement; TypeDefinitionStatement songType = nsDecl.TypeDeclarations[1] as TypeDefinitionStatement; Assert.AreEqual(2, boatType.Statements.Count); Assert.AreEqual(2, songType.Statements.Count); MethodDefinitionStatement initMethod = boatType.Statements[0] as MethodDefinitionStatement; SingleVariableDeclarationStatement boatVarDecl = boatType.Statements[1] as SingleVariableDeclarationStatement; MethodDefinitionStatement saveMethod = songType.Statements[0] as MethodDefinitionStatement; SingleVariableDeclarationStatement songVarDecl = songType.Statements[1] as SingleVariableDeclarationStatement; Assert.AreEqual(1, initMethod.Statements.Count); Assert.AreEqual(1, saveMethod.Statements.Count); ExpressionStatement assignStmt1 = initMethod.Statements[0] as ExpressionStatement; ExpressionStatement assignStmt2 = saveMethod.Statements[0] as ExpressionStatement; Assert.IsNotNull(assignStmt1); Assert.IsNotNull(assignStmt2); AssignmentExpression assignExp1 = assignStmt1.Expression as AssignmentExpression; AssignmentExpression assignExp2 = assignStmt2.Expression as AssignmentExpression; Assert.IsNotNull(assignExp1); Assert.IsNotNull(assignExp2); Assert.AreEqual("@x", (assignExp1.Target as VariableReferenceExpression).Identifier.Name); Assert.AreEqual("1", (assignExp1.Value as LiteralReferenceExpression).Content); Assert.AreEqual("@name", (assignExp2.Target as VariableReferenceExpression).Identifier.Name); Assert.AreEqual("1", (assignExp2.Value as LiteralReferenceExpression).Content); }