dispatchTable
This commit is contained in:
parent
d4aeee16cc
commit
bcbafc9972
@ -24,8 +24,10 @@
|
||||
|
||||
#include "cgen.h"
|
||||
#include "cgen_gc.h"
|
||||
#include "cool-tree.h"
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
extern void emit_string_constant(ostream &str, char *s);
|
||||
extern int cgen_debug;
|
||||
@ -375,11 +377,8 @@ void StringEntry::code_def(ostream &s, int stringclasstag) {
|
||||
<< WORD << stringclasstag << endl // tag
|
||||
<< WORD << (DEFAULT_OBJFIELDS + STRING_SLOTS + (len + 4) / 4)
|
||||
<< endl // size
|
||||
<< WORD;
|
||||
<< WORD << STRINGNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
|
||||
|
||||
/***** Add dispatch information for class String ******/
|
||||
|
||||
s << endl; // dispatch table
|
||||
s << WORD;
|
||||
lensym->code_ref(s);
|
||||
s << endl; // string length
|
||||
@ -417,9 +416,7 @@ void IntEntry::code_def(ostream &s, int intclasstag) {
|
||||
<< WORD << (DEFAULT_OBJFIELDS + INT_SLOTS) << endl // object size
|
||||
<< WORD;
|
||||
|
||||
/***** Add dispatch information for class Int ******/
|
||||
|
||||
s << endl; // dispatch table
|
||||
s << WORD << INTNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
|
||||
s << WORD << str << endl; // integer value
|
||||
}
|
||||
|
||||
@ -455,9 +452,7 @@ void BoolConst::code_def(ostream &s, int boolclasstag) {
|
||||
<< WORD << (DEFAULT_OBJFIELDS + BOOL_SLOTS) << endl // object size
|
||||
<< WORD;
|
||||
|
||||
/***** Add dispatch information for class Bool ******/
|
||||
|
||||
s << endl; // dispatch table
|
||||
s << WORD << BOOLNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
|
||||
s << WORD << val << endl; // value (0 or 1)
|
||||
}
|
||||
|
||||
@ -595,7 +590,16 @@ void CgenClassTable::code_class_nameTable() {
|
||||
}
|
||||
}
|
||||
|
||||
void CgenClassTable::code_dispatchTable() {}
|
||||
void CgenClassTable::code_dispatchTable() {
|
||||
for (auto node : nodes) {
|
||||
str << node->name << DISPTAB_SUFFIX << LABEL;
|
||||
for (auto method_record : *node->get_methods()) {
|
||||
auto class_node = method_record.first;
|
||||
auto method = method_record.second;
|
||||
str << WORD << class_node->name << "." << method->name << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CgenClassTable::code_prototypeObject() {}
|
||||
|
||||
@ -797,6 +801,62 @@ void CgenNode::traverse_dump(int pad) {
|
||||
}
|
||||
}
|
||||
|
||||
void CgenNode::traverse_generate_object() {
|
||||
int parent_method_end = 0;
|
||||
if (parentnd) {
|
||||
// Inherit attrs & methods
|
||||
auto parent_attrs = parentnd->get_attributes();
|
||||
for (auto attr : *parent_attrs) {
|
||||
this->attributes.push_back(attr);
|
||||
}
|
||||
auto parent_methods = parentnd->get_methods();
|
||||
for (auto method : *parent_methods) {
|
||||
this->methods.push_back(method);
|
||||
}
|
||||
parent_method_end = this->methods.size();
|
||||
}
|
||||
for (auto feature_i = features->first(); features->more(feature_i);
|
||||
feature_i = features->next(feature_i)) {
|
||||
auto feature = features->nth(feature_i);
|
||||
if (typeid(*feature) == typeid(attr_class)) {
|
||||
this->attributes.push_back(static_cast<attr_class *>(feature));
|
||||
// inherited attrs cannot be redefined, so simply add to list
|
||||
} else {
|
||||
auto method = static_cast<method_class *>(feature);
|
||||
auto overridden_flag = false;
|
||||
for (auto i = 0; i < parent_method_end; ++i) {
|
||||
if (this->methods[i].second->name == method->name) {
|
||||
this->methods[i] =
|
||||
std::make_pair(static_cast<class__class *>(this), method);
|
||||
// overridden method with the same name
|
||||
overridden_flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!overridden_flag) {
|
||||
this->methods.push_back(
|
||||
std::make_pair(static_cast<class__class *>(this), method));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cgen_debug) {
|
||||
std::cerr << "Object info -- " << this->name << "\n";
|
||||
std::cerr << "Attributes:\n";
|
||||
for (auto attr : attributes) {
|
||||
std::cerr << " " << attr->name << ":" << attr->type_decl << "\n";
|
||||
}
|
||||
std::cerr << "Methods:\n";
|
||||
for (auto method : methods) {
|
||||
std::cerr << " " << method.first->name << "." << method.second->name
|
||||
<< ":" << method.second->return_type << "\n";
|
||||
}
|
||||
std::cerr << "\n";
|
||||
}
|
||||
for (auto child : children) {
|
||||
child->traverse_generate_object();
|
||||
}
|
||||
}
|
||||
|
||||
void CgenClassTable::dump_inheritance_tree() {
|
||||
CgenNode *object_node = nullptr;
|
||||
|
||||
@ -838,6 +898,11 @@ void CgenClassTable::code() {
|
||||
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();
|
||||
// Add your code to emit
|
||||
// - prototype objects
|
||||
// - class_nameTab
|
||||
|
||||
@ -2,10 +2,12 @@
|
||||
#include "emit.h"
|
||||
#include "symtab.h"
|
||||
#include <assert.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
enum Basicness { Basic, NotBasic };
|
||||
#define TRUE 1
|
||||
@ -17,6 +19,9 @@ typedef CgenClassTable *CgenClassTableP;
|
||||
class CgenNode;
|
||||
typedef CgenNode *CgenNodeP;
|
||||
|
||||
typedef std::vector<std::pair<class__class *, method_class *>> MethodListT;
|
||||
typedef std::vector<attr_class *> AttrListT;
|
||||
|
||||
class CgenClassTable : public SymbolTable<Symbol, CgenNode> {
|
||||
private:
|
||||
std::vector<CgenNode *> nodes;
|
||||
@ -67,18 +72,26 @@ private:
|
||||
/* Allocate a class_tag on first scan increase in scanning order,
|
||||
starting from 1, so 0 is actually invalid by design
|
||||
*/
|
||||
AttrListT attributes;
|
||||
// attr list including inherited
|
||||
MethodListT methods;
|
||||
// method list including inherited and overidden methods
|
||||
|
||||
public:
|
||||
CgenNode(Class_ c, Basicness bstatus, CgenClassTableP class_table);
|
||||
|
||||
void add_child(CgenNodeP child);
|
||||
std::vector<CgenNode*>& get_children() { return children; }
|
||||
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; }
|
||||
void set_class_tag(uint32_t val) { _class_tag = val; }
|
||||
void traverse_dump(int pad);
|
||||
uint32_t get_object_size() { return (3 + attributes.size()); }
|
||||
void traverse_generate_object();
|
||||
AttrListT *get_attributes() { return &attributes; };
|
||||
MethodListT *get_methods() { return &methods; };
|
||||
};
|
||||
|
||||
class BoolConst {
|
||||
|
||||
@ -10,6 +10,9 @@ class A inherits IO {
|
||||
method_common(x1: Int) : SELF_TYPE {
|
||||
self
|
||||
};
|
||||
method_common2() : String {
|
||||
"A"
|
||||
};
|
||||
};
|
||||
|
||||
class B inherits A {
|
||||
@ -21,6 +24,18 @@ class C inherits A {
|
||||
method_common(x1: Int) : SELF_TYPE {
|
||||
self
|
||||
};
|
||||
method_common2() : String {
|
||||
"C"
|
||||
};
|
||||
method_1(x1: Int) : Bool {
|
||||
true
|
||||
};
|
||||
};
|
||||
|
||||
class D inherits C {
|
||||
method_common(x1: Int) : SELF_TYPE {
|
||||
self
|
||||
};
|
||||
};
|
||||
|
||||
class Main inherits IO {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user