Commit b4061d29 authored by zygzagZ's avatar zygzagZ

refactor v2

parent 37fabd11
......@@ -1427,6 +1427,7 @@ ClassT::ClassT(PIdent *p1)
ClassT::ClassT(const ClassT & other)
{
pident_ = other.pident_->clone();
binding = other.binding;
}
ClassT &ClassT::operator=(const ClassT & other)
......
......@@ -719,11 +719,12 @@ public:
Array(const Array &);
Array &operator=(const Array &);
Array(Type *p1);
Array() : type_(nullptr) {};
~Array();
virtual void accept(Visitor *v);
virtual Array *clone() const;
void swap(Array &);
std::string printName() const { return type_->printName() + "[]"; }
std::string printName() const { return type_ ? type_->printName() + "[]" : "array"; }
bool isEqual(Type const *other) const {
if (const Array* casted = dynamic_cast<const Array*>(other))
return *type_ == *casted->type_;
......
......@@ -36,7 +36,7 @@ public:
weak_ptr<ClassInfo> klass;
weak_ptr<Binding> binding;
FunctionInfo(FuncDef *expr, ClassInfoPtr klass = nullptr);
FunctionInfo(string name, TypePtr type) : VarInfo(name, type) {};
FunctionInfo(string name, TypePtr type) : VarInfo(name, type), block(nullptr) {};
// FunctionInfo(PIdent *ident, ClassInfoPtr klass = nullptr) : VarInfo(ident), block(NULL), klass(klass) {};
virtual string kind() const { return "function"; }
......
......@@ -208,18 +208,14 @@ void TypeCheck::visitCondElse(CondElse *cond_else)
void TypeCheck::visitWhile(While *while_)
{
while_->expr_->accept(this);
Bool expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, while_->expr_);
}
evalExpr<Bool>(while_->expr_);
while_->stmt_->accept(this);
returnType = nullptr;
}
void TypeCheck::visitSExp(SExp *s_exp)
{
s_exp->expr_->accept(this);
evalExpr(s_exp->expr_);
}
void TypeCheck::visitForEach(ForEach *for_each)
......@@ -228,8 +224,8 @@ void TypeCheck::visitForEach(ForEach *for_each)
for_each->type_->accept(this);
Type &iterType = *lastType;
Array expect(for_each->type_);
for_each->expr_->accept(this);
if (*lastType != expect) {
auto arrType = evalExpr<Array>(for_each->expr_);
if (*arrType != expect) {
throw InvalidTypeError(expect, {lastType}, for_each->expr_);
}
......@@ -283,16 +279,9 @@ void TypeCheck::visitEVar(EVar *e_var)
void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc)
{
e_index_acc->expr_1->accept(this);
shared_ptr<Array> type = dynamic_pointer_cast<Array>(lastType);
if (!type) {
throw ParseError("Table expected", e_index_acc->expr_1);
}
e_index_acc->expr_2->accept(this);
Int expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, e_index_acc->expr_2);
}
auto type = evalExpr<Array>(e_index_acc->expr_1);
evalExpr<Int>(e_index_acc->expr_2);
shared_ptr<Type> last(type->type_->clone());
last->binding = scope->currentBinding;
lastType = last;
......@@ -300,11 +289,11 @@ void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc)
void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
{
e_cls_mmbr->expr_->accept(this);
shared_ptr<ClassT> type = dynamic_pointer_cast<ClassT>(lastType);
auto exprType = evalExpr(e_cls_mmbr->expr_);
shared_ptr<ClassT> type = dynamic_pointer_cast<ClassT>(exprType);
if (!type) {
// it is an array and we ask for length
if (dynamic_pointer_cast<Array>(lastType)) {
if (dynamic_pointer_cast<Array>(exprType)) {
if (e_cls_mmbr->pident_->string_ == "length") {
lastType = make_shared<Int>();
return;
......@@ -330,11 +319,10 @@ void TypeCheck::visitEApp(EApp *e_app)
for (unsigned int i = 0; i < type->listtype_->size(); i++) {
try {
Expr *expr = e_app->listexpr_->at(i);
expr->accept(this);
if (!lastType) throw ParseError("No expr return type", expr);
auto exprType = evalExpr(expr);
auto *expect = type->listtype_->at(i);
if (*expect != *lastType) {
throw InvalidTypeError(*expect, {lastType}, expr);
if (*expect != *exprType) {
throw InvalidTypeError(*expect, {exprType}, expr);
}
} catch (const ParseError &e) {
throw ParseError(string(e.what()) + "\nIn argument " + to_string(i+1) + " of function call:", e_app);
......@@ -368,18 +356,13 @@ void TypeCheck::visitEString(EString *e)
void TypeCheck::visitENewArray(ENewArray *e)
{
e->expr_->accept(this);
auto a = lastType;
Int expect;
if (*a != expect) {
throw InvalidTypeError(expect, {a}, e->expr_);
}
evalExpr<Int>(e->expr_);
e->type_->accept(this);
if (dynamic_cast<Void*>(e->type_)) {
throw ParseError("Tablica typu void!", e);
}
auto ret = make_shared<Array>(e->type_); // make type
ret->binding = scope->currentBinding;
auto ret = make_shared<Array>(e->type_->clone()); // make type
ret->type_->binding = scope->currentBinding;
lastType = ret;
}
......@@ -455,26 +438,16 @@ void TypeCheck::visitERel(ERel *e)
void TypeCheck::visitEAnd(EAnd *e)
{
e->expr_1->accept(this);
auto a = lastType;
e->expr_2->accept(this);
auto b = lastType;
Bool expect;
if (!a || !b || *a != expect || *a != *b) {
throw InvalidTypeError(expect, {a, b}, e);
}
auto a = evalExpr<Bool>(e->expr_1);
auto b = evalExpr<Bool>(e->expr_2);
lastType = b;
}
void TypeCheck::visitEOr(EOr *e)
{
e->expr_1->accept(this);
auto a = lastType;
e->expr_2->accept(this);
auto b = lastType;
Bool expect;
if (!a || !b || *a != expect || *a != *b) {
throw InvalidTypeError(expect, {a, b}, e);
}
auto a = evalExpr<Bool>(e->expr_1);
auto b = evalExpr<Bool>(e->expr_2);
lastType = b;
}
void TypeCheck::visitListTopDef(ListTopDef *list_top_def)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment