/* semant.cc * * Will contain all the code for semantic analysis, including member function * definitions for Semant class, and any new AST node member functions. * * The main program (in testsemant.cc) will call the Semant * constructor, and then calls Semant::analyzeProg. This second * function is the entry point to your code (see comments below). * * Put member function definitions for new ast node methods for * semantic analysis in *this* file. We'll just leave ast.cc as is ,to contain * all the parser-related tree stuff (i.e., constructors, and dump routines). * When you add new methods/fields to AST nodes, you will, of course, have to * also change ast.h * * This file may also contain member function definitions for other * classes you create for use in semantic analysis, or other regular * functions you define. * * Code in the starter file: pp * * We have written and called "addBuitIns" for you, which puts the * built-in types into the symbol table for types, called * ClassTable. Definition of ClassTable is given in ast.h. * * You are not required to do the ClassTable the way it's done here * (see ast.h for typedef): if you prefer, you can use a different * data-type to associate with class names in its symbol table. * E.g., you could define your own class to store the info about one * class, instead of using the Class AST node (the latter is what * this code does). * * * */ #include "ast.h" #include "SymTab.h" #include "SError.h" #include "semant.h" // Some useful symbol "literals" to have access to // (if these are already in stringtab, addString just returns the existing // symbol) // You can add to this list if you find it useful to have other // hard-coded symbols static Symbol * intSym = stringtab.addString("int"); static Symbol * booleanSym = stringtab.addString("boolean"); static Symbol * stringSym = stringtab.addString("String[]"); static Symbol * nullSym = stringtab.addString("null"); static Symbol * thisSym = stringtab.addString("this"); static Symbol * dummySym = stringtab.addString(""); // stuff for semantic analysis Semant::Semant(Program *theAST, const string &filename) : ast(theAST), fileName(filename), classSymTab(new ClassTable()) { addBuiltIns(); // add any other init code you want to here as needed. } void Semant::addBuiltIns() { // create "dummy" empty Class nodes for each built in class. // they need to be in the symbol table as recognized classes. classSymTab->add(intSym, new Class(intSym, new MemberList())); classSymTab->add(booleanSym, new Class(booleanSym, new MemberList())); classSymTab->add(stringSym, new Class(stringSym, new MemberList())); } /* * Semant::analyzeProg is your entry point to the semantic analyzer. * All the code you write will be directly or indirectly called * from here. Although, you may also add code to the constructor above, too. * * Please see main in testsemant.cc to see how the Semant class is used. */ void Semant::analyzeProg() { // add code here } /* * Code for printing VarInfo and descendent type nodes */ ostream & operator<<(ostream&o, const VarInfo *varInfoPtr) { return o << *varInfoPtr; } ostream & operator<<(ostream &o, const VarInfo &varInfo) { // "dump" is virtual: you can make diff versions of dump return varInfo.dump(o); } ostream & FormalInfo::dump(ostream &o) const { return defaultDump(o) << " (formal) "; } ostream & LocalInfo::dump(ostream &o) const { return defaultDump(o) << " (local) "; } ostream & FieldInfo::dump(ostream &o) const { return defaultDump(o) << " (field) "; } ostream & ThisInfo::dump(ostream &o) const { return defaultDump(o) << " (this) "; }