source: proto/s2k/trunk/framework/src/toolchain/s2k/transformer/visitors/S2K2S2K/CombineScopes.java @ 3775

Last change on this file since 3775 was 3775, checked in by ksherdy, 4 years ago

Fixed bug in S2K2B2K transformer.

File size: 8.6 KB
Line 
1/*
2 * Creates a single function-level scope.
3 *
4 * (1) Substitutes mangled name for each non-mangled name.
5 * (2) Splits variable declarations with initializations.
6 * (3) Moves block-level variable declarations to the function-level scope.
7 *     
8 * TODO - KH: Move to s2k2b2k on implementation of b2k SemanticAnalysis
9 *
10 * @author Ken Herdy <ksherdy at sfu dot ca>
11 */
12
13package toolchain.s2k.transformer.visitors.S2K2S2K;
14
15import static toolchain.util.MapUtil.addValueToList;
16
17import java.util.*;
18import java.util.Map.Entry;
19
20import s2k.ast.*;
21import s2k.inputHandler.Locator;
22import s2k.logging.ScatterLogger;
23import toolchain.s2k.ast.*;
24import toolchain.s2k.lang.type.*;
25import toolchain.s2k.semanticAnalyzer.*;
26import toolchain.util.Labeller;
27
28public class CombineScopes {
29       
30        static public ASTNode apply(ASTNode ASTree) {
31           
32            ASTNode xASTree = SplitVarDeclInits.apply(ASTree);
33           
34            InstallVarDeclBindingsVisitor installer = new InstallVarDeclBindingsVisitor();
35            xASTree.accept(installer);
36           
37            SubstituteMangledNamesVisitor mangler = new SubstituteMangledNamesVisitor();
38            xASTree.accept(mangler);
39
40            CombineVarDeclsVisitor combiner = new CombineVarDeclsVisitor();
41            xASTree.accept(combiner);
42           
43                return xASTree;                         
44        }   
45
46    static private class InstallVarDeclBindingsVisitor extends VoidVisitor.Default {
47
48        private Labeller labeller;
49       
50        public void visitEnter(FilterDefNode node) {
51            node.setSymbolTable(new SymbolTable());
52            labeller = new Labeller("_v");
53        }
54
55        public void visitEnter(ProgramNode node) {
56            node.setSymbolTable(new SymbolTable());
57        }
58       
59        public void visitEnter(StructDeclNode node) {
60            node.setSymbolTable(new SymbolTable());
61        }
62       
63        public void visitEnter(BlockStmtNode node) {
64            node.setSymbolTable(new SymbolTable());
65        }
66       
67        public void visitLeave(VarDeclNode node) {
68             
69            SymbolTable symbolTable = findEnclosingSymbolTable(node);
70           
71            String varName = Accessors.name(node);
72           
73            if(symbolTable.hasBinding(varName)) {
74                multipleDefinitionError(node, varName);
75            } 
76
77            Binding binding = Binding.make(varName, node.getType() );
78            String mangledName = varName + labeller.newLabel();
79            binding.setMangledName(mangledName);
80            symbolTable.add(binding);
81
82        }
83       
84        public void visitLeave(StreamTypeNode node) {
85            Type type = StreamType.STREAM(node.getFieldWidth());
86            node.setType(type);
87        }
88       
89        private SymbolTable findEnclosingSymbolTable(ASTNode node) {
90            ASTNode parent = node.getParent();
91            while(parent != ASTNode.NO_PARENT) {
92                if( parent instanceof HasSymbolTableNodeType) {
93                    return ((HasSymbolTableNodeType)parent).getSymbolTable();
94                }
95                parent = parent.getParent();
96            }
97            assert false : "Symbol table not found.";
98            return SymbolTable.getNullInstance();
99        }
100       
101        private void multipleDefinitionError(ASTNode node, String variableName) {
102            combineScopes(node, "identifier " + variableName + " multiply defined.");
103        }
104       
105        private void combineScopes(Locator locator, String errorDescription) {
106            ScatterLogger log = ScatterLogger.getLogger("s2k.CombineScopes");
107            String message = "" + locator.getLocation() + ": " + "semantic error--" + errorDescription;
108            log.severe(message);
109        }
110    }   
111       
112
113    static private class SubstituteMangledNamesVisitor extends VoidVisitor.Default {
114
115        public void visitLeave(CompoundIdentifierNode node) {
116            node.skipChildren();
117        }
118       
119        public void visitLeave(IdentifierNode node) {
120            // KH: logic, if hasMangledName, substitute mangled name for normal name
121            if(node.getParent() instanceof FilterDefNode) {
122                // no action
123            } else if (node.getParent() instanceof FilterParameterNode) {
124                // no action
125            } else if (node.getParent() instanceof StructTypeNode) {
126                // no action
127            } else if (node.getParent() instanceof StructDeclNode) {
128                // no action
129            } else if (node.getParent() instanceof StructMemberNode) {
130                // no action
131            } else if (node.getParent() instanceof CompoundIdentifierNode) {
132                // no action
133            } else if (node.getParent() instanceof FuncCallNode) {
134                // no action
135            } else if (Accessors.name(node).startsWith("carry_set")) {  // TODO - KH: remove on move of Semantic Analysis to b2k
136                // no action
137            } else if (Accessors.name(node).equals("EOF_mask")) {       // TODO - KH: remove on move of Semantic Analysis to b2k
138                // no action
139            } else {
140             
141                Binding binding = bindingOrError(node,node);
142                Locator locator = node;
143                IdentifierNode replacement = Generators.makeIdentifierNode(locator, binding.getMangledName());
144                node.updateSelf(replacement);
145
146            }
147        }
148       
149        private Binding bindingOrError(ASTNode startNode, ASTNode nameNode) {
150            String name = Accessors.lexeme(nameNode);   
151            for(ASTNode ancestor: startNode.pathToRoot()) {
152                if(ancestor instanceof HasSymbolTableNodeType) {
153                    SymbolTable symbolTable = ((HasSymbolTableNodeType) ancestor).getSymbolTable();
154                    if(symbolTable.hasBinding(name)) {
155                        return symbolTable.bindingFor(name);
156                    }
157                }
158            }
159            combineScopes(startNode, "undefined identifier: " + name);
160            return Binding.getNullInstance();
161        }
162       
163        private void combineScopes(Locator locator, String errorDescription) {
164            ScatterLogger log = ScatterLogger.getLogger("s2k.CombineScopes");
165            String message = "" + locator.getLocation() + ": " + "semantic error--" + errorDescription;
166            log.severe(message);
167        }
168    }
169   
170    static private class CombineVarDeclsVisitor extends VoidVisitor.Default {
171
172        private final ASTNode NO_ENCLOSING_BLOCK_STMT = null;
173       
174        List<ASTNode> varDecls;
175        Map<ASTNode, List<ASTNode>> varDeclsForDeletion;
176       
177       
178        public void visitEnter(FilterDefNode node) {
179            varDecls = new ArrayList<ASTNode>();
180            varDeclsForDeletion = new LinkedHashMap<ASTNode, List<ASTNode>>();   
181        }
182               
183        public void visitLeave(FilterDefNode node) {
184
185            Collections.reverse(varDecls);
186            for(ASTNode varDecl : varDecls) {
187                Accessors.blockStmtNode(node).insertChild(0, varDecl);
188            }
189            varDecls.clear();         
190           
191            for (Entry<ASTNode, List<ASTNode>> entry : varDeclsForDeletion.entrySet()) {
192                ASTNode varDeclParent = entry.getKey();
193                for(ASTNode varDecl : entry.getValue()) {
194                  varDeclParent.removeChild(varDecl);
195                }
196            }
197            varDeclsForDeletion.clear();
198        }
199   
200        public void visitEnter(VarDeclNode node) {
201            BlockStmtNode blockStmt          = getEnclosingBlockStmt(node);
202            addValueToList(varDeclsForDeletion, blockStmt, node);
203            varDecls.add(node.deepCopy());
204        }   
205   
206        //////////////////////////////////////////////////////////////
207        // helpers
208        private BlockStmtNode getEnclosingBlockStmt(ASTNode node) {
209            BlockStmtNode enclosingBlockStmt = (BlockStmtNode) getEnclosingNodeOfType(node, BlockStmtNode.class);
210            assert enclosingBlockStmt != NO_ENCLOSING_BLOCK_STMT : "getEnclosingBlockStmt(node) has no ancestor of type 'BlockStmtNode'";
211            return enclosingBlockStmt;
212        }
213       
214        private ASTNode getEnclosingNodeOfType(ASTNode node, Class<?> clazz) {
215            ASTNode current = node.getParent();
216            while(current != NO_ENCLOSING_BLOCK_STMT) {
217                if(current.getClass().isAssignableFrom(clazz)) {
218                    return current;
219                }
220                current = current.getParent();
221            }
222
223            return NO_ENCLOSING_BLOCK_STMT; 
224        }
225
226    }
227   
228}
Note: See TracBrowser for help on using the repository browser.