package synthesijer.ast.opt; import synthesijer.ast.Expr; import synthesijer.ast.Method; import synthesijer.ast.Module; import synthesijer.ast.Scope; import synthesijer.ast.Statement; import synthesijer.ast.expr.ArrayAccess; import synthesijer.ast.expr.AssignExpr; import synthesijer.ast.expr.AssignOp; import synthesijer.ast.expr.BinaryExpr; import synthesijer.ast.expr.CondExpr; import synthesijer.ast.expr.FieldAccess; import synthesijer.ast.expr.Ident; import synthesijer.ast.expr.Literal; import synthesijer.ast.expr.MethodInvocation; import synthesijer.ast.expr.NewArray; import synthesijer.ast.expr.NewClassExpr; import synthesijer.ast.expr.ParenExpr; import synthesijer.ast.expr.TypeCast; import synthesijer.ast.expr.UnaryExpr; import synthesijer.ast.statement.BlockStatement; import synthesijer.ast.statement.BreakStatement; import synthesijer.ast.statement.ContinueStatement; import synthesijer.ast.statement.DoWhileStatement; import synthesijer.ast.statement.ExprStatement; import synthesijer.ast.statement.ForStatement; import synthesijer.ast.statement.IfStatement; import synthesijer.ast.statement.ReturnStatement; import synthesijer.ast.statement.SkipStatement; import synthesijer.ast.statement.SwitchStatement; import synthesijer.ast.statement.SynchronizedBlock; import synthesijer.ast.statement.TryStatement; import synthesijer.ast.statement.VariableDecl; import synthesijer.ast.statement.WhileStatement; public class NullOptimizer { public Module conv(Module m){ Module newM = new Module(m.getParentScope(), m.getName(), m.getImportTable(), m.getExtending(), m.getImplementingList()); newM.setSynthesijerHDL(m.isSynthesijerHDL()); for(VariableDecl v: m.getVariableDecls()){ VariableDecl newV = conv(newM, v); newM.addVariableDecl(newV); } for(Method method: m.getMethods()){ Method newMethod = conv(newM, method); newM.addMethod(newMethod); } return newM; } private VariableDecl conv(Scope parent, VariableDecl v){ Expr newInitExpr = conv(parent, v.getInitExpr()); VariableDecl newV = new VariableDecl(parent, v.getName(), v.getType(), newInitExpr); newV.setGlobalConstant(v.isGlobalConstant()); newV.setPublic(v.isPublic()); newV.setVolatile(v.isVolatile()); newV.setMethodParam(v.isMethodParam()); return newV; } private Method conv(Module parent, Method m){ Method newMethod = new Method(parent, m.getName(), m.getType()); newMethod.setUnsynthesizableFlag(m.isUnsynthesizable()); newMethod.setAutoFlag(m.isAuto()); newMethod.setAutoFlag(m.isSynchronized()); newMethod.setPrivateFlag(m.isPrivate()); newMethod.setRawFlag(m.isRaw()); newMethod.setCombinationFlag(m.isCombination()); newMethod.setCombinationFlag(m.isParallel()); newMethod.setNoWaitFlag(m.isNoWait()); newMethod.setConstructorFlag(m.isConstructor()); newMethod.setCallStackFlag(m.hasCallStack()); newMethod.setCallStackSize(m.getCallStackSize()); newMethod.setArgs(m.getArgs()); for(VariableDecl v: m.getVariableDecls()){ VariableDecl newV = conv(newMethod, v); newMethod.addVariableDecl(newV); } // inner block for(VariableDecl v: m.getBody().getVariableDecls()){ VariableDecl newV = conv(m.getBody(), v); newMethod.getBody().addVariableDecl(newV); } for(Statement s: m.getBody().getStatements()){ Statement newS = conv(m.getBody(), s); newMethod.getBody().addStatement(newS); } return newMethod; } /* * convert statements */ public Statement conv(Scope scope, Statement stmt){ if(stmt == null){ return null; }else if(stmt instanceof BlockStatement){ return conv(scope, (BlockStatement)stmt); }else if(stmt instanceof BreakStatement){ return conv(scope, (BreakStatement)stmt); }else if(stmt instanceof ContinueStatement){ return conv(scope, (ContinueStatement)stmt); }else if(stmt instanceof DoWhileStatement){ return conv(scope, (DoWhileStatement)stmt); }else if(stmt instanceof ExprStatement){ return conv(scope, (ExprStatement)stmt); }else if(stmt instanceof ForStatement){ return conv(scope, (ForStatement)stmt); }else if(stmt instanceof IfStatement){ return conv(scope, (IfStatement)stmt); }else if(stmt instanceof ReturnStatement){ return conv(scope, (ReturnStatement)stmt); }else if(stmt instanceof SkipStatement){ return conv(scope, (SkipStatement)stmt); }else if(stmt instanceof SwitchStatement){ return conv(scope, (SwitchStatement)stmt); }else if(stmt instanceof SynchronizedBlock){ return conv(scope, (SynchronizedBlock)stmt); }else if(stmt instanceof TryStatement){ return conv(scope, (TryStatement)stmt); }else if(stmt instanceof VariableDecl){ return conv(scope, (VariableDecl)stmt); }else if(stmt instanceof WhileStatement){ return conv(scope, (WhileStatement)stmt); }else{ throw new RuntimeException("[Internal Error] no convesion rule for " + stmt); } } /* * convert expressions */ public Expr conv(Scope scope, Expr expr){ if(expr == null){ return null; }else if(expr instanceof ArrayAccess){ return conv(scope, (ArrayAccess)expr); }else if(expr instanceof AssignExpr){ return conv(scope, (AssignExpr)expr); }else if(expr instanceof AssignOp){ return conv(scope, (AssignOp)expr); }else if(expr instanceof BinaryExpr){ return conv(scope, (BinaryExpr)expr); }else if(expr instanceof CondExpr){ return conv(scope, (CondExpr)expr); }else if(expr instanceof FieldAccess){ return conv(scope, (FieldAccess)expr); }else if(expr instanceof Ident){ return conv(scope, (Ident)expr); }else if(expr instanceof Literal){ return conv(scope, (Literal)expr); }else if(expr instanceof MethodInvocation){ return conv(scope, (MethodInvocation)expr); }else if(expr instanceof NewArray){ return conv(scope, (NewArray)expr); }else if(expr instanceof NewClassExpr){ return conv(scope, (NewClassExpr)expr); }else if(expr instanceof ParenExpr){ return conv(scope, (ParenExpr)expr); }else if(expr instanceof TypeCast){ return conv(scope, (TypeCast)expr); }else if(expr instanceof UnaryExpr){ return conv(scope, (UnaryExpr)expr); }else{ throw new RuntimeException("[Internal Error] no convesion rule for " + expr); } } private BlockStatement conv(Scope scope, BlockStatement stmt){ BlockStatement newS = new BlockStatement(scope); for(VariableDecl v: stmt.getVariableDecls()){ newS.addVariableDecl(conv(newS, v)); } for(Statement s: stmt.getStatements()){ newS.addStatement(conv(newS, s)); } return newS; } private BreakStatement conv(Scope scope, BreakStatement stmt){ BreakStatement newS = new BreakStatement(scope); return newS; } private ContinueStatement conv(Scope scope, ContinueStatement stmt){ ContinueStatement newS = new ContinueStatement(scope); return newS; } private DoWhileStatement conv(Scope scope, DoWhileStatement stmt){ DoWhileStatement newS = new DoWhileStatement(scope); newS.setBody(conv(scope, stmt.getBody())); newS.setCondition(conv(scope, stmt.getCondition())); return newS; } private ExprStatement conv(Scope scope, ExprStatement stmt){ Expr newE = conv(scope, stmt.getExpr()); ExprStatement newS = new ExprStatement(scope, newE); return newS; } private ForStatement conv(Scope scope, ForStatement stmt){ ForStatement newS = new ForStatement(scope); for(VariableDecl v: stmt.getVariableDecls()){ newS.addVariableDecl(conv(newS, v)); } for(Statement s: stmt.getInitializations()){ newS.addInitialize(conv(newS, s)); } newS.setCondition(conv(newS, stmt.getCondition())); for(Statement s: stmt.getUpdates()){ newS.addUpdate(conv(newS, s)); } newS.setBody(conv(newS, stmt.getBody())); return newS; } private IfStatement conv(Scope scope, IfStatement stmt){ IfStatement newS = new IfStatement(scope); newS.setCondition(conv(scope, stmt.getCondition())); newS.setThenPart(conv(scope, stmt.getThenPart())); if(stmt.getElsePart() != null){ newS.setElsePart(conv(scope, stmt.getElsePart())); } return newS; } private ReturnStatement conv(Scope scope, ReturnStatement stmt){ ReturnStatement newS = new ReturnStatement(scope); newS.setExpr(conv(scope, stmt.getExpr())); return newS; } private SkipStatement conv(Scope scope, SkipStatement stmt){ SkipStatement newS = new SkipStatement(scope); return newS; } private SwitchStatement conv(Scope scope, SwitchStatement stmt){ SwitchStatement newS = new SwitchStatement(scope); newS.setSelector(conv(scope, stmt.getSelector())); for(SwitchStatement.Elem elem : stmt.getElements()){ Expr pat = elem.getPattern(); SwitchStatement.Elem newElem = newS.newElement(conv(scope, pat)); for(Statement s: elem.getStatements()){ newElem.addStatement(conv(scope, s)); } } for(Statement s: stmt.getDefaultElement().getStatements()){ newS.getDefaultElement().addStatement(conv(scope, s)); } return newS; } private SynchronizedBlock conv(Scope scope, SynchronizedBlock stmt){ SynchronizedBlock newS = new SynchronizedBlock(scope); for(VariableDecl v: stmt.getVariableDecls()){ newS.addVariableDecl(conv(newS, v)); } for(Statement s: stmt.getStatements()){ newS.addStatement(conv(newS, s)); } return newS; } private TryStatement conv(Scope scope, TryStatement stmt){ TryStatement newS = new TryStatement(scope); newS.setBody(stmt.getBody()); return newS; } private WhileStatement conv(Scope scope, WhileStatement stmt){ WhileStatement newS = new WhileStatement(scope); newS.setCondition(conv(scope, stmt.getCondition())); newS.setBody(conv(scope, stmt.getBody())); return newS; } private Expr conv(Scope scope, ArrayAccess expr){ ArrayAccess newE = new ArrayAccess(scope); newE.setIndex(conv(scope, expr.getIndex())); newE.setIndexed(conv(scope, expr.getIndexed())); return newE; } private Expr conv(Scope scope, AssignExpr expr){ AssignExpr newE = new AssignExpr(scope); newE.setRhs(conv(scope, expr.getRhs())); newE.setLhs(conv(scope, expr.getLhs())); return newE; } private Expr conv(Scope scope, AssignOp expr){ AssignOp newE = new AssignOp(scope); newE.setRhs(conv(scope, expr.getRhs())); newE.setLhs(conv(scope, expr.getLhs())); newE.setOp(expr.getOp()); return newE; } private Expr conv(Scope scope, BinaryExpr expr){ BinaryExpr newE = new BinaryExpr(scope); newE.setRhs(conv(scope, expr.getRhs())); newE.setLhs(conv(scope, expr.getLhs())); newE.setOp(expr.getOp()); return newE; } private Expr conv(Scope scope, CondExpr expr){ CondExpr newE = new CondExpr(scope); newE.setCond(conv(scope, expr.getCond())); newE.setTruePart(conv(scope, expr.getTruePart())); newE.setFalsePart(conv(scope, expr.getFalsePart())); return newE; } private Expr conv(Scope scope, FieldAccess expr){ FieldAccess newE = new FieldAccess(scope); Expr ident = conv(scope, expr.getIdent()); if(!(ident instanceof Ident)){ throw new RuntimeException("FieildAccess should be Ident: " + ident); } newE.setIdent((Ident)(conv(scope, expr.getIdent()))); newE.setSelected(conv(scope, expr.getSelected())); return newE; } private Expr conv(Scope scope, Ident expr){ Ident newE = new Ident(scope); newE.setIdent(expr.getSymbol()); return newE; } private Expr conv(Scope scope, Literal expr){ Literal newE = expr.copy(scope); return newE; } private Expr conv(Scope scope, MethodInvocation expr){ MethodInvocation newE = new MethodInvocation(scope); newE.setMethod(conv(scope, expr.getMethod())); for(Expr e: expr.getParameters()){ newE.addParameter(conv(scope, e)); } return newE; } private Expr conv(Scope scope, NewArray expr){ NewArray newE = new NewArray(scope); for(Expr e: expr.getDimExpr()){ newE.addDimExpr(conv(scope, e)); } for(Expr e: expr.getElems()){ newE.addElem(conv(scope, e)); } return newE; } private Expr conv(Scope scope, NewClassExpr expr){ NewClassExpr newE = new NewClassExpr(scope); for(Expr e: expr.getParameters()){ newE.addParam(conv(scope, e)); } newE.setClassName(expr.getClassName()); return newE; } private Expr conv(Scope scope, ParenExpr expr){ ParenExpr newE = new ParenExpr(scope); newE.setExpr(conv(scope, expr.getExpr())); return newE; } private Expr conv(Scope scope, TypeCast expr){ TypeCast newE = new TypeCast(scope); newE.setExpr(conv(scope, expr.getExpr())); newE.setTargetType(expr.getType()); return newE; } private Expr conv(Scope scope, UnaryExpr expr){ UnaryExpr newE = new UnaryExpr(scope); newE.setArg(conv(scope, expr.getArg())); newE.setOp(expr.getOp()); newE.setPostfix(expr.isPostfix()); return newE; } }