Changeset 3267 for proto/pabloj/trunk


Ignore:
Timestamp:
Jun 5, 2013, 12:45:31 AM (6 years ago)
Author:
shermer
Message:

Hypothetical completion of semantic analyzer.
Semantic analyzer not yet plugged in to application; needs testing.

Location:
proto/pabloj/trunk/src/toolchain/pabloS
Files:
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • proto/pabloj/trunk/src/toolchain/pabloS/ast/Accessors.java

    r3259 r3267  
    9393        // LocalVarDeclNode
    9494        ////////////////////////////////////////////////////////////////////////////
    95         public static ASTNode type(LocalVarDeclNode node) {
    96                 return node.child(0);
    97         }       
    98        
     95        public static ASTNode typeNode(LocalVarDeclNode node) {
     96                return node.child(0);
     97        }       
     98
    9999        public static IdentifierNode identifier(LocalVarDeclNode node) {
    100100                ASTNode child = node.child(1);
     
    193193        ////////////////////////////////////////////////////////////////////////////
    194194       
    195         //TS: what is node.child(0) ?
     195        public static ASTNode typeNode(FuncDefNode node) {
     196                return node.child(0);
     197        }
     198        public static Type type(FuncDefNode node) {
     199                return typeNode(node).getType();
     200        }
    196201        public static IdentifierNode funcIdentifier(FuncDefNode node) {
    197202                return (IdentifierNode) node.child(1);
     
    199204        public static String funcName(FuncDefNode node) {
    200205                return lexeme(funcIdentifier(node));
    201         }       
     206        }
     207        public static int numParameters(FuncDefNode node) {
     208                if(hasParameters(node)) {
     209                        return parameterListNode(node).nChildren();
     210                }
     211                else {
     212                        return 0;
     213                }
     214        }
    202215        public static boolean hasParameters(FuncDefNode node) {
    203                 ASTNode child2 = node.child(2);
    204                
    205                 if ((node.nChildren()) > 2 && (child2 instanceof ParameterListNode)) {
    206                         return true;
    207                 }
    208                 return false;
     216                return (node.nChildren()) > 2 && (node.child(2) instanceof ParameterListNode);
    209217        }
    210218        public static ParameterListNode parameterListNode(FuncDefNode node) {   
     
    215223                return null;
    216224        }
     225        public static ParameterNode parameter(FuncDefNode node, int i) {
     226                ASTNode list = parameterListNode(node);
     227                return (ParameterNode)list.child(i);
     228        }
    217229        public static BlockStmtNode body(FuncDefNode node) {
    218230                return blockStmtNode(node);
     
    221233                int blockStmtNodeIndex;
    222234               
    223                 if(Accessors.hasParameters(node)) {
     235                if(hasParameters(node)) {
    224236                        blockStmtNodeIndex = 3;
    225237                } else {
     
    231243        return (BlockStmtNode) child;
    232244        }
    233        
     245
     246        ////////////////////////////////////////////////////////////////////////////
     247        // ParameterNode
     248        ////////////////////////////////////////////////////////////////////////////
     249        public static ASTNode typeNode(ParameterNode node) {
     250                return node.child(0);
     251        }
     252        public static Type declarationType(ParameterNode node) {
     253                ASTNode typeNode = typeNode(node);
     254                return typeNode.getType();
     255        }
     256        public static IdentifierNode variableNode(ParameterNode node) {
     257                return (IdentifierNode)(node.child(1));
     258        }
     259        public static String variableName(ParameterNode node) {
     260                return lexeme(variableNode(node));
     261        }
     262
     263        ////////////////////////////////////////////////////////////////////////////
     264        // StructMemberNode
     265        ////////////////////////////////////////////////////////////////////////////
     266        public static ASTNode typeNode(StructMemberNode node) {
     267                return node.child(0);
     268        }
     269        public static Type declarationType(StructMemberNode node) {
     270                ASTNode typeNode = typeNode(node);
     271                return typeNode.getType();
     272        }
     273        public static IdentifierNode variableNode(StructMemberNode node) {
     274                return (IdentifierNode)(node.child(1));
     275        }
     276        public static String variableName(StructMemberNode node) {
     277                return lexeme(variableNode(node));
     278        }
    234279
    235280        ////////////////////////////////////////////////////////////////////////////
     
    314359        // StructTypeNode
    315360        ////////////////////////////////////////////////////////////////////////////
     361
     362        public static IdentifierNode nameNode(StructTypeNode node) {
     363                return (IdentifierNode)(node.child(0));
     364        }
    316365        public static String structName(StructTypeNode node) {
    317         String name = new String();
    318         name = Accessors.name(node.child(0));
    319         return name;
    320         }
    321        
    322         public static String structTypeLexeme(StructTypeNode node) {           
    323                 return node.getToken().getLexeme();
    324         }               
     366                return lexeme(nameNode(node));
     367        }
    325368       
    326369        ////////////////////////////////////////////////////////////////////////////
     
    418461                return result;
    419462        }
    420 
    421463}
  • proto/pabloj/trunk/src/toolchain/pabloS/lang/type/StructureType.java

    r3260 r3267  
    33import toolchain.pabloS.semanticAnalyzer.SymbolTable;
    44
    5 public class StreamStructure implements CompoundType {
     5public class StructureType implements CompoundType {
     6        public static StructureType make(SymbolTable symbolTable) {
     7                return new StructureType(symbolTable);
     8        }
     9
    610        private SymbolTable symbolTable;
    711       
    8        
    9         public StreamStructure(SymbolTable symbolTable) {
     12        private StructureType(SymbolTable symbolTable) {
    1013                super();
    1114                this.symbolTable = symbolTable;
  • proto/pabloj/trunk/src/toolchain/pabloS/semanticAnalyzer/SemanticAnalyzer.java

    r3259 r3267  
    99import toolchain.pabloS.ast.Accessors;
    1010import toolchain.pabloS.lang.PabloSBuiltinTypeBuilder;
    11 import toolchain.pabloS.lang.signatures.FunctionSignature;
    12 import toolchain.pabloS.lang.signatures.FunctionSignatures;
    13 import toolchain.pabloS.lang.signatures.OperatorSignatures;
    14 import toolchain.pabloS.lang.type.CompoundType;
    15 import toolchain.pabloS.lang.type.FunctionType;
    16 import toolchain.pabloS.lang.type.PrimitiveType;
    17 import toolchain.pabloS.lang.type.StreamType;
    18 import toolchain.pabloS.lang.type.Type;
     11import toolchain.pabloS.lang.signatures.*;
     12import toolchain.pabloS.lang.type.*;
    1913
    2014public class SemanticAnalyzer {
     
    3630                }
    3731                @Override
    38                 public void visitLeave(ProgramNode node) {
    39                         // TODO Auto-generated method stub     
    40                 }
     32                public void visitLeave(ProgramNode node) {}
    4133               
    4234                //
     
    4941                @Override
    5042                public void visitLeave(StructDeclNode node) {
    51                         // TODO Auto-generated method stub     
     43                        Binding binding = bindingForStructDefinition(node);
     44                        installOnEnclosingSymbolTable(node, binding);
    5245                }               
    53                 @Override
    54                 public void visitLeave(StructDeclBodyNode node) {
    55                         // TODO Auto-generated method stub     
    56                 }
     46                private Binding bindingForStructDefinition(StructDeclNode node) {
     47                        SymbolTable symbolTable = node.getSymbolTable();
     48                        Type structType = StructureType.make(symbolTable);
     49                        return Binding.make(Accessors.structName(node), structType);
     50                }
     51
     52                @Override
     53                public void visitLeave(StructDeclBodyNode node) {}
    5754                @Override
    5855                public void visitLeave(StructMemberNode node) {
    59                         // TODO Auto-generated method stub     
     56                        Type declarationType = Accessors.declarationType(node);
     57                        String variableName = Accessors.variableName(node);
     58                       
     59                        Binding binding = Binding.make(variableName, declarationType);
     60                        installOnEnclosingSymbolTable(node, binding);
     61                       
     62                        node.setType(declarationType);
    6063                }
    6164               
     
    6972                @Override
    7073                public void visitLeave(FuncDefNode node) {
    71                         // TODO Auto-generated method stub
    72                 }
    73                 @Override
    74                 public void visitLeave(ParameterListNode node) {
    75                         // TODO Auto-generated method stub
    76                 }
     74                        Binding binding = bindingForFunctionDefinition(node);
     75                        installOnEnclosingSymbolTable(node, binding);
     76                }
     77                private Binding bindingForFunctionDefinition(FuncDefNode node) {
     78                        Type[] types = typeArrayForSignature(node);
     79                        FunctionSignature signature = new FunctionSignature(null, types);
     80                        Type functionType = FunctionType.make(signature);
     81                       
     82                        return Binding.make(Accessors.funcName(node), functionType );
     83                }
     84                private Type[] typeArrayForSignature(FuncDefNode node) {
     85                        int numTypes = Accessors.numParameters(node) + 1;
     86                        Type[] types = new Type[numTypes];
     87                       
     88                        if(Accessors.hasParameters(node)) {
     89                                for(int i=0; i<numTypes-1; i++) {
     90                                        ParameterNode param = Accessors.parameter(node, i);
     91                                        types[i] = param.getType();
     92                                }
     93                        }
     94                        Type returnType = Accessors.type(node);
     95                        types[numTypes-1] = returnType;
     96                       
     97                        return types;
     98                }
     99
     100                @Override
     101                public void visitLeave(ParameterListNode node) {}
    77102                @Override
    78103                public void visitLeave(ParameterNode node) {
    79                         // TODO Auto-generated method stub
    80                 }
     104                        Type declarationType = Accessors.declarationType(node);
     105                        String variableName = Accessors.variableName(node);
     106                       
     107                        Binding binding = Binding.make(variableName, declarationType);
     108                        installOnEnclosingSymbolTable(node, binding);
     109                       
     110                        node.setType(declarationType);
     111                }
     112
    81113               
    82114                //
     
    85117                @Override
    86118                public void visitLeave(BlockStmtNode node) {
    87                         // TODO Check that each child that is an expression
    88                         //      is a function call.
    89                 }
    90                
     119                        for(ASTNode child: node.getChildren()) {
     120                                if(isAnExpression(child) && !(child instanceof FuncCallNode)) {
     121                                        expressionStatementError(child);
     122                                }
     123                        }
     124                }
     125                // this mechanism is fragile w.r.t. additional expression types.
     126                private boolean isAnExpression(ASTNode node) {
     127                        return (node instanceof BinaryOperatorNode) ||
     128                                   (node instanceof UnaryOperatorNode)  ||
     129                                   (node instanceof FuncCallNode)       ||
     130                                   (node instanceof IdentifierNode)     ||
     131                                   (node instanceof CompoundIdentifierNode)  ||
     132                                   (node instanceof IntegerConstantNode) ||
     133                                   (node instanceof StringConstantNode);
     134                }
     135
    91136                //
    92137                // s t a t e m e n t s
     
    94139                @Override
    95140                public void visitLeave(LocalVarDeclNode node) {
    96                         // TODO Check initialization type vs. declared type;
    97                         //      then enter into symbol table
    98                 }
     141                        ASTNode typeNode = Accessors.typeNode(node);
     142                       
     143                        if(Accessors.hasInitializationAssign(node)) {
     144                                ASTNode rhs = Accessors.rhs(node);
     145                                typecheckAssignment(node, typeNode, rhs);
     146                        }
     147                        else {
     148                                node.setType(typeNode.getType());
     149                        }
     150                       
     151                        IdentifierNode identifierNode = Accessors.identifier(node);
     152                        String variableName = Accessors.lexeme(identifierNode);
     153
     154                        Binding binding = Binding.make(variableName, typeNode.getType());
     155                        installOnEnclosingSymbolTable(node, binding);
     156                }
     157
     158                private void installOnEnclosingSymbolTable(ASTNode node, Binding binding) {
     159                        SymbolTable symbolTable = findEnclosingSymbolTable(node);
     160                        String variableName = binding.getName();
     161                       
     162                        if(symbolTable.hasBinding(variableName)) {
     163                                multipleDefinitionError(node, variableName);
     164                        }
     165                        else {
     166                                symbolTable.add(binding);
     167                        }
     168                }
     169                // issues error and returns null instance if no symbol table found.
     170                // does not search on the given node.
     171                private SymbolTable findEnclosingSymbolTable(ASTNode node) {
     172                        ASTNode parent = node.getParent();
     173                        for(ASTNode ancestor: parent.pathToRoot()) {
     174                                if( ancestor instanceof HasSymbolTableNodeType) {
     175                                        return ((HasSymbolTableNodeType)ancestor).getSymbolTable();
     176                                }
     177                        }
     178                        notInFunctionBodyError(node, "declaration");
     179                        return SymbolTable.getNullInstance();
     180                }
     181
     182
     183                private void typecheckAssignment(ASTNode parent, ASTNode lhs, ASTNode rhs) {
     184                        Type variableType = lhs.getType();
     185                        Type assignedType = rhs.getType();
     186                        if(!canBeAssignmentTypes(variableType, assignedType)) {
     187                                operatorTypeCheckError(parent, "ASSIGN", variableType, assignedType);
     188                        }
     189                        parent.setType(variableType);
     190                }
     191                private boolean canBeAssignmentTypes(Type variableType, Type assignedType) {
     192                        return variableType.equals(assignedType);
     193                }
     194
    99195                @Override
    100196                public void visitLeave(AssignNode node) {
    101                         // TODO typecheck left = right
     197                        typecheckAssignment(node, Accessors.lhs(node), Accessors.rhs(node));
    102198                }
    103199                @Override
     
    111207                @Override
    112208                public void visitLeave(ReturnStmtNode node) {
    113                         // TODO Verify child is same type as declared return type of
    114                         //      enclosing stream function declaration
     209                        FuncDefNode function = findEnclosingFunctionNode(node);
     210                        Type functionType = Accessors.type(function);
     211                        Type returnType = (node.nChildren() == 0) ? PrimitiveType.VOID
     212                                                                              : node.child(0).getType();
     213                        if(!canBeAssignmentTypes(functionType, returnType)) {
     214                                returnTypecheckError(node);
     215                        }
     216                       
     217                        node.setType(returnType);
     218                }
     219
     220                // issues error and returns null instance if no function node found.
     221                private FuncDefNode findEnclosingFunctionNode(ASTNode node) {
     222                        for(ASTNode ancestor: node.pathToRoot()) {
     223                                if( ancestor instanceof FuncDefNode) {
     224                                        return (FuncDefNode)ancestor;
     225                                }
     226                        }
     227                        notInFunctionBodyError(node, "return ");
     228                        return null;
    115229                }
    116230
     
    184298                public void visitLeave(FuncCallArgListNode node) {}
    185299               
     300               
    186301            //   
    187302                // i d e n t i f i e r s
     
    266381                }
    267382                private boolean isBeingDefined(IdentifierNode node) {
     383                        return isFunctionBeingDefined(node) || isVariableBeingDefined(node);
     384                }
     385
     386                private boolean isFunctionBeingDefined(IdentifierNode node) {
    268387                        ASTNode parent = node.getParent();
    269388                        return ((parent instanceof FuncDefNode) && node == Accessors.funcIdentifier((FuncDefNode) parent));
    270389                }
    271 
    272             //   
     390                private boolean isVariableBeingDefined(IdentifierNode node) {
     391                        ASTNode parent = node.getParent();
     392                        return ((parent instanceof LocalVarDeclNode) && node == Accessors.identifier((LocalVarDeclNode) parent));
     393                }
     394
     395                //   
    273396                // c o n s t a n t s
    274397                //
     
    300423                @Override
    301424                public void visitLeave(StructTypeNode node) {
    302                         // TODO Auto-generated method stub                     
     425                        IdentifierNode nameNode = Accessors.nameNode(node);
     426                        Binding binding = bindingOrError(node, nameNode);
     427                        Type bindingType = binding.getType();
     428                       
     429                        if(bindingType instanceof StructureType) {
     430                                node.setType(bindingType);
     431                        }
     432                        else {
     433                                notStructureTypeError(node, nameNode);
     434                        }
     435                       
    303436                }
    304437               
     
    309442                @Override
    310443                public void visitLeave(FuncCallOrAssignStmtNode node) {
    311                         // really a functionCallStatement.  Check that expr
    312                         // in statement position is a function call.
    313                         // I don't think this node ever occurs.
     444                        // TS: I don't think this node ever occurs.
     445                        assert(false);
    314446                }
    315447                @Override
     
    325457                // e r r o r s
    326458                //
     459                private void notStructureTypeError(ASTNode node, IdentifierNode nameNode) {
     460                        semanticError(node, Accessors.lexeme(nameNode) + " not declared as struct type.");
     461                }
     462                private void expressionStatementError(ASTNode node) {
     463                        semanticError(node, "expression found where statement or function call expected.");
     464                }
     465                private void returnTypecheckError(ReturnStmtNode node) {
     466                        semanticError(node, "return type not compatible with declared function type.");
     467                }
     468                private void multipleDefinitionError(ASTNode node, String variableName) {
     469                        semanticError(node, "identifier " + variableName + " multiply defined.");
     470                }
     471                private void notInFunctionBodyError(ASTNode node, String item) {
     472                        semanticError(node, item + " outside of function body." );     
     473                }
    327474                private void operatorTypeCheckError(ASTNode node, String operatorName, List<Type> operandTypes) {
     475                        semanticError(node, "operator " + operatorName + " not defined for types " + operandTypes.toString() + ".");   
     476                }                       
     477                private void operatorTypeCheckError(ASTNode node, String operatorName, Type... operandTypes) {
    328478                        semanticError(node, "operator " + operatorName + " not defined for types " + operandTypes.toString() + ".");   
    329479                }       
  • proto/pabloj/trunk/src/toolchain/pabloS/transformer/visitors/InitializeStreamDefaults.java

    r3240 r3267  
    3939                        }
    4040
    41                         ASTNode type                            = Accessors.type(node);
     41                        ASTNode type                            = Accessors.typeNode(node);
    4242                        IdentifierNode identifier       = Accessors.identifier(node);
    4343
Note: See TracChangeset for help on using the changeset viewer.