source: proto/pablo/src/compiler/semanticAnalyzer/visitors/CarryIntroXFormer.java @ 2702

Last change on this file since 2702 was 2702, checked in by ksherdy, 6 years ago

General refactoring (variable names). Added final block XFormer. Move final block operations atEOF/inFile out of carry intro transformer to final block transformer.

File size: 7.9 KB
Line 
1package compiler.semanticAnalyzer.visitors;
2
3import ast.*;
4import tokens.LextantToken;
5import lexicalAnalyzer.Lextant;
6import compiler.ast.Accessors;
7import compiler.ast.Generators;
8import compiler.lang.carryset.CarrySet;
9import compiler.lang.carryset.CarrySet2Lang;
10import compiler.lang.pablo.BuiltinsUtil;
11
12public class CarryIntroXFormer {
13               
14        private ASTNode ASTTree; 
15        private CarrySet2Lang carrySet2Lang;
16               
17    public CarryIntroXFormer(ASTNode node, CarrySet2Lang carrySet2Lang) {
18        this.ASTTree = node; 
19        this.carrySet2Lang = carrySet2Lang;
20    }
21
22    public void XForm(boolean ci /*, boolean co*/) { 
23                XFormer visitor = new XFormer(ci /*, co*/);
24                ASTTree.accept(visitor);
25    }                   
26       
27        private class XFormer extends VoidVisitor.Default {
28
29                //private final String ciSuffix = "_ci";
30                //private final String coSuffix = "_co";
31                //private String [] pendindCarryQName = {CarryQ.CarryQ_PACKAGE_NAME, CarryQ.GETCARRYIN.cPPCode()};
32                //private String [] pending64QName = {CarryQ.CarryQ_PACKAGE_NAME, CarryQ.GETPENDING64.cPPCode()};
33               
34                private boolean ciMode;
35                //private boolean coMode;
36                               
37                private int currentCarry;
38                //private int currentAdvN;
39                //private int lastStmtCarries;
40               
41                XFormer(boolean ciMode /*, boolean coMode */) {
42                        this.ciMode = ciMode;
43                        //this.coMode = coMode;
44                        this.currentCarry = 0;
45                        //this.currentAdvN = 0;
46                        //this.lastStmtCarries = 0;
47                }
48               
49                //              def xfrm_fndef(self, fndef):
50                //          self.current_carry = 0
51                //          self.current_adv_n = 0
52                //          carry_count = CarryCounter().count(fndef)
53                //          if carry_count == 0: return fndef
54                //          self.generic_visit(fndef)
55                //      #   
56                //      #    fndef.body.insert(0, mkCallStmt('CarryDeclare', [self.carryvar, ast.Num(carry_count)]))
57                //          return fndef
58                public void visitEnter(FuncDefNode node) { 
59                        this.currentCarry = 0;
60                        //this.currentAdvN = 0;
61                        //this.lastStmtCarries = 0;
62                       
63                        int carryCount = (new CarryCounterVisitor(node)).count();
64                        if(carryCount > 0) { 
65                       
66                                IntegerConstantNode carryCountNode =  Generators.makeIntegerConstantNode(carryCount, node.getToken());
67                               
68                                FuncCallNode carryAdjustFuncCall = (FuncCallNode) Generators.makeFuncCallNode(
69                                                new String [] {CarrySet.CarryQ_IDENTIFIER, carrySet2Lang.getCode(CarrySet.CARRYQADJUST)},
70                                                node.getToken(),
71                                                new ASTNode [] {carryCountNode});
72                               
73                                BlockStmtNode blockStmtNode = Accessors.blockStmtNode(node);
74                                blockStmtNode.appendChild(carryAdjustFuncCall);
75                        }
76                }               
77               
78                public void visitLeave(FuncCallNode node) {
79                        if(BuiltinsUtil.isCarryOne(node)) {
80                                this.currentCarry += 1;
81                        }                                       
82                }
83               
84                //def visit_If(self, ifNode):
85                //carry_base = self.current_carry
86                //carries = CarryCounter().count(ifNode)
87                //assert adv_nCounter().count(ifNode) == 0, "Advance(x,n) within if: illegal\n"
88                //self.generic_visit(ifNode)
89                //if carries == 0 or self.carryin == "": return ifNode
90                //#CARRYSET
91                //carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
92                //new_test = ast.BoolOp(ast.Or(), [ifNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
93                //new_else_part = ifNode.orelse + [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]
94                //return ast.If(new_test, ifNode.body, new_else_part)
95
96                public void visitEnter(IfStmtNode node) { // Current if strategy does not test any_carry() on n bits
97                        assert (new AdvanceNCounterVisitor(node).count() == 0): "Advance(x,n) within if: illegal\n";
98                       
99                        int carryBase = this.currentCarry;
100                        int carryCount = (new CarryCounterVisitor(node)).count();
101                                               
102                        if(carryCount == 0) { 
103                                return;
104                        }
105                       
106                        if(!this.ciMode) { // while loop body
107                                return;
108                        }
109                               
110                        // if test, replace if test
111                        String lexeme = Lextant.OR.getPrimaryLexeme();
112                        LextantToken binaryOperatorToken = LextantToken.make(node.getToken().getLocation(), lexeme, Lextant.OR);
113                       
114                        ASTNode lhs = Accessors.ifTest(node);
115
116                        IntegerConstantNode carryBaseNode = Generators.makeIntegerConstantNode(carryBase, node.getToken());
117                        IntegerConstantNode carryCountNode =  Generators.makeIntegerConstantNode(carryCount, node.getToken());
118               
119                        FuncCallNode rhs = (FuncCallNode) Generators.makeFuncCallNode(
120                                        new String [] {CarrySet.CarryQ_IDENTIFIER, carrySet2Lang.getCode(CarrySet.CARRYTEST)},
121                                        node.getToken(),
122                                        new ASTNode [] {carryBaseNode, carryCountNode});
123                       
124                        BinaryOperatorNode replacementIfTestNode = Generators.makeBinaryOperatorNode(lhs, 
125                                                                                                                                        rhs,
126                                                                                                                                        binaryOperatorToken);
127                       
128                        node.replaceChild(Accessors.ifTest(node), replacementIfTestNode);
129                       
130                        // else part, append CarryDequeueEnqueue call
131                        FuncCallNode carryDequeueEnqueue = (FuncCallNode) Generators.makeFuncCallNode(
132                                        new String [] {CarrySet.CarryQ_IDENTIFIER, carrySet2Lang.getCode(CarrySet.CARRYDEQUEUEENQUEUE)},
133                                        node.getToken(),
134                                        new ASTNode [] {carryBaseNode, carryCountNode});
135
136                       
137                        if (Accessors.hasElseBlockStmt(node)) { 
138                                Accessors.elseBlockStmt(node).appendChild(carryDequeueEnqueue);
139                        } else {
140                                BlockStmtNode blockStmtNode = 
141                                                Generators.makeBlockStmtNode(LextantToken.make(node.getToken().getLocation(),
142                                                                                                                        Lextant.LCURLY.getPrimaryLexeme(),
143                                                                                                                        Lextant.LCURLY));
144                                blockStmtNode.appendChild(carryDequeueEnqueue);
145                                node.appendChild(blockStmtNode); 
146                        }
147                                               
148                }
149        }
150}
151
152//class CarryIntro(ast.NodeXFormer):
153
154//        def generic_xfrm(self, node):
155//          self.current_carry = 0
156//          self.current_adv_n = 0
157//          carry_count = CarryCounter().count(node)
158//          adv_n_count = adv_nCounter().count(node)
159//          if carry_count == 0 and adv_n_count == 0: return node
160//          self.generic_visit(node)
161//          return node
162
163//def visit_If(self, ifNode):
164//carry_base = self.current_carry
165//carries = CarryCounter().count(ifNode)
166//assert adv_nCounter().count(ifNode) == 0, "Advance(x,n) within if: illegal\n"
167//self.generic_visit(ifNode)
168//if carries == 0 or self.carryin == "": return ifNode
169//#CARRYSET
170//carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
171//new_test = ast.BoolOp(ast.Or(), [ifNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
172//new_else_part = ifNode.orelse + [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]
173//return ast.If(new_test, ifNode.body, new_else_part)
174
175//        def visit_While(self, whileNode):
176//          if self.carryout == '':
177//            whileNode.test.args[0] = mkCall("simd_and", [whileNode.test.args[0], ast.Name('EOF_mask', ast.Load())])
178//          carry_base = self.current_carry
179//          assert adv_nCounter().count(whileNode) == 0, "Advance(x,n) within while: illegal\n"
180//          carries = CarryCounter().count(whileNode)
181//          #CARRYSET
182//          if carries == 0: return whileNode
183//          carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
184//          local_carryvar = 'sub' + self.carryvar.id
185//          inner_while = CarryIntro(local_carryvar, '', self.carryout).generic_xfrm(copy.deepcopy(whileNode))
186//          self.generic_visit(whileNode)
187//          local_carry_decl = mkCallStmt('LocalCarryDeclare', [ast.Name(local_carryvar, ast.Load()), ast.Num(carries)])
188//          inner_while.body.insert(0, local_carry_decl)
189//          final_combine = mkCallStmt(ast.Attribute(self.carryvar, 'CarryCombine', ast.Load()), [ast.Attribute(ast.Name(local_carryvar, ast.Load()), 'cq', ast.Load()),ast.Num(carry_base), ast.Num(carries)])
190//          inner_while.body.append(final_combine)
191//          #CARRYSET
192//          if self.carryin == '': new_test = whileNode.test
193//          else: new_test = ast.BoolOp(ast.Or(), [whileNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
194//          else_part = [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]   
195//          return ast.If(new_test, whileNode.body + [inner_while], else_part)
Note: See TracBrowser for help on using the repository browser.