dispatchTable

This commit is contained in:
ridethepig 2023-03-29 21:52:44 +08:00
parent d4aeee16cc
commit bcbafc9972
3 changed files with 116 additions and 23 deletions

View File

@ -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;
@ -374,12 +376,9 @@ void StringEntry::code_def(ostream &s, int stringclasstag) {
s << LABEL // label
<< WORD << stringclasstag << endl // tag
<< WORD << (DEFAULT_OBJFIELDS + STRING_SLOTS + (len + 4) / 4)
<< endl // size
<< WORD;
<< endl // size
<< 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,10 +416,8 @@ 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 << str << endl; // integer value
s << WORD << INTNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
s << WORD << str << endl; // integer value
}
//
@ -455,10 +452,8 @@ 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 << val << endl; // value (0 or 1)
s << WORD << BOOLNAME << DISPTAB_SUFFIX << endl; // dispatch ptr
s << WORD << val << endl; // value (0 or 1)
}
#pragma endregion
@ -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

View File

@ -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,9 +19,12 @@ 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;
std::vector<CgenNode *> nodes;
ostream &str;
int stringclasstag;
int intclasstag;
@ -49,7 +54,7 @@ private:
void code_class_nameTable();
void code_dispatchTable();
void code_prototypeObject();
CgenNode* get_node(Symbol);
CgenNode *get_node(Symbol);
public:
CgenClassTable(Classes, ostream &str);
@ -59,26 +64,34 @@ public:
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
uint32_t _class_tag = 0;
CgenNodeP parentnd; // Parent of class
std::vector<CgenNode *> children; // Children of class
Basicness basic_status; // `Basic' if class is basic
// `NotBasic' otherwise
uint32_t _class_tag = 0;
/* 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 {

View File

@ -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 {