From bcbafc9972bc7129b0213482df981747d058a95f Mon Sep 17 00:00:00 2001 From: ridethepig Date: Wed, 29 Mar 2023 21:52:44 +0800 Subject: [PATCH] dispatchTable --- assignments/PA5/cgen.cc | 93 ++++++++++++++++++++++++++++++++------ assignments/PA5/cgen.h | 31 +++++++++---- assignments/PA5/example.cl | 15 ++++++ 3 files changed, 116 insertions(+), 23 deletions(-) diff --git a/assignments/PA5/cgen.cc b/assignments/PA5/cgen.cc index bad2b89..e7a0b4a 100644 --- a/assignments/PA5/cgen.cc +++ b/assignments/PA5/cgen.cc @@ -24,8 +24,10 @@ #include "cgen.h" #include "cgen_gc.h" +#include "cool-tree.h" #include #include +#include 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(feature)); + // inherited attrs cannot be redefined, so simply add to list + } else { + auto method = static_cast(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(this), method); + // overridden method with the same name + overridden_flag = true; + break; + } + } + if (!overridden_flag) { + this->methods.push_back( + std::make_pair(static_cast(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 diff --git a/assignments/PA5/cgen.h b/assignments/PA5/cgen.h index 4b0d955..527674b 100644 --- a/assignments/PA5/cgen.h +++ b/assignments/PA5/cgen.h @@ -2,10 +2,12 @@ #include "emit.h" #include "symtab.h" #include +#include #include -#include #include #include +#include +#include enum Basicness { Basic, NotBasic }; #define TRUE 1 @@ -17,9 +19,12 @@ typedef CgenClassTable *CgenClassTableP; class CgenNode; typedef CgenNode *CgenNodeP; +typedef std::vector> MethodListT; +typedef std::vector AttrListT; + class CgenClassTable : public SymbolTable { private: - std::vector nodes; + std::vector 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 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 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& get_children() { return children; } + std::vector *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 { diff --git a/assignments/PA5/example.cl b/assignments/PA5/example.cl index 89fd448..163f1a9 100644 --- a/assignments/PA5/example.cl +++ b/assignments/PA5/example.cl @@ -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 {