Commit 37fabd11 authored by zygzagZ's avatar zygzagZ

refactor evalExpr

parent eb4aaa96
...@@ -75,7 +75,7 @@ void Prog::swap(Prog & other) ...@@ -75,7 +75,7 @@ void Prog::swap(Prog & other)
Prog::~Prog() Prog::~Prog()
{ {
delete(listtopdef_); if (listtopdef_) delete(listtopdef_);
} }
...@@ -119,7 +119,7 @@ void FnDef::swap(FnDef & other) ...@@ -119,7 +119,7 @@ void FnDef::swap(FnDef & other)
FnDef::~FnDef() FnDef::~FnDef()
{ {
delete(fundef_); if (fundef_) delete(fundef_);
} }
...@@ -163,7 +163,7 @@ void ClDef::swap(ClDef & other) ...@@ -163,7 +163,7 @@ void ClDef::swap(ClDef & other)
ClDef::~ClDef() ClDef::~ClDef()
{ {
delete(classdef_); if (classdef_) delete(classdef_);
} }
...@@ -216,10 +216,10 @@ void FuncDef::swap(FuncDef & other) ...@@ -216,10 +216,10 @@ void FuncDef::swap(FuncDef & other)
FuncDef::~FuncDef() FuncDef::~FuncDef()
{ {
delete(type_); if (type_) delete(type_);
delete(pident_); if (pident_) delete(pident_);
delete(listarg_); if (listarg_) delete(listarg_);
delete(block_); if (block_) delete(block_);
} }
...@@ -266,8 +266,8 @@ void Ar::swap(Ar & other) ...@@ -266,8 +266,8 @@ void Ar::swap(Ar & other)
Ar::~Ar() Ar::~Ar()
{ {
delete(type_); if (type_) delete(type_);
delete(pident_); if (pident_) delete(pident_);
} }
...@@ -314,8 +314,8 @@ void ClassDefN::swap(ClassDefN & other) ...@@ -314,8 +314,8 @@ void ClassDefN::swap(ClassDefN & other)
ClassDefN::~ClassDefN() ClassDefN::~ClassDefN()
{ {
delete(pident_); if (pident_) delete(pident_);
delete(classblock_); if (classblock_) delete(classblock_);
} }
...@@ -365,9 +365,9 @@ void ClassDefE::swap(ClassDefE & other) ...@@ -365,9 +365,9 @@ void ClassDefE::swap(ClassDefE & other)
ClassDefE::~ClassDefE() ClassDefE::~ClassDefE()
{ {
delete(pident_1); if (pident_1) delete(pident_1);
delete(pident_2); if (pident_2) delete(pident_2);
delete(classblock_); if (classblock_) delete(classblock_);
} }
...@@ -411,7 +411,7 @@ void ClassBl::swap(ClassBl & other) ...@@ -411,7 +411,7 @@ void ClassBl::swap(ClassBl & other)
ClassBl::~ClassBl() ClassBl::~ClassBl()
{ {
delete(listclassblockdef_); if (listclassblockdef_) delete(listclassblockdef_);
} }
...@@ -455,7 +455,7 @@ void ClassMthd::swap(ClassMthd & other) ...@@ -455,7 +455,7 @@ void ClassMthd::swap(ClassMthd & other)
ClassMthd::~ClassMthd() ClassMthd::~ClassMthd()
{ {
delete(fundef_); if (fundef_) delete(fundef_);
} }
...@@ -502,8 +502,8 @@ void ClassFld::swap(ClassFld & other) ...@@ -502,8 +502,8 @@ void ClassFld::swap(ClassFld & other)
ClassFld::~ClassFld() ClassFld::~ClassFld()
{ {
delete(type_); if (type_) delete(type_);
delete(listitem_); if (listitem_) delete(listitem_);
} }
...@@ -547,7 +547,7 @@ void Blk::swap(Blk & other) ...@@ -547,7 +547,7 @@ void Blk::swap(Blk & other)
Blk::~Blk() Blk::~Blk()
{ {
delete(liststmt_); if (liststmt_) delete(liststmt_);
} }
...@@ -631,7 +631,7 @@ void BStmt::swap(BStmt & other) ...@@ -631,7 +631,7 @@ void BStmt::swap(BStmt & other)
BStmt::~BStmt() BStmt::~BStmt()
{ {
delete(block_); if (block_) delete(block_);
} }
...@@ -678,8 +678,8 @@ void Decl::swap(Decl & other) ...@@ -678,8 +678,8 @@ void Decl::swap(Decl & other)
Decl::~Decl() Decl::~Decl()
{ {
delete(type_); if (type_) delete(type_);
delete(listitem_); if (listitem_) delete(listitem_);
} }
...@@ -726,8 +726,8 @@ void Ass::swap(Ass & other) ...@@ -726,8 +726,8 @@ void Ass::swap(Ass & other)
Ass::~Ass() Ass::~Ass()
{ {
delete(expr_1); if (expr_1) delete(expr_1);
delete(expr_2); if (expr_2) delete(expr_2);
} }
...@@ -771,7 +771,7 @@ void Incr::swap(Incr & other) ...@@ -771,7 +771,7 @@ void Incr::swap(Incr & other)
Incr::~Incr() Incr::~Incr()
{ {
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -815,7 +815,7 @@ void Decr::swap(Decr & other) ...@@ -815,7 +815,7 @@ void Decr::swap(Decr & other)
Decr::~Decr() Decr::~Decr()
{ {
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -859,7 +859,7 @@ void Ret::swap(Ret & other) ...@@ -859,7 +859,7 @@ void Ret::swap(Ret & other)
Ret::~Ret() Ret::~Ret()
{ {
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -946,8 +946,8 @@ void Cond::swap(Cond & other) ...@@ -946,8 +946,8 @@ void Cond::swap(Cond & other)
Cond::~Cond() Cond::~Cond()
{ {
delete(expr_); if (expr_) delete(expr_);
delete(stmt_); if (stmt_) delete(stmt_);
} }
...@@ -997,9 +997,9 @@ void CondElse::swap(CondElse & other) ...@@ -997,9 +997,9 @@ void CondElse::swap(CondElse & other)
CondElse::~CondElse() CondElse::~CondElse()
{ {
delete(expr_); if (expr_) delete(expr_);
delete(stmt_1); if (stmt_1) delete(stmt_1);
delete(stmt_2); if (stmt_2) delete(stmt_2);
} }
...@@ -1046,8 +1046,8 @@ void While::swap(While & other) ...@@ -1046,8 +1046,8 @@ void While::swap(While & other)
While::~While() While::~While()
{ {
delete(expr_); if (expr_) delete(expr_);
delete(stmt_); if (stmt_) delete(stmt_);
} }
...@@ -1091,7 +1091,7 @@ void SExp::swap(SExp & other) ...@@ -1091,7 +1091,7 @@ void SExp::swap(SExp & other)
SExp::~SExp() SExp::~SExp()
{ {
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -1144,10 +1144,10 @@ void ForEach::swap(ForEach & other) ...@@ -1144,10 +1144,10 @@ void ForEach::swap(ForEach & other)
ForEach::~ForEach() ForEach::~ForEach()
{ {
delete(type_); if (type_) delete(type_);
delete(pident_); if (pident_) delete(pident_);
delete(expr_); if (expr_) delete(expr_);
delete(stmt_); if (stmt_) delete(stmt_);
} }
...@@ -1194,8 +1194,8 @@ void Item::swap(Item & other) ...@@ -1194,8 +1194,8 @@ void Item::swap(Item & other)
Item::~Item() Item::~Item()
{ {
delete(pident_); if (pident_) delete(pident_);
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -1402,7 +1402,7 @@ void Array::swap(Array & other) ...@@ -1402,7 +1402,7 @@ void Array::swap(Array & other)
Array::~Array() Array::~Array()
{ {
delete(type_); if (type_) delete(type_);
} }
...@@ -1444,7 +1444,7 @@ void ClassT::swap(ClassT & other) ...@@ -1444,7 +1444,7 @@ void ClassT::swap(ClassT & other)
ClassT::~ClassT() ClassT::~ClassT()
{ {
delete(pident_); if (pident_) delete(pident_);
} }
...@@ -1491,8 +1491,8 @@ void Fun::swap(Fun & other) ...@@ -1491,8 +1491,8 @@ void Fun::swap(Fun & other)
Fun::~Fun() Fun::~Fun()
{ {
delete(type_); if (type_) delete(type_);
delete(listtype_); if (listtype_) delete(listtype_);
} }
...@@ -1536,7 +1536,7 @@ void EVar::swap(EVar & other) ...@@ -1536,7 +1536,7 @@ void EVar::swap(EVar & other)
EVar::~EVar() EVar::~EVar()
{ {
delete(pident_); if (pident_) delete(pident_);
} }
...@@ -1583,8 +1583,8 @@ void EIndexAcc::swap(EIndexAcc & other) ...@@ -1583,8 +1583,8 @@ void EIndexAcc::swap(EIndexAcc & other)
EIndexAcc::~EIndexAcc() EIndexAcc::~EIndexAcc()
{ {
delete(expr_1); if (expr_1) delete(expr_1);
delete(expr_2); if (expr_2) delete(expr_2);
} }
...@@ -1631,8 +1631,8 @@ void EClsMmbr::swap(EClsMmbr & other) ...@@ -1631,8 +1631,8 @@ void EClsMmbr::swap(EClsMmbr & other)
EClsMmbr::~EClsMmbr() EClsMmbr::~EClsMmbr()
{ {
delete(expr_); if (expr_) delete(expr_);
delete(pident_); if (pident_) delete(pident_);
} }
...@@ -1679,8 +1679,8 @@ void EApp::swap(EApp & other) ...@@ -1679,8 +1679,8 @@ void EApp::swap(EApp & other)
EApp::~EApp() EApp::~EApp()
{ {
delete(expr_); if (expr_) delete(expr_);
delete(listexpr_); if (listexpr_) delete(listexpr_);
} }
...@@ -1893,8 +1893,8 @@ void ENewArray::swap(ENewArray & other) ...@@ -1893,8 +1893,8 @@ void ENewArray::swap(ENewArray & other)
ENewArray::~ENewArray() ENewArray::~ENewArray()
{ {
delete(type_); if (type_) delete(type_);
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -1938,7 +1938,7 @@ void ENewClass::swap(ENewClass & other) ...@@ -1938,7 +1938,7 @@ void ENewClass::swap(ENewClass & other)
ENewClass::~ENewClass() ENewClass::~ENewClass()
{ {
delete(pident_); if (pident_) delete(pident_);
} }
...@@ -1982,7 +1982,7 @@ void NullCast::swap(NullCast & other) ...@@ -1982,7 +1982,7 @@ void NullCast::swap(NullCast & other)
NullCast::~NullCast() NullCast::~NullCast()
{ {
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -2026,7 +2026,7 @@ void Neg::swap(Neg & other) ...@@ -2026,7 +2026,7 @@ void Neg::swap(Neg & other)
Neg::~Neg() Neg::~Neg()
{ {
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -2070,7 +2070,7 @@ void Not::swap(Not & other) ...@@ -2070,7 +2070,7 @@ void Not::swap(Not & other)
Not::~Not() Not::~Not()
{ {
delete(expr_); if (expr_) delete(expr_);
} }
...@@ -2120,9 +2120,9 @@ void EMul::swap(EMul & other) ...@@ -2120,9 +2120,9 @@ void EMul::swap(EMul & other)
EMul::~EMul() EMul::~EMul()
{ {
delete(expr_1); if (expr_1) delete(expr_1);
delete(mulop_); if (mulop_) delete(mulop_);
delete(expr_2); if (expr_2) delete(expr_2);
} }
...@@ -2172,9 +2172,9 @@ void EAdd::swap(EAdd & other) ...@@ -2172,9 +2172,9 @@ void EAdd::swap(EAdd & other)
EAdd::~EAdd() EAdd::~EAdd()
{ {
delete(expr_1); if (expr_1) delete(expr_1);
delete(addop_); if (addop_) delete(addop_);
delete(expr_2); if (expr_2) delete(expr_2);
} }
...@@ -2224,9 +2224,9 @@ void ERel::swap(ERel & other) ...@@ -2224,9 +2224,9 @@ void ERel::swap(ERel & other)
ERel::~ERel() ERel::~ERel()
{ {
delete(expr_1); if (expr_1) delete(expr_1);
delete(relop_); if (relop_) delete(relop_);
delete(expr_2); if (expr_2) delete(expr_2);
} }
...@@ -2273,8 +2273,8 @@ void EAnd::swap(EAnd & other) ...@@ -2273,8 +2273,8 @@ void EAnd::swap(EAnd & other)
EAnd::~EAnd() EAnd::~EAnd()
{ {
delete(expr_1); if (expr_1) delete(expr_1);
delete(expr_2); if (expr_2) delete(expr_2);
} }
...@@ -2321,8 +2321,8 @@ void EOr::swap(EOr & other) ...@@ -2321,8 +2321,8 @@ void EOr::swap(EOr & other)
EOr::~EOr() EOr::~EOr()
{ {
delete(expr_1); if (expr_1) delete(expr_1);
delete(expr_2); if (expr_2) delete(expr_2);
} }
...@@ -2879,6 +2879,7 @@ ListExpr *ListExpr::clone() const ...@@ -2879,6 +2879,7 @@ ListExpr *ListExpr::clone() const
std::string Fun::printName() const{ std::string Fun::printName() const{
if (!type_) return "function";
std::string ret = type_->printName() + "("; std::string ret = type_->printName() + "(";
bool fst = true; bool fst = true;
for (auto i : *listtype_) { for (auto i : *listtype_) {
......
...@@ -665,7 +665,7 @@ public: ...@@ -665,7 +665,7 @@ public:
virtual void accept(Visitor *v); virtual void accept(Visitor *v);
virtual Str *clone() const; virtual Str *clone() const;
void swap(Str &); void swap(Str &);
std::string printName() const { return "str"; } std::string printName() const { return "string"; }
bool isEqual(Type const *other) const { bool isEqual(Type const *other) const {
if (dynamic_cast<const Str*>(other)) if (dynamic_cast<const Str*>(other))
return true; return true;
...@@ -739,11 +739,12 @@ public: ...@@ -739,11 +739,12 @@ public:
ClassT(const ClassT &); ClassT(const ClassT &);
ClassT &operator=(const ClassT &); ClassT &operator=(const ClassT &);
ClassT(PIdent *p1); ClassT(PIdent *p1);
ClassT() : pident_(nullptr) {};
~ClassT(); ~ClassT();
virtual void accept(Visitor *v); virtual void accept(Visitor *v);
virtual ClassT *clone() const; virtual ClassT *clone() const;
void swap(ClassT &); void swap(ClassT &);
std::string printName() const { return "class " + pident_->string_; } std::string printName() const { return pident_ ? ("class " + pident_->string_) : "class"; }
bool isEqual(Type const *other) const; bool isEqual(Type const *other) const;
}; };
...@@ -754,6 +755,7 @@ public: ...@@ -754,6 +755,7 @@ public:
ListType *listtype_; ListType *listtype_;
Fun(const Fun &); Fun(const Fun &);
Fun() : type_(nullptr), listtype_(nullptr) {};
Fun &operator=(const Fun &); Fun &operator=(const Fun &);
Fun(Type *p1, ListType *p2); Fun(Type *p1, ListType *p2);
~Fun(); ~Fun();
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
FunctionInfo::FunctionInfo(FuncDef *expr, ClassInfoPtr klass) FunctionInfo::FunctionInfo(FuncDef *expr, ClassInfoPtr klass)
: VarInfo(expr->pident_, nullptr), block(expr->block_), klass(klass) : VarInfo(expr->pident_, nullptr), block(expr->block_), klass(klass)
{ {
// TODO: tutaj leakujemy listtype
ListType *funArgs = new ListType(); ListType *funArgs = new ListType();
type = make_shared<Fun>(expr->type_, funArgs); type = make_shared<Fun>(expr->type_, funArgs);
arguments.reserve(expr->listarg_->size()); arguments.reserve(expr->listarg_->size());
...@@ -29,6 +27,8 @@ ClassInfo::ClassInfo(PIdent *ident, BindingPtr parent /*= nullptr*/) ...@@ -29,6 +27,8 @@ ClassInfo::ClassInfo(PIdent *ident, BindingPtr parent /*= nullptr*/)
: VarInfo(ident), : VarInfo(ident),
Binding(parent) Binding(parent)
{ {
type = make_shared<ClassT>(ident->clone());
type->binding = parent;
}; };
......
...@@ -12,8 +12,11 @@ class VarInfo { ...@@ -12,8 +12,11 @@ class VarInfo {
public: public:
VarInfo(PIdent* ident, TypePtr type) : ident(ident), name(ident->string_), type(type), lineLocation(ident->lineno) {} VarInfo(PIdent* ident, TypePtr type) : ident(ident), name(ident->string_), type(type), lineLocation(ident->lineno) {}
VarInfo(PIdent* ident, Type* type = nullptr) : ident(ident), name(ident->string_), type(type), lineLocation(ident->lineno) {} VarInfo(PIdent* ident, Type* type = nullptr) : ident(ident), name(ident->string_), type(type), lineLocation(ident->lineno) {}
VarInfo(string name, TypePtr type) : name(name), type(type), lineLocation(-1) {}
VarInfo(Ar* arg) : VarInfo(arg->pident_, arg->type_) {} VarInfo(Ar* arg) : VarInfo(arg->pident_, arg->type_) {}
virtual ~VarInfo() {} virtual ~VarInfo() {}
virtual string kind() const { return "variable"; }
string describe() const { return kind() + " " + name + " at line " + to_string(lineLocation); }
PIdent *ident; PIdent *ident;
string name; string name;
...@@ -33,7 +36,10 @@ public: ...@@ -33,7 +36,10 @@ public:
weak_ptr<ClassInfo> klass; weak_ptr<ClassInfo> klass;
weak_ptr<Binding> binding; weak_ptr<Binding> binding;
FunctionInfo(FuncDef *expr, ClassInfoPtr klass = nullptr); FunctionInfo(FuncDef *expr, ClassInfoPtr klass = nullptr);
FunctionInfo(string name, TypePtr type) : VarInfo(name, type) {};
// FunctionInfo(PIdent *ident, ClassInfoPtr klass = nullptr) : VarInfo(ident), block(NULL), klass(klass) {}; // FunctionInfo(PIdent *ident, ClassInfoPtr klass = nullptr) : VarInfo(ident), block(NULL), klass(klass) {};
virtual string kind() const { return "function"; }
}; };
...@@ -56,7 +62,7 @@ public: ...@@ -56,7 +62,7 @@ public:
ClassInfo(PIdent *ident, BindingPtr parent = nullptr); ClassInfo(PIdent *ident, BindingPtr parent = nullptr);
// ClassInfoPtr getParent() const { return dynamic_pointer_cast<ClassInfo>(parent); }; virtual string kind() const { return "class"; }
}; };
......
...@@ -70,7 +70,7 @@ int main(int argc, char ** argv) ...@@ -70,7 +70,7 @@ int main(int argc, char ** argv)
TypeCheck checker; TypeCheck checker;
checker.check(parse_tree); checker.check(parse_tree);
} catch (ParseError const &e) { } catch (ParseError const &e) {
std::cerr << "Error: " << e.what() << std::endl; std::cerr << e.what() << std::endl;
return 1; return 1;
} }
std::cout << "OK!" << endl; std::cout << "OK!" << endl;
......
...@@ -6,28 +6,17 @@ using namespace std; ...@@ -6,28 +6,17 @@ using namespace std;
ParseError::ParseError(string reason, int line) : runtime_error("ParseError"), line(line) ParseError::ParseError(string reason, int line) : runtime_error("ParseError"), line(line)
{ {
stringstream ss; msg = reason + "\nAt line " + to_string(line);
ss << "ParseError";
if (line != -1) {
ss << " at line " << line;
}
ss << ": " << reason;
msg = ss.str();
} }
ParseError::ParseError(string reason, Visitable *expr) : runtime_error("ParseError") ParseError::ParseError(string reason, Visitable *expr) : runtime_error("ParseError")
{ {
stringstream ss;
ss << "ParseError";
if (expr) {
line = expr->lineno; line = expr->lineno;
ss << " at line " << line; msg = reason + "\nIn expression at line " + to_string(line) + ": " + PrintAbsyn().print(expr);
} }
ss << ": " << reason;
if (expr) { ParseError::ParseError(string reason, VarInfo &var) : runtime_error("ParseError") {
ss << " Expression: " << PrintAbsyn().print(expr); msg = reason + "\nIn " + var.describe();
}
msg = ss.str();
} }
RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) { RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) {
...@@ -46,7 +35,7 @@ UndefinedError::UndefinedError(PIdent *ident) { ...@@ -46,7 +35,7 @@ UndefinedError::UndefinedError(PIdent *ident) {
InvalidTypeError::InvalidTypeError(Type &expected, vector<shared_ptr<Type>> received, Visitable *expr) { InvalidTypeError::InvalidTypeError(Type &expected, vector<shared_ptr<Type>> received, Visitable *expr) {
stringstream ss; stringstream ss;
ss << "Invalid expression type at line " << expr->lineno << ". Expected \"" << expected.printName() << "\", instead received "; ss << "Invalid expression type: Expected " << expected.printName() << ", instead received ";
bool fst = true; bool fst = true;
for (auto i : received) { for (auto i : received) {
if (fst) fst = false; if (fst) fst = false;
...@@ -55,17 +44,15 @@ InvalidTypeError::InvalidTypeError(Type &expected, vector<shared_ptr<Type>> rece ...@@ -55,17 +44,15 @@ InvalidTypeError::InvalidTypeError(Type &expected, vector<shared_ptr<Type>> rece
} }
ss << "."; ss << ".";
if (expr) { if (expr) {
ss << " In: "; line = expr->lineno;
PrintAbsyn p; ss << "\nIn expression at line " << line << ": " << PrintAbsyn().print(expr);
ss << p.print(expr);
} }
msg = ss.str(); msg = ss.str();
line = expr->lineno;
} }
InvalidTypeError::InvalidTypeError(Type &expected, vector<Type*> received, Visitable *expr) { InvalidTypeError::InvalidTypeError(Type &expected, vector<Type*> received, Visitable *expr) {
stringstream ss; stringstream ss;
ss << "Invalid expression type at line " << expr->lineno << ". Expected \"" << expected.printName() << "\", instead received "; ss << "Invalid expression type: Expected " << expected.printName() << ", instead received ";
bool fst = true; bool fst = true;
for (auto i : received) { for (auto i : received) {
if (fst) fst = false; if (fst) fst = false;
...@@ -74,9 +61,8 @@ InvalidTypeError::InvalidTypeError(Type &expected, vector<Type*> received, Visit ...@@ -74,9 +61,8 @@ InvalidTypeError::InvalidTypeError(Type &expected, vector<Type*> received, Visit
} }
ss << "."; ss << ".";
if (expr) { if (expr) {
ss << " In: "; line = expr->lineno;
PrintAbsyn p; ss << "\nIn expression at line " << line << ": " << PrintAbsyn().print(expr);
ss << p.print(expr);
} }
msg = ss.str(); msg = ss.str();
line = expr->lineno; line = expr->lineno;
......
...@@ -18,6 +18,8 @@ protected: ...@@ -18,6 +18,8 @@ protected:
public: public:
ParseError(string reason, int line = -1); ParseError(string reason, int line = -1);
ParseError(string reason, Visitable *expr); ParseError(string reason, Visitable *expr);
ParseError(string reason, VarInfo &var);
ParseError(const ParseError &e, Visitable *expr) : ParseError(e.what(), expr) {};
virtual const char * what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW { return msg.data(); } virtual const char * what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW { return msg.data(); }
}; };
......
...@@ -52,8 +52,7 @@ void TypeCheck::visitFuncDef(FuncDef *def) ...@@ -52,8 +52,7 @@ void TypeCheck::visitFuncDef(FuncDef *def)
FunctionInfoPtr f = make_shared<FunctionInfo>(def, scope->currentClass); FunctionInfoPtr f = make_shared<FunctionInfo>(def, scope->currentClass);
def->type_->accept(this); def->type_->accept(this);
// def->pident_->accept(this); // tego nie trzeba bo definiujemy a nie odwołujemy się // pident nie trzeba bo definiujemy a nie odwołujemy się
// FunctionInfo tworzy argumenty // FunctionInfo tworzy argumenty
def->listarg_->accept(this); def->listarg_->accept(this);
...@@ -102,7 +101,6 @@ void TypeCheck::visitClassFld(ClassFld *decl) ...@@ -102,7 +101,6 @@ void TypeCheck::visitClassFld(ClassFld *decl)
VarInfoPtr var = make_shared<VarInfo>(el->pident_, type); VarInfoPtr var = make_shared<VarInfo>(el->pident_, type);
el->pident_->var = var; el->pident_->var = var;
scope->currentClass->variables << var; scope->currentClass->variables << var;
cout << "class " << scope->currentClass << " adding ident " << el->pident_->string_ << endl;
} }
} }
...@@ -135,13 +133,13 @@ void TypeCheck::visitDecl(Decl *decl) ...@@ -135,13 +133,13 @@ void TypeCheck::visitDecl(Decl *decl)
for (Item * el : *decl->listitem_) { for (Item * el : *decl->listitem_) {
// el->accept(this); // nie trzeba bo el to tylko ident = expr // el->accept(this); // nie trzeba bo el to tylko ident = expr
if (el->expr_) { if (el->expr_) {
el->expr_->accept(this); auto exprType = evalExpr(el->expr_);
if (*type != *lastType) { if (*type != *exprType) {
throw InvalidTypeError(*type, {lastType}, el->expr_); throw InvalidTypeError(*type, {exprType}, el->expr_);
} }
} }
VarInfoPtr var = make_shared<VarInfo>(el->pident_, type); VarInfoPtr var = make_shared<VarInfo>(el->pident_, type->clone());
el->pident_->var = var; el->pident_->var = var;
scope->currentBinding->variables << var; scope->currentBinding->variables << var;
} }
...@@ -149,10 +147,8 @@ void TypeCheck::visitDecl(Decl *decl) ...@@ -149,10 +147,8 @@ void TypeCheck::visitDecl(Decl *decl)
void TypeCheck::visitAss(Ass *ass) void TypeCheck::visitAss(Ass *ass)
{ {
ass->expr_1->accept(this); auto a = evalExpr(ass->expr_1);
auto a = lastType; auto b = evalExpr(ass->expr_2);
ass->expr_2->accept(this);
auto b = lastType;
if (*a != *b) { if (*a != *b) {
throw InvalidTypeError(*a, {b}, ass->expr_1); throw InvalidTypeError(*a, {b}, ass->expr_1);
} }
...@@ -160,28 +156,18 @@ void TypeCheck::visitAss(Ass *ass) ...@@ -160,28 +156,18 @@ void TypeCheck::visitAss(Ass *ass)
void TypeCheck::visitIncr(Incr *incr) void TypeCheck::visitIncr(Incr *incr)
{ {
Expr *e = incr->expr_; evalExpr<Int>(incr->expr_);
e->accept(this);
Int expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, e);
}
} }
void TypeCheck::visitDecr(Decr *decr) void TypeCheck::visitDecr(Decr *decr)
{ {
Expr *e = decr->expr_; evalExpr<Int>(decr->expr_);
e->accept(this);
Int expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, e);
}
} }
void TypeCheck::visitRet(Ret *ret) void TypeCheck::visitRet(Ret *ret)
{ {
ret->expr_->accept(this); auto type = evalExpr(ret->expr_);
checkReturnStatement(lastType, ret); checkReturnStatement(type, ret);
} }
void TypeCheck::visitVRet(VRet *v_ret) void TypeCheck::visitVRet(VRet *v_ret)
...@@ -191,28 +177,26 @@ void TypeCheck::visitVRet(VRet *v_ret) ...@@ -191,28 +177,26 @@ void TypeCheck::visitVRet(VRet *v_ret)
void TypeCheck::visitCond(Cond *cond) void TypeCheck::visitCond(Cond *cond)
{ {
cond->expr_->accept(this); auto type = evalExpr<Bool>(cond->expr_);
Bool expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, cond->expr_);
}
cond->stmt_->accept(this); cond->stmt_->accept(this);
if (!dynamic_cast<ELitTrue*>(cond->expr_)) {
returnType = nullptr; returnType = nullptr;
}
} }
void TypeCheck::visitCondElse(CondElse *cond_else) void TypeCheck::visitCondElse(CondElse *cond_else)
{ {
cond_else->expr_->accept(this); evalExpr<Bool>(cond_else->expr_);
Bool expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, cond_else->expr_);
}
cond_else->stmt_1->accept(this); cond_else->stmt_1->accept(this);
auto ret1 = returnType; auto ret1 = returnType;
returnType = nullptr; returnType = nullptr;
cond_else->stmt_2->accept(this); cond_else->stmt_2->accept(this);
auto ret2 = returnType; auto ret2 = returnType;
if (ret1 && ret2) { if (dynamic_cast<ELitTrue*>(cond_else->expr_)) {
returnType = ret1;
} else if (dynamic_cast<ELitFalse*>(cond_else->expr_)) {
returnType = ret2;
} else if (ret1 && ret2) {
if (*ret1 != *ret2) { if (*ret1 != *ret2) {
throw InvalidTypeError(*ret1, {ret2}, cond_else); throw InvalidTypeError(*ret1, {ret2}, cond_else);
} }
...@@ -242,6 +226,7 @@ void TypeCheck::visitForEach(ForEach *for_each) ...@@ -242,6 +226,7 @@ void TypeCheck::visitForEach(ForEach *for_each)
{ {
BindingPtr binding = make_shared<Binding>(scope->currentBinding); BindingPtr binding = make_shared<Binding>(scope->currentBinding);
for_each->type_->accept(this); for_each->type_->accept(this);
Type &iterType = *lastType;
Array expect(for_each->type_); Array expect(for_each->type_);
for_each->expr_->accept(this); for_each->expr_->accept(this);
if (*lastType != expect) { if (*lastType != expect) {
...@@ -252,8 +237,6 @@ void TypeCheck::visitForEach(ForEach *for_each) ...@@ -252,8 +237,6 @@ void TypeCheck::visitForEach(ForEach *for_each)
binding->variables << var; binding->variables << var;
scope->currentBinding = binding; scope->currentBinding = binding;
// TODO: czy chcemy tutaj do blocku przypisać binding?
for_each->stmt_->accept(this); for_each->stmt_->accept(this);
scope->currentBinding = binding->getParent(); scope->currentBinding = binding->getParent();
...@@ -303,7 +286,7 @@ void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc) ...@@ -303,7 +286,7 @@ void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc)
e_index_acc->expr_1->accept(this); e_index_acc->expr_1->accept(this);
shared_ptr<Array> type = dynamic_pointer_cast<Array>(lastType); shared_ptr<Array> type = dynamic_pointer_cast<Array>(lastType);
if (!type) { if (!type) {
throw ParseError("Oczekiwano tablicy", e_index_acc->expr_1); throw ParseError("Table expected", e_index_acc->expr_1);
} }
e_index_acc->expr_2->accept(this); e_index_acc->expr_2->accept(this);
Int expect; Int expect;
...@@ -317,11 +300,17 @@ void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc) ...@@ -317,11 +300,17 @@ void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc)
void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr) void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
{ {
/* Code For EClsMmbr Goes Here */
e_cls_mmbr->expr_->accept(this); e_cls_mmbr->expr_->accept(this);
shared_ptr<ClassT> type = dynamic_pointer_cast<ClassT>(lastType); shared_ptr<ClassT> type = dynamic_pointer_cast<ClassT>(lastType);
if (!type) { if (!type) {
throw ParseError("Oczekiwano klasy", e_cls_mmbr->expr_); // it is an array and we ask for length
if (dynamic_pointer_cast<Array>(lastType)) {
if (e_cls_mmbr->pident_->string_ == "length") {
lastType = make_shared<Int>();
return;
}
}
throw ParseError("Class expected", e_cls_mmbr->expr_);
} }
ClassInfoPtr klass = scope->currentBinding->classes[type->pident_]; ClassInfoPtr klass = scope->currentBinding->classes[type->pident_];
VarInfoPtr var = klass->variables.local(e_cls_mmbr->pident_->string_); VarInfoPtr var = klass->variables.local(e_cls_mmbr->pident_->string_);
...@@ -334,15 +323,25 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr) ...@@ -334,15 +323,25 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
void TypeCheck::visitEApp(EApp *e_app) void TypeCheck::visitEApp(EApp *e_app)
{ {
e_app->expr_->accept(this); shared_ptr<Fun> type = evalExpr<Fun>(e_app->expr_);
// FunctionInfo type nie jest poprawny, powinien być Fun! if (type->listtype_->size() != e_app->listexpr_->size()) {
shared_ptr<Fun> type = dynamic_pointer_cast<Fun>(lastType); throw ParseError("Expected " + to_string(type->listtype_->size()) + " arguments, " + to_string(e_app->listexpr_->size()) + " given", e_app);
if (!type) { }
throw ParseError("Oczekiwano funkcji", e_app->expr_); 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 *expect = type->listtype_->at(i);
if (*expect != *lastType) {
throw InvalidTypeError(*expect, {lastType}, expr);
}
} catch (const ParseError &e) {
throw ParseError(string(e.what()) + "\nIn argument " + to_string(i+1) + " of function call:", e_app);
} }
e_app->listexpr_->accept(this); }
lastType = shared_ptr<Type>(type->type_->clone()); lastType = shared_ptr<Type>(type->type_->clone());
// TODO: sprawdzić parametry funkcji!
} }
void TypeCheck::visitELitInt(ELitInt *e_lit_int) void TypeCheck::visitELitInt(ELitInt *e_lit_int)
...@@ -386,81 +385,62 @@ void TypeCheck::visitENewArray(ENewArray *e) ...@@ -386,81 +385,62 @@ void TypeCheck::visitENewArray(ENewArray *e)
void TypeCheck::visitENewClass(ENewClass *e_new_class) void TypeCheck::visitENewClass(ENewClass *e_new_class)
{ {
e_new_class->pident_->accept(this); // e_new_class->pident_->accept(this);
ClassInfoPtr klass = dynamic_pointer_cast<ClassInfo>(e_new_class->pident_->var.lock()); lastType = evalExpr<ClassT>(e_new_class->pident_);
if (!klass) { // ClassInfoPtr klass = dynamic_pointer_cast<ClassInfo>(e_new_class->pident_->var.lock());
throw ParseError("Oczekiwano nazwy klasy", e_new_class->pident_); // if (!klass) {
} // throw ParseError("Class expected", e_new_class->pident_);
auto ret = make_shared<ClassT>(e_new_class->pident_); // make type // }
ret->binding = scope->currentBinding;
lastType = ret; // auto ret = make_shared<ClassT>(e_new_class->pident_); // make type
// ret->binding = scope->currentBinding;
// lastType = ret;
} }
void TypeCheck::visitNullCast(NullCast *null_cast) void TypeCheck::visitNullCast(NullCast *null_cast)
{ {
lastType = nullptr; lastType = evalExpr<ClassT>(null_cast->expr_);
null_cast->expr_->accept(this);
shared_ptr<ClassT> type = dynamic_pointer_cast<ClassT>(lastType);
if (!type) {
throw ParseError("Oczekiwano klasy", null_cast->expr_);
}
} }
void TypeCheck::visitNeg(Neg *e) void TypeCheck::visitNeg(Neg *e)
{ {
e->expr_->accept(this); lastType = evalExpr<Int>(e->expr_);
auto a = lastType;
Int expect;
if (!a || *a != expect) {
throw InvalidTypeError(expect, {a}, e);
}
} }
void TypeCheck::visitNot(Not *e) void TypeCheck::visitNot(Not *e)
{ {
e->expr_->accept(this); lastType = evalExpr<Bool>(e->expr_);
auto a = lastType;
Bool expect;
if (!a || *a != expect) {
throw InvalidTypeError(expect, {a}, e);
}
} }
void TypeCheck::visitEMul(EMul *e) void TypeCheck::visitEMul(EMul *e)
{ {
e->expr_1->accept(this); auto a = evalExpr<Int>(e->expr_1);
auto a = lastType; auto b = evalExpr<Int>(e->expr_2);
e->expr_2->accept(this); lastType = b;
auto b = lastType;
Int expect;
if (!a || !b || *a != expect || *a != *b) {
throw InvalidTypeError(expect, {a, b}, e);
}
} }
void TypeCheck::visitEAdd(EAdd *e) void TypeCheck::visitEAdd(EAdd *e)
{ {
e->expr_1->accept(this); auto a = evalExpr(e->expr_1);
auto a = lastType; auto b = evalExpr(e->expr_2);
e->expr_2->accept(this); if (dynamic_cast<Plus*>(e->addop_)) {
auto b = lastType; if (*a != *b) {
throw InvalidTypeError(*a, {b}, e);
}
} else {
Int expect; Int expect;
if (!a || !b || *a != expect || *a != *b) { if (*a != expect || *a != *b) {
throw InvalidTypeError(expect, {a, b}, e); throw InvalidTypeError(expect, {a, b}, e);
} }
}
lastType = b;
} }
void TypeCheck::visitERel(ERel *e) void TypeCheck::visitERel(ERel *e)
{ {
e->expr_1->accept(this); auto a = evalExpr(e->expr_1);
auto a = lastType; auto b = evalExpr(e->expr_2);
if (!a) throw ParseError("Brak typu wyrażenia", e->expr_1);
e->expr_2->accept(this);
auto b = lastType;
if (!b) throw ParseError("Brak typu wyrażenia", e->expr_2);
if (dynamic_cast<EQU*>(e->relop_)) { if (dynamic_cast<EQU*>(e->relop_)) {
// equal
// TODO: EQUAL
if (*a != *b) { if (*a != *b) {
throw InvalidTypeError(*a, {b}, e); throw InvalidTypeError(*a, {b}, e);
} }
...@@ -563,8 +543,26 @@ TypeCheck::TypeCheck() ...@@ -563,8 +543,26 @@ TypeCheck::TypeCheck()
: state(initialized), scope(make_shared<Scope>()) : state(initialized), scope(make_shared<Scope>())
{} {}
void TypeCheck::setupEnv() { void TypeCheck::addIOFunctions(Type &type) {
string name = type.printName();
name[0] += 'A' - 'a';
TypePtr fun = make_shared<Fun>(type.clone(), new ListType()); // read
FunctionInfoPtr read = make_shared<FunctionInfo>("read" + name, fun);
scope->functions << read;
auto *v = new ListType();
v->push_back(type.clone());
fun = make_shared<Fun>(new Void(), v); // print
FunctionInfoPtr print = make_shared<FunctionInfo>("print" + name, fun);
scope->functions << print;
}
void TypeCheck::setupEnv() {
{ Int x; addIOFunctions(x); }
{ Str x; addIOFunctions(x); }
// { Bool x; addIOFunctions(x); }
} }
void TypeCheck::check(Visitable *v) void TypeCheck::check(Visitable *v)
...@@ -572,15 +570,20 @@ void TypeCheck::check(Visitable *v) ...@@ -572,15 +570,20 @@ void TypeCheck::check(Visitable *v)
if (state != State::initialized) { if (state != State::initialized) {
throw std::runtime_error("already initialized"); throw std::runtime_error("already initialized");
} }
setupEnv();
state = State::checkType; state = State::checkType;
v->accept(this); v->accept(this);
for (auto c : scope->classes) { for (auto c : scope->classes) {
scope->currentClass = c; scope->currentClass = c;
try {
for (auto f : c->functions) { for (auto f : c->functions) {
checkFunction(f); checkFunction(f);
} }
} catch (const ParseError &e) {
throw ParseError(e.what(), *c);
}
scope->currentClass = nullptr; scope->currentClass = nullptr;
} }
...@@ -604,6 +607,8 @@ void TypeCheck::checkReturnStatement(shared_ptr<Type> type, Stmt *stmt) { ...@@ -604,6 +607,8 @@ void TypeCheck::checkReturnStatement(shared_ptr<Type> type, Stmt *stmt) {
void TypeCheck::checkFunction(FunctionInfoPtr f) void TypeCheck::checkFunction(FunctionInfoPtr f)
{ {
if (!f->block) return;
try {
scope->currentFunction = f; scope->currentFunction = f;
if (f->binding.lock()) throw runtime_error("Ale ten binding juz istnieje"); if (f->binding.lock()) throw runtime_error("Ale ten binding juz istnieje");
...@@ -625,6 +630,9 @@ void TypeCheck::checkFunction(FunctionInfoPtr f) ...@@ -625,6 +630,9 @@ void TypeCheck::checkFunction(FunctionInfoPtr f)
scope->currentBinding = nullptr; scope->currentBinding = nullptr;
scope->currentFunction = nullptr; scope->currentFunction = nullptr;
} catch (const ParseError &e) {
throw ParseError(e.what(), *f);
}
} }
void TypeCheck::checkFunctionRet() { void TypeCheck::checkFunctionRet() {
...@@ -634,7 +642,7 @@ void TypeCheck::checkFunctionRet() { ...@@ -634,7 +642,7 @@ void TypeCheck::checkFunctionRet() {
auto funRet = funType->type_; auto funRet = funType->type_;
if (*funRet != Void()) { if (*funRet != Void()) {
if (!returnType || returnType == nullptr) { if (!returnType || returnType == nullptr) {
throw ParseError("Funkcja " + f->name + " nie zwróciła wyniku!", f->lineLocation); throw ParseError("Function " + f->name + " did not return!", f->lineLocation);
} }
if (*returnType != *funRet) { if (*returnType != *funRet) {
throw InvalidTypeError(*returnType, {funRet}, f->block); throw InvalidTypeError(*returnType, {funRet}, f->block);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "Absyn.h" #include "Absyn.h"
#include "Info.h" #include "Info.h"
#include "ParseError.h"
#include <memory> #include <memory>
...@@ -17,11 +18,44 @@ class TypeCheck : public Visitor ...@@ -17,11 +18,44 @@ class TypeCheck : public Visitor
shared_ptr<Scope> scope; shared_ptr<Scope> scope;
shared_ptr<Type> lastType, returnType; shared_ptr<Type> lastType, returnType;
set<int> posv;
void checkFunction(FunctionInfoPtr f); void checkFunction(FunctionInfoPtr f);
void checkReturnStatement(shared_ptr<Type> type, Stmt *stmt); void checkReturnStatement(shared_ptr<Type> type, Stmt *stmt);
void checkFunctionRet(); void checkFunctionRet();
void addIOFunctions(Type &type);
void setupEnv(); void setupEnv();
template<typename T>
shared_ptr<T> evalExpr(Visitable *expr) {
if (!expr) throw runtime_error("No expr to eval");
lastType = nullptr;
try {
expr->accept(this);
} catch (const ParseError &err) {
throw ParseError(err, expr);
}
shared_ptr<T> ret = dynamic_pointer_cast<T>(lastType);
if (!ret) {
T expect;
throw InvalidTypeError(expect, {lastType}, expr);
}
lastType = nullptr;
return ret;
};
shared_ptr<Type> evalExpr(Visitable *expr) {
if (!expr) throw runtime_error("No expr to eval");
try {
expr->accept(this);
} catch (const ParseError &err) {
throw ParseError(err, expr);
}
if (!lastType) throw ParseError("No expression type", expr);
auto ret = lastType;
lastType = nullptr;
return ret;
};
public: public:
BindingPtr getParentBinding() const { return scope->currentClass ? static_pointer_cast<Binding>(scope->currentClass) : static_pointer_cast<Binding>(scope); } BindingPtr getParentBinding() const { return scope->currentClass ? static_pointer_cast<Binding>(scope->currentClass) : static_pointer_cast<Binding>(scope); }
TypeCheck(); TypeCheck();
......
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