#ifndef _AST #define _AST /* * Class Hierarchy for Abstract Syntax Tree nodes for Espresso * * * NOTE: * You will not need to change any of the code in this file to write your * parser. You will just be calling constructors. testparser.cc * (already written) calls dump on the root to dump the whole tree. * * However, when you do the later parts of the compiler * will need to add data members and/or member functions to the classes. * Do not remove stuff or move stuff around, though, or you will break the * dump routines already written for you. * * See separate document: "Espresso ASTs" for documentation on using this * code. * * Some notes on the structure: * * class TreeNode: * -- the base class for all non-list node classes * -- contains the line number of the line in the file where we found * the Espresso constuct. This gets initialized by the constructor * directly from the global var linenum. (It's not passed as a param.) * -- that linenum will be the LAST line of the construct, since we don't * create the node until we have seen the whole construct and reduce * * class Expr * -- the base class for all expression node classes * -- it contains a "type" field for storing the type of the expression * -- the constructor inits "type" to NULL, and the dump func * prints no_type when it is NULL * -- "type" will get sed in the semantic analysis phase * * The list AST classes (e.g., ClassList, MemberList, etc.) * These are defined by typedefs given in parser.h * They are all just convenient names for STL vector instantiations. * As with the other AST types, we will allocate these objects dynamically * and pass around a pointer to the dynamically allocated object. * * Unlike the other AST types, the list types are not of a class * defined by us, so we cannot add functionality to them by adding * member functions. To add functionality to list types you need * to use non-member functions: * * * To add a function that works on *any* list type, create a * template (non-member) function. See the template dump function * defined at the bottom of this file for an example of this. Of * course, this only makes sense if the code would be the same for * such a function for all list types. You can also call existing STL * algorithms that work on vectors. * * * To add a function that works on just one list type, create a * non-member non-template function that passes that list type as a * parameter. E.g., here's the prototype for a function: * void addClassNames(ClassList *classList, . . .); * * Note: * any classes noted below with an "ABC" comment are Abstract Base * Classes. These ones have a pure virtual function, and can't be * instantiated. * * * CHANGE HISTORY * * Modified 1/25/05 by CMB * Changed design of lists to use vector directly with typedef. * 9/05: removed comments relating to old lists. * * Modified 1/20/05 by CMB * Added missing getType func body for Expr * * Modified 10/21/04 by CMB * Student version did not have change of 9/30 mentioned below. * Now the code matches what the comment says. * * Modified 10/04 by CMB * Added ClassTable typedef so we can pass ClassTable* objects to * ast member functions. * * Modified 9/30/04 by CMB * Changed vector in ListAbstract to be "protected" * so subclasses can access. * * Created 9/04 by CMB * */ // TreeNode depends on global var linenum // as explained above extern int linenum; #include #include using namespace std; #include "parser.h" /********************************************************************/ /* THE DECLS IN THIS SECTION ARE NEEDED FOR THE SEMANTIC ANALYZER */ // forward decl of SymTab template type template class SymTab; // forward decl of class for typedef below class Class; /* * ClassTable a convenient name for a template instantiation. In this * symbol table: the key is the name of the class, the value is a * pointer to the AST for that class. We can put any other info we * need about a class in fields in the Class tree node or subtrees. * ClassTable is used in ast.h and semant.cc */ typedef SymTab ClassTable; /********************************************************************/ class TreeNode { // ABC protected: int myLineNum; public: TreeNode() : myLineNum(linenum) { } int getLineNum() { return myLineNum; } void dumpLineNum(ostream &o); virtual void dump(ostream &o, int n) = 0; virtual ~TreeNode() { } }; class Program : public TreeNode { protected: Class *mainClass; ClassList *classList; public: Program(Class *mc, ClassList *cl) : mainClass(mc), classList(cl) { } virtual void dump(ostream &o, int n); }; class Class : public TreeNode { protected: Symbol *name; MemberList *memberList; public: Class(Symbol *n, MemberList *ml) : name(n), memberList(ml) { } virtual void dump(ostream &o, int n); }; // for Methods or Fields class Member : public TreeNode { // ABC public: Member() { } virtual void dump(ostream &o, int n) = 0; }; class Field : public Member { protected: Symbol *name; Symbol *type; public: // pass in type first to match order in espresso decls Field(Symbol *t, Symbol *n) : name(n), type(t) { } virtual void dump(ostream &o, int n); }; class MethodAbstract : public Member { // ABC protected: // stuff common to all methods FormalList *formalList; LocalList *localList; StmtList *stmtList; // n is the indentation for the Method // the function adds extra for fields void defaultDump(ostream &o, int n); // dumps fields defined here public: MethodAbstract(FormalList *fl, LocalList *ll, StmtList *sl) : formalList(fl), localList(ll), stmtList(sl) { } virtual void dump(ostream &o, int n) = 0; }; class MainMethod : public MethodAbstract { public: MainMethod(FormalList *fl, LocalList *ll, StmtList *sl) : MethodAbstract (fl, ll, sl) { } virtual void dump(ostream &o, int n); }; class Method : public MethodAbstract { protected: Symbol *name; Symbol *returnType; Expr *returnExpr; public: Method(Symbol *n, FormalList *fl, Symbol *rt, LocalList *ll, StmtList *sl, Expr *re) : MethodAbstract (fl, ll, sl), name(n), returnType(rt), returnExpr(re) { } virtual void dump(ostream &o, int n); }; class Formal : public TreeNode { protected: Symbol *name; Symbol *type; public: // pass in type first to match order in espresso decls Formal(Symbol *t, Symbol *n): name(n), type(t) { } virtual void dump(ostream &o, int n); }; class Local : public TreeNode { protected: Symbol *name; Symbol *type; public: // pass in type first to match order in espresso decls Local(Symbol *t, Symbol *n) : name(n), type(t) { } virtual void dump(ostream &o, int n); }; class Stmt : public TreeNode { // ABC public: virtual void dump(ostream &o, int n) = 0; }; class ExprStmt : public Stmt { protected: Expr *expr; public: ExprStmt(Expr *e) : expr(e) { } virtual void dump(ostream &o, int n); }; class Block : public Stmt { protected: StmtList *stmtList; public: Block(StmtList *sl) : stmtList(sl) { } virtual void dump(ostream &o, int n); }; // elsePart may be NULL class If : public Stmt { protected: Expr *cond; Stmt *thenPart; Stmt *elsePart; public: If(Expr *e, Stmt *t, Stmt *el) : cond(e), thenPart(t), elsePart(el) { } virtual void dump(ostream &o, int n); }; class While : public Stmt { protected: Expr *cond; Stmt *body; public: While(Expr *e, Stmt *b): cond(e), body(b) { } virtual void dump(ostream &o, int n); }; // arg may be NULL class Println : public Stmt { protected: Expr *arg; public: Println(Expr *e) : arg(e) { } virtual void dump(ostream &o, int n); }; // the type field will be assigned later by the semantic analyzer class Expr : public TreeNode { // ABC protected: Symbol *type; public: Expr() : type(NULL) { } Symbol *getType() { return type; }; void setType(Symbol *t) { type = t; } void dumpType(ostream &o); virtual void dump(ostream &o, int n) = 0; }; class Assgt : public Expr { protected: Symbol *id; Expr *expr; public: Assgt(Symbol *lhs, Expr *rhs) : id(lhs), expr(rhs) { } virtual void dump(ostream &o, int n); }; class VarRef : public Expr { protected: Symbol *id; public: VarRef(Symbol *theVar) : id(theVar) { } virtual void dump(ostream &o, int n); }; class BoolLiteral : public Expr { protected: bool value; public: BoolLiteral(bool v) : value(v) { } virtual void dump(ostream &o, int n); }; class IntLiteral : public Expr { protected: int value; public: IntLiteral(int v) : value(v) { } virtual void dump(ostream &o, int n); }; class Null : public Expr { protected: public: Null() { } virtual void dump(ostream &o, int n); }; class New : public Expr { protected: Symbol *objType; public: New(Symbol *ot) : objType(ot) { } virtual void dump(ostream &o, int n); }; class FuncCall : public Expr { protected: Expr *objExpr; Symbol *funcName; ExprList *argList; public: FuncCall(Expr *o, Symbol *f, ExprList *args) : objExpr(o), funcName(f), argList(args) { } virtual void dump(ostream &o, int n); }; class Not : public Expr { protected: Expr *expr; public: Not(Expr *e) : expr(e) { } virtual void dump(ostream &o, int n); }; class BinOp : public Expr { // ABC protected: Expr *left; Expr *right; // defaultDump dumps linenum, type, and the left and right operands // n is the indentation for the BinOp // the function adds extra for fields void defaultDump(ostream &o, int n); public: BinOp(Expr *l, Expr *r) : left(l), right(r) { } virtual void dump(ostream &o, int n) = 0; }; class Plus : public BinOp { protected: public: Plus(Expr *l, Expr *r): BinOp(l,r) { } virtual void dump(ostream &o, int n); }; class Times : public BinOp { protected: public: Times(Expr *l, Expr *r): BinOp(l,r) { } virtual void dump(ostream &o, int n); }; class Minus : public BinOp { protected: public: Minus(Expr *l, Expr *r): BinOp(l,r) { } virtual void dump(ostream &o, int n); }; class Equals : public BinOp { protected: public: Equals(Expr *l, Expr *r): BinOp(l,r) { } virtual void dump(ostream &o, int n); }; class NotEquals : public BinOp { protected: public: NotEquals(Expr *l, Expr *r): BinOp(l,r) { } virtual void dump(ostream &o, int n); }; class LessThan : public BinOp { protected: public: LessThan(Expr *l, Expr *r): BinOp(l,r) { } virtual void dump(ostream &o, int n); }; class And : public BinOp { protected: public: And(Expr *l, Expr *r): BinOp(l,r) { } virtual void dump(ostream &o, int n); }; // non member template function to dump any kind of list AST // list AST typedefs are in parser.h template void dump(ostream &o, const vector *astList, int n) { for (typename vector::const_iterator i = astList->begin(); i != astList->end(); i++) { (*i)->dump(o, n); } } #endif