source: icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp @ 5042

Last change on this file since 5042 was 5042, checked in by cameron, 3 years ago

Add pablo.atEOF; clean out bit4/6 hack for unterminated final lines in icgrep.

File size: 21.2 KB
Line 
1/*
2 *  Copyright (c) 2014 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include <pablo/codegenstate.h>
8#include <iostream>
9#include <pablo/printer_pablos.h>
10
11namespace pablo {
12
13Zeroes PabloBlock::mZeroes;
14
15Ones PabloBlock::mOnes;
16
17inline PabloAST * PabloBlock::renameNonNamedNode(PabloAST * expr, const std::string && prefix) {
18    if (Statement * stmt = dyn_cast<Statement>(expr)) {
19        if (stmt->getName()->isGenerated()) {
20            stmt->setName(makeName(prefix, false));
21        }
22    }
23    return expr;
24}
25
26void PabloBlock::insert(Statement * const statement) {
27    assert (statement);
28    if (LLVM_UNLIKELY(mInsertionPoint == nullptr)) {
29        if (mFirst) {
30            statement->insertBefore(mFirst);
31        } else {
32            statement->removeFromParent();
33            statement->mParent = this;
34            mFirst = mLast = statement;
35        }
36    } else if (LLVM_LIKELY(statement != mInsertionPoint)) {
37        statement->insertAfter(mInsertionPoint);
38        mLast = (mLast == mInsertionPoint) ? statement : mLast;
39        assert (statement->mPrev == mInsertionPoint);
40    }
41    mInsertionPoint = statement;
42}
43
44/// UNARY CREATE FUNCTIONS
45
46Assign * PabloBlock::createAssign(const std::string && prefix, PabloAST * const expr)  {
47    assert ("Assign expression cannot be null!" && expr);
48    return insertAtInsertionPoint(new Assign(expr, makeName(prefix, false)));
49}
50
51PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
52    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
53        return expr;
54    }
55    return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName("advance")));
56}
57
58PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
59    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
60        return expr;
61    }
62    return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName(prefix, false)));
63}
64
65PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount) {
66    if (isa<Zeroes>(expr) || shiftAmount == 0) {
67        return expr;
68    }
69    return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName("advance")));
70}
71
72PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
73    if (isa<Zeroes>(expr) || shiftAmount == 0) {
74        return renameNonNamedNode(expr, std::move(prefix));
75    }
76    return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName(prefix, false)));
77}
78
79PabloAST * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount) {
80    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
81        return expr;
82    }
83    return insertAtInsertionPoint(new Lookahead(expr, shiftAmount, makeName("lookahead")));
84}
85
86PabloAST * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
87    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
88        return expr;
89    }
90    return insertAtInsertionPoint(new Lookahead(expr, shiftAmount, makeName(prefix, false)));
91}
92
93PabloAST * PabloBlock::createLookahead(PabloAST * expr, const Integer::Type shiftAmount) {
94    if (isa<Zeroes>(expr) || shiftAmount == 0) {
95        return expr;
96    }
97    return insertAtInsertionPoint(new Lookahead(expr, getInteger(shiftAmount), makeName("lookahead")));
98}
99
100PabloAST * PabloBlock::createLookahead(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
101    if (isa<Zeroes>(expr) || shiftAmount == 0) {
102        return renameNonNamedNode(expr, std::move(prefix));
103    }
104    return insertAtInsertionPoint(new Lookahead(expr, getInteger(shiftAmount), makeName(prefix, false)));
105}
106
107Call * PabloBlock::createCall(PabloAST * prototype, const std::vector<PabloAST *> &) {
108    assert (prototype);
109    return insertAtInsertionPoint(new Call(prototype));
110}
111
112
113PabloAST * PabloBlock::createNot(PabloAST * expr) {
114    assert (expr);
115    if (isa<Ones>(expr)) {
116        return createZeroes();
117    }
118    else if (isa<Zeroes>(expr)){
119        return createOnes();
120    }
121    else if (Not * not1 = dyn_cast<Not>(expr)) {
122        return not1->getOperand(0);
123    }
124    return insertAtInsertionPoint(new Not(expr, makeName("not_")));
125}
126
127PabloAST * PabloBlock::createNot(PabloAST * expr, const std::string prefix) {
128    assert (expr);
129    if (isa<Ones>(expr)) {
130        return createZeroes();
131    }
132    else if (isa<Zeroes>(expr)){
133        return createOnes();
134    }
135    else if (Not * not1 = dyn_cast<Not>(expr)) {       
136        return renameNonNamedNode(not1->getOperand(0), std::move(prefix));
137    }
138    return insertAtInsertionPoint(new Not(expr, makeName(prefix, false)));
139}
140
141Var * PabloBlock::createVar(PabloAST * name) {
142    assert (name);
143    return new Var(name);
144}
145
146PabloAST * PabloBlock::createCount(PabloAST * expr) {
147    assert (expr);
148    return insertAtInsertionPoint(new Count(expr, makeName("count_")));
149}
150
151PabloAST * PabloBlock::createCount(PabloAST * expr, const std::string prefix) {
152    assert (expr);
153    return insertAtInsertionPoint(new Count(expr, makeName(prefix, false)));
154}
155
156PabloAST * PabloBlock::createInFile(PabloAST * expr) {
157    assert (expr);
158    return insertAtInsertionPoint(new InFile(expr, makeName("inFile_")));
159}
160
161PabloAST * PabloBlock::createInFile(PabloAST * expr, const std::string prefix) {
162    assert (expr);
163    return insertAtInsertionPoint(new InFile(expr, makeName(prefix, false)));
164}
165
166
167PabloAST * PabloBlock::createAtEOF(PabloAST * expr) {
168    assert (expr);
169    return insertAtInsertionPoint(new AtEOF(expr, makeName("atEOF_")));
170}
171
172PabloAST * PabloBlock::createAtEOF(PabloAST * expr, const std::string prefix) {
173    assert (expr);
174    return insertAtInsertionPoint(new AtEOF(expr, makeName(prefix, false)));
175}
176   
177   
178    /// BINARY CREATE FUNCTIONS
179
180Next * PabloBlock::createNext(Assign * assign, PabloAST * expr) {
181    assert (assign && expr);
182    return insertAtInsertionPoint(new Next(assign, expr));
183}
184
185PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass) {
186    assert (marker && charclass);
187    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
188        return marker;
189    }
190    return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName("matchstar")));
191}
192
193PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const std::string prefix) {
194    assert (marker && charclass);
195    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
196        return renameNonNamedNode(marker, std::move(prefix));
197    }
198    return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName(prefix, false)));
199}
200
201PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {
202    assert (from && thru);
203    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
204        return from;
205    }
206    return insertAtInsertionPoint(new ScanThru(from, thru, makeName("scanthru")));
207}
208
209PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, const std::string prefix) {
210    assert (from && thru);
211    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {       
212        return renameNonNamedNode(from, std::move(prefix));
213    }
214    return insertAtInsertionPoint(new ScanThru(from, thru, makeName(prefix, false)));
215}
216
217template<typename Type>
218static inline Type * isBinary(PabloAST * expr) {
219    if (isa<Type>(expr) && cast<Type>(expr)->getNumOperands() == 2) {
220        return cast<Type>(expr);
221    }
222    return nullptr;
223}
224
225PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
226    assert (expr1 && expr2);
227    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
228        return expr2;
229    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
230        return expr1;
231    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
232        if (Not * not2 = dyn_cast<Not>(expr2)) {
233            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)));
234        } else if (equals(not1->getOperand(0), expr2)) {
235            return createZeroes();
236        }
237    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
238        if (equals(expr1, not2->getOperand(0))) {
239            return createZeroes();
240        }
241    } else if (Or * or1 = isBinary<Or>(expr1)) {
242        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
243            return expr2;
244        }
245    } else if (Or * or2 = isBinary<Or>(expr2)) {
246        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
247            return expr1;
248        }
249    }
250    return insertAtInsertionPoint(new And(expr1, expr2, makeName("and_")));
251}
252
253PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
254    assert (expr1 && expr2);
255    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
256        return renameNonNamedNode(expr2, std::move(prefix));
257    }
258    else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
259        return renameNonNamedNode(expr1, std::move(prefix));
260    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
261        if (Not * not2 = dyn_cast<Not>(expr2)) {
262            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)), prefix);
263        }
264        else if (equals(not1->getOperand(0), expr2)) {
265            return createZeroes();
266        }
267    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
268        if (equals(expr1, not2->getOperand(0))) {
269            return createZeroes();
270        }
271    } else if (Or * or1 = isBinary<Or>(expr1)) {
272        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
273            return expr2;
274        }
275    } else if (Or * or2 = isBinary<Or>(expr2)) {
276        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
277            return expr1;
278        }
279    }
280    return insertAtInsertionPoint(new And(expr1, expr2, makeName(prefix, false)));
281}
282
283And * PabloBlock::createAnd(const unsigned reserved) {
284    return insertAtInsertionPoint(new And(reserved, makeName("and_")));
285}
286
287And * PabloBlock::createAnd(const unsigned reserved, const std::string prefix) {
288    return insertAtInsertionPoint(new And(reserved, makeName(prefix, false)));
289}
290
291PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
292    assert (expr1 && expr2);
293    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
294        return expr2;
295    }
296    if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
297        return expr1;
298    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
299        // ¬a√b = ¬¬(¬a √ b) = ¬(a ∧ ¬b)
300        return createNot(createAnd(not1->getOperand(0), createNot(expr2)));
301    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
302        // a√¬b = ¬¬(¬b √ a) = ¬(b ∧ ¬a)
303        return createNot(createAnd(not2->getOperand(0), createNot(expr1)));
304    } else if (equals(expr1, expr2)) {
305        return expr1;
306    } else if (And * and1 = isBinary<And>(expr1)) {
307        if (And * and2 = isBinary<And>(expr2)) {
308            PabloAST * const expr1a = and1->getOperand(0);
309            PabloAST * const expr1b = and1->getOperand(1);
310            PabloAST * const expr2a = and2->getOperand(0);
311            PabloAST * const expr2b = and2->getOperand(1);
312            //These optimizations factor out common components that can occur when sets are formed by union
313            //(e.g., union of [a-z] and [A-Z].
314            if (equals(expr1a, expr2a)) {
315                return createAnd(expr1a, createOr(expr1b, expr2b));
316            } else if (equals(expr1b, expr2b)) {
317                return createAnd(expr1b, createOr(expr1a, expr2a));
318            } else if (equals(expr1a, expr2b)) {
319                return createAnd(expr1a, createOr(expr1b, expr2a));
320            } else if (equals(expr1b, expr2a)) {
321                return createAnd(expr1b, createOr(expr1a, expr2b));
322            }
323        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
324            // (a ∧ b) √ a = a
325            return expr2;
326        }
327    } else if (And * and2 = isBinary<And>(expr2)) {
328        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
329            return expr1;
330        }
331    }
332    return insertAtInsertionPoint(new Or(expr1, expr2, makeName("or_")));
333}
334
335PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
336    assert (expr1 && expr2);
337    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
338        return renameNonNamedNode(expr2, std::move(prefix));
339    }
340    else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
341        return renameNonNamedNode(expr1, std::move(prefix));
342    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
343        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
344        return createNot(createAnd(not1->getOperand(0), createNot(expr2)), prefix);
345    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
346        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
347        return createNot(createAnd(not2->getOperand(0), createNot(expr1)), prefix);
348    } else if (And * and1 = isBinary<And>(expr1)) {
349        if (And * and2 = isBinary<And>(expr2)) {
350            PabloAST * const expr1a = and1->getOperand(0);
351            PabloAST * const expr1b = and1->getOperand(1);
352            PabloAST * const expr2a = and2->getOperand(0);
353            PabloAST * const expr2b = and2->getOperand(1);
354            //These optimizations factor out common components that can occur when sets are formed by union
355            //(e.g., union of [a-z] and [A-Z].
356            if (equals(expr1a, expr2a)) {
357                return createAnd(expr1a, createOr(expr1b, expr2b), prefix);
358            } else if (equals(expr1b, expr2b)) {
359                return createAnd(expr1b, createOr(expr1a, expr2a), prefix);
360            } else if (equals(expr1a, expr2b)) {
361                return createAnd(expr1a, createOr(expr1b, expr2a), prefix);
362            } else if (equals(expr1b, expr2a)) {
363                return createAnd(expr1b, createOr(expr1a, expr2b), prefix);
364            }
365        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
366            // (a∧b) √ a = a
367            return expr2;
368        }
369    } else if (And * and2 = isBinary<And>(expr2)) {
370        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
371            return expr1;
372        }
373    }
374    return insertAtInsertionPoint(new Or(expr1, expr2, makeName(prefix, false)));
375}
376
377Or * PabloBlock::createOr(const unsigned reserved) {
378    return insertAtInsertionPoint(new Or(reserved, makeName("or_")));
379}
380
381Or * PabloBlock::createOr(const unsigned reserved, const std::string prefix) {
382    return insertAtInsertionPoint(new Or(reserved, makeName(prefix, false)));
383}
384
385PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
386    assert (expr1 && expr2);
387    if (expr1 == expr2) {
388        return PabloBlock::createZeroes();
389    }
390    if (isa<Ones>(expr1)) {
391        return createNot(expr2);
392    } else if (isa<Zeroes>(expr1)){
393        return expr2;
394    } else if (isa<Ones>(expr2)) {
395        return createNot(expr1);
396    } else if (isa<Zeroes>(expr2)){
397        return expr1;
398    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
399        if (Not * not2 = dyn_cast<Not>(expr2)) {
400            return createXor(not1->getOperand(0), not2->getOperand(0));
401        }
402    }
403    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName("xor_")));
404}
405
406PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
407    assert (expr1 && expr2);
408    if (expr1 == expr2) {
409        return PabloBlock::createZeroes();
410    }
411    if (isa<Ones>(expr1)) {
412        return createNot(expr2, prefix);
413    } else if (isa<Zeroes>(expr1)){
414        return expr2;
415    } else if (isa<Ones>(expr2)) {
416        return createNot(expr1, prefix);
417    } else if (isa<Zeroes>(expr2)){
418        return expr1;
419    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
420        if (Not * not2 = dyn_cast<Not>(expr2)) {
421            return createXor(not1->getOperand(0), not2->getOperand(0), prefix);
422        }
423    }
424    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName(prefix, false)));
425}
426
427Xor * PabloBlock::createXor(const unsigned reserved) {
428    return insertAtInsertionPoint(new Xor(reserved, makeName("xor_")));
429}
430
431Xor * PabloBlock::createXor(const unsigned reserved, const std::string prefix) {
432    return insertAtInsertionPoint(new Xor(reserved, makeName(prefix, false)));
433}
434
435/// TERNARY CREATE FUNCTION
436
437PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
438    assert (condition && trueExpr && falseExpr);
439    if (isa<Ones>(condition)) {
440        return trueExpr;
441    } else if (isa<Zeroes>(condition)){
442        return falseExpr;
443    } else if (isa<Ones>(trueExpr)) {
444        return createOr(condition, falseExpr);
445    } else if (isa<Zeroes>(trueExpr)){
446        return createAnd(createNot(condition), falseExpr);
447    } else if (isa<Ones>(falseExpr)) {
448        return createOr(createNot(condition), trueExpr);
449    } else if (isa<Zeroes>(falseExpr)){
450        return createAnd(condition, trueExpr);
451    } else if (equals(trueExpr, falseExpr)) {
452        return trueExpr;
453    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
454        return createXor(condition, falseExpr);
455    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
456        return createXor(condition, trueExpr);
457    }
458    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName("sel")));
459}
460
461PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const std::string prefix) {
462    assert (condition && trueExpr && falseExpr);
463    if (isa<Zeroes>(condition)){
464        return renameNonNamedNode(falseExpr, std::move(prefix));
465    }
466    else if (isa<Ones>(condition) || equals(trueExpr, falseExpr)) {
467        return renameNonNamedNode(trueExpr, std::move(prefix));
468    }
469    else if (isa<Ones>(trueExpr)) {
470        return createOr(condition, falseExpr, prefix);
471    }
472    else if (isa<Zeroes>(trueExpr)){
473        return createAnd(createNot(condition), falseExpr, prefix);
474    }
475    else if (isa<Ones>(falseExpr)) {
476        return createOr(createNot(condition), trueExpr, prefix);
477    }
478    else if (isa<Zeroes>(falseExpr)){
479        return createAnd(condition, trueExpr, prefix);
480    }
481    else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
482        return createXor(condition, falseExpr, prefix);
483    }
484    else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
485        return createXor(condition, trueExpr, prefix);
486    }
487    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName(prefix, false)));
488}
489
490If * PabloBlock::createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock * body) {
491    assert (condition);
492    return insertAtInsertionPoint(new If(condition, definedVars, body));
493}
494
495If * PabloBlock::createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock * body) {
496    assert (condition);
497    return insertAtInsertionPoint(new If(condition, definedVars, body));
498}
499
500If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock * body) {
501    assert (condition);
502    return insertAtInsertionPoint(new If(condition, definedVars, body));
503}
504
505While * PabloBlock::createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock * body) {
506    assert (condition);
507    return insertAtInsertionPoint(new While(condition, nextVars, body));
508}
509
510While * PabloBlock::createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock * body) {
511    assert (condition);
512    return insertAtInsertionPoint(new While(condition, nextVars, body));
513}
514
515While * PabloBlock::createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock * body) {
516    assert (condition);
517    return insertAtInsertionPoint(new While(condition, nextVars, body));
518}
519
520/** ------------------------------------------------------------------------------------------------------------- *
521 * @brief eraseFromParent
522 ** ------------------------------------------------------------------------------------------------------------- */
523void PabloBlock::eraseFromParent(const bool recursively) {
524    Statement * stmt = front();
525    // Note: by erasing the scope block, any Assign/Next nodes will be replaced with Zero and removed from
526    // the If/While node
527    while (stmt) {
528        stmt = stmt->eraseFromParent(recursively);
529    }
530    mAllocator.deallocate(reinterpret_cast<Allocator::pointer>(this));
531}
532
533
534// Assign sequential scope indexes, returning the next unassigned index   
535
536unsigned PabloBlock::enumerateScopes(unsigned baseScopeIndex) {
537    mScopeIndex = baseScopeIndex;
538    unsigned nextScopeIndex = baseScopeIndex + 1;
539    for (Statement * stmt : *this) {
540        if (If * ifStatement = dyn_cast<If>(stmt)) {
541            nextScopeIndex = ifStatement->getBody()->enumerateScopes(nextScopeIndex);
542        }
543        else if (While * whileStatement = dyn_cast<While>(stmt)) {
544            nextScopeIndex = whileStatement->getBody()->enumerateScopes(nextScopeIndex);
545        }
546    }
547    return nextScopeIndex;
548}   
549   
550/// CONSTRUCTOR
551
552PabloBlock::PabloBlock(SymbolGenerator * symbolGenerator) noexcept
553: PabloAST(PabloAST::ClassTypeId::Block)
554, mSymbolGenerator(symbolGenerator)
555, mParent(nullptr)
556, mBranch(nullptr)
557, mScopeIndex(0)
558{
559
560}
561
562PabloBlock::~PabloBlock() {
563
564}
565
566}
Note: See TracBrowser for help on using the repository browser.