dispatchTable
This commit is contained in:
parent
d4aeee16cc
commit
bcbafc9972
@ -24,8 +24,10 @@
|
|||||||
|
|
||||||
#include "cgen.h"
|
#include "cgen.h"
|
||||||
#include "cgen_gc.h"
|
#include "cgen_gc.h"
|
||||||
|
#include "cool-tree.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
extern void emit_string_constant(ostream &str, char *s);
|
extern void emit_string_constant(ostream &str, char *s);
|
||||||
extern int cgen_debug;
|
extern int cgen_debug;
|
||||||
@ -375,11 +377,8 @@ void StringEntry::code_def(ostream &s, int stringclasstag) {
|
|||||||
<< WORD << stringclasstag << endl // tag
|
<< WORD << stringclasstag << endl // tag
|
||||||
<< WORD << (DEFAULT_OBJFIELDS + STRING_SLOTS + (len + 4) / 4)
|
<< WORD << (DEFAULT_OBJFIELDS + STRING_SLOTS + (len + 4) / 4)
|
||||||
<< endl // size
|
<< endl // size
|
||||||
<< WORD;
|
<< WORD << STRINGNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
|
||||||
|
|
||||||
/***** Add dispatch information for class String ******/
|
|
||||||
|
|
||||||
s << endl; // dispatch table
|
|
||||||
s << WORD;
|
s << WORD;
|
||||||
lensym->code_ref(s);
|
lensym->code_ref(s);
|
||||||
s << endl; // string length
|
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 << (DEFAULT_OBJFIELDS + INT_SLOTS) << endl // object size
|
||||||
<< WORD;
|
<< WORD;
|
||||||
|
|
||||||
/***** Add dispatch information for class Int ******/
|
s << WORD << INTNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
|
||||||
|
|
||||||
s << endl; // dispatch table
|
|
||||||
s << WORD << str << endl; // integer value
|
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 << (DEFAULT_OBJFIELDS + BOOL_SLOTS) << endl // object size
|
||||||
<< WORD;
|
<< WORD;
|
||||||
|
|
||||||
/***** Add dispatch information for class Bool ******/
|
s << WORD << BOOLNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
|
||||||
|
|
||||||
s << endl; // dispatch table
|
|
||||||
s << WORD << val << endl; // value (0 or 1)
|
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() {}
|
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() {
|
void CgenClassTable::dump_inheritance_tree() {
|
||||||
CgenNode *object_node = nullptr;
|
CgenNode *object_node = nullptr;
|
||||||
|
|
||||||
@ -838,6 +898,11 @@ void CgenClassTable::code() {
|
|||||||
cout << "coding class_nameTab" << endl;
|
cout << "coding class_nameTab" << endl;
|
||||||
code_class_nameTable();
|
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
|
// Add your code to emit
|
||||||
// - prototype objects
|
// - prototype objects
|
||||||
// - class_nameTab
|
// - class_nameTab
|
||||||
|
|||||||
@ -2,10 +2,12 @@
|
|||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
enum Basicness { Basic, NotBasic };
|
enum Basicness { Basic, NotBasic };
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
@ -17,6 +19,9 @@ typedef CgenClassTable *CgenClassTableP;
|
|||||||
class CgenNode;
|
class CgenNode;
|
||||||
typedef CgenNode *CgenNodeP;
|
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> {
|
class CgenClassTable : public SymbolTable<Symbol, CgenNode> {
|
||||||
private:
|
private:
|
||||||
std::vector<CgenNode *> nodes;
|
std::vector<CgenNode *> nodes;
|
||||||
@ -67,18 +72,26 @@ private:
|
|||||||
/* Allocate a class_tag on first scan increase in scanning order,
|
/* Allocate a class_tag on first scan increase in scanning order,
|
||||||
starting from 1, so 0 is actually invalid by design
|
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:
|
public:
|
||||||
CgenNode(Class_ c, Basicness bstatus, CgenClassTableP class_table);
|
CgenNode(Class_ c, Basicness bstatus, CgenClassTableP class_table);
|
||||||
|
|
||||||
void add_child(CgenNodeP child);
|
void add_child(CgenNodeP child);
|
||||||
std::vector<CgenNode*>& get_children() { return children; }
|
std::vector<CgenNode *> *get_children() { return &children; }
|
||||||
void set_parentnd(CgenNodeP p);
|
void set_parentnd(CgenNodeP p);
|
||||||
CgenNodeP get_parentnd() { return parentnd; }
|
CgenNodeP get_parentnd() { return parentnd; }
|
||||||
int basic() { return (basic_status == Basic); }
|
int basic() { return (basic_status == Basic); }
|
||||||
uint32_t get_class_tag() { return _class_tag; }
|
uint32_t get_class_tag() { return _class_tag; }
|
||||||
void set_class_tag(uint32_t val) { _class_tag = val; }
|
void set_class_tag(uint32_t val) { _class_tag = val; }
|
||||||
void traverse_dump(int pad);
|
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 {
|
class BoolConst {
|
||||||
|
|||||||
@ -10,6 +10,9 @@ class A inherits IO {
|
|||||||
method_common(x1: Int) : SELF_TYPE {
|
method_common(x1: Int) : SELF_TYPE {
|
||||||
self
|
self
|
||||||
};
|
};
|
||||||
|
method_common2() : String {
|
||||||
|
"A"
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class B inherits A {
|
class B inherits A {
|
||||||
@ -21,6 +24,18 @@ class C inherits A {
|
|||||||
method_common(x1: Int) : SELF_TYPE {
|
method_common(x1: Int) : SELF_TYPE {
|
||||||
self
|
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 {
|
class Main inherits IO {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user