refine code, comment; small bug fix

This commit is contained in:
ridethepig 2023-03-27 16:45:03 +08:00
parent 67cdb55125
commit 891e07e968
5 changed files with 126 additions and 164 deletions

View File

@ -22,6 +22,8 @@ class ErrTest {
SELF_TYPE => self;
x5:
SELF_TYPE => self;
self:
SELF_TYPE => self;
esac;
1 + case (new Ok2_2) of
x1 : Ok2_1 => new Ok2_1;

View File

@ -36,7 +36,6 @@ class Class__class : public tree_node {
public:
tree_node *copy() { return copy_Class_(); }
virtual Class_ copy_Class_() = 0;
virtual void semant(ClassTable*) = 0;
#ifdef Class__EXTRAS
Class__EXTRAS
@ -51,7 +50,6 @@ class Feature_class : public tree_node {
public:
tree_node *copy() { return copy_Feature(); }
virtual Feature copy_Feature() = 0;
virtual void semant(Class_, ClassTable*) = 0;
#ifdef Feature_EXTRAS
Feature_EXTRAS
@ -80,7 +78,6 @@ class Expression_class : public tree_node {
public:
tree_node *copy() { return copy_Expression(); }
virtual Expression copy_Expression() = 0;
virtual Symbol semant(Class_, ClassTable*) = 0;
#ifdef Expression_EXTRAS
Expression_EXTRAS
#endif
@ -167,7 +164,6 @@ public:
Symbol get_name() const { return name; }
Symbol get_parent() const { return parent; }
Features get_features() const { return features; }
void semant(ClassTable*);
#ifdef Class__SHARED_EXTRAS
Class__SHARED_EXTRAS
@ -199,7 +195,6 @@ public:
Formals get_formals() const { return formals; };
Symbol get_return_type() const { return return_type; };
Expression get_expr() const { return expr; };
void semant(Class_, ClassTable*);
#ifdef Feature_SHARED_EXTRAS
Feature_SHARED_EXTRAS
@ -228,7 +223,6 @@ public:
Symbol get_name() const { return name; };
Symbol get_type_decl() const { return type_decl; };
Expression get_init() const { return init; };
void semant(Class_, ClassTable*);
#ifdef Feature_SHARED_EXTRAS
Feature_SHARED_EXTRAS

View File

@ -56,20 +56,23 @@ void dump_with_types(ostream&, int);
#define Class__EXTRAS \
virtual Symbol get_filename() = 0; \
virtual void dump_with_types(ostream&,int) = 0;
virtual void dump_with_types(ostream&,int) = 0; \
virtual void semant(ClassTable*) = 0;
#define class__EXTRAS \
Symbol get_filename() { return filename; } \
void dump_with_types(ostream&,int);
void dump_with_types(ostream&,int); \
void semant(ClassTable*);
#define Feature_EXTRAS \
virtual void dump_with_types(ostream&,int) = 0;
virtual void dump_with_types(ostream&,int) = 0; \
virtual void semant(Class_, ClassTable*) = 0;
#define Feature_SHARED_EXTRAS \
void dump_with_types(ostream&,int);
void dump_with_types(ostream&,int); \
void semant(Class_, ClassTable*);
@ -97,7 +100,9 @@ Symbol get_type() { return type; } \
Expression set_type(Symbol s) { type = s; return this; } \
virtual void dump_with_types(ostream&,int) = 0; \
void dump_type(ostream&, int); \
Expression_class() { type = (Symbol) NULL; }
Expression_class() { type = (Symbol) NULL; } \
virtual Symbol semant(Class_, ClassTable*) = 0;
#define Expression_SHARED_EXTRAS \
void dump_with_types(ostream&,int); \

View File

@ -222,7 +222,7 @@ void ClassTable::install_all_features() {
_symtab_obj[cur_name] = new SymbolTable<Symbol, Entry>;
_symtab_met[cur_name]->enterscope();
_symtab_obj[cur_name]->enterscope();
_symtab_obj[cur_name]->addid(self, SELF_TYPE);
auto cur_features = cur_class->get_features();
for (auto j = cur_features->first(); cur_features->more(j); j = cur_features->next(j)) {
auto cur_feature = cur_features->nth(j);
@ -492,7 +492,7 @@ ostream& ClassTable::semant_error()
*/
bool ClassTable::conform(Symbol T1, Symbol T0) const {
if (T1 == T0) return true;
if (!class_exist(T0) || !class_exist(T1))
if (!class_defined(T0) || !class_defined(T1))
return true;
auto cur_node_itr = name_to_node.find(T1);
if (cur_node_itr == name_to_node.end()){
@ -509,6 +509,9 @@ bool ClassTable::conform(Symbol T1, Symbol T0) const {
return false;
}
/*
* conformance check with SELF_TYPE support
*/
bool ClassTable::conform_self(Symbol T1, Symbol T0, Symbol env_class) const {
if (T1 == T0) return true;
/*
@ -525,11 +528,17 @@ bool ClassTable::conform_self(Symbol T1, Symbol T0, Symbol env_class) const {
}
}
/*
* conformance check with SELF_TYPE support
*/
bool ClassTable::conform_self(Symbol T1, Symbol T0, Class_ env_class) const {
return conform_self(T1, T0, class_to_name(env_class));
}
bool ClassTable::class_exist(Symbol class_id) const {
/*
* Check whether a class is defined (not including SELF_TYPE)
*/
bool ClassTable::class_defined(Symbol class_id) const {
return name_to_node.find(class_id) != name_to_node.end();
}
@ -541,17 +550,23 @@ bool ClassTable::class_exist(Symbol class_id) const {
* - declared type of a let variable
* - declared type of an attribute
*/
bool ClassTable::class_exist_self(Symbol class_id) const {
bool ClassTable::class_defined_self(Symbol class_id) const {
if (class_id == SELF_TYPE) return true;
else return class_exist(class_id);
else return class_defined(class_id);
}
/*
* Get the `join` of two types, aka Lowest Upper Bound
* Actually it is the LCA of the two nodes on inheritence tree
*
* Warning:
* If either of the inputs is undefined, the operation returns Object
*/
Symbol ClassTable::lub(Symbol T1, Symbol T2) const {
if (T1 == T2) return T1;
auto node1_iter = name_to_node.find(T1);
auto node2_iter = name_to_node.find(T2);
// assert(node1_iter != name_to_node.end());
// assert(node2_iter != name_to_node.end());
/* Return Object if one of the argument is undefined for recovery */
if (node1_iter == name_to_node.end() || node2_iter == name_to_node.end()) {
return Object;
}
@ -585,11 +600,25 @@ Symbol ClassTable::lub(Symbol T1, Symbol T2) const {
return node_lower->get_class()->get_name();
}
/*
* lub operation with SELF_TYPE support
*/
Symbol ClassTable::lub(Symbol T1, Symbol T2, Symbol env_class) const {
if (T1 == SELF_TYPE) T1 = env_class;
if (T2 == SELF_TYPE) T2 = env_class;
return lub(T1, T2);
}
/*
* Wrapper for the Object Symbol Table
*/
SymbolTable<Symbol, Entry>* ClassTable::symtab_obj(Class_ class_i) const {
auto class_id = static_cast<class__class*>(class_i)->get_name();
auto _iter = _symtab_obj.find(class_id);
if (_iter == _symtab_obj.end()) return nullptr;
return _iter->second;
};
/* This is the entry point to the semantic checker.
Your checker should do the following two things:
@ -619,13 +648,7 @@ void program_class::semant()
classtable->install_all_features();
/* Top down type checking */
for (auto class_i : classtable->class_vec()) {
// before we enter a class, add self:SELF_TYPE to its scope
// TODO: Maybe integrate this into last scan
classtable->symtab_obj(class_i)->enterscope();
classtable->symtab_obj(class_i)->addid(self, SELF_TYPE);
class_i->semant(classtable);
// leave scope
classtable->symtab_obj(class_i)->exitscope();
}
if (classtable->errors()) {
@ -649,7 +672,7 @@ void attr_class::semant(Class_ cur_class, ClassTable * classtable)
* Check if Declared Type is defined, if so, do nothing because already
* in AST; else, error report and set its type to Object
*/
if (!classtable->class_exist_self(type_decl)) {
if (!classtable->class_defined_self(type_decl)) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Class " << type_decl
<< " of attribute " << name
@ -674,6 +697,12 @@ void attr_class::semant(Class_ cur_class, ClassTable * classtable)
}
}
/*
* Method:
* Check formal types and and them to scope
* Checks the body of the method in an env in which formals and `self` bounded
* Check body type conforms to the declared return type
*/
void method_class::semant(Class_ cur_class, ClassTable * classtable)
{
auto symtab_obj = classtable->symtab_obj(cur_class);
@ -694,7 +723,7 @@ void method_class::semant(Class_ cur_class, ClassTable * classtable)
<< "Formal parameter " << formal_i_name
<< " is multiply defined.\n";
}
if (!classtable->class_exist(formal_i_type)) {
if (!classtable->class_defined(formal_i_type)) {
classtable->semant_error(cur_class->get_filename(), formal_i)
<< "Class " << formal_i_type
<< " of formal parameter " << formal_i_name
@ -702,7 +731,7 @@ void method_class::semant(Class_ cur_class, ClassTable * classtable)
}
}
auto expr_type = this->expr->semant(cur_class, classtable);
if (!classtable->class_exist_self(this->return_type)) {
if (!classtable->class_defined_self(this->return_type)) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Undefined return type " << this->return_type
<< " in method " << this->name
@ -725,15 +754,14 @@ void method_class::semant(Class_ cur_class, ClassTable * classtable)
*/
Symbol assign_class::semant(Class_ cur_class, ClassTable* classtable)
{
// auto lhs_type = classtable->symtab_obj(cur_class)->lookup(name);
if (this->name == self) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Cannot assign to 'self'.\n";
}
auto lhs_type = classtable->symtab_object_lookup_parent(cur_class, name);
auto lhs_type = classtable->symtab_object_lookup_parent(cur_class, this->name);
if (lhs_type == nullptr) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Assignment to undeclared variable " << name << ".\n";
<< "Assignment to undeclared variable " << this->name << ".\n";
lhs_type = Object;
}
auto rhs_type = this->expr->semant(cur_class, classtable);
@ -741,7 +769,7 @@ Symbol assign_class::semant(Class_ cur_class, ClassTable* classtable)
classtable->semant_error(cur_class->get_filename(), this)
<< "Type " << rhs_type
<< " of assigned expression does not conform to declared type " << lhs_type
<< " of identifier " << name
<< " of identifier " << this->name
<< ".\n";
}
this->type = rhs_type;
@ -750,14 +778,14 @@ Symbol assign_class::semant(Class_ cur_class, ClassTable* classtable)
Symbol static_dispatch_class::semant(Class_ cur_class, ClassTable* classtable)
{
auto expr_type = expr->semant(cur_class, classtable);
auto expr_type = this->expr->semant(cur_class, classtable);
std::vector<Symbol> _param_type;
for (auto i = actual->first(); actual->more(i); i = actual->next(i)) {
auto param_i = actual->nth(i);
for (auto i = this->actual->first(); this->actual->more(i); i = this->actual->next(i)) {
auto param_i = this->actual->nth(i);
auto param_i_type = param_i->semant(cur_class, classtable);
_param_type.push_back(param_i_type);
}
if (!classtable->class_exist(this->type_name)) {
if (!classtable->class_defined(this->type_name)) {
if (this->type_name == SELF_TYPE){
classtable->semant_error(cur_class->get_filename(), this)
<< "Static dispatch to SELF_TYPE.\n";
@ -767,33 +795,27 @@ Symbol static_dispatch_class::semant(Class_ cur_class, ClassTable* classtable)
<< "Static dispatch on undefined class " << this->type_name
<< ".\n";
}
this->type = Object;
return this->type;
return (this->type = Object);
}
if (!classtable->conform_self(expr_type, this->type_name, cur_class)) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Expression type " << expr_type
<< " does not conform to declared static dispatch type " << this->type_name
<< ".\n";
this->type = Object;
return this->type;
return (this->type = Object);
}
// auto symtab_method = classtable->symtab_met(this->type_name);
// auto cur_method = symtab_method->lookup(name);
auto cur_method = classtable->symtab_method_lookup_parent(this->type_name, this->name);
if (cur_method == nullptr) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Static dispatch to undefined method " << name
<< "Static dispatch to undefined method " << this->name
<< ".\n";
this->type = Object;
return Object;
return (this->type = Object);
}
if (actual->len() != cur_method->get_formals()->len()) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Method " << name
<< "Method " << this->name
<< " called with wrong number of arguments.\n";
this->type = Object;
return Object;
return (this->type = Object);
}
auto formals = cur_method->get_formals();
auto _param_type_iter = _param_type.begin();
@ -814,8 +836,7 @@ Symbol static_dispatch_class::semant(Class_ cur_class, ClassTable* classtable)
return_type = expr_type;
// if expr_type (T_0) is SELF_TYPE, then dispath type just keep it
}
this->type = return_type;
return this->type;
return (this->type = return_type);
}
/*
@ -826,10 +847,10 @@ Symbol static_dispatch_class::semant(Class_ cur_class, ClassTable* classtable)
*/
Symbol dispatch_class::semant(Class_ cur_class, ClassTable* classtable)
{
auto expr_type = expr->semant(cur_class, classtable); // T_0
auto expr_type = this->expr->semant(cur_class, classtable); // T_0
std::vector<Symbol> _param_type; // T_i
for (auto i = actual->first(); actual->more(i); i = actual->next(i)) {
auto param_i = actual->nth(i);
for (auto i = this->actual->first(); this->actual->more(i); i = this->actual->next(i)) {
auto param_i = this->actual->nth(i);
auto param_i_type = param_i->semant(cur_class, classtable);
_param_type.push_back(param_i_type);
}
@ -837,29 +858,27 @@ Symbol dispatch_class::semant(Class_ cur_class, ClassTable* classtable)
if (expr_type == SELF_TYPE) {
method_env_class = classtable->class_to_name(cur_class);
}
if (!classtable->class_exist(method_env_class)) {
if (!classtable->class_defined(method_env_class)) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Dispatch on undefined class " << method_env_class
<< ".\n";
this->type = Object;
return this->type;
}
// auto symtab_method = classtable->symtab_met(method_env_class);
// auto cur_method = symtab_method->lookup(name);
auto cur_method = classtable->symtab_method_lookup_parent(method_env_class, this->name);
if (cur_method == nullptr) {
if (semant_debug) {
std::cerr << "lookup method " << this->name << " in class " << method_env_class << "\n";
}
classtable->semant_error(cur_class->get_filename(), this)
<< "Dispatch to undefined method " << name
<< "Dispatch to undefined method " << this->name
<< ".\n";
this->type = Object;
return Object;
}
if (actual->len() != cur_method->get_formals()->len()) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Method " << name
<< "Method " << this->name
<< " called with wrong number of arguments.\n";
this->type = Object;
return Object;
@ -886,8 +905,7 @@ Symbol dispatch_class::semant(Class_ cur_class, ClassTable* classtable)
if (return_type == SELF_TYPE) {
return_type = expr_type;
}
this->type = return_type;
return this->type;
return (this->type = return_type);
}
/*
@ -924,8 +942,7 @@ Symbol loop_class::semant(Class_ cur_class, ClassTable* classtable)
<< "Loop condition does not have type Bool.\n";
}
auto _ = this->body->semant(cur_class, classtable);
this->type = Object;
return Object;
return (this->type = Object);
}
/*
@ -939,8 +956,8 @@ Symbol typcase_class::semant(Class_ cur_class, ClassTable* classtable)
auto _ = this->expr->semant(cur_class, classtable);
std::set<Symbol> _existed_type;
Symbol entire_type = nullptr;
for (auto i = cases->first(); cases->more(i); i = cases->next(i)) {
auto branch_i = static_cast<branch_class*>(cases->nth(i));
for (auto i = this->cases->first(); this->cases->more(i); i = this->cases->next(i)) {
auto branch_i = static_cast<branch_class*>(this->cases->nth(i));
auto type_decl_i = branch_i->get_type_decl();
auto name_i = branch_i->get_name();
// first check duplicated type
@ -957,12 +974,16 @@ Symbol typcase_class::semant(Class_ cur_class, ClassTable* classtable)
if the type does not exist, it continue to use the undefined type
for later expr typing
*/
if (name_i == self) {
classtable->semant_error(cur_class->get_filename(), branch_i)
<< "\'self\' bound in 'case'.\n";
}
if (type_decl_i == SELF_TYPE) {
classtable->semant_error(cur_class->get_filename(), branch_i)
<< "Identifier " << name_i
<< " declared with type SELF_TYPE in case branch.\n";
}
else if (!classtable->class_exist(type_decl_i)) {
else if (!classtable->class_defined(type_decl_i)) {
classtable->semant_error(cur_class->get_filename(), branch_i)
<< "Class " << type_decl_i
<< " of case branch is undefined.\n";
@ -980,8 +1001,7 @@ Symbol typcase_class::semant(Class_ cur_class, ClassTable* classtable)
entire_type = classtable->lub(entire_type, branch_expr_type);
}
}
this->type = entire_type;
return this->type;
return (this->type = entire_type);
}
/*
@ -991,11 +1011,10 @@ Symbol typcase_class::semant(Class_ cur_class, ClassTable* classtable)
Symbol block_class::semant(Class_ cur_class, ClassTable* classtable)
{
Symbol type_i;
for (auto i = body->first(); body->more(i); i = body->next(i)) {
type_i = body->nth(i)->semant(cur_class, classtable);
for (auto i = this->body->first(); this->body->more(i); i = this->body->next(i)) {
type_i = this->body->nth(i)->semant(cur_class, classtable);
}
this->type = type_i;
return type_i;
return (this->type = type_i);
}
/*
@ -1012,28 +1031,27 @@ Symbol let_class::semant(Class_ cur_class, ClassTable* classtable)
classtable->semant_error(cur_class->get_filename(), this)
<< "\'self\' cannot be bound in a \'let\' expression.\n";
}
if (!classtable->class_exist_self(type_decl)) {
if (!classtable->class_defined_self(this->type_decl)) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Class " << type_decl
<< " of let-bound identifier " << identifier
<< "Class " << this->type_decl
<< " of let-bound identifier " << this->identifier
<< " is undefined.\n";
}
if (typeid(*init) != typeid(no_expr_class)) {
auto init_type = init->semant(cur_class, classtable);
if (!classtable->conform_self(init_type, type_decl, cur_class)) {
if (typeid(*this->init) != typeid(no_expr_class)) {
auto init_type = this->init->semant(cur_class, classtable);
if (!classtable->conform_self(init_type, this->type_decl, cur_class)) {
classtable->semant_error(cur_class->get_filename(), this)
<< "Inferred type " << init_type
<< " of initialization of " << identifier
<< " does not conform to identifier's declared type " << type_decl
<< " of initialization of " << this->identifier
<< " does not conform to identifier's declared type " << this->type_decl
<< ".\n";
}
}
classtable->symtab_obj(cur_class)->enterscope();
classtable->symtab_obj(cur_class)->addid(identifier, type_decl);
classtable->symtab_obj(cur_class)->addid(this->identifier, this->type_decl);
auto expr_type = this->body->semant(cur_class, classtable);
classtable->symtab_obj(cur_class)->exitscope();
this->type = expr_type;
return this->type;
return (this->type = expr_type);
}
/*
@ -1050,8 +1068,7 @@ Symbol plus_class::semant(Class_ cur_class, ClassTable* classtable)
<< " + " << e2_type
<< "\n";
}
this->type = Int;
return Int;
return (this->type = Int);
}
/*
@ -1068,8 +1085,7 @@ Symbol sub_class::semant(Class_ cur_class, ClassTable* classtable)
<< " - " << e2_type
<< "\n";
}
this->type = Int;
return Int;
return (this->type = Int);
}
/*
@ -1086,8 +1102,7 @@ Symbol mul_class::semant(Class_ cur_class, ClassTable* classtable)
<< " * " << e2_type
<< "\n";
}
this->type = Int;
return Int;
return (this->type = Int);
}
/*
@ -1104,8 +1119,7 @@ Symbol divide_class::semant(Class_ cur_class, ClassTable* classtable)
<< " / " << e2_type
<< "\n";
}
this->type = Int;
return Int;
return (this->type = Int);
}
/*
@ -1120,8 +1134,7 @@ Symbol neg_class::semant(Class_ cur_class, ClassTable* classtable)
<< "Argument of '~' has type " << type_subexpr
<< " instead of Int.\n";
}
this->type = Int;
return Int;
return (this->type = Int);
}
/*
@ -1138,8 +1151,7 @@ Symbol lt_class::semant(Class_ cur_class, ClassTable* classtable)
<< " < " << e2_type
<< "\n";
}
this->type = Bool;
return Bool;
return (this->type = Bool);
}
/*
@ -1159,8 +1171,7 @@ Symbol eq_class::semant(Class_ cur_class, ClassTable* classtable)
classtable->semant_error(cur_class->get_filename(), this)
<< "Illegal comparison with a basic type.\n";
}
this->type = Bool;
return Bool;
return (this->type = Bool);
}
/*
@ -1177,8 +1188,7 @@ Symbol leq_class::semant(Class_ cur_class, ClassTable* classtable)
<< " <= " << e2_type
<< "\n";
}
this->type = Bool;
return Bool;
return (this->type = Bool);
}
/*
@ -1201,8 +1211,7 @@ Symbol comp_class::semant(Class_ cur_class, ClassTable* classtable)
<< "Argument of 'not' has type " << type_subexpr
<< " instead of Bool.\n";
}
this->type = Bool;
return Bool;
return (this->type = Bool);
}
/*
@ -1211,8 +1220,7 @@ Symbol comp_class::semant(Class_ cur_class, ClassTable* classtable)
*/
Symbol int_const_class::semant(Class_ cur_class, ClassTable* classtable)
{
this->type = Int;
return this->type;
return (this->type = Int);
}
/*
@ -1221,8 +1229,7 @@ Symbol int_const_class::semant(Class_ cur_class, ClassTable* classtable)
*/
Symbol bool_const_class::semant(Class_ cur_class, ClassTable* classtable)
{
this->type = Bool;
return this->type;
return (this->type = Bool);
}
/*
@ -1231,8 +1238,7 @@ Symbol bool_const_class::semant(Class_ cur_class, ClassTable* classtable)
*/
Symbol string_const_class::semant(Class_ cur_class, ClassTable* classtable)
{
this->type = Str;
return this->type;
return (this->type = Str);
}
/*
@ -1248,13 +1254,13 @@ Symbol string_const_class::semant(Class_ cur_class, ClassTable* classtable)
*/
Symbol new__class::semant(Class_ cur_class, ClassTable* classtable)
{
if (classtable->class_exist_self(this->type_name)) {
if (classtable->class_defined_self(this->type_name)) {
this->type = this->type_name;
}
else {
classtable->semant_error(cur_class->get_filename(), this)
<< "\'new\' used with undefined class " << this->type_name
<< ".\n";
<< "\'new\' used with undefined class " << this->type_name
<< ".\n";
this->type = Object;
}
return this->type;
@ -1267,8 +1273,7 @@ Symbol new__class::semant(Class_ cur_class, ClassTable* classtable)
Symbol isvoid_class::semant(Class_ cur_class, ClassTable* classtable)
{
auto _ = this->e1->semant(cur_class, classtable);
this->type = Bool;
return Bool;
return (this->type = Bool);
}
/*
@ -1289,20 +1294,13 @@ Symbol no_expr_class::semant(Class_ cur_class, ClassTable* classtable)
*/
Symbol object_class::semant(Class_ cur_class, ClassTable* classtable)
{
auto object_type = classtable->symtab_object_lookup_parent(cur_class, name);
auto object_type = classtable->symtab_object_lookup_parent(cur_class, this->name);
if (object_type != nullptr) {
this->type = object_type;
return object_type;
return (this->type = object_type);
}
else {
if (semant_debug) {
std::cerr << "Cannot find " << name << " in Class " << classtable->class_to_name(cur_class) << "\n";
classtable->symtab_obj(cur_class)->dump();
std::cerr << "-------------------\n";
}
classtable->semant_error(cur_class->get_filename(), this)
<< "Undeclared identifier " << name<< ".\n";
this->type = Object;
return Object;
<< "Undeclared identifier " << this->name<< ".\n";
return (this->type = Object);
}
}

View File

@ -103,32 +103,9 @@ public:
class__class* get_class() {
return static_cast<class__class*>(self);
}
// static void traverse_iter(ClassGraphNode* root) {
// auto cur_node = root;
// std::vector<size_t> stk;
// stk.push_back(0);
// std::cout << pad((stk.size()-1) * 4) << cur_node->get_class()->get_name() << "\n";
// while (!stk.empty()) {
// if (cur_node->children.size() == stk.back()) {
// // we have finished all the children
// stk.pop_back();
// cur_node = cur_node->parent;
// continue;
// }
// auto next_idx = stk.back();
// stk.pop_back();
// stk.push_back(next_idx + 1);
// cur_node = cur_node->children[next_idx];
// std::cout << pad((stk.size()) * 2) << cur_node->get_class()->get_name() << "\n";
// stk.push_back(0);
// }
// }
};
// First we need a tree-like struct to store inheritence relationship
// Since class doesn't need to be defined before used, I guess first
class ClassTable {
private:
int semant_errors;
@ -153,6 +130,7 @@ private:
public:
ClassTable(Classes);
/* helpers */
void install_all_features();
void symtab_dump(Symbol);
@ -163,30 +141,15 @@ public:
bool conform(Symbol, Symbol) const;
bool conform_self(Symbol, Symbol, Symbol) const;
bool conform_self(Symbol, Symbol, Class_) const;
bool class_exist(Symbol) const;
bool class_exist_self(Symbol) const;
bool class_defined(Symbol) const;
bool class_defined_self(Symbol) const;
Symbol lub(Symbol, Symbol) const;
Symbol lub(Symbol, Symbol, Symbol) const;
static Symbol class_to_name(Class_ class_item) { return static_cast<class__class*>(class_item)->get_name(); }
/* wrappers */
std::vector<class__class*>& class_vec() { return _class_vec; }
SymbolTable<Symbol, Entry>* symtab_obj(Class_ class_i) const {
auto class_id = static_cast<class__class*>(class_i)->get_name();
auto _iter = _symtab_obj.find(class_id);
if (_iter == _symtab_obj.end()) return nullptr;
return _iter->second;
};
SymbolTable<Symbol, method_class>* symtab_met(Class_ class_i) const {
auto class_id = static_cast<class__class*>(class_i)->get_name();
auto _iter = _symtab_met.find(class_id);
if (_iter == _symtab_met.end()) return nullptr;
return _iter->second;
};
SymbolTable<Symbol, method_class>* symtab_met(Symbol class_id) const {
auto _iter = _symtab_met.find(class_id);
if (_iter == _symtab_met.end()) return nullptr;
return _iter->second;
};
SymbolTable<Symbol, Entry>* symtab_obj(Class_ class_i) const;
int errors() { return semant_errors; }
ostream& semant_error();