176 lines
4.9 KiB
C++
176 lines
4.9 KiB
C++
#include "cool-tree.h"
|
|
#include "cool-tree.handcode.h"
|
|
#include "emit.h"
|
|
#include "symtab.h"
|
|
#include <assert.h>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <iostream>
|
|
#include <stdio.h>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
enum Basicness { Basic, NotBasic, Trivial };
|
|
enum VariableLocation { Attribute, Stack };
|
|
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
|
|
class CgenClassTable;
|
|
typedef CgenClassTable *CgenClassTableP;
|
|
|
|
class CgenNode;
|
|
typedef CgenNode *CgenNodeP;
|
|
|
|
class BoolConst;
|
|
|
|
typedef std::vector<std::pair<class__class *, method_class *>> MethodListT;
|
|
typedef std::vector<std::pair<class__class *, attr_class *>> AttrListT;
|
|
|
|
struct LocationTableItem {
|
|
LocationTableItem(Symbol id, VariableLocation loc, int off)
|
|
: id(id), location(loc), offset(off) {}
|
|
Symbol id;
|
|
VariableLocation location;
|
|
int offset;
|
|
};
|
|
|
|
class LocationTable {
|
|
private:
|
|
std::vector<LocationTableItem> table;
|
|
std::vector<size_t> scope;
|
|
|
|
public:
|
|
// lookup the inner-most item with the same id as name
|
|
LocationTableItem *lookup(Symbol name) {
|
|
for (auto itr = table.rbegin(); itr != table.rend(); ++itr) {
|
|
if (itr->id == name) {
|
|
return &*itr;
|
|
}
|
|
}
|
|
assert(0);
|
|
return nullptr;
|
|
}
|
|
void add(LocationTableItem item) { table.push_back(item); };
|
|
void enterscope() { scope.push_back(table.size()); }
|
|
void exitscope() {
|
|
auto end = scope.back();
|
|
scope.pop_back();
|
|
table.erase(table.begin() + end, table.end());
|
|
}
|
|
void dump() {
|
|
scope.push_back(table.size());
|
|
for (size_t i = 0; i < scope.size() - 1; ++i) {
|
|
std::cerr << "scope" << i << "\n";
|
|
for (size_t j = scope[i]; j < scope[i + 1]; j++) {
|
|
std::cerr << table[j].id << ", " << table[j].location << ", "
|
|
<< table[j].offset << "\n";
|
|
}
|
|
}
|
|
scope.pop_back();
|
|
}
|
|
};
|
|
|
|
class CgenClassTable : public SymbolTable<Symbol, CgenNode> {
|
|
private:
|
|
ostream &str;
|
|
int stringclasstag;
|
|
int intclasstag;
|
|
int boolclasstag;
|
|
IntEntry *_int_default = nullptr;
|
|
StringEntry *_str_default = nullptr;
|
|
BoolConst *_bool_default = nullptr;
|
|
int label_count = 0; // an incremental counter to avoid label conflicts
|
|
|
|
// The following methods emit code for
|
|
// constants and global declarations.
|
|
|
|
void code_global_data();
|
|
void code_global_text();
|
|
void code_bools(int);
|
|
void code_select_gc();
|
|
void code_constants();
|
|
|
|
// The following creates an inheritance graph from
|
|
// a list of classes. The graph is implemented as
|
|
// a tree of `CgenNode', and class names are placed
|
|
// in the base class symbol table.
|
|
|
|
void install_basic_classes();
|
|
void install_class(CgenNodeP nd);
|
|
void install_classes(Classes cs);
|
|
void build_inheritance_tree();
|
|
void set_relations(CgenNodeP nd);
|
|
//* New Methods
|
|
void dump_inheritance_tree();
|
|
void code_class_nameTable();
|
|
void code_dispatchTable();
|
|
void code_prototypeObject();
|
|
CgenNode *get_node(Symbol);
|
|
void code_objectTab();
|
|
void gen_init_code();
|
|
void gen_method_code();
|
|
|
|
public:
|
|
LocationTable loctab;
|
|
Symbol expr_type_decl;
|
|
std::vector<CgenNode *> nodes;
|
|
CgenNode *cur_class;
|
|
CgenClassTable(Classes, ostream &str);
|
|
void code();
|
|
CgenNode *root() { return nodes[0]; }
|
|
/* aquire an unused label index */
|
|
int alloc_label_index() { return label_count++; }
|
|
IntEntry *int_default() const { return _int_default; };
|
|
StringEntry *str_default() const { return _str_default; };
|
|
BoolConst *bool_default() const { return _bool_default; };
|
|
int get_method_index(Symbol class_name, Symbol method_name);
|
|
};
|
|
|
|
class CgenNode : public class__class {
|
|
private:
|
|
CgenNodeP parentnd; // Parent of class
|
|
std::vector<CgenNode *> children; // Children of class
|
|
Basicness basic_status; // `Basic' if class is basic
|
|
// `NotBasic' otherwise
|
|
/* class_tag is allocated in pre-order */
|
|
uint32_t _class_tag = 0;
|
|
/* record children's class tag range for type case code gen */
|
|
uint32_t _children_tag_range;
|
|
|
|
AttrListT attributes;
|
|
// attr list including inherited
|
|
MethodListT methods;
|
|
// method list including inherited and overidden methods
|
|
|
|
public:
|
|
CgenNode(Class_ c, Basicness bstatus);
|
|
|
|
void add_child(CgenNodeP child);
|
|
std::vector<CgenNode *> *get_children() { return &children; }
|
|
void set_parentnd(CgenNodeP p);
|
|
CgenNodeP get_parentnd() { return parentnd; }
|
|
int basic() { return (basic_status == Basic); }
|
|
uint32_t get_class_tag() { return _class_tag; }
|
|
uint32_t get_children_tag() { return _children_tag_range; }
|
|
void traverse_dump(int pad);
|
|
uint32_t get_object_size() { return (3 + attributes.size()); }
|
|
void traverse_generate_object();
|
|
void traverse_allocate_tag();
|
|
AttrListT *get_attributes() { return &attributes; };
|
|
MethodListT *get_methods() { return &methods; };
|
|
};
|
|
|
|
class BoolConst {
|
|
private:
|
|
int val;
|
|
|
|
public:
|
|
BoolConst(int);
|
|
void code_def(ostream &, int boolclasstag);
|
|
void code_ref(ostream &) const;
|
|
};
|
|
|
|
inline bool is_no_expr(Expression expr) {
|
|
return typeid(*expr) == typeid(no_expr_class);
|
|
} |