source: proto/pabloj/trunk/src/toolchain/s2k/ast/Accessors.java @ 3706

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

Added odds n ends.

File size: 16.2 KB
Line 
1/*
2 * S2K AST accessor methods.
3 *
4 * @author <ksherdy at sfu dot ca>
5 *
6 */
7package toolchain.s2k.ast;
8
9import s2k.ast.*;
10import toolchain.s2k.lang.type.Type;
11
12import java.util.ArrayList;
13import java.util.List;
14
15public class Accessors {
16
17        ////////////////////////////////////////////////////////////////////////////
18        // Program
19        ////////////////////////////////////////////////////////////////////////////
20        public static List<StructDeclNode> structDeclNodes(ProgramNode node) {
21               
22                List<StructDeclNode> structTypeDecls = new ArrayList<StructDeclNode>();
23               
24                for(ASTNode child: node.getChildren()) {
25                        if(child instanceof StructDeclNode) {
26                                structTypeDecls.add((StructDeclNode)child);
27                        }
28                }
29               
30                return structTypeDecls;
31        }
32
33        public static List<FuncDefNode> funcDefs(ProgramNode node) {
34               
35                assert node instanceof ProgramNode;
36                List<FuncDefNode> funcDefs = new ArrayList<FuncDefNode>();
37               
38                for(ASTNode child: node.getChildren()) {
39                        if (child instanceof FuncDefNode) {
40                                funcDefs.add((FuncDefNode)child);
41                        }
42                }
43                return funcDefs;
44        }
45       
46        public static List<String> funcDefNames(ProgramNode node) {
47
48            assert node instanceof ProgramNode;
49           
50            List<String> names = new ArrayList<String>();
51           
52            for(FuncDefNode funcDef : funcDefs(node)) {
53                names.add(name(funcDef));
54            }
55            return names;
56        }
57       
58    public static FuncDefNode funcDefForName(ASTNode node, String name) {
59
60        if(node instanceof FuncDefNode) {
61            if(name(node).equals(name)) {
62                return (FuncDefNode)node;
63            }
64        }
65
66        FuncDefNode result = null;
67
68        for(ASTNode child : node.getChildren()) {
69            result = funcDefForName(child, name);
70            if (result != null) {
71                return result;
72            }
73        }
74       
75        return null; 
76    }
77               
78        public static boolean isTerminal(ASTNode node) {
79                return 0 == node.nChildren();
80        }
81
82        public static boolean isAssignmentRhs(ASTNode node) {
83                return isAssignNodeRhs(node) || isVarDeclNodeRhs(node);
84        }
85       
86        ////////////////////////////////////////////////////////////////////////////
87        // AssignNode
88        ////////////////////////////////////////////////////////////////////////////
89        public static ASTNode lhs(AssignNode node) {
90                return node.child(0);
91        }       
92       
93        public static ASTNode rhs(AssignNode node) {
94                return node.child(1);
95        }       
96
97        public static String assignOperatorLexeme(AssignNode node) {
98                return node.getToken().getLexeme();
99        }
100       
101        public static boolean isAssignNodeRhs(ASTNode node) {
102                ASTNode parent = node.getParent();
103                if ((parent instanceof AssignNode)) {
104                        if (Accessors.rhs((AssignNode)parent) == node) {
105                                return true;
106                        }
107                }
108                return false;
109        }
110       
111        ////////////////////////////////////////////////////////////////////////////
112        // VarDeclNode
113        ////////////////////////////////////////////////////////////////////////////
114        public static ASTNode typeNode(VarDeclNode node) {
115                return node.child(0);
116        }       
117
118        public static IdentifierNode identifier(VarDeclNode node) {
119                ASTNode child = node.child(1);
120                assert child instanceof IdentifierNode;
121                return (IdentifierNode)node.child(1);
122        }       
123       
124    public static boolean hasInitializationExpr(VarDeclNode node) {
125        if(3 == node.nChildren()) {
126            return true;
127        }
128        return false;
129    }           
130       
131        public static ASTNode rhs(VarDeclNode node) {
132                return node.child(2);
133        }               
134
135        public static boolean isVarDeclNodeRhs(ASTNode node) {
136                ASTNode parent = node.getParent();
137                if ((parent instanceof VarDeclNode)) {
138                        if (Accessors.rhs((VarDeclNode)parent) == node) {
139                                return true;
140                        }
141                }
142                return false;
143        }
144       
145        public static String assignOperatorLexeme(VarDeclNode node) {
146                return node.getToken().getLexeme();
147        }       
148
149        public static ASTNode nameNode(VarDeclNode node) {
150            return node.child(1);
151        }
152       
153        ////////////////////////////////////////////////////////////////////////////
154        // UnaryOperatorNode
155        ////////////////////////////////////////////////////////////////////////////
156        public static ASTNode operand(UnaryOperatorNode node) {
157                return node.child(0);
158        }
159
160        public static String operatorLexeme(UnaryOperatorNode node) {
161                return node.getToken().getLexeme();
162        }
163
164        ////////////////////////////////////////////////////////////////////////////
165        // BinaryOperatorNode
166        ////////////////////////////////////////////////////////////////////////////
167        public static ASTNode lhs(BinaryOperatorNode node) {
168                return node.child(0);
169        }               
170
171        public static ASTNode rhs(BinaryOperatorNode node) {
172                return node.child(1);
173        }
174       
175        public static String operatorLexeme(BinaryOperatorNode node) {
176                return node.getToken().getLexeme();
177        }               
178
179        ////////////////////////////////////////////////////////////////////////////
180        // IfStmtNode
181        ////////////////////////////////////////////////////////////////////////////
182        public static ASTNode condition(IfStmtNode node) {
183                return (ASTNode) node.child(0);
184        }
185
186        public static BlockStmtNode ifBlockStmt(IfStmtNode node) {
187                return (BlockStmtNode) node.child(1);
188        }       
189       
190        public static boolean hasElseBlockStmt(IfStmtNode node) {
191                return hasElseClause(node);
192        }       
193        public static boolean hasElseClause(IfStmtNode node) {
194                return node.nChildren() > 2;
195        }
196       
197        public static BlockStmtNode elseBlockStmt(IfStmtNode node) {
198                return elseClause(node);
199        }       
200        public static BlockStmtNode elseClause(IfStmtNode node) {
201                return (BlockStmtNode) node.child(2);
202        }
203
204        ////////////////////////////////////////////////////////////////////////////
205        // WhileStmtNode
206        ////////////////////////////////////////////////////////////////////////////
207        public static ASTNode condition(WhileStmtNode node) {
208                return node.child(0);
209        }
210
211        public static BlockStmtNode body(WhileStmtNode node) {
212                return (BlockStmtNode) node.child(1);
213        }
214       
215        ////////////////////////////////////////////////////////////////////////////
216        // FuncDefNode
217        ////////////////////////////////////////////////////////////////////////////
218       
219        public static ASTNode typeNode(FuncDefNode node) {
220                return node.child(0);
221        }
222        public static ASTNode nameNode(FuncDefNode node) {
223            return node.child(1);
224        }
225        public static Type type(FuncDefNode node) {
226                return typeNode(node).getType();
227        }
228        public static IdentifierNode funcIdentifier(FuncDefNode node) {
229                return (IdentifierNode) node.child(1);
230        }
231        public static String funcName(FuncDefNode node) {
232                return lexeme(funcIdentifier(node));
233        }
234        public static boolean hasParameters(FuncDefNode node) {
235                return (node.nChildren()) > 2 && (node.child(2) instanceof ParameterListNode);
236        }
237        public static int numParameters(FuncDefNode node) {
238            if(hasParameters(node)) {
239                return parameterListNode(node).nChildren();
240            }
241            else {
242                return 0;
243            }
244        }
245        public static ParameterListNode parameterListNode(FuncDefNode node) {   
246                return (ParameterListNode) node.child(2);
247        }
248        public static ParameterNode parameter(FuncDefNode node, int i) {
249                ASTNode list = parameterListNode(node);
250                return (ParameterNode)list.child(i);
251        }
252        public static BlockStmtNode body(FuncDefNode node) {
253                return blockStmtNode(node);
254        }
255        public static BlockStmtNode blockStmtNode(FuncDefNode node) {
256                int blockStmtNodeIndex;
257               
258                if(hasParameters(node)) {
259                        blockStmtNodeIndex = 3;
260                } else {
261                        blockStmtNodeIndex = 2;
262                }
263               
264                ASTNode child = node.child(blockStmtNodeIndex);
265                assert child instanceof BlockStmtNode;
266        return (BlockStmtNode) child;
267        }
268
269        ////////////////////////////////////////////////////////////////////////////
270        // ParameterNode
271        ////////////////////////////////////////////////////////////////////////////
272        public static ASTNode typeNode(ParameterNode node) {
273                return node.child(0);
274        }
275       
276        public static ASTNode nameNode(ParameterNode node) {
277            return node.child(1);
278        }
279       
280        public static Type declarationType(ParameterNode node) {
281                ASTNode typeNode = typeNode(node);
282                return typeNode.getType();
283        }
284        public static IdentifierNode variableNode(ParameterNode node) {
285                return (IdentifierNode)(node.child(1));
286        }
287
288        ////////////////////////////////////////////////////////////////////////////
289        // StructMemberNode
290        ////////////////////////////////////////////////////////////////////////////
291        public static ASTNode typeNode(StructMemberNode node) {
292                return node.child(0);
293        }
294    public static ASTNode nameNode(StructMemberNode node) {
295        return node.child(1);
296    }
297        public static Type declarationType(StructMemberNode node) {
298                ASTNode typeNode = typeNode(node);
299                return typeNode.getType();
300        }
301       
302        ////////////////////////////////////////////////////////////////////////////
303        // FuncCallNode
304        ////////////////////////////////////////////////////////////////////////////
305       
306        public static ASTNode nameNode(FuncCallNode node) {
307                return node.child(0);
308        }
309        public static ASTNode argsListNode(FuncCallNode node) {
310                return node.child(1);
311        }
312        public static int argCount(FuncCallNode node) {
313                ASTNode argList = Accessors.argsListNode(node);
314                if (argList == null) {
315                        return 0;
316                }
317                return argList.nChildren();
318        }
319       
320        public static ASTNode argument(FuncCallNode node, int index) {
321                if((index + 1) > Accessors.argsListNode(node).getChildren().size()) {
322                        throw new RuntimeException("Function invocation argument out of range.");
323                }
324                return Accessors.argsListNode(node).child(index);
325        }
326       
327        public static List<ASTNode> argsList(FuncCallNode node) {
328                return Accessors.argsListNode(node).getChildren();
329        }
330    public static String funcCallName(ASTNode node) { // special case
331        String name = new String();
332        if(node instanceof IdentifierNode) {
333            name = Accessors.name((IdentifierNode)node);
334        }
335        else if (node instanceof CompoundIdentifierNode) {
336            ASTNode pckage = node.child(0);
337            ASTNode member = node.child(1);
338            name = Accessors.name((IdentifierNode)pckage);
339            name += ".";
340            name += Accessors.name((IdentifierNode)member); 
341        }
342        else {  // TS: added
343                assert false: "Accessors.funcCallName() called on node of improper type.";
344        }
345        return name;
346    }   
347   
348    public static String baseName(CompoundIdentifierNode node) {
349        ASTNode member = node.child(node.nChildren()-1);
350        return Accessors.name(member);
351    }
352
353        public static List<Type> argumentTypes(FuncCallNode node) {
354                return childTypes(argsListNode(node));
355        }
356
357        ////////////////////////////////////////////////////////////////////////////
358        // StructDeclNode
359        ////////////////////////////////////////////////////////////////////////////
360        public static ASTNode nameNode(StructDeclNode node) {
361            return node.child(0);
362        }
363
364        public static StructDeclBodyNode structBody(StructDeclNode node) {
365                ASTNode child = node.child(1);
366                assert child instanceof StructDeclBodyNode;
367        return (StructDeclBodyNode) child;
368        }       
369
370        ////////////////////////////////////////////////////////////////////////////
371        // StructTypeNode
372        ////////////////////////////////////////////////////////////////////////////
373
374        public static ASTNode nameNode(StructTypeNode node) {
375                return node.child(0);
376        }
377       
378        ////////////////////////////////////////////////////////////////////////////
379        // StreamTypeNode
380        //
381        // 2^k stream type
382        ////////////////////////////////////////////////////////////////////////////
383
384        ////////////////////////////////////////////////////////////////////////////
385        // CompoundIdentifierNode
386        ////////////////////////////////////////////////////////////////////////////
387
388        public static String nameBefore(CompoundIdentifierNode compound, ASTNode lastChild) {
389                StringBuilder result = new StringBuilder();
390                List<ASTNode> children = compound.getChildren();
391                for(int i=0;i<children.size(); i++) {
392                        ASTNode child = children.get(i);
393                        if(child==lastChild) {
394                                break;
395                        }
396                        if(i > 0) {
397                                result.append(".");
398                        }
399                        result.append(lexeme(child));
400                }
401                return result.toString();
402        }
403        public static String nameUpTo(CompoundIdentifierNode compound, ASTNode lastChild) {
404                StringBuilder result = new StringBuilder();
405                List<ASTNode> children = compound.getChildren();
406                for(int i=0;i<children.size(); i++) {
407                        ASTNode child = children.get(i);
408                        if(i > 0) {
409                                result.append(".");
410                        }
411                        result.append(lexeme(child));
412                       
413                        if(child==lastChild) {
414                                break;
415                        }
416                }
417                return result.toString();
418        }
419        public static String pckageName(CompoundIdentifierNode compound) {
420            IdentifierNode pckageNode = pckageNode(compound);
421                return name(pckageNode);
422        }
423        public static IdentifierNode pckageNode(CompoundIdentifierNode compound) {
424                return (IdentifierNode)compound.child(0);
425        }
426
427        public static IdentifierNode funcNameNode(CompoundIdentifierNode compound) {
428                return (IdentifierNode)compound.child(1);
429        }
430        public static String name(CompoundIdentifierNode compound) {
431                return nameUpTo(compound, null);
432        }
433       
434        ////////////////////////////////////////////////////////////////////////////
435        // IdentifierNode
436        ////////////////////////////////////////////////////////////////////////////
437        public static String name(IdentifierNode node) {
438            return node.getToken().getLexeme();
439        }
440       
441        ////////////////////////////////////////////////////////////////////////////
442        // any node
443        ////////////////////////////////////////////////////////////////////////////
444        public static String name(ASTNode node) {
445            if(node instanceof IdentifierNode) {
446                return name((IdentifierNode) node);
447            } else if(node instanceof CompoundIdentifierNode) {
448                return name((CompoundIdentifierNode) node);
449            } else if(node instanceof FuncCallNode) {
450                return funcCallName(nameNode((FuncCallNode)node)); // special case
451            } else if(node instanceof FuncDefNode) {
452                return name(nameNode((FuncDefNode)node));
453            } else if(node instanceof StructDeclNode) {
454                return name(nameNode((StructDeclNode)node));
455            } else if(node instanceof StructMemberNode) {
456                return name(nameNode((StructMemberNode)node));
457            } else if(node instanceof StructTypeNode) {
458                return name(nameNode((StructTypeNode)node));
459            }  else if(node instanceof VarDeclNode) {
460                return name(nameNode((VarDeclNode)node));
461            }  else if(node instanceof ParameterNode) {
462                return name(nameNode((ParameterNode)node));
463            } 
464            assert false : "Accessors.name(ASTNode node) method not implemented on node class : " + node.getClass();
465            return null;
466        }
467       
468    ////////////////////////////////////////////////////////////////////////////
469    // helpers
470    ////////////////////////////////////////////////////////////////////////////       
471        public static String lexeme(ASTNode node) {
472                return node.getToken().getLexeme();
473        }                       
474        public static ASTNode headChild(ASTNode node) {
475                return node.child(0);
476        }
477        public static List<ASTNode> tailChildren(ASTNode compound) {
478                List<ASTNode> children = compound.getChildren();
479                return children.subList(1, children.size());
480        }
481        public static List<Type> childTypes(ASTNode node) {
482                List<Type> result = new ArrayList<Type>(node.nChildren());
483                for(ASTNode child: node.getChildren()) {
484                        result.add(child.getType());
485                }
486                return result;
487        }
488       
489        public static final ASTNode NO_ENCLOSING_NODE = null;
490       
491        public static BlockStmtNode getEnclosingBlockStmt(ASTNode node) {
492            BlockStmtNode enclosingBlockStmt = (BlockStmtNode) getEnclosingNodeOfType(node, BlockStmtNode.class);
493            assert enclosingBlockStmt != NO_ENCLOSING_NODE : "getEnclosingBlockStmt(node) has no ancestor of type 'BlockStmtNode'";
494            return enclosingBlockStmt;
495        }
496
497        public static boolean hasEnclosingWhileStmt(ASTNode node) {
498            return hasEnclosingNodeOfType(node, WhileStmtNode.class);
499        }
500       
501        public static boolean hasEnclosingNodeOfType(ASTNode node, Class<?> clazz) {
502            if(getEnclosingNodeOfType(node, clazz) != NO_ENCLOSING_NODE) {
503                return true;
504            } else {
505                return false;
506            }
507        }
508       
509        public static ASTNode getEnclosingNodeOfType(ASTNode node, Class<?> clazz) {
510            ASTNode current = node.getParent();
511            while(current != NO_ENCLOSING_NODE) {
512                if(current.getClass().isAssignableFrom(clazz)) {
513                    return current;
514                }
515                current = current.getParent();
516            }
517
518            return NO_ENCLOSING_NODE; 
519        }       
520}
Note: See TracBrowser for help on using the repository browser.