Changeset 1261


Ignore:
Timestamp:
Aug 3, 2011, 2:17:28 AM (8 years ago)
Author:
shermer
Message:

v0.6.4

wide-ranging changes to more-fully implement structures and their fields:

Symbol tables now are constructed at nodes with scopes.
Symbol tables are used to collect the field information for structs.
StructAnalyzer? now visits struct children in the visitor, and it also checks struct.field expressions for validity.

Parser will now parse "new<struct> instance" statements and construct proper AST for struct.field expressions (called "compoundIdentifier").

Added a rudimentary StructInstanceType? to handle structure instances.

Location:
proto/pebble/trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • proto/pebble/trunk/.project

    r1242 r1261  
    3030                <nature>org.eclipse.jdt.core.javanature</nature>
    3131                <nature>org.deved.antlride.core.nature</nature>
     32                <nature>org.python.pydev.pythonNature</nature>
    3233                <nature>com.javadude.derived.warning.cleaner.derivedWarningCleanerNature</nature>
    33                 <nature>org.python.pydev.pythonNature</nature>
    3434        </natures>
    3535</projectDescription>
  • proto/pebble/trunk/inputs/input-11.pbl

    r1256 r1261  
    11
    22// used for checking local def-use chain construction.
    3 
     3struct Abc {
     4        a, b, c,
     5}
    46macro first {
     7        new<Abc> abc
    58        a = b & c
    69        d = a | b
    710        g = d ^ a
     11       
     12        abc.a = a | b
     13#       none.b = c | d
     14#       abc.notafield = a | c
     15       
    816#       j = ~g
    917#       l = j
     
    1220        g = b +> d
    1321        f = d ^ a
     22        new<Abc> def
    1423        d = m <> b
    1524       
    1625        if v & d | x not allone then {
    17                 x = 0
     26                x = [abc]
     27                y = >[cd]
     28                z = "r[st]u[vw]"
    1829                g = a +> d
    1930                h = x1
     
    2132        else {
    2233                m = 1
     34                y = >>>>[cd]
    2335                f = r <> m
    2436                g = x2
  • proto/pebble/trunk/src/incode/Pythonater.java

    r1248 r1261  
    33import java.io.PrintStream;
    44
    5 import lexicalStream.LexicalCollector;
    65import symbolTable.StructType;
    76import symbolTable.SymbolInfo;
     
    1312        private static final int NUM_BITS_PER_CHAR = 8;
    1413
    15         public static void apply(SymbolTable symbolTable, LexicalCollector headCollector, BasicBlock head) {
    16                 printPythonStructs(headCollector, symbolTable, System.out);
     14        public static void apply(SymbolTable symbolTable, BasicBlock head) {
     15                printPythonStructs(symbolTable, System.out);
    1716                printMainPythonRoutine(head, System.out);
    1817        }
     
    2120        // structs
    2221        ///////////////////////////////////////////////////////////////
    23         private static void printPythonStructs(LexicalCollector headCollector, SymbolTable symtab, PrintStream out) {
     22        private static void printPythonStructs(SymbolTable symtab, PrintStream out) {
    2423//              out.println(Pythonater.buildBasisBitStruct());
    2524                out.println(buildUserStructs(symtab));
    26                 out.println(headCollector.structs());
    2725        }
    2826        @SuppressWarnings("unused")
     
    3937        private static String buildUserStructs(SymbolTable symtab) {
    4038                String result = "";
    41                 for(String symbol: symtab.structNames()) {
    42                         result += buildUserStruct(symtab, symbol);
     39                for(SymbolInfo info: symtab.structInfos()) {
     40                        result += buildUserStruct(info);
    4341                        result += "\n";                                 // extra separating newline
    4442                }
    4543                return result;
    4644        }
    47         private static String buildUserStruct(SymbolTable symtab, String symbol) {
     45        private static String buildUserStruct(SymbolInfo info) {
    4846                PStringBuilder builder = new PStringBuilder(0);
    49                 SymbolInfo info = symtab.get(symbol);
    5047                StructType type = (StructType)(info.getType());
    5148
    52                 builder.appendLine("class %s():", symbol);
     49                builder.appendLine("class %s():", info.getName());
    5350                builder.indent();
    5451                for(SymbolInfo fieldInfo: type) {
    55                         builder.appendLine("%s = 0", fieldInfo.getName());
     52                        builder.appendLine(fieldInfo.fieldString());
    5653                }
    5754                return builder.toString();
    5855        }
    59 
    6056
    6157        ///////////////////////////////////////////////////////////////
     
    6561                out.println("def parabix_parse(u8data):");
    6662                out.println("    (bit, EOF_mask) = bitutil.transpose_streams(u8data)");
    67                 out.println("    lex = Lex()");                         // overkill (and error) if no lex, shift, and/or seq
    68                 out.println("    shift = Shift()");
    69                 out.println("    seq = Seq()");
     63//              out.println("    lex = Lex()");                         // overkill (and error) if no lex, shift, and/or seq
     64//              out.println("    shift = Shift()");
     65//              out.println("    seq = Seq()");
    7066
    7167                String python = head.pythonate(1);
  • proto/pebble/trunk/src/lexicalStream/LexicalCollector.java

    r1249 r1261  
    55
    66import java.util.ArrayList;
    7 import java.util.Collections;
    87import java.util.Comparator;
    98import java.util.HashMap;
     
    1615import parser.SeqElement;
    1716import parser.SequenceTokenData;
    18 
     17import symbolTable.PrimitiveType;
     18import symbolTable.StructType;
     19import symbolTable.SymbolInfo;
     20import symbolTable.SymbolTable;
     21import util.Position;
     22import util.range.Range;
    1923import ast.AST;
    2024import ast.exprNodes.CharClassASTB;
    2125import ast.exprNodes.SequenceASTB;
    2226
    23 import util.PStringBuilder;
    24 import util.Position;
    25 import util.range.Range;
    26 
    2727
    2828
     
    3030        private static final String LEXICAL_CLASS_NAME = "Lex";
    3131        private static final String SHIFTED_CLASS_NAME = "Shift";
    32         private static final Object SEQUENCES_CLASS_NAME = "Seq";
     32        private static final String SEQUENCES_CLASS_NAME = "Seq";
    3333        private static final Position zero = new Position(0);
    3434       
     
    204204       
    205205        ///////////////////////////////////////////////////////////
    206         // structs()
     206        // putStructsInSymbolTable()
    207207        //
    208         // returns a string that consists of the Python class
    209         // (C++ struct) definitions for the data blocks needed
    210         // by the lexical streams in this collector and all its
    211         // descendants.
     208        // make structs to hold all of the lexical streams, and
     209        // place these in the symbol table.  Looks not only at
     210        // this collector's streams, but also at all descendant
     211        // collectors' lexical streams.
    212212        //
    213213        // The current strategy is to place all CC streams into
     
    219219        // At some point this should become an option.
    220220        ///////////////////////////////////////////////////////////
    221         public String structs() {
    222                 PStringBuilder builder = new PStringBuilder(0);
    223                 buildLexicalStruct(builder);
    224                 buildShiftedStruct(builder);
    225                 buildSequencesStruct(builder);
    226                 return builder.toString();
    227         }
    228         private void buildLexicalStruct(PStringBuilder builder) {
     221        public void putStructsInSymbolTable(SymbolTable symbolTable) {
     222                insertLexicalStruct(symbolTable);
     223                insertShiftedStruct(symbolTable);
     224                insertSequencesStruct(symbolTable);
     225        }       
     226        private void insertSequencesStruct(SymbolTable symbolTable) {
     227                Set<SequenceDescriptor> sequences = descendantSQDescriptors();
     228                if(sequences.size()==0) {
     229                        return;
     230                }
     231                List<SequenceDescriptor> uniqueSequences = uniqueSequences(sequences);
     232
     233                String name = SEQUENCES_CLASS_NAME;
     234                SymbolInfo info = symbolTable.add(name);
     235                StructType structType = new StructType(null);
     236                info.setType(structType);
     237               
     238                for(SequenceDescriptor descriptor : uniqueSequences) {
     239                        String fieldName = descriptor.noPrefixVariableName();
     240                        SymbolInfo fieldInfo = new SymbolInfo(fieldName, PrimitiveType.Bitstream);
     241                        fieldInfo.setComment(descriptor.getSpecifier());
     242                        structType.addField(fieldInfo);
     243                }
     244        }
     245        private List<SequenceDescriptor> uniqueSequences(
     246                        Set<SequenceDescriptor> sequences) {
     247                Set<String> specifiers = new HashSet<String>();
     248                List<SequenceDescriptor> uniqueSequences = new ArrayList<SequenceDescriptor>();
     249                for(SequenceDescriptor sequence: sequences) {
     250                        if(!specifiers.contains(sequence.getSpecifier())) {
     251                                specifiers.add(sequence.getSpecifier());
     252                                uniqueSequences.add(sequence);
     253                        }
     254                }
     255//              Collections.sort(uniqueSequences, new sqDescriptorSortByVar());
     256                return uniqueSequences;
     257        }
     258        private void insertLexicalStruct(SymbolTable symbolTable) {
    229259                Set<CharClassDescriptor> unshifted = descendantCCDescriptors();
    230260                if(unshifted.size()==0) {
    231261                        return;
    232262                }
     263               
     264                List<CharClassDescriptor> uniqueCharClasses = uniqueCharClasses(unshifted);
     265
     266                String name = LEXICAL_CLASS_NAME;
     267                SymbolInfo info = symbolTable.add(name);
     268                StructType structType = new StructType(null);
     269                info.setType(structType);
     270               
     271                for(CharClassDescriptor descriptor : uniqueCharClasses) {
     272                        String fieldName = descriptor.noPrefixVariableName();
     273                        SymbolInfo fieldInfo = new SymbolInfo(fieldName, PrimitiveType.Bitstream);
     274                        fieldInfo.setComment(descriptor.getSpecifier());
     275                        structType.addField(fieldInfo);
     276                }
     277        }
     278        private Set<CharClassDescriptor> descendantCCDescriptors() {
     279                Set<CharClassDescriptor> result = ccDescriptors();
     280                for(LexicalCollector child: children) {
     281                        result.addAll(child.descendantCCDescriptors());
     282                }
     283                return result;
     284        }
     285        private List<CharClassDescriptor> uniqueCharClasses(
     286                        Set<CharClassDescriptor> unshifted) {
     287                List<CharClassDescriptor> uniqueCharClasses = new ArrayList<CharClassDescriptor>();
    233288                Set<String> specifiers = new HashSet<String>();
    234                 List<CharClassDescriptor> uniqueCharClasses = new ArrayList<CharClassDescriptor>();
    235289                for(CharClassDescriptor charClass: unshifted) {
    236290                        if(!specifiers.contains(charClass.getSpecifier())) {
     
    239293                        }
    240294                }
    241                 Collections.sort(uniqueCharClasses, new ccDescriptorSortByVar());
    242                 builder.appendLine(String.format("class %s():", LEXICAL_CLASS_NAME));
    243                 builder.indent();
    244                 for(CharClassDescriptor descriptor : uniqueCharClasses) {
    245                         String code = String.format("%s = 0", descriptor.noPrefixVariableName());
    246                         builder.appendLine("%-20s\t# [%s]", code, descriptor.getSpecifier());
    247                 }
    248                 builder.dedent();
    249                 builder.appendLine("");
    250         }
    251         private Set<CharClassDescriptor> descendantCCDescriptors() {
    252                 Set<CharClassDescriptor> result = ccDescriptors();
    253                 for(LexicalCollector child: children) {
    254                         result.addAll(child.descendantCCDescriptors());
    255                 }
    256                 return result;
    257         }
     295
     296//              Collections.sort(uniqueCharClasses, new ccDescriptorSortByVar());
     297                return uniqueCharClasses;
     298        }
     299
     300        private void insertShiftedStruct(SymbolTable symbolTable) {
     301                List<CharClassPositionsPair> filteredPairs = condenseDescendentCCPairs();
     302                if(filteredPairs.size()==0) {
     303                        return;
     304                }
     305
     306//              Collections.sort(filteredPairs, new ccPairSortByVar() );
     307               
     308                String name = SHIFTED_CLASS_NAME;
     309                SymbolInfo info = symbolTable.add(name);
     310                StructType structType = new StructType(null);
     311                info.setType(structType);
     312               
     313                for(CharClassPositionsPair pair : filteredPairs) {
     314                        for(Position p: pair.positions) {
     315                                String fieldName = pair.descriptor.noPrefixVariableName(p);
     316                                SymbolInfo fieldInfo = new SymbolInfo(fieldName, PrimitiveType.Bitstream);
     317                                structType.addField(fieldInfo);
     318                        }
     319                }
     320        }
     321
     322
     323
    258324        private Set<CharClassDescriptor> ccDescriptors() {
    259325                Set<CharClassDescriptor> result = new HashSet<CharClassDescriptor>();
     
    271337                return result;
    272338        }
    273         private void buildShiftedStruct(PStringBuilder builder) {
    274                 List<CharClassPositionsPair> filteredPairs = condenseDescendentCCPairs();
    275                 if(filteredPairs.size()==0) {
    276                         return;
    277                 }
    278 
    279                 Collections.sort(filteredPairs, new ccPairSortByVar() );
    280                 builder.appendLine(String.format("class %s():", SHIFTED_CLASS_NAME));
    281                 builder.indent();
    282                 for(CharClassPositionsPair pair: filteredPairs) {
    283                         for(Position p: pair.positions) {
    284                                 builder.appendLine("%s = 0", pair.descriptor.noPrefixVariableName(p));
    285                         }
    286                 }
    287                 builder.dedent();
    288                 builder.appendLine("");
    289         }
     339
    290340        private List<CharClassPositionsPair> condenseDescendentCCPairs() {
    291341                List<CharClassPositionsPair> descendentPairs = descendentCCPairs();
     
    319369                return result;
    320370        }
    321         private void buildSequencesStruct(PStringBuilder builder) {
    322                 Set<SequenceDescriptor> sequences = descendantSQDescriptors();
    323                 if(sequences.size()==0) {
    324                         return;
    325                 }
    326                 Set<String> specifiers = new HashSet<String>();
    327                 List<SequenceDescriptor> uniqueSequences = new ArrayList<SequenceDescriptor>();
    328                 for(SequenceDescriptor sequence: sequences) {
    329                         if(!specifiers.contains(sequence.getSpecifier())) {
    330                                 specifiers.add(sequence.getSpecifier());
    331                                 uniqueSequences.add(sequence);
    332                         }
    333                 }
    334                 Collections.sort(uniqueSequences, new sqDescriptorSortByVar());
    335                 builder.appendLine(String.format("class %s():", SEQUENCES_CLASS_NAME));
    336                 builder.indent();
    337                 for(SequenceDescriptor descriptor : uniqueSequences) {
    338                         String code = String.format("%s = 0", descriptor.noPrefixVariableName());
    339                         builder.appendLine("%-20s\t# \"%s\"", code, descriptor.getSpecifier());
    340                 }
    341                 builder.dedent();
    342                 builder.appendLine("");
    343         }
     371        @SuppressWarnings("unused")
    344372        private class sqDescriptorSortByVar implements Comparator<SequenceDescriptor> {
    345373                public int compare(SequenceDescriptor d1, SequenceDescriptor d2) {
     
    347375                }
    348376        }
     377        @SuppressWarnings("unused")
    349378        private class ccDescriptorSortByVar implements Comparator<CharClassDescriptor> {
    350379                public int compare(CharClassDescriptor d1, CharClassDescriptor d2) {
     
    352381                }
    353382        }
     383        @SuppressWarnings("unused")
    354384        private class ccPairSortByVar implements Comparator<CharClassPositionsPair> {
    355385                public int compare(CharClassPositionsPair p1, CharClassPositionsPair p2) {
  • proto/pebble/trunk/src/lexicalStream/MoveLexdefsToBranchStarts.java

    r1258 r1261  
    33import java.util.Deque;
    44import java.util.LinkedList;
     5
     6import symbolTable.StructInstanceType;
     7import symbolTable.Type;
    58
    69import ast.AST;
     
    1417                ast.accept(mover);
    1518        }
     19
     20
    1621       
    1722        private static class LexdefMover extends ASTVisitor.Default {
     
    3540                        return descriptor.variableName();
    3641                }
    37                
     42                private void insertInstances(AST node) {
     43                        AST lex = instanceAST("lex", "Lex");
     44                        AST seq = instanceAST("seq", "Seq");
     45                        AST shift = instanceAST("shift", "Shift");
     46                       
     47                        node.insertChild(shift);        // TODO: this is overkill and error if there is no Lex, Seq, or Shift
     48                        node.insertChild(seq);
     49                        node.insertChild(lex);
     50                }
     51                private AST instanceAST(String instanceName, String structName) {
     52                        AST instanceVar = VariableASTB.make(instanceName);
     53                        Type type = new StructInstanceType(structName);
     54                        AST decl = new DeclarationASTN();
     55                        decl.addChild(instanceVar);
     56                        decl.setType(type);
     57                        return decl;
     58                }
    3859                private void insertLexicalStreams(AST node) {
    3960                        LexicalCollector collector = stackOfCollectors.pop();
     
    6788                public void visitLeave(ExecutionBlockASTN node) {
    6889                        insertLexicalStreams(node);
     90                        insertInstances(node);
    6991                }
    7092                public void visitLeave(BlockStatementASTN node) {
  • proto/pebble/trunk/src/main/Main.java

    r1256 r1261  
    33import incode.Fragment;
    44import incode.Pythonater;
    5 import incode.global.LivenessProperty;
    65import incode.global.MergeBlocks;
    76import incode.localOptimization.ReuseAvailableExpressions;
     
    1413import parser.PebbleParser;
    1514import semantic.StructAnalyzer;
    16 import symbolTable.SymbolTable;
    1715
    1816import org.antlr.runtime.ANTLRFileStream;
     
    5048            MacroExpander.buildAndApply(tree);
    5149            MoveLexdefsToBranchStarts.apply(tree);
     50            LexicalCollector headCollector = ((ProgramBlockASTN)tree).getCollector();
     51 
    5252            AssumptionIncorporator.apply(tree);
     53//            System.err.println("tree:\n"+tree);
    5354           
    54             SymbolTable symbolTable = StructAnalyzer.apply(tree);
    55             LexicalCollector headCollector = ((ProgramBlockASTN)tree).getCollector();
     55            headCollector.putStructsInSymbolTable(tree.getSymbolTable());
     56            StructAnalyzer.apply(tree);
     57           
    5658            BasicBlock headBlock = ASTtoIncode.apply(tree);
    5759            MergeBlocks.apply(Fragment.make(headBlock), false);
     
    6365            ReuseAvailableExpressions.apply(headBlock);
    6466//            LocalDeadCodeEliminator.apply(headBlock);
    65             LivenessProperty.build(Fragment.make(headBlock));
     67//            LivenessProperty.build(Fragment.make(headBlock));
    6668           
    67             Pythonater.apply(symbolTable, headCollector, headBlock);
     69            Pythonater.apply(tree.getSymbolTable(), headBlock);
    6870           
    6971        } catch (RecognitionException e) {
  • proto/pebble/trunk/src/parser/Pebble.g

    r1248 r1261  
    147147                                                 $secondTree = $a.secondTree; }
    148148        | e=expandStatement {$asTree = $e.asTree;}
    149         ;
    150        
     149        | n=newStatement        {$asTree = $n.asTree;}
     150        ;
     151
     152newStatement returns [AST asTree]
     153        :       'new' '<' type=Identifier '>' name=Identifier {
     154                        $asTree = new DeclarationASTN();
     155                        $asTree.addChild(VariableASTB.make($name.text));
     156                        $asTree.setType(new StructInstanceType($type.text));
     157                }
     158        ;
    151159expandStatement returns [AST asTree]
    152160        :       'expand' i=Identifier {
     
    228236       
    229237assignTarget returns [AST decl, AST variable;]
    230         : t=variableType? i=Identifier {
    231                         if(t!=null) {
    232                                 $decl = new DeclarationASTN();
    233                                 $decl.setType($t.type);
    234                                 $decl.addChild( VariableASTB.make($i.text) );
    235                         }
    236                         else {
    237                                 $decl = null;
    238                         }
     238        : t=variableType i=Identifier {
     239                        $decl = new DeclarationASTN();
     240                        $decl.setType($t.type);
     241                        $decl.addChild( VariableASTB.make($i.text) );
     242
    239243                        $variable = VariableASTB.make($i.text);
     244                }
     245        | c=compoundVariable {
     246                        $decl = null;
     247                        $variable = $c.asTree;
     248                }
     249        ;
     250       
     251        // wrong associativity, but it doesn't (currently) nest so there's no problem.
     252compoundVariable returns [AST asTree]
     253        : s=Identifier ('.' f=Identifier)? {
     254                        $asTree = VariableASTB.make($s.text);
     255                        if($f!=null) {
     256                                AST field = VariableASTB.make($f.text);
     257                                $asTree = StructFieldASTB.make($asTree, field);
     258                        }
    240259                }
    241260        ;
     
    432451                        }
    433452      }
    434     | i = Identifier {
    435                         $asTree = VariableASTB.make($i.text);
    436       }
     453    | v = compoundVariable {
     454                        $asTree = $v.asTree;
     455        }
     456//    | i = Identifier {
     457//                      $asTree = VariableASTB.make($i.text);
     458//      }
    437459    | n = IntegerConstant {
    438460                int value = Integer.parseInt($n.text);
     
    483505                        seqData.add(SequenceTokenData.singleCharacterClassData((char)(util.StringUtils.escapeValue($esc.text))));
    484506                     }
    485 //                |  dot = ColonedIdentifier {
    486 //                              // System.out.println("seq dotted: " + $dot.text);
    487 //                      seqData.add(trimDots($dot.text));
     507//                |  col = ColonedIdentifier {
     508//                              // System.out.println("seq coloned: " + $col.text);
     509//                      seqData.add(trimColons($col.text));
    488510//                       }
    489511                  |  cc = CharClassFrag {
     
    521543                          }
    522544//                      | col=ColonedIdentifier {
    523 //                              // System.out.println("CC dot: " + $dot.text);
     545//                              // System.out.println("CC colon: " + $col.text);
    524546//                              charClassData.addStream(trimDots($col.text));
    525547//                        }
     
    543565//                                      clean it up!
    544566//              '$' included for array indexing.
    545         :       ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.'|'$')*
     567        :       ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'$')*
    546568        ;
    547569fragment
  • proto/pebble/trunk/src/semantic/StructAnalyzer.java

    r1246 r1261  
    11package semantic;
    22
     3import symbolTable.StructInstanceType;
    34import symbolTable.StructType;
    45import symbolTable.SymbolInfo;
     
    67import ast.AST;
    78import ast.ASTVisitor;
     9import ast.exprNodes.StructFieldASTB;
    810import ast.exprNodes.VariableASTB;
    911import ast.nodes.DeclarationASTN;
     
    1214public class StructAnalyzer {
    1315
    14         public static SymbolTable apply(AST ast) {
     16        public static void apply(AST ast) {
    1517                StructAnalyzerVisitor analyzer = new StructAnalyzerVisitor();
    16                 SymbolTable table = new SymbolTable();
    17                 analyzer.setSymbolTable(table);
    1818                ast.accept(analyzer);
    19                 return table;
    2019        }
    2120       
    2221        private static class StructAnalyzerVisitor extends ASTVisitor.Default {
    23                 private SymbolTable symbolTable;
    24 
    25                 public void setSymbolTable(SymbolTable table) {
    26                         this.symbolTable = table;
     22               
     23                // make an entry in the ProgramBlockASTN SymbolTable for each StructBlock
     24                public void visitEnter(StructBlockASTN node) {
     25                        String name = node.getName();
     26                        SymbolTable symbolTable = node.getEnclosingSymbolTable();
     27                       
     28                        SymbolInfo info = symbolTable.add(name);
     29                        StructType structType = new StructType(node);
     30                        info.setType(structType);
    2731                }
    2832               
    29                 public void visitLeave(StructBlockASTN node) {
    30                         String name = node.getName();
    31                         if(symbolTable.containsSymbol(name)) {
    32                                 reportError("Structure name " + name + " already defined.");
     33                // make an entry in the closest (i.e. structType) symbol table for each decl in a struct.
     34                // make an entry in the closest scope's symbol table for each other decl.
     35                public void visitLeave(DeclarationASTN node) {
     36                        AST declVariable = node.getChild(DeclarationASTN.VARIABLE);
     37                        String declName = ((VariableASTB)declVariable).getName();
     38                        SymbolInfo declInfo = new SymbolInfo(declName, node.getType());
     39                       
     40
     41                        SymbolTable symbolTable = node.getEnclosingSymbolTable();
     42                        symbolTable.add(declName, declInfo);
     43                }
     44               
     45                // check that the struct has been declared and has the field.
     46                public void visitLeave(StructFieldASTB node) {
     47                        String structInstanceName = node.structName();
     48                        String fieldName = node.fieldName();
     49                       
     50                        SymbolTable table = node.getEnclosingSymbolTable();
     51                        if(!table.containsSymbolOnPath(structInstanceName)) {
     52                                String construct = structInstanceName + "." + fieldName;
     53                                reportError("Symbol " + structInstanceName + " in " + construct + " is not declared.");
    3354                                return;
    3455                        }
    3556                       
    36                         SymbolInfo info = symbolTable.add(name);
    37                         StructType structType = new StructType();
    38                         info.setType(structType);
     57                        SymbolInfo structInstanceInfo = table.lookupOnPath(structInstanceName);
     58                        if(!(structInstanceInfo.getType() instanceof StructInstanceType)) {
     59                                String construct = structInstanceName + "." + fieldName;
     60                                reportError("Symbol " + structInstanceName + " in " + construct + " is not a structure instance.");
     61                                return;
     62                        }
     63                        StructInstanceType instanceType = (StructInstanceType)structInstanceInfo.getType();
     64                        String structTypeName = instanceType.getStructTypeName();
     65                        SymbolInfo structTypeInfo = table.lookupOnPath(structTypeName);
     66                        if(!(structTypeInfo.getType() instanceof StructType)) {
     67                                String construct = structInstanceName + "." + fieldName;
     68                                reportError("Compiler error - Symbol " + structInstanceName + " in " + construct + " has a non-structure type.");
     69                                return;
     70                        }
     71                        StructType type = (StructType) structTypeInfo.getType();
    3972                       
    40                         for(AST child: node.children()) {
    41                                 if(!(child instanceof DeclarationASTN)) {
    42                                         reportError("Structure element in " + name + " not declaration:\n" + child);
    43                                         continue;
    44                                 }
    45                                 DeclarationASTN decl = (DeclarationASTN) child;
    46                                 AST declVariable = decl.getChild(DeclarationASTN.VARIABLE);
    47                                 String declName = ((VariableASTB)declVariable).getName();
    48                                 SymbolInfo declInfo = new SymbolInfo(declName, decl.getType());
    49                                 structType.addField(declInfo);
    50                                 declInfo.setParent(info);
     73                        if(!type.containsField(fieldName)) {
     74                                String construct = structInstanceName + "." + fieldName;
     75                                reportError("Symbol " + fieldName + " in " + construct + " is not in the structure "+ structInstanceName +".");
     76                                return;
    5177                        }
     78                       
    5279                }
    5380
    5481                private void reportError(String string) {
    55                         System.err.println(string);
     82                        System.err.println("error: " + string);
    5683                }
    5784        }
  • proto/pebble/trunk/src/symbolTable/StructType.java

    r1242 r1261  
    11package symbolTable;
    22
    3 import java.util.ArrayList;
    43import java.util.Iterator;
    5 import java.util.List;
     4
     5import ast.AST;
    66
    77public class StructType implements Type, Iterable<SymbolInfo> {
    8         private List<SymbolInfo> fields;
     8        private SymbolTable symbolTable;
    99       
    10         public StructType() {
    11                 fields = new ArrayList<SymbolInfo>();
     10        public StructType(AST definingNode) {
     11                if(definingNode==null) {
     12                        symbolTable = new SymbolTable(null);
     13                }
     14                else {
     15                        symbolTable = definingNode.getSymbolTable();
     16                }
    1217        }
    1318       
    1419        public void addField(SymbolInfo info) {
    15                 fields.add(info);
     20                String symbol = info.getName();
     21                symbolTable.add(symbol, info);
    1622        }
    1723
     24        public boolean containsField(String symbol) {
     25                return symbolTable.containsSymbol(symbol);
     26        }
    1827        @Override
    1928        public Iterator<SymbolInfo> iterator() {
    20                 return fields.iterator();
     29                return symbolTable.allInfo().iterator();
    2130        }
    22 
    2331}
  • proto/pebble/trunk/src/symbolTable/SymbolInfo.java

    r1242 r1261  
    44        private Type type;
    55        private String name;
    6         private SymbolInfo parent;
     6        private String comment;
     7        private SymbolTable containingSymbolTable;
    78       
    89        public SymbolInfo(String name) {
     
    1213                this.name = name;
    1314                this.type = type;
    14                 this.parent = null;
     15                containingSymbolTable = null;
     16                this.comment = "";
    1517        }
    1618       
     
    2830                return name;
    2931        }
    30         public boolean isAField() {
    31                 return parent != null;
     32        public SymbolTable getContainingSymbolTable() {
     33                return containingSymbolTable;
    3234        }
    33         public SymbolInfo getParent() {
    34                 return parent;
     35        public void setContainingSymbolTable(SymbolTable table) {
     36                this.containingSymbolTable = table;
    3537        }
    36         public void setParent(SymbolInfo parent) {
    37                 this.parent = parent;
     38        public void setComment(String comment) {
     39                this.comment = comment;
    3840        }
    3941
     42        ////////////////////////////////////////////////////////
     43        // copy
     44        ////////////////////////////////////////////////////////
    4045
    41        
     46        public SymbolInfo copy() {
     47                SymbolInfo result = new SymbolInfo(name, type);
     48                result.setComment(comment);
     49                return result;
     50        }
     51        ////////////////////////////////////////////////////////
     52        // String representation
     53        ////////////////////////////////////////////////////////
     54        public String fieldString() {
     55                String init = String.format("%s = 0", name);
     56                if(comment==null || comment.isEmpty()) {
     57                        return init;
     58                }
     59                return  String.format("%-20s\t# [%s]", init, comment);
     60        }
    4261       
    4362        ////////////////////////////////////////////////////////
  • proto/pebble/trunk/src/symbolTable/SymbolTable.java

    r1242 r1261  
    22
    33import java.util.ArrayList;
     4import java.util.Collections;
     5import java.util.Comparator;
    46import java.util.HashMap;
    57import java.util.List;
    68import java.util.Map;
    79
     10
     11import ast.AST;
     12
    813public class SymbolTable {
    914        private Map<String, SymbolInfo> table;
    10        
    11         public SymbolTable() {
     15        private AST containingNode;
     16
     17        ///////////////////////////////////////////////////////////
     18        // Constructor
     19        ///////////////////////////////////////////////////////////
     20        public SymbolTable(AST node) {
    1221                table = new HashMap<String, SymbolInfo>();
     22                containingNode = node;
    1323        }
    1424
     25       
    1526        ///////////////////////////////////////////////////////////
    1627        // Adding symbols
     
    1829        public void add(String symbol, SymbolInfo info) {
    1930                table.put(symbol, info);
     31                info.setContainingSymbolTable(this);
    2032        }
    2133        public SymbolInfo add(String symbol) {
     34                if(table.containsKey(symbol)) {
     35                        reportError("Symbol name " + symbol + " already defined.");
     36                        return table.get(symbol);
     37                }
    2238                SymbolInfo info = new SymbolInfo(symbol);
    2339                add(symbol, info);
     
    4056                return table.containsKey(symbol);
    4157        }
    42         public SymbolInfo get(String symbol) {
     58        public SymbolInfo lookup(String symbol) {
    4359                if(table.containsKey(symbol)) {
    4460                        return table.get(symbol);
     
    4864                }
    4965        }
     66        public List<SymbolInfo> allInfo() {
     67                List<SymbolInfo> infos = new ArrayList<SymbolInfo>(table.values());
     68                Collections.sort(infos, new infoSortByName());
     69                return infos;
     70        }
     71        private class infoSortByName implements Comparator<SymbolInfo> {
     72                public int compare(SymbolInfo p1, SymbolInfo p2) {
     73                        return p1.getName().compareTo(p2.getName());
     74                }
     75        }
    5076
     77       
     78        ///////////////////////////////////////////////////////////
     79        // looking up info, up the path to the root
     80        ///////////////////////////////////////////////////////////
     81        public boolean containsSymbolOnPath(String symbol) {
     82                if(table.containsKey(symbol))
     83                        return true;
     84               
     85                SymbolTable nextTable = containingNode.getEnclosingSymbolTable();
     86                if(nextTable==null) {
     87                        return false;
     88                }
     89                return nextTable.containsSymbolOnPath(symbol);
     90        }
     91        public SymbolInfo lookupOnPath(String symbol) {
     92                if(table.containsKey(symbol)) {
     93                        return table.get(symbol);
     94                }
     95               
     96                SymbolTable nextTable = containingNode.getEnclosingSymbolTable();
     97                if(nextTable==null) {
     98                        return SymbolInfo.nullSymbol();
     99                }
     100
     101                return nextTable.lookupOnPath(symbol);
     102        }
     103
     104       
    51105        ///////////////////////////////////////////////////////////
    52106        // information about structs
    53107        ///////////////////////////////////////////////////////////
    54         public List<String> structNames() {
    55                 List<String> result = new ArrayList<String>();
    56                 for(String symbol: table.keySet()) {
    57                         if(isStruct(symbol)) {
    58                                 result.add(symbol);
     108        public List<SymbolInfo> structInfos() {
     109                List<SymbolInfo> result = new ArrayList<SymbolInfo>();
     110                for(SymbolInfo info: allInfo()) {
     111                        if(isStruct(info)) {
     112                                result.add(info);
    59113                        }
    60114                }
    61115                return result;
    62116        }
    63         private boolean isStruct(String symbol) {
    64                 SymbolInfo info = get(symbol);
     117        private boolean isStruct(SymbolInfo info) {
    65118                return info.getType() instanceof StructType;
    66119        }
     120
     121       
     122        ///////////////////////////////////////////////////////////
     123        // error-reporting
     124        ///////////////////////////////////////////////////////////
     125        private void reportError(String string) {
     126                System.err.println("error: " + string);
     127        }
    67128}
Note: See TracChangeset for help on using the changeset viewer.