add a simple vector based symtab for location
This commit is contained in:
parent
2db8b1f4e7
commit
d279a73fb5
@ -93,6 +93,7 @@ static char *gc_collect_names[] = {"_NoGC_Collect", "_GenGC_Collect",
|
|||||||
BoolConst falsebool(FALSE);
|
BoolConst falsebool(FALSE);
|
||||||
BoolConst truebool(TRUE);
|
BoolConst truebool(TRUE);
|
||||||
|
|
||||||
|
static int rel_stack_depth;
|
||||||
//*********************************************************
|
//*********************************************************
|
||||||
//
|
//
|
||||||
// Define method for code generation
|
// Define method for code generation
|
||||||
@ -297,6 +298,17 @@ static void emit_branch(int l, ostream &s) {
|
|||||||
static void emit_push(char *reg, ostream &str) {
|
static void emit_push(char *reg, ostream &str) {
|
||||||
emit_store(reg, 0, SP, str);
|
emit_store(reg, 0, SP, str);
|
||||||
emit_addiu(SP, SP, -4, str);
|
emit_addiu(SP, SP, -4, str);
|
||||||
|
rel_stack_depth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_pop(ostream &str) {
|
||||||
|
emit_addiu(SP, SP, 4, str);
|
||||||
|
rel_stack_depth--;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_pop(size_t count, ostream &str) {
|
||||||
|
emit_addiu(SP, SP, 4 * count, str);
|
||||||
|
rel_stack_depth -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -674,13 +686,13 @@ void CgenClassTable::install_basic_classes() {
|
|||||||
//
|
//
|
||||||
addid(No_class,
|
addid(No_class,
|
||||||
new CgenNode(class_(No_class, No_class, nil_Features(), filename),
|
new CgenNode(class_(No_class, No_class, nil_Features(), filename),
|
||||||
Basic, this));
|
Trivial));
|
||||||
addid(SELF_TYPE,
|
addid(SELF_TYPE,
|
||||||
new CgenNode(class_(SELF_TYPE, No_class, nil_Features(), filename),
|
new CgenNode(class_(SELF_TYPE, No_class, nil_Features(), filename),
|
||||||
Basic, this));
|
Trivial));
|
||||||
addid(prim_slot,
|
addid(prim_slot,
|
||||||
new CgenNode(class_(prim_slot, No_class, nil_Features(), filename),
|
new CgenNode(class_(prim_slot, No_class, nil_Features(), filename),
|
||||||
Basic, this));
|
Trivial));
|
||||||
|
|
||||||
//
|
//
|
||||||
// The Object class has no parent class. Its methods are
|
// The Object class has no parent class. Its methods are
|
||||||
@ -702,7 +714,7 @@ void CgenClassTable::install_basic_classes() {
|
|||||||
single_Features(
|
single_Features(
|
||||||
method(copy, nil_Formals(), SELF_TYPE, no_expr()))),
|
method(copy, nil_Formals(), SELF_TYPE, no_expr()))),
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic));
|
||||||
|
|
||||||
//
|
//
|
||||||
// The IO class inherits from Object. Its methods are
|
// The IO class inherits from Object. Its methods are
|
||||||
@ -727,7 +739,7 @@ void CgenClassTable::install_basic_classes() {
|
|||||||
method(in_string, nil_Formals(), Str, no_expr()))),
|
method(in_string, nil_Formals(), Str, no_expr()))),
|
||||||
single_Features(method(in_int, nil_Formals(), Int, no_expr()))),
|
single_Features(method(in_int, nil_Formals(), Int, no_expr()))),
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic));
|
||||||
|
|
||||||
//
|
//
|
||||||
// The Int class has no methods and only a single attribute, the
|
// The Int class has no methods and only a single attribute, the
|
||||||
@ -736,7 +748,7 @@ void CgenClassTable::install_basic_classes() {
|
|||||||
install_class(new CgenNode(
|
install_class(new CgenNode(
|
||||||
class_(Int, Object, single_Features(attr(val, prim_slot, no_expr())),
|
class_(Int, Object, single_Features(attr(val, prim_slot, no_expr())),
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bool also has only the "val" slot.
|
// Bool also has only the "val" slot.
|
||||||
@ -744,7 +756,7 @@ void CgenClassTable::install_basic_classes() {
|
|||||||
install_class(new CgenNode(
|
install_class(new CgenNode(
|
||||||
class_(Bool, Object, single_Features(attr(val, prim_slot, no_expr())),
|
class_(Bool, Object, single_Features(attr(val, prim_slot, no_expr())),
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic));
|
||||||
|
|
||||||
//
|
//
|
||||||
// The class Str has a number of slots and operations:
|
// The class Str has a number of slots and operations:
|
||||||
@ -774,7 +786,7 @@ void CgenClassTable::install_basic_classes() {
|
|||||||
single_Formals(formal(arg2, Int))),
|
single_Formals(formal(arg2, Int))),
|
||||||
Str, no_expr()))),
|
Str, no_expr()))),
|
||||||
filename),
|
filename),
|
||||||
Basic, this));
|
Basic));
|
||||||
|
|
||||||
stringclasstag = get_node(Str)->get_class_tag();
|
stringclasstag = get_node(Str)->get_class_tag();
|
||||||
intclasstag = get_node(Int)->get_class_tag();
|
intclasstag = get_node(Int)->get_class_tag();
|
||||||
@ -802,7 +814,7 @@ void CgenClassTable::install_class(CgenNodeP nd) {
|
|||||||
|
|
||||||
void CgenClassTable::install_classes(Classes cs) {
|
void CgenClassTable::install_classes(Classes cs) {
|
||||||
for (int i = cs->first(); cs->more(i); i = cs->next(i))
|
for (int i = cs->first(); cs->more(i); i = cs->next(i))
|
||||||
install_class(new CgenNode(cs->nth(i), NotBasic, this));
|
install_class(new CgenNode(cs->nth(i), NotBasic));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -825,6 +837,127 @@ void CgenClassTable::set_relations(CgenNodeP nd) {
|
|||||||
parent_node->add_child(nd);
|
parent_node->add_child(nd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CgenClassTable::dump_inheritance_tree() {
|
||||||
|
CgenNode *object_node = nullptr;
|
||||||
|
|
||||||
|
for (auto cur_node : nodes) {
|
||||||
|
if (cur_node->name == Object) {
|
||||||
|
object_node = cur_node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object_node->traverse_dump(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CgenNode *CgenClassTable::get_node(Symbol class_name) {
|
||||||
|
for (auto node : nodes) {
|
||||||
|
if (node->name == class_name) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cgen_debug)
|
||||||
|
std::cerr << "get_node " << class_name << " not found\n";
|
||||||
|
assert(0);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CgenClassTable::code() {
|
||||||
|
if (cgen_debug)
|
||||||
|
cout << "coding global data" << endl;
|
||||||
|
code_global_data();
|
||||||
|
|
||||||
|
if (cgen_debug)
|
||||||
|
cout << "choosing gc" << endl;
|
||||||
|
code_select_gc();
|
||||||
|
|
||||||
|
if (cgen_debug)
|
||||||
|
cout << "coding constants" << endl;
|
||||||
|
code_constants();
|
||||||
|
|
||||||
|
if (cgen_debug)
|
||||||
|
cout << "coding class_nameTab" << endl;
|
||||||
|
code_class_nameTable();
|
||||||
|
|
||||||
|
if (cgen_debug)
|
||||||
|
cout << "coding dispatch tables" << endl;
|
||||||
|
nodes[0]->traverse_generate_object();
|
||||||
|
// nodes[0] is the Object class
|
||||||
|
code_dispatchTable();
|
||||||
|
|
||||||
|
if (cgen_debug)
|
||||||
|
cout << "coding prototype objects" << endl;
|
||||||
|
code_prototypeObject();
|
||||||
|
|
||||||
|
if (cgen_debug)
|
||||||
|
cout << "coding global text" << endl;
|
||||||
|
code_global_text();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// test my symtab impl
|
||||||
|
for (auto node : nodes) {
|
||||||
|
auto attrs = *node->get_attributes();
|
||||||
|
auto methods = *node->get_methods();
|
||||||
|
std::cerr << node->name << std::endl;
|
||||||
|
loctab.enterscope();
|
||||||
|
for (size_t i = 0; i < attrs.size(); ++ i) {
|
||||||
|
auto attr = attrs[i];
|
||||||
|
loctab.add(LocationTableItem(attr->name, Attribute, i));
|
||||||
|
}
|
||||||
|
loctab.enterscope();
|
||||||
|
for (size_t i = 0; i < methods.size(); ++ i) {
|
||||||
|
auto method = methods[i];
|
||||||
|
loctab.add(LocationTableItem(method.second->name, Attribute, i));
|
||||||
|
}
|
||||||
|
loctab.enterscope();
|
||||||
|
for (size_t i = 0; i < attrs.size(); ++ i) {
|
||||||
|
auto attr = attrs[i];
|
||||||
|
loctab.add(LocationTableItem(attr->name, Attribute, i + 10000));
|
||||||
|
}
|
||||||
|
// loctab.dump();
|
||||||
|
for (size_t i = 0; i < attrs.size(); ++ i) {
|
||||||
|
auto attr = attrs[i];
|
||||||
|
assert(loctab.lookup(attr->name));
|
||||||
|
assert(loctab.lookup(attr->name)->offset == i + 10000);
|
||||||
|
}
|
||||||
|
loctab.exitscope();
|
||||||
|
for (size_t i = 0; i < attrs.size(); ++ i) {
|
||||||
|
auto attr = attrs[i];
|
||||||
|
assert(loctab.lookup(attr->name) && loctab.lookup(attr->name)->offset == i);
|
||||||
|
}
|
||||||
|
loctab.exitscope();
|
||||||
|
for (size_t i = 0; i < attrs.size(); ++ i) {
|
||||||
|
auto attr = attrs[i];
|
||||||
|
assert(loctab.lookup(attr->name) && loctab.lookup(attr->name)->offset == i);
|
||||||
|
}
|
||||||
|
loctab.exitscope();
|
||||||
|
for (size_t i = 0; i < attrs.size(); ++ i) {
|
||||||
|
auto attr = attrs[i];
|
||||||
|
assert(loctab.lookup(attr->name) == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Add your code to emit
|
||||||
|
// - object initializer
|
||||||
|
// - the class methods
|
||||||
|
// - etc...
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// CgenNode methods
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma region CgenNode
|
||||||
|
|
||||||
|
CgenNode::CgenNode(Class_ nd, Basicness bstatus)
|
||||||
|
: class__class((const class__class &)*nd), parentnd(NULL),
|
||||||
|
basic_status(bstatus) {
|
||||||
|
if (!(bstatus == Trivial))
|
||||||
|
stringtable.add_string(
|
||||||
|
name->get_string()); // Add class name to string table
|
||||||
|
}
|
||||||
|
|
||||||
void CgenNode::add_child(CgenNodeP n) { children.push_back(n); }
|
void CgenNode::add_child(CgenNodeP n) { children.push_back(n); }
|
||||||
|
|
||||||
void CgenNode::set_parentnd(CgenNodeP p) {
|
void CgenNode::set_parentnd(CgenNodeP p) {
|
||||||
@ -898,80 +1031,7 @@ void CgenNode::traverse_generate_object() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CgenClassTable::dump_inheritance_tree() {
|
#pragma endregion
|
||||||
CgenNode *object_node = nullptr;
|
|
||||||
|
|
||||||
for (auto cur_node : nodes) {
|
|
||||||
if (cur_node->name == Object) {
|
|
||||||
object_node = cur_node;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
object_node->traverse_dump(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CgenNode *CgenClassTable::get_node(Symbol class_name) {
|
|
||||||
for (auto node : nodes) {
|
|
||||||
if (node->name == class_name) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cgen_debug)
|
|
||||||
std::cerr << "get_node " << class_name << " not found\n";
|
|
||||||
assert(0);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CgenClassTable::code() {
|
|
||||||
if (cgen_debug)
|
|
||||||
cout << "coding global data" << endl;
|
|
||||||
code_global_data();
|
|
||||||
|
|
||||||
if (cgen_debug)
|
|
||||||
cout << "choosing gc" << endl;
|
|
||||||
code_select_gc();
|
|
||||||
|
|
||||||
if (cgen_debug)
|
|
||||||
cout << "coding constants" << endl;
|
|
||||||
code_constants();
|
|
||||||
|
|
||||||
if (cgen_debug)
|
|
||||||
cout << "coding class_nameTab" << endl;
|
|
||||||
code_class_nameTable();
|
|
||||||
|
|
||||||
if (cgen_debug)
|
|
||||||
cout << "coding dispatch tables" << endl;
|
|
||||||
nodes[0]->traverse_generate_object();
|
|
||||||
// nodes[0] is the Object class
|
|
||||||
code_dispatchTable();
|
|
||||||
|
|
||||||
if (cgen_debug)
|
|
||||||
cout << "coding prototype objects" << endl;
|
|
||||||
code_prototypeObject();
|
|
||||||
|
|
||||||
if (cgen_debug)
|
|
||||||
cout << "coding global text" << endl;
|
|
||||||
code_global_text();
|
|
||||||
|
|
||||||
// Add your code to emit
|
|
||||||
// - object initializer
|
|
||||||
// - the class methods
|
|
||||||
// - etc...
|
|
||||||
}
|
|
||||||
|
|
||||||
CgenNodeP CgenClassTable::root() { return probe(Object); }
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// CgenNode methods
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
CgenNode::CgenNode(Class_ nd, Basicness bstatus, CgenClassTableP ct)
|
|
||||||
: class__class((const class__class &)*nd), parentnd(NULL),
|
|
||||||
basic_status(bstatus) {
|
|
||||||
stringtable.add_string(name->get_string()); // Add class name to string table
|
|
||||||
}
|
|
||||||
|
|
||||||
//******************************************************************
|
//******************************************************************
|
||||||
//
|
//
|
||||||
@ -1041,7 +1101,11 @@ void block_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void let_class::code(ostream &s, CgenClassTable *classtab) {}
|
void let_class::code(ostream &s, CgenClassTable *classtab) {
|
||||||
|
this->init->code(s, classtab);
|
||||||
|
emit_push(ZERO, s); // make space for let's new object
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Operations for Int objects is the most simple one, let's start here
|
Operations for Int objects is the most simple one, let's start here
|
||||||
@ -1073,7 +1137,7 @@ void plus_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
emit_add(T1, T1, ACC, s); // $t1 <- val(e1) + val(e2)
|
emit_add(T1, T1, ACC, s); // $t1 <- val(e1) + val(e2)
|
||||||
emit_load(ACC, 1, SP, s); // load new object addr
|
emit_load(ACC, 1, SP, s); // load new object addr
|
||||||
emit_store_int(T1, ACC, s); // store result(now in $t1) to the object
|
emit_store_int(T1, ACC, s); // store result(now in $t1) to the object
|
||||||
emit_addiu(SP, SP, 8, s); // maintain stack balance
|
emit_pop(2, s); // maintain stack balance
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1092,7 +1156,7 @@ void sub_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
emit_sub(T1, T1, ACC, s); // $t1 <- val(e1),$t1 + val(e2),$a0
|
emit_sub(T1, T1, ACC, s); // $t1 <- val(e1),$t1 + val(e2),$a0
|
||||||
emit_load(ACC, 1, SP, s);
|
emit_load(ACC, 1, SP, s);
|
||||||
emit_store_int(T1, ACC, s);
|
emit_store_int(T1, ACC, s);
|
||||||
emit_addiu(SP, SP, 8, s);
|
emit_pop(2, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1111,7 +1175,7 @@ void mul_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
emit_mul(T1, T1, ACC, s); // $t1 <- val(e1),$t1 + val(e2),$a0
|
emit_mul(T1, T1, ACC, s); // $t1 <- val(e1),$t1 + val(e2),$a0
|
||||||
emit_load(ACC, 1, SP, s);
|
emit_load(ACC, 1, SP, s);
|
||||||
emit_store_int(T1, ACC, s);
|
emit_store_int(T1, ACC, s);
|
||||||
emit_addiu(SP, SP, 8, s);
|
emit_pop(2, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void divide_class::code(ostream &s, CgenClassTable *classtab) {
|
void divide_class::code(ostream &s, CgenClassTable *classtab) {
|
||||||
@ -1126,7 +1190,7 @@ void divide_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
emit_div(T1, T1, ACC, s); // $t1 <- val(e1),$t1 + val(e2),$a0
|
emit_div(T1, T1, ACC, s); // $t1 <- val(e1),$t1 + val(e2),$a0
|
||||||
emit_load(ACC, 1, SP, s);
|
emit_load(ACC, 1, SP, s);
|
||||||
emit_store_int(T1, ACC, s);
|
emit_store_int(T1, ACC, s);
|
||||||
emit_addiu(SP, SP, 8, s);
|
emit_pop(2, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1179,7 +1243,7 @@ void lt_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
emit_label_def(label_index_true, s); // first branch goes to here
|
emit_label_def(label_index_true, s); // first branch goes to here
|
||||||
emit_load_bool(ACC, truebool, s); // branch means true
|
emit_load_bool(ACC, truebool, s); // branch means true
|
||||||
emit_label_def(label_index_exit, s); // second jump goes to here
|
emit_label_def(label_index_exit, s); // second jump goes to here
|
||||||
emit_addiu(SP, SP, 4, s); // cleanup anyway, only one push is made
|
emit_pop(1, s); // cleanup anyway, only one push is made
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1200,7 +1264,7 @@ void leq_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
emit_label_def(label_index_true, s);
|
emit_label_def(label_index_true, s);
|
||||||
emit_load_bool(ACC, truebool, s);
|
emit_load_bool(ACC, truebool, s);
|
||||||
emit_label_def(label_index_exit, s);
|
emit_label_def(label_index_exit, s);
|
||||||
emit_addiu(SP, SP, 4, s);
|
emit_pop(1, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1250,7 +1314,7 @@ void eq_class::code(ostream &s, CgenClassTable *classtab) {
|
|||||||
// at this point, $t1=&e1, $t2=&e2, $a0=true, $a1=false. ready to call
|
// at this point, $t1=&e1, $t2=&e2, $a0=true, $a1=false. ready to call
|
||||||
// $a0 will be either true or false, so just keep it as the result
|
// $a0 will be either true or false, so just keep it as the result
|
||||||
emit_label_def(label_index_exit, s);
|
emit_label_def(label_index_exit, s);
|
||||||
emit_addiu(SP, SP, 4, s); // balance stack, 1 push in this expression
|
emit_pop(1, s); // balance stack, 1 push in this expression
|
||||||
}
|
}
|
||||||
|
|
||||||
void int_const_class::code(ostream &s, CgenClassTable *classtab) {
|
void int_const_class::code(ostream &s, CgenClassTable *classtab) {
|
||||||
|
|||||||
@ -9,7 +9,9 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
enum Basicness { Basic, NotBasic };
|
enum Basicness { Basic, NotBasic, Trivial };
|
||||||
|
enum VariableLocation { Attribute, Stack };
|
||||||
|
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
|
||||||
@ -22,6 +24,51 @@ typedef CgenNode *CgenNodeP;
|
|||||||
typedef std::vector<std::pair<class__class *, method_class *>> MethodListT;
|
typedef std::vector<std::pair<class__class *, method_class *>> MethodListT;
|
||||||
typedef std::vector<attr_class *> AttrListT;
|
typedef std::vector<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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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> {
|
class CgenClassTable : public SymbolTable<Symbol, CgenNode> {
|
||||||
private:
|
private:
|
||||||
std::vector<CgenNode *> nodes;
|
std::vector<CgenNode *> nodes;
|
||||||
@ -59,9 +106,10 @@ private:
|
|||||||
void gen_init_code();
|
void gen_init_code();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
LocationTable loctab;
|
||||||
CgenClassTable(Classes, ostream &str);
|
CgenClassTable(Classes, ostream &str);
|
||||||
void code();
|
void code();
|
||||||
CgenNodeP root();
|
CgenNode* root() { return nodes[0]; }
|
||||||
/* aquire an unused label index */
|
/* aquire an unused label index */
|
||||||
int alloc_label_index() { return label_count++; }
|
int alloc_label_index() { return label_count++; }
|
||||||
};
|
};
|
||||||
@ -82,7 +130,7 @@ private:
|
|||||||
// method list including inherited and overidden methods
|
// method list including inherited and overidden methods
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CgenNode(Class_ c, Basicness bstatus, CgenClassTableP class_table);
|
CgenNode(Class_ c, Basicness bstatus);
|
||||||
|
|
||||||
void add_child(CgenNodeP child);
|
void add_child(CgenNodeP child);
|
||||||
std::vector<CgenNode *> *get_children() { return &children; }
|
std::vector<CgenNode *> *get_children() { return &children; }
|
||||||
|
|||||||
@ -71,6 +71,14 @@ class E {
|
|||||||
method_isvoid(x1: Object) : Bool {
|
method_isvoid(x1: Object) : Bool {
|
||||||
isvoid x1
|
isvoid x1
|
||||||
};
|
};
|
||||||
|
method_let1(x1: Int) : Object {
|
||||||
|
let x2 : Int <- x1 + 10 in
|
||||||
|
x2 <- x1
|
||||||
|
};
|
||||||
|
method_let2(x1: Int) : Object {
|
||||||
|
let x2 : Int <- x1 in
|
||||||
|
x2 <- x1 + 100
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Main inherits IO {
|
class Main inherits IO {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user