disable inheritance from int bool str

This commit is contained in:
ridethepig 2023-03-24 11:56:17 +00:00
parent 2c4d9cdcc8
commit e3673e17d3
3 changed files with 29 additions and 8 deletions

View File

@ -27,6 +27,14 @@ class Ok2_2 inherits Ok1 {};
class Ok3 inherits Ok2_1 {}; class Ok3 inherits Ok2_1 {};
class Ok4 inherits Ok2_2 {}; class Ok4 inherits Ok2_2 {};
(* Cool has restrictions on inheriting from basic classes *)
class Err1 inherits Int {};
class Err3 inherits String {};
class Err3 inherits Bool {};
class Err4 inherits Err3 {};
class Err4 inherits NOEXIST {};
class Main inherits IO { class Main inherits IO {
main(): Object { main(): Object {

View File

@ -1,2 +1,2 @@
#!/bin/csh -f #!/bin/bash
./lexer $* | ./parser $* | ./semant $* ./lexer $* | ./parser $* | ./semant $*

View File

@ -5,6 +5,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <utility> #include <utility>
#include <vector>
#include "cool-tree.h" #include "cool-tree.h"
#include "semant.h" #include "semant.h"
#include "utilities.h" #include "utilities.h"
@ -88,25 +89,37 @@ static void initialize_constants(void)
ClassTable::ClassTable(Classes classes) : semant_errors(0) , error_stream(cerr) { ClassTable::ClassTable(Classes classes) : semant_errors(0) , error_stream(cerr) {
install_basic_classes(); install_basic_classes();
std::vector<class__class* > class_vec;
for (auto i = classes->first(); classes->more(i); i = classes->next(i)) { for (auto i = classes->first(); classes->more(i); i = classes->next(i)) {
auto class_i = static_cast<class__class*>(classes->nth(i)); auto class_i = static_cast<class__class*>(classes->nth(i));
if (name_to_node.find(class_i->get_name()) != name_to_node.end()) { if (name_to_node.find(class_i->get_name()) != name_to_node.end()) {
semant_error(class_i) << "Class `" << class_i->get_name() << "` was previously defined.\n"; semant_error(class_i) << "Class " << class_i->get_name() << " was previously defined.\n";
} }
else { else {
name_to_node[class_i->get_name()] = new ClassGraphNode(class_i, nullptr); name_to_node[class_i->get_name()] = new ClassGraphNode(class_i, nullptr);
// null means we have this class, but not yet build inheritence graph for it // null means we have this class, but not yet build inheritence graph for it
class_vec.push_back(class_i);
} }
} }
for (auto i = classes->first(); classes->more(i); i = classes->next(i)) {
auto class_i = static_cast<class__class*>(classes->nth(i)); auto sym_Bool = idtable.lookup_string("Bool");
if (name_to_node.find(class_i->get_parent()) == name_to_node.end()) { auto sym_Int = idtable.lookup_string("Int");
auto sym_String = idtable.lookup_string("String");
for (auto class_i : class_vec) {
auto sym_parent = class_i->get_parent();
// Cool has restrictions on inheriting from the basic classes
if ( sym_parent == sym_Bool || sym_parent == sym_Int || sym_parent == sym_String) {
semant_error(class_i) << "Class " << class_i->get_name()
<< " cannot inherit class " << sym_parent << ".\n";
}
else if (name_to_node.find(sym_parent) == name_to_node.end()) {
semant_error(class_i) << "Class `" << class_i->get_name() << "` inherits from an undefined class `" semant_error(class_i) << "Class `" << class_i->get_name() << "` inherits from an undefined class `"
<< class_i->get_parent() << "`\n"; << sym_parent << "`\n";
} }
else { else {
auto class_parent = name_to_node[class_i->get_parent()]; auto class_parent = name_to_node[sym_parent];
assert(class_parent != nullptr); // assert(class_parent != nullptr);
class_parent->append_child(name_to_node[class_i->get_name()]); class_parent->append_child(name_to_node[class_i->get_name()]);
} }
} }