source: proto/pabloj/trunk/src/compilers/pabloS/semanticAnalyzer/visitors/CarryIntroXFormer.java @ 2952

Last change on this file since 2952 was 2952, checked in by ksherdy, 5 years ago

Restructed PabloJ compile to provide clear separation between PabloS and PabloB.

File size: 28.8 KB
Line 
1package compilers.pabloS.semanticAnalyzer.visitors;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import pabloS.ast.*;
7import pabloS.tokens.LextantToken;
8import pabloS.lexicalAnalyzer.Lextant;
9
10import compilers.pabloB.lang.carry.CarryBuiltins2Lang;
11import compilers.pabloB.lang.idisa.SIMD;
12import compilers.pabloS.ast.Accessors;
13import compilers.pabloS.ast.Generators;
14import compilers.pabloS.lang.*;
15
16/*
17 * Translates carry dependent PabloS language features to PabloB. The translation process
18 * parameterized on 'carry' mode and 'final-block' mode.
19 *
20 * Target language independent Carry Set builtins calls are appended to the PabloB
21 * AST in the translation of PabloS 'if' and PabloS 'while' statements translated in
22 * 'carry-in' mode.
23 *
24 * By default, carry-in and carry-out mode are enabled
25 * for translation of PabloS language constructs
26 * to PabloB constructs.
27 *
28 * For example,
29 *
30 * PabloS if statements translate to PabloB syntax as follows.
31 *
32 * 'carry-in' - enabled
33 *
34 * if (E) { S* } => if (E | CarryTest(base,count)) { S* }
35 *
36 * 'carry-in' - disabled
37 *
38 * if (E) { S* } => if (E) { S* }
39 *
40 * Carry-in mode is enable in the initial iteration of while loops.
41 * Carry-in mode is disable for the translation of subsequent while loop iterations.
42 *
43 * PabloS while statements translate to PabloB syntax as follows.
44 *
45 * 'carry-in' - enabled
46 *
47 * while (E) { S* } =>
48 *
49 * if (E | CarryTest(base, count) )
50 * {
51 *              S'*
52 *              while (E)
53 *              {
54 *                      S''*
55 *                      CarryCombine(base, count)
56 *              }
57 * }
58 *
59 * wherein, S'
60 *
61 * 'carry-in' disabled
62 *
63 * Final-block mode.
64 *
65 * 'And Complement' EOF_mask
66 * ...
67 */
68
69public class CarryIntroXFormer {
70               
71        private ASTNode ASTTree;       
72        private Builtins2Lang builtins2Lang;
73        private CarryBuiltins2Lang carrySet2Lang;
74       
75    public CarryIntroXFormer(ASTNode node, Builtins2Lang builtins2Lang, CarryBuiltins2Lang carrySet2Lang) {
76        this.ASTTree = node; 
77        this.builtins2Lang = builtins2Lang;
78        this.carrySet2Lang = carrySet2Lang;
79    }   
80       
81    public void XForm(boolean finalBlockMode) {
82                XFormer visitor = new XFormer();
83                visitor.setFinalBlockMode(finalBlockMode);
84                ASTTree.accept(visitor);
85    }                   
86
87    public void XForm(boolean finalBlockMode, boolean ciMode, String carrySetIdentifier) {
88                XFormer visitor = new XFormer();
89                visitor.setFinalBlockMode(finalBlockMode);
90                visitor.setCiMode(ciMode);
91                visitor.setCarrySetIdentifier(carrySetIdentifier);
92                ASTTree.accept(visitor);
93    }     
94   
95        private class XFormer extends VoidVisitor.Default {
96
97                //private final String ciSuffix = "_ci";
98                //private final String coSuffix = "_co";
99                //private String [] pendindCarryQName = {CarryQ.CarryQ_PACKAGE_NAME, CarryQ.GETCARRYIN.cPPCode()};
100                //private String [] pending64QName = {CarryQ.CarryQ_PACKAGE_NAME, CarryQ.GETPENDING64.cPPCode()};
101               
102                private boolean finalBlockMode;
103                private boolean ciMode;
104                //private boolean coMode;
105               
106                private String carrySetIdentifier;
107               
108                private int currentCarry;
109                private int currentAdvN;
110                //private int lastStmtCarries;
111                               
112                @SuppressWarnings("static-access")
113                XFormer(/*boolean finalBlockModeboolean ciMode , boolean coMode */) {
114                       
115                        this.finalBlockMode = false;                                                   
116                        this.currentCarry = 0;
117                        this.currentAdvN = 0;
118                        //this.lastStmtCarries = 0;
119                       
120                        this.ciMode = true;                                                                                                     
121                        //this.coMode = coMode;
122                        this.carrySetIdentifier = carrySet2Lang.CARRYQNAME;     
123                }
124
125                protected boolean isCiMode() {
126                        return ciMode;
127                }
128
129                protected void setCiMode(boolean ciMode) {
130                        this.ciMode = ciMode;
131                }
132
133                protected String getCarrySetIdentifier() {
134                        return carrySetIdentifier;
135                }
136
137                protected void setCarrySetIdentifier(String carrySetIdentifier) {
138                        this.carrySetIdentifier = carrySetIdentifier;
139                }
140
141                protected boolean isFinalBlockMode() {
142                        return finalBlockMode;
143                }
144
145                protected void setFinalBlockMode(boolean finalBlockMode) {
146                        this.finalBlockMode = finalBlockMode;
147                }
148               
149                // xFormers
150               
151                //              def xfrm_fndef(self, fndef):
152                //          self.current_carry = 0
153                //          self.current_adv_n = 0
154                //          carry_count = CarryCounter().count(fndef)
155                //          if carry_count == 0: return fndef
156                //          self.generic_visit(fndef)
157                //      #   
158                //      #    fndef.body.insert(0, mkCallStmt('CarryDeclare', [self.carryvar, ast.Num(carry_count)]))
159                //          return fndef
160               
161                public void visitEnter(FuncDefNode node) { 
162                        this.currentCarry = 0;
163                        this.currentAdvN = 0;
164                        //this.lastStmtCarries = 0;
165                       
166                        int carryCount = (new CarryCounterVisitor(node)).count();
167                       
168                        if(carryCount > 0) { 
169                               
170                                IntegerConstantNode carryCountNode =  Generators.makeIntegerConstantNode(carryCount, node.getToken());
171                               
172                                @SuppressWarnings("static-access")
173                                FuncCallNode carryAdjustFuncCall = (FuncCallNode) Generators.makeFuncCallNode(
174                                                new String [] {carrySet2Lang.CARRYQNAME, carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.CARRYQADJUST)},
175                                                node.getToken(),
176                                                new ASTNode [] {carryCountNode});
177                               
178                                BlockStmtNode blockStmtNode = Accessors.blockStmtNode(node);
179                                if(!isFinalBlockMode()) {
180                                        blockStmtNode.appendChild(carryAdjustFuncCall);
181                                }       
182                        }               
183                }               
184               
185                public void visitLeave(FuncDefNode node) { 
186                        if(isFinalBlockMode()) {
187                                ParameterNode EOFMaskParameter = Generators.makeEOFMaskParameter(builtins2Lang, node.getToken());
188                                Generators.appendParameter(node, EOFMaskParameter);
189                        }
190                }               
191               
192                //public void visitLeave(FuncCallNode node) {
193                //      if(BuiltinsUtil.isCarryOne(node)) {
194                //              this.currentCarry += 1;
195                //      }                                       
196                //}
197               
198                public void visitLeave(FuncCallNode node) {
199                               
200                        ASTNode replacementNode;
201                       
202                        ASTNode carryCall;
203                        IntegerConstantNode currentCarry = Generators.makeIntegerConstantNode(this.currentCarry, node.getToken());
204                       
205                        ASTNode advNCall;
206                        IntegerConstantNode currentAdvN = Generators.makeIntegerConstantNode(this.currentAdvN, node.getToken());
207
208                        //                  if self.carryin == "_ci":
209                        //              carry_args = [mkCall(self.carryvar.id + "." + 'get_carry_in', [ast.Num(self.current_carry)]), ast.Num(self.current_carry)]
210                        //              adv_n_args = [mkCall(self.carryvar.id + "." + 'get_pending64', [ast.Num(self.current_adv_n)]), ast.Num(self.current_adv_n)]
211                        //          else:
212                        //              carry_args = [mkCall('simd<1>::constant<0>', []), ast.Num(self.current_carry)]
213                        //              adv_n_args = [mkCall('simd<1>::constant<0>', []), ast.Num(self.current_adv_n)]
214                       
215                        if(isCiMode()) {
216                                carryCall = Generators.makeFuncCallNode(
217                                                new String [] {getCarrySetIdentifier(), carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.GETCARRYIN)}, 
218                                                node.getToken(),
219                                                new ASTNode [] {currentCarry});
220                               
221                                advNCall = Generators.makeFuncCallNode(
222                                                new String [] {getCarrySetIdentifier(), carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.GETPENDING64)}, 
223                                                node.getToken(),
224                                                new ASTNode [] {currentAdvN});
225                        } else {
226                                carryCall = Generators.makeFuncCallNode(SIMD.CONSTANT.IDISAConstantLexeme("0", "1"), node.getToken());
227                                advNCall = Generators.makeFuncCallNode(SIMD.CONSTANT.IDISAConstantLexeme("0", "1"), node.getToken());
228                        }
229                                               
230                        //                  if is_BuiltIn_Call(callnode, 'Advance', 1):         
231                        //                    #CARRYSET
232                        //                    rtn = self.carryvar.id + "." + "BitBlock_advance_ci_co"
233                        //                    c = mkCall(rtn, callnode.args + carry_args)
234                        //                    self.current_carry += 1
235                        //                    return c
236                       
237                        if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCE.pabloSName(), Builtins.ADVANCE.argCount())) {         
238                               
239                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
240                               
241                                replaceFuncCallNode(node, 
242                                                getCarrySetIdentifier(), 
243                                                builtins2Lang.getCode(Builtins.ADVANCE), 
244                                                arguments,
245                                                carryCall, 
246                                                currentCarry);
247                               
248                                this.currentCarry += 1;
249                        }
250       
251                        //      #CARRYSET
252                        //      rtn = self.carryvar.id + "." + "BitBlock_scanthru_ci_co"
253                        //      c = mkCall(rtn, callnode.args + carry_args)
254                        //      self.current_carry += 1
255                        //      return c                                                       
256                       
257                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SCANTHRU.pabloSName(), Builtins.SCANTHRU.argCount())) {                         
258                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
259                               
260                                replaceFuncCallNode(node, 
261                                                getCarrySetIdentifier(), 
262                                                builtins2Lang.getCode(Builtins.SCANTHRU),
263                                                arguments,
264                                                carryCall, 
265                                                currentCarry);
266                                this.currentCarry += 1;
267                        }
268                               
269                        //          elif is_BuiltIn_Call(callnode, 'AdvanceThenScanThru', 2):
270                        //          #CARRYSET
271                        //          rtn = self.carryvar.id + "." + "BitBlock_advance_then_scanthru"
272                        //          c = mkCall(rtn, callnode.args + carry_args)
273                        //          self.current_carry += 1
274                        //          return c                   
275                       
276                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCETHENSCANTHRU.pabloSName(), Builtins.ADVANCETHENSCANTHRU.argCount())) {
277                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
278                               
279                                replaceFuncCallNode(node, 
280                                                getCarrySetIdentifier(), 
281                                                builtins2Lang.getCode(Builtins.ADVANCETHENSCANTHRU), 
282                                                arguments,
283                                                carryCall, 
284                                                currentCarry);
285                                this.currentCarry += 1;
286                        }               
287       
288                        //      elif is_BuiltIn_Call(callnode, 'SpanUpTo', 2):
289                        //      #CARRYSET
290                        //      rtn = self.carryvar.id + "." + "BitBlock_span_upto"
291                        //      c = mkCall(rtn, callnode.args + carry_args)
292                        //      self.current_carry += 1
293                        //      return c
294                       
295                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SPANUPTO.pabloSName(), Builtins.SPANUPTO.argCount())) {
296                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
297                               
298                                replaceFuncCallNode(node, 
299                                                getCarrySetIdentifier(), 
300                                                builtins2Lang.getCode(Builtins.SPANUPTO), 
301                                                arguments,
302                                                carryCall, 
303                                                currentCarry);                         
304                                this.currentCarry += 1;
305                        }               
306                       
307                        //              elif is_BuiltIn_Call(callnode, 'AdvanceThenScanTo', 2):
308                        //      #CARRYSET
309                        //      rtn = self.carryvar.id + "." + "BitBlock_advance_then_scanthru"
310                        //      if self.carryout == "":  scanclass = mkCall('simd_andc', [ast.Name('EOF_mask', ast.Load()), callnode.args[1]])
311                        //      else: scanclass = mkCall('simd_not', [callnode.args[1]])
312                        //      c = mkCall(rtn, [callnode.args[0], scanclass] + carry_args)
313                        //      self.current_carry += 1
314                        //          return c                   
315                       
316                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCETHENSCANTO.pabloSName(), Builtins.ADVANCETHENSCANTO.argCount())) {
317                                ASTNode argNode = Accessors.funcCallArg(node, 1);
318                                if(isFinalBlockMode()) {
319                                        replacementNode = Generators.makeSIMDEOFMaskAndCNodeFuncCall(argNode, builtins2Lang);
320                                } else {
321                                        replacementNode = Generators.makeSIMDNotFuncCall(argNode, builtins2Lang);
322                                }
323                                Accessors.funcCallArgsListNode(node).replaceChild(argNode, replacementNode);
324                               
325                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
326                               
327                                replaceFuncCallNode(node, 
328                                                getCarrySetIdentifier(), 
329                                                builtins2Lang.getCode(Builtins.ADVANCETHENSCANTHRU), 
330                                                arguments,
331                                                carryCall, 
332                                                currentCarry);
333                                this.currentCarry += 1;
334                        }               
335                       
336                        //          elif is_BuiltIn_Call(callnode, 'InclusiveSpan', 2):
337                        //            #CARRYSET
338                        //      #      rtn = self.carryvar.id + "." + "BitBlock_span_upto"
339                        //      #      c = mkCall('simd_or', [mkCall(rtn, callnode.args + carry_args), callnode.args[1]])
340                        //            rtn = self.carryvar.id + "." + "BitBlock_inclusive_span"
341                        //            c = mkCall(rtn, callnode.args + carry_args)
342                        //            self.current_carry += 1
343                        //            return c
344       
345                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.INCLUSIVESPAN.pabloSName(), Builtins.INCLUSIVESPAN.argCount())) {
346                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
347                               
348                                replaceFuncCallNode(node, 
349                                                getCarrySetIdentifier(), 
350                                                builtins2Lang.getCode(Builtins.INCLUSIVESPAN),
351                                                arguments,
352                                                carryCall, 
353                                                currentCarry);
354                                this.currentCarry += 1;
355                        }                               
356                       
357                        //          elif is_BuiltIn_Call(callnode, 'ExclusiveSpan', 2):
358                        //            #CARRYSET
359                        //      #      rtn = self.carryvar.id + "." + "BitBlock_span_upto"
360                        //      #      c = mkCall('simd_andc', [mkCall(rtn, callnode.args + carry_args), callnode.args[0]])
361                        //            rtn = self.carryvar.id + "." + "BitBlock_exclusive_span"
362                        //            c = mkCall(rtn, callnode.args + carry_args)
363                        //            self.current_carry += 1
364                        //            return c
365       
366                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.EXCLUSIVESPAN.pabloSName(), Builtins.EXCLUSIVESPAN.argCount())) {
367                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
368                               
369                                replaceFuncCallNode(node, 
370                                                getCarrySetIdentifier(), 
371                                                builtins2Lang.getCode(Builtins.EXCLUSIVESPAN),
372                                                arguments,
373                                                carryCall, 
374                                                currentCarry);
375                                this.currentCarry += 1;
376                        }                                               
377                       
378                        //          elif is_BuiltIn_Call(callnode, 'ScanTo', 2):
379                        //            # Modified Oct. 9, 2011 to directly use BitBlock_scanthru, eliminating duplication
380                        //            # in having a separate BitBlock_scanto routine.
381                        //            #CARRYSET
382                        //            rtn = self.carryvar.id + "." + "BitBlock_scanthru_ci_co"
383                        //            if self.carryout == "":  scanclass = mkCall('simd_andc', [ast.Name('EOF_mask', ast.Load()), callnode.args[1]])
384                        //            else: scanclass = mkCall('simd_not', [callnode.args[1]])
385                        //            c = mkCall(rtn, [callnode.args[0], scanclass] + carry_args)
386                        //            self.current_carry += 1
387                        //            return c
388       
389                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SCANTO.pabloSName(), Builtins.SCANTO.argCount())) {
390                               
391                                ASTNode argNode = Accessors.funcCallArg(node, 1);
392                                if(isFinalBlockMode()) {
393                                        replacementNode = Generators.makeSIMDEOFMaskAndCNodeFuncCall(argNode, builtins2Lang);                                                                   
394                                } else {
395                                        replacementNode = Generators.makeSIMDNotFuncCall(argNode, builtins2Lang);
396                                }
397                                Accessors.funcCallArgsListNode(node).replaceChild(argNode, replacementNode);
398                               
399                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
400                               
401                                replaceFuncCallNode(node, 
402                                                getCarrySetIdentifier(), 
403                                                builtins2Lang.getCode(Builtins.SCANTHRU), 
404                                                arguments,
405                                                carryCall, 
406                                                currentCarry);
407                                this.currentCarry += 1;
408                        }                                                               
409                       
410                        //          elif is_BuiltIn_Call(callnode, 'ScanToFirst', 1):
411                        //            #CARRYSET
412                        //            rtn = self.carryvar.id + "." + "BitBlock_scantofirst"
413                        //            #if self.carryout == "":  carry_args = [ast.Name('EOF_mask', ast.Load())] + carry_args
414                        //            c = mkCall(rtn, callnode.args + carry_args)
415                        //            self.current_carry += 1
416                        //            return c
417
418                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.SCANTOFIRST.pabloSName(), Builtins.SCANTOFIRST.argCount())) {
419                        //                      if(finalBlockMode) {
420                        //                              // TODO - Wrap within simd_andc(scan_class, EOF_mask)
421                        //                      }
422                               
423                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
424                               
425                                replaceFuncCallNode(node, 
426                                                getCarrySetIdentifier(), 
427                                                builtins2Lang.getCode(Builtins.SCANTOFIRST), 
428                                                arguments,
429                                                carryCall, 
430                                                currentCarry);
431                                this.currentCarry += 1;
432                        }                                                                               
433       
434                        //          elif is_BuiltIn_Call(callnode, 'Advance32', 1):     
435                        //            #CARRYSET
436                        //            rtn = self.carryvar.id + "." + "BitBlock_advance_n_<32>"
437                        //            c = mkCall(rtn, callnode.args + adv_n_args)
438                        //            self.current_adv_n += 1
439                        //            return c
440                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCE32.pabloSName(), Builtins.ADVANCE32.argCount())) {
441                                //replaceFuncCallNode(node, CarryQ.CarryQ_PACKAGE_NAME, BuiltinOperations.ADVANCE32.cPPCode(), carryCall, currentAdvN);
442                                // TODO ==> Verify implementation.
443                               
444                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
445                               
446                                replaceFuncCallNode(node, 
447                                                getCarrySetIdentifier(), 
448                                                builtins2Lang.getCode(Builtins.ADVANCE32), 
449                                                arguments,
450                                                advNCall, 
451                                                currentAdvN);
452                                this.currentAdvN += 1;
453                        }                       
454                       
455                        //          if is_BuiltIn_Call(callnode, 'Advance', 2):         
456                        //            #CARRYSET
457                        //            rtn = self.carryvar.id + "." + "BitBlock_advance_n_<%i>" % callnode.args[1].n
458                        //            c = mkCall(rtn, [callnode.args[0]] + adv_n_args)
459                        //            self.current_adv_n += 1
460                        //            return c         
461                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ADVANCEN.pabloSName(), Builtins.ADVANCEN.argCount())) {
462                                //replaceFuncCallNode(node, CarryQ.CarryQ_PACKAGE_NAME, BuiltinOperations.ADVANCEN.cPPCode(), carryCall, currentAdvN);                                 
463                               
464                                ASTNode formatValue = Accessors.funcCallArg(node, 1);
465                                String value = Accessors.integerConstantLexeme((IntegerConstantNode)formatValue);
466                               
467                                List<ASTNode> arguments = Accessors.funcCallArgsListNode(node).getChildren();
468                               
469                                String formattedAdvanceN = String.format(builtins2Lang.getCode(Builtins.ADVANCEN), value);
470                               
471                                replaceFuncCallNode(node, 
472                                                getCarrySetIdentifier(), 
473                                                formattedAdvanceN,
474                                                arguments.subList(0, arguments.size()-1),
475                                                advNCall, 
476                                                currentAdvN);           
477                                this.currentAdvN += 1;                 
478                        }                                       
479               
480                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.ATEOF.pabloSName(), Builtins.ATEOF.argCount())) {
481                                 
482                                if(isFinalBlockMode()) { 
483                                        ASTNode argNode = Accessors.funcCallArg(node, 0);
484                                        replacementNode = Generators.makeSIMDAndCEOFMaskFuncCall(argNode, builtins2Lang);
485                                } else {
486                                        replacementNode = Generators.makeFuncCallNode(SIMD.CONSTANT.IDISAConstantLexeme("0", "1"), node.getToken());                                   
487                                }
488                                node.updateSelf(replacementNode);
489                        }                                       
490       
491                        //          elif is_BuiltIn_Call(callnode, 'inFile', 1):
492                        //            if self.carryout != "": 
493                        //              # Non final block: inFile(x) = x.
494                        //              return callnode.args[0]
495                        //            else: return mkCall('simd_and', [callnode.args[0], ast.Name('EOF_mask', ast.Load())])
496                        else if (BuiltinsUtil.isCall(node, BuiltinsUtil.BUILTIN_PACKAGE_NAME, Builtins.INFILE.pabloSName(), Builtins.INFILE.argCount())) {
497                               
498                                if(isFinalBlockMode()) {                                       
499                                        ASTNode argNode = Accessors.funcCallArg(node, 0);
500                                        replacementNode = Generators.makeSIMDAndEOFMaskFuncCall(argNode, builtins2Lang);
501                                } else {
502                                        replacementNode = Accessors.funcCallArg(node,0);
503                                }
504                                node.updateSelf(replacementNode);
505                        }                       
506                       
507                        //                      Deprecated - New bitblock iterators replace StreamScan.
508                        //                     
509                        //              elif is_BuiltIn_Call(callnode, 'StreamScan', 2):
510                        //                      rtn = "StreamScan"           
511                        //                      c = mkCall(rtn, [ast.Name('(ScanBlock *) &' + callnode.args[0].id, ast.Load()),
512                        //                                                 ast.Name('sizeof(BitBlock)/sizeof(ScanBlock)', ast.Load()),
513                        //                                                 ast.Name(callnode.args[1].id, ast.Load())])
514                        //              return c                                       
515                        //
516                        //                      else if (Builtins.isCall(node, Builtins.BUILTIN_PACKAGE_NAME, NoCarry.STREAMSCAN.pabloName(), NoCarry.STREAMSCAN.argCount())) {
517                        //                              replacementNode = Generators.makeFuncCallNode(NoCarry.STREAMSCAN.cPPCode(), node.getToken());
518                        //                             
519                        //                              ASTNode arg0 = Generators.makeIdentifierNode("(ScanBlock *) &" + Accessors.identifierLexeme(Accessors.FuncCallArg(node, 0)), node.getToken());
520                        //                              ASTNode arg1 = Generators.makeIdentifierNode("sizeof(BitBlock)/sizeof(ScanBlock)", node.getToken());
521                        //                              ASTNode arg2 = Accessors.FuncCallArg(node, 1);
522                        //                             
523                        //                              replacementNode.appendChild(arg0);
524                        //                              replacementNode.appendChild(arg1);
525                        //                              replacementNode.appendChild(arg2);
526                        //                      }
527                                               
528                        //                  else:
529                        //                    #dump_Call(callnode)
530                        //                    return callnode
531                        else {
532                                // do nothing // TODO - allow calls to pass ?
533                        }
534                       
535                }
536               
537                //      def visit_If(self, ifNode):
538                //      carry_base = self.current_carry
539                //      carries = CarryCounter().count(ifNode)
540                //      assert adv_nCounter().count(ifNode) == 0, "Advance(x,n) within if: illegal\n"
541                //      self.generic_visit(ifNode)
542                //      if carries == 0 or self.carryin == "": return ifNode
543                //      #CARRYSET
544                //      carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
545                //      new_test = ast.BoolOp(ast.Or(), [ifNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
546                //      new_else_part = ifNode.orelse + [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]
547                //      return ast.If(new_test, ifNode.body, new_else_part)
548               
549                public void visitEnter(IfStmtNode node) { // current PabloS if statement implementation does not support n-bit CarryTest for Advance(x,n)
550                        assert (new AdvanceNCounterVisitor(node).count() == 0): "Advance(x,n) within if: illegal\n";
551                       
552                        int carryBase = this.currentCarry;
553                        int carryCount = (new CarryCounterVisitor(node)).count();
554                                               
555                        if(carryCount == 0) { 
556                                return;
557                        }
558                       
559                        if(!this.isCiMode()) { // e.g. not within the context of the 1st iteration of a while loop body
560                                return;
561                        }
562
563                        IntegerConstantNode carryBaseNode = Generators.makeIntegerConstantNode(carryBase, node.getToken());
564                        IntegerConstantNode carryCountNode = Generators.makeIntegerConstantNode(carryCount, node.getToken());
565                       
566                        BinaryOperatorNode replacementIfTestNode = makeBitwiseOrCarryTest(Accessors.ifTest(node), carryBaseNode, carryCountNode);
567                       
568                        node.replaceChild(Accessors.ifTest(node), replacementIfTestNode);
569                       
570                        // else part, append CarryDequeueEnqueue call
571                        FuncCallNode carryDequeueEnqueue = (FuncCallNode) Generators.makeFuncCallNode(
572                                        new String [] {getCarrySetIdentifier(), carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.CARRYDEQUEUEENQUEUE)},
573                                        node.getToken(),
574                                        new ASTNode [] {carryBaseNode, carryCountNode});
575                       
576                        if (Accessors.hasElseBlockStmt(node)) { 
577                                Accessors.elseBlockStmt(node).appendChild(carryDequeueEnqueue);
578                        } else {
579                                BlockStmtNode blockStmtNode = Generators.makeBlockStmtNode(node.getToken());
580                                blockStmtNode.appendChild(carryDequeueEnqueue);
581                                node.appendChild(blockStmtNode); 
582                        }                               
583                }
584               
585                public void visitEnter(WhileStmtNode node) {
586
587                        //          if self.carryout == '':
588                        //            whileNode.test.args[0] = mkCall("simd_and", [whileNode.test.args[0], ast.Name('EOF_mask', ast.Load())])
589                        //          carry_base = self.current_carry
590                        //          assert adv_nCounter().count(whileNode) == 0, "Advance(x,n) within while: illegal\n"
591                        //          carries = CarryCounter().count(whileNode)
592                        //          #CARRYSET
593                        //          if carries == 0: return whileNode
594                        //          carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
595                        //          local_carryvar = 'sub' + self.carryvar.id
596                       
597                        if(isFinalBlockMode()) {
598                                ASTNode whileConditionNode = Accessors.whileTest(node);
599                                ASTNode replacementNode = Generators.makeSIMDAndEOFMaskFuncCall(whileConditionNode, builtins2Lang);
600                                node.replaceChild(whileConditionNode, replacementNode);                                 
601                        }
602               
603                        assert (new AdvanceNCounterVisitor(node).count() == 0): "Advance(x,n) within if: illegal\n";
604                       
605                        int carryBase   = this.currentCarry;
606                        int carryCount  = (new CarryCounterVisitor(node)).count();                     
607               
608                        if(carryCount == 0) { 
609                                return;
610                        }
611               
612                        IntegerConstantNode carryBaseNode       = Generators.makeIntegerConstantNode(carryBase, node.getToken());
613                        IntegerConstantNode carryCountNode      = Generators.makeIntegerConstantNode(carryCount, node.getToken());
614                       
615                        IdentifierNode localCarryId                     
616                                                                = Generators.makeIdentifierNode(compilers.pabloB.lang.carry.CarryBuiltins2Lang.LOCALCARRYQNAME, 
617                                                                                                                                node.getToken());
618                       
619                        CompoundIdentifierNode localCarryQArrayQName   
620                                                                = Generators.makeCompoundIdentifierNode(
621                                                                                new String [] {compilers.pabloB.lang.carry.CarryBuiltins2Lang.LOCALCARRYQNAME, 
622                                                                                                compilers.pabloB.lang.carry.CarryBuiltins2Lang.LOCALCARRYQARRAYNAME}, 
623                                                                                node.getToken());
624                       
625                        /*
626
627                        StringConstantNode localCarryQArrayQName       
628                                        = Generators.makeStringConstantNode(
629                                                        CarrySetBuiltins2Lang.LOCALCARRYQNAME
630                                                        + "."
631                                                        + CarrySetBuiltins2Lang.LOCALCARRYQARRAYNAME,
632                                                        node.getToken());
633                        */
634
635                        //          inner_while = CarryIntro(local_carryvar, '', self.carryout).generic_xfrm(copy.deepcopy(whileNode))
636                        //          self.generic_visit(whileNode)
637                        //          local_carry_decl = mkCallStmt('LocalCarryDeclare', [ast.Name(local_carryvar, ast.Load()), ast.Num(carries)])
638                        //          inner_while.body.insert(0, local_carry_decl)
639                        //          final_combine =
640                        //                      mkCallStmt      (ast.Attribute(self.carryvar, 'CarryCombine', ast.Load()),
641                        //                                                      [ast.Attribute(ast.Name(local_carryvar, ast.Load()),
642////////////                    //                                                              'cq', ast.Load()),
643                        //                                                              ast.Num(carry_base),
644                        //                                                              ast.Num(carries)
645                        //                                                      ]
646                        //                                              )
647                        //          inner_while.body.append(final_combine)                     
648
649                        //              translate inner while ciMode disabled and local carry object
650                        WhileStmtNode innerWhile = node.deepCopy();
651                        CarryIntroXFormer xFormer = new CarryIntroXFormer(Accessors.whileBlockStmt(innerWhile), builtins2Lang, carrySet2Lang);
652                        xFormer.XForm(finalBlockMode, false, compilers.pabloB.lang.carry.CarryBuiltins2Lang.LOCALCARRYQNAME);
653                       
654                        FuncCallNode localCarryDeclare = (FuncCallNode) Generators.makeFuncCallNode(
655                                        carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.LOCALCARRYDECLARE),
656                                        node.getToken(),
657                                        new ASTNode [] {localCarryId, carryCountNode});
658
659                        Accessors.whileBlockStmt(innerWhile).insertChild(localCarryDeclare);
660
661                        FuncCallNode carryCombine = (FuncCallNode) Generators.makeFuncCallNode(
662                                        new String [] {getCarrySetIdentifier(), carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.CARRYCOMBINE)},
663                                        node.getToken(),
664                                        new ASTNode [] {localCarryQArrayQName, carryBaseNode, carryCountNode});
665                       
666                        Accessors.whileBlockStmt(innerWhile).appendChild(carryCombine);
667                       
668                        //
669                        //          #CARRYSET
670                        //          if self.carryin == '': new_test = whileNode.test
671                        //          else: new_test = ast.BoolOp(ast.Or(), [whileNode.test, mkCall(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
672                        //          else_part = [mkCallStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]   
673                        //          return ast.If(new_test, whileNode.body + [inner_while], else_part)
674                       
675                       
676                        // if condition
677                        ASTNode ifTest = Accessors.whileTest(node).deepCopy();
678                       
679                        if(!isCiMode()) {
680                                ifTest = Accessors.whileTest(node).deepCopy();
681                        } else {                               
682                                ifTest = makeBitwiseOrCarryTest(ifTest, carryBaseNode, carryCountNode);
683                        }
684                       
685                        // if body
686                        BlockStmtNode ifBlockStmtNode = Generators.makeBlockStmtNode(node.getToken());
687                        ifBlockStmtNode.appendChild(Accessors.whileBlockStmt(node));
688                        ifBlockStmtNode.appendChild(innerWhile);
689                       
690                        FuncCallNode carryDequeueEnqueue = (FuncCallNode) Generators.makeFuncCallNode(
691                                        new String [] {getCarrySetIdentifier(), carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.CARRYDEQUEUEENQUEUE)},
692                                        node.getToken(),
693                                        new ASTNode [] {carryBaseNode, carryCountNode});
694                       
695                        // else body                   
696                        BlockStmtNode elseBlockStmtNode = Generators.makeBlockStmtNode(node.getToken());
697                        elseBlockStmtNode.appendChild(carryDequeueEnqueue);
698                       
699                        IfStmtNode ifStmtNode = Generators.makeIfStmtNode(node.getToken(),
700                                        ifTest, 
701                                        ifBlockStmtNode,
702                                        elseBlockStmtNode);
703                       
704                        node.updateSelf(ifStmtNode);
705                }
706       
707                // Helpers             
708                private void replaceFuncCallNode(FuncCallNode node, 
709                                String targetPackage, String targetName,
710                                List<ASTNode> arguments,
711                                ASTNode call, IntegerConstantNode carry) {
712                        FuncCallNode replacementNode;
713       
714                        List<ASTNode> args = new ArrayList<ASTNode>();
715                                                                       
716                        for(ASTNode arg : arguments) {
717                                args.add(arg);
718                        }       
719                        args.add(call);
720                        args.add(carry);
721                       
722                        replacementNode = Generators.makeFuncCallNode(
723                                        new String [] {targetPackage, targetName}, 
724                                        node.getToken(),
725                                        args);
726                       
727                        node.updateSelf(replacementNode);
728                }
729       
730                private BinaryOperatorNode makeBitwiseOrCarryTest(ASTNode ifTest,
731                                IntegerConstantNode carryBaseNode,
732                                IntegerConstantNode carryCountNode) {
733       
734                        ASTNode lhs = ifTest;
735                               
736                        String lexeme = Lextant.OR.getPrimaryLexeme();
737                        LextantToken binaryOperatorToken = LextantToken.make(lhs.getToken().getLocation(), lexeme, Lextant.OR);
738                       
739                        FuncCallNode rhs = (FuncCallNode) Generators.makeFuncCallNode(
740                                        new String [] {getCarrySetIdentifier(), carrySet2Lang.getCode(compilers.pabloB.lang.carry.CarryBuiltins.CARRYTEST)},
741                                        lhs.getToken(),
742                                        new ASTNode [] {carryBaseNode, carryCountNode});
743                       
744                        BinaryOperatorNode replacementIfTestNode = Generators.makeBinaryOperatorNode(lhs, 
745                                                                                                                                        rhs,
746                                                                                                                                        binaryOperatorToken);
747                        return replacementIfTestNode;
748                }       
749       
750        }
751}       
Note: See TracBrowser for help on using the repository browser.