public override bool Visit(VarDeclaration node) { Visit((ValueDeclaration)node); TraverseSetParent(node, node.init); return(true); }
public void Visit(VarDeclaration node) { // add the names for each vardecl in the statement node.IfNotNull(n => n.Children.ForEach(v => v.Accept(this))); }
private void GenStmt(Stmt stmt, ILGenerator il, Type[] argtypes) { if (stmt is VarDeclaration) { VarDeclaration var = (VarDeclaration)stmt; string tname = var.Type.GetTypeName(); if (typeTable.ContainsKey(tname)) { TypeBuilder typeBuilder = typeTable[tname]; ConstructorBuilder ctorBuilder = ctorTable[tname]; LocalBuilder localBuilder = il.DeclareLocal(typeBuilder); symbolTable[var.Name] = localBuilder; il.Emit(OpCodes.Newobj, ctorBuilder); il.Emit(OpCodes.Stloc, localBuilder); } else { Type vtype = var.Type.GetAType(); symbolTable[var.Name] = il.DeclareLocal(vtype); GenExpr(var.Expr, TypeOfExpr(var.Expr, argtypes), il, argtypes); Store(var.Name, TypeOfExpr(var.Expr, argtypes), il); } } else if (stmt is Assign) { Assign assign = (Assign)stmt; GenExpr(assign.Expr, TypeOfExpr(assign.Expr, argtypes), il, argtypes); Store(assign.Name, TypeOfExpr(assign.Expr, argtypes), il); } else if (stmt is ExprStmt) { Expr expr = ((ExprStmt)stmt).Expr; if (expr is FuncCall) { FuncCall funcCall = (FuncCall)expr; if (funcCall.Name.Count > 1 && funcCall.Name[0] != "System") { if (symbolTable.ContainsKey(funcCall.Name[0])) { LocalBuilder localBuilder = (LocalBuilder)symbolTable[funcCall.Name[0]]; il.Emit(OpCodes.Ldloc, localBuilder); } } Type[] typeArgs = new Type[funcCall.Args.Count]; for (int i = 0; i < funcCall.Args.Count; i++) { typeArgs[i] = TypeOfExpr(funcCall.Args[i], argtypes); GenExpr(funcCall.Args[i], typeArgs[i], il, argtypes); } string strFunc = funcCall.Name[funcCall.Name.Count - 1]; // "WriteLine" if (funcCall.Name[0] == "System") { string strType = funcCall.Name[0]; for (int i = 1; i < funcCall.Name.Count - 1; i++) { strType += "." + funcCall.Name[i]; } Type typeFunc = Type.GetType(strType); // System.Console il.Emit(OpCodes.Call, typeFunc.GetMethod(strFunc, typeArgs)); } else if (funcCall.Name.Count > 1) { MethodBuilder methodBuilder = funcTable[strFunc]; il.EmitCall(OpCodes.Call, methodBuilder, null); } else { if (!funcTable.ContainsKey(strFunc)) { throw new Exception("undeclared function '" + strFunc + "'"); } MethodBuilder funcBuilder = funcTable[strFunc]; il.EmitCall(OpCodes.Call, funcBuilder, null); } } } }
Stmt ParseStmt() { Modifier modifier = ParseModifier(); IList<string> name1 = ParseName(); // Type of Variable IList<string> name2 = ParseName(); // Variable string symb = GetSymbol(); if (name1.Count > 0 && name2.Count > 0 && symb == "(") { FuncDefinition result = new FuncDefinition(); result.Modifier = modifier; result.Type = new AType(); result.Type.Name = name1; result.Name = name2[0]; result.Args = ParseArguments(); Skip(":"); result.Body = ParseCompoundStmt(); return result; } else if (name1.Count > 0 && name2.Count > 0 && symb == "=") { VarDeclaration var = new VarDeclaration(); var.Type = new AType(); var.Type.Name = name1; var.Name = name2[0]; var.Expr = ParseExpr(); Skip(";"); return var; } else if (name1.Count > 0 && name2.Count == 0 && symb == "=") { VarDeclaration result = new VarDeclaration(); return result; } else if (name1.Count > 0 && name2.Count == 0 && symb == "(") {// Ex. hello.Print(str); ExprStmt stmt = new ExprStmt(); stmt.Expr = ParseFuncCall(false, name1); return stmt; } else { ExprStmt stmt = new ExprStmt(); stmt.Expr = ParseExpr(); return stmt; } }
static int RelocateForInVar(BlockStatement block, int insertAt, VarDeclaration varStatement, ForInStatement forIn) { // there should only be one decl in the for-in var statement. There should not be any initializer. // If not, then ignore it VariableDeclaration varDecl; if (varStatement.Count == 1 && (varDecl = varStatement[0]).Initializer == null) { // if there are more than three names, then we don't want to move them var bindingNames = BindingsVisitor.Bindings(varDecl.Binding); //if (bindingNames.Count < 3) { // replace the varStatement in the for-in with a reference version of the binding forIn.Variable = BindingTransform.FromBinding(varDecl.Binding); // if this is a simple binding identifier, then leave it as-is. Otherwise we // need to flatten it for the move to the front of the scope. if (!(varDecl.Binding is BindingIdentifier)) { // then flatten all the name in the binding and add them to the var first = true; foreach (var declName in bindingNames) { if (first) { varStatement[0] = new VariableDeclaration(declName.Context) { Binding = new BindingIdentifier(declName.Context) { Name = declName.Name, VariableField = declName.VariableField } }; first = false; } else { // otherwise we want to insert a new one at the current position + 1 varStatement.Append(new VariableDeclaration(declName.Context) { Binding = new BindingIdentifier(declName.Context) { Name = declName.Name, VariableField = declName.VariableField } }); } } } // then move the var statement to the front of the scope // if the statement at the insertion point is a var-statement already, // then we just need to append our vardecls to it. Otherwise we'll insert our // var statement at the right point var existingVar = block[insertAt] as VarDeclaration; if (existingVar != null) { // append the varstatement we want to move to the existing var, which will // transfer all the vardecls to it. existingVar.Append(varStatement); } else { // insert it at the insert point block.Insert(insertAt, varStatement); } } } return(insertAt); }
static int RelocateVar(BlockStatement block, int insertAt, VarDeclaration varStatement) { var forInParent = varStatement.Parent as ForInStatement; if (forInParent != null) { insertAt = ReorderScopeVisitor.RelocateForInVar(block, insertAt, varStatement, forInParent); } else { // if the var statement is at the next position to insert, then we don't need // to do anything. if (block[insertAt] != varStatement) { // check to see if the current position is a var and we are the NEXT statement. // if that's the case, we don't need to break out the initializer, just append all the // vardecls as-is to the current position. ForStatement forStatement; var existingVar = block[insertAt] as VarDeclaration; if (existingVar != null && block[insertAt + 1] == varStatement) { // two var-s one right after the other. // just append our vardecls to the insertion point, then delete our statement existingVar.Append(varStatement); block.RemoveAt(insertAt + 1); } else if (existingVar != null && (forStatement = varStatement.Parent as ForStatement) != null && forStatement.Initializer == varStatement && forStatement == block[insertAt + 1]) { // this var statement is the initializer of a for-statement, which is // immediately after the var we would insert our vardecls into. // rather than moving our vardecls into the outside var-statement, let's // move the outside var-statement into our for-statement. varStatement.InsertAt(0, existingVar); block.RemoveAt(insertAt); } else { // iterate through the decls and count how many have initializers var initializerCount = 0; for (var ndx = 0; ndx < varStatement.Count; ++ndx) { // count the number of vardecls with initializers if (varStatement[ndx].Initializer != null) { ++initializerCount; } } // if there are more than two decls with initializers, then we won't actually // be gaining anything by moving the var to the top. We'll get rid of the four // bytes for the "var ", but we'll be adding two bytes for the name and comma // because name=init will still need to remain behind. if (initializerCount <= 2) { // first iterate through all the declarations in the var statement, // constructing an expression statement that is made up of assignment // operators for each of the declarations that have initializers (if any) // and removing all the initializers var assignments = new List <AstNode>(); for (var ndx = 0; ndx < varStatement.Count; ++ndx) { var varDecl = varStatement[ndx]; if (varDecl.Initializer != null) { // hold on to the object so we don't lose it to the GC var initializer = varDecl.Initializer; // remove it from the vardecl varDecl.Initializer = null; var reference = BindingTransform.FromBinding(varDecl.Binding); if (varDecl.IsCCSpecialCase) { // we don't want to add the special-case to the binary operator class, // so just create a copy of the vardecl for this location, using a reference // for the "binding" assignments.Add(new VariableDeclaration(varDecl.Context) { Binding = reference, AssignContext = varDecl.AssignContext, Initializer = initializer, IsCCSpecialCase = true, UseCCOn = varDecl.UseCCOn, TerminatingContext = varDecl.TerminatingContext }); } else { assignments.Add(new BinaryExpression(varDecl.Context) { Operand1 = reference, Operand2 = initializer, OperatorToken = JSToken.Assign, OperatorContext = varDecl.AssignContext }); } } // if the vardecl we are moving isn't a binding pattern, we need to // break it down into a simple list of names. if (!(varDecl.Binding is BindingIdentifier)) { // place the original vardecl with the first one var first = true; foreach (var declName in BindingsVisitor.Bindings(varDecl.Binding)) { if (first) { varStatement[ndx] = new VariableDeclaration(declName.Context) { Binding = new BindingIdentifier(declName.Context) { Name = declName.Name, VariableField = declName.VariableField } }; first = false; } else { // otherwise we want to insert a new one at the current position + 1 varStatement.InsertAt(++ndx, new VariableDeclaration(declName.Context) { Binding = new BindingIdentifier(declName.Context) { Name = declName.Name, VariableField = declName.VariableField } }); } } } } // now if there were any initializers... if (assignments.Count > 0) { // we want to create one big expression from all the assignments and replace the // var statement with the assignment(s) expression. Start at position n=1 and create // a binary operator of n-1 as the left, n as the right, and using a comma operator. var expression = assignments[0]; for (var ndx = 1; ndx < assignments.Count; ++ndx) { expression = CommaExpression.CombineWithComma(expression.Context.FlattenToStart(), expression, assignments[ndx]); } // replace the var with the expression. // we still have a pointer to the var, so we can insert it back into the proper // place next. varStatement.Parent.ReplaceChild(varStatement, expression); } else { // no initializers. // just remove the var statement altogether varStatement.Parent.ReplaceChild(varStatement, null); } // if the statement at the insertion point is a var-statement already, // then we just need to append our vardecls to it. Otherwise we'll insert our // var statement at the right point if (existingVar != null) { // append the varstatement we want to move to the existing var, which will // transfer all the vardecls to it. existingVar.Append(varStatement); } else { // move the var to the insert point, incrementing the position or next time block.Insert(insertAt, varStatement); } } } } } return(insertAt); }
public void TestVarDeclaration() { VarDeclaration node = GetVarDeclaration(); CheckSerializationRoundTrip(node); }
public override Void Visit(VarDeclaration node, Void param) { node.Type = Clean(node.Type); return(base.Visit(node, param)); }