Commit 08a16dd0 authored by zygzagZ's avatar zygzagZ

lineno do kazdego visitable

WIP typecheck
parent 0cd3f111
...@@ -8,13 +8,11 @@ ...@@ -8,13 +8,11 @@
PIdent::PIdent(String p1, Integer p2) PIdent::PIdent(String p1, Integer p2)
{ {
string_ = p1; string_ = p1;
integer_ = p2;
} }
PIdent::PIdent(const PIdent & other) PIdent::PIdent(const PIdent & other)
{ {
string_ = other.string_; string_ = other.string_;
integer_ = other.integer_;
var = other.var; var = other.var;
} }
...@@ -28,7 +26,6 @@ PIdent &PIdent::operator=(const PIdent & other) ...@@ -28,7 +26,6 @@ PIdent &PIdent::operator=(const PIdent & other)
void PIdent::swap(PIdent & other) void PIdent::swap(PIdent & other)
{ {
std::swap(string_, other.string_); std::swap(string_, other.string_);
std::swap(integer_, other.integer_);
std::swap(var, other.var); std::swap(var, other.var);
} }
......
...@@ -127,6 +127,7 @@ public: ...@@ -127,6 +127,7 @@ public:
class Visitable class Visitable
{ {
public: public:
int lineno;
virtual ~Visitable() {} virtual ~Visitable() {}
virtual void accept(Visitor *v) = 0; virtual void accept(Visitor *v) = 0;
}; };
...@@ -232,7 +233,6 @@ public: ...@@ -232,7 +233,6 @@ public:
class Expr : public Visitable class Expr : public Visitable
{ {
public: public:
int lineno;
virtual Expr *clone() const = 0; virtual Expr *clone() const = 0;
}; };
...@@ -264,12 +264,11 @@ class PIdent : public Visitable ...@@ -264,12 +264,11 @@ class PIdent : public Visitable
{ {
public: public:
String string_; String string_;
Integer integer_;
std::weak_ptr<VarInfo> var; std::weak_ptr<VarInfo> var;
PIdent(const PIdent &); PIdent(const PIdent &);
PIdent &operator=(const PIdent &); PIdent &operator=(const PIdent &);
PIdent(String p1, Integer p2); PIdent(String p1, Integer p2 = 0);
~PIdent(); ~PIdent();
virtual void accept(Visitor *v); virtual void accept(Visitor *v);
virtual PIdent *clone() const; virtual PIdent *clone() const;
......
...@@ -11,7 +11,7 @@ FunctionInfo::FunctionInfo(FuncDef *expr, ClassInfoPtr klass) ...@@ -11,7 +11,7 @@ FunctionInfo::FunctionInfo(FuncDef *expr, ClassInfoPtr klass)
Binding::Binding(shared_ptr<Binding> parent) Binding::Binding(shared_ptr<Binding> parent)
: variables(parent->variables), : variables(parent ? parent->variables : nullptr),
parent(parent) parent(parent)
{ {
......
...@@ -10,7 +10,7 @@ using namespace std; ...@@ -10,7 +10,7 @@ using namespace std;
class VarInfo { class VarInfo {
public: public:
VarInfo(PIdent* ident, Type* type = NULL) : ident(ident), name(ident->string_), type(type), lineLocation(ident->integer_) {} VarInfo(PIdent* ident, Type* type = NULL) : ident(ident), name(ident->string_), type(type), lineLocation(ident->lineno) {}
VarInfo(Ar* arg) : VarInfo(arg->pident_, arg->type_) {} VarInfo(Ar* arg) : VarInfo(arg->pident_, arg->type_) {}
PIdent *ident; PIdent *ident;
......
...@@ -23,7 +23,7 @@ template<typename T, ...@@ -23,7 +23,7 @@ template<typename T,
class InfoList : public set<TPtr, Compare<TPtr>> { class InfoList : public set<TPtr, Compare<TPtr>> {
public: public:
InfoList<T> *parent; InfoList<T> *parent;
InfoList(InfoList<T> *parent = nullptr) : parent(parent) {}; InfoList(InfoList<T> *p = nullptr) { parent = p; };
TPtr operator[](PIdent *ident) const { TPtr operator[](PIdent *ident) const {
TPtr ret = local(ident->string_); TPtr ret = local(ident->string_);
if (ret) return ret; if (ret) return ret;
......
...@@ -72,6 +72,7 @@ int main(int argc, char ** argv) ...@@ -72,6 +72,7 @@ int main(int argc, char ** argv)
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
return 1; return 1;
} }
std::cout << "OK!" << endl;
/*Compiler c(file); /*Compiler c(file);
std::string out = c.compile(parse_tree); std::string out = c.compile(parse_tree);
......
...@@ -6,22 +6,22 @@ using namespace std; ...@@ -6,22 +6,22 @@ using namespace std;
RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) { RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) {
stringstream ss; stringstream ss;
ss << "Variable \"" << ident->string_ << "\" at line " << ident->integer_ << " redeclared! First declaration at line " << orig->lineLocation; ss << "Variable \"" << ident->string_ << "\" at line " << ident->lineno << " redeclared! First declaration at line " << orig->lineLocation;
msg = ss.str(); msg = ss.str();
line = ident->integer_; line = ident->lineno;
} }
UndefinedError::UndefinedError(PIdent *ident) { UndefinedError::UndefinedError(PIdent *ident) {
stringstream ss; stringstream ss;
ss << "Undefined reference to \"" << ident->string_ << "\" at line " << ident->integer_; ss << "Undefined reference to \"" << ident->string_ << "\" at line " << ident->lineno;
msg = ss.str(); msg = ss.str();
line = ident->integer_; line = ident->lineno;
} }
InvalidTypeError::InvalidTypeError(int lineno, Type &expected, vector<shared_ptr<Type>> received, Expr *expr) { InvalidTypeError::InvalidTypeError(Type &expected, vector<shared_ptr<Type>> received, Visitable *expr) {
stringstream ss; stringstream ss;
ss << "Invalid expression type at line " << lineno << ". Expected \"" << expected.printName() << "\", instead received "; ss << "Invalid expression type at line " << expr->lineno << ". 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;
...@@ -30,11 +30,11 @@ InvalidTypeError::InvalidTypeError(int lineno, Type &expected, vector<shared_ptr ...@@ -30,11 +30,11 @@ InvalidTypeError::InvalidTypeError(int lineno, Type &expected, vector<shared_ptr
} }
ss << "."; ss << ".";
if (expr) { if (expr) {
ss << " Expression: "; ss << " In: ";
PrintAbsyn p; PrintAbsyn p;
ss << p.print(expr); ss << p.print(expr);
} }
msg = ss.str(); msg = ss.str();
line = lineno; line = expr->lineno;
} }
\ No newline at end of file
...@@ -34,7 +34,7 @@ public: ...@@ -34,7 +34,7 @@ public:
class InvalidTypeError : public ParseError { class InvalidTypeError : public ParseError {
public: public:
InvalidTypeError(int lineno, Type &expected, vector<shared_ptr<Type>> received, Expr *expr = NULL); InvalidTypeError(Type &expected, vector<shared_ptr<Type>> received, Visitable *expr = NULL);
}; };
#endif #endif
\ No newline at end of file
...@@ -1967,7 +1967,7 @@ yyreduce: ...@@ -1967,7 +1967,7 @@ yyreduce:
default: break; default: break;
} }
// if (yyval.expr_) yyval.expr_->lineno = yy_mylinenumber; if (2 <= yyn && yyn <= 85) yyval.expr_->lineno = yy_mylinenumber; // mozna uzyc czegokolwiek bo lineno jest w virtualu
/* User semantic actions sometimes alter yychar, and that requires /* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken. approach of translating immediately before every use of yytoken.
......
...@@ -1092,7 +1092,7 @@ void ShowAbsyn::visitPIdent(PIdent *p) ...@@ -1092,7 +1092,7 @@ void ShowAbsyn::visitPIdent(PIdent *p)
bufAppend(' '); bufAppend(' ');
visitString(p->string_); visitString(p->string_);
bufAppend(' '); bufAppend(' ');
visitInteger(p->integer_); visitInteger(p->lineno);
bufAppend(')'); bufAppend(')');
} }
void ShowAbsyn::visitProgram(Program *p) {} //abstract class void ShowAbsyn::visitProgram(Program *p) {} //abstract class
......
#include "TypeCheck.h" #include "TypeCheck.h"
#include "ParseError.h" #include "ParseError.h"
#include <stdexcept> #include <stdexcept>
#include <iostream>
void TypeCheck::visitClassDef(ClassDef *t) { void TypeCheck::visitClassDef(ClassDef *t) {
const string name = t->getName()->string_; const string name = t->getName()->string_;
ClassInfoPtr parent = NULL; ClassInfoPtr parent = NULL;
...@@ -22,7 +22,6 @@ void TypeCheck::visitClassDef(ClassDef *t) { ...@@ -22,7 +22,6 @@ void TypeCheck::visitClassDef(ClassDef *t) {
void TypeCheck::visitPIdent(PIdent *p_ident) void TypeCheck::visitPIdent(PIdent *p_ident)
{ {
visitString(p_ident->string_); visitString(p_ident->string_);
visitInteger(p_ident->integer_);
} }
void TypeCheck::visitProg(Prog *prog) void TypeCheck::visitProg(Prog *prog)
...@@ -122,47 +121,52 @@ void TypeCheck::visitDecl(Decl *decl) ...@@ -122,47 +121,52 @@ void TypeCheck::visitDecl(Decl *decl)
el->expr_->accept(this); el->expr_->accept(this);
VarInfoPtr var = make_shared<VarInfo>(el->pident_, type); VarInfoPtr var = make_shared<VarInfo>(el->pident_, type);
el->pident_->var = var;
scope.currentBinding->variables << var; scope.currentBinding->variables << var;
} }
} }
void TypeCheck::visitAss(Ass *ass) void TypeCheck::visitAss(Ass *ass)
{ {
// auto var = scope.currentBinding->variables[]
ass->expr_1->accept(this); ass->expr_1->accept(this);
auto a = lastType;
ass->expr_2->accept(this); ass->expr_2->accept(this);
auto b = lastType;
if (*a != *b) {
throw InvalidTypeError(*a, {b}, ass->expr_1);
}
} }
void TypeCheck::visitIncr(Incr *incr) void TypeCheck::visitIncr(Incr *incr)
{ {
/* Code For Incr Goes Here */ Expr *e = incr->expr_;
e->accept(this);
incr->expr_->accept(this); Int expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, e);
}
} }
void TypeCheck::visitDecr(Decr *decr) void TypeCheck::visitDecr(Decr *decr)
{ {
/* Code For Decr Goes Here */ Expr *e = decr->expr_;
e->accept(this);
decr->expr_->accept(this); Int expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, e);
}
} }
void TypeCheck::visitRet(Ret *ret) void TypeCheck::visitRet(Ret *ret)
{ {
/* Code For Ret Goes Here */ /* Code For Ret Goes Here */
ret->expr_->accept(this); ret->expr_->accept(this);
checkReturn(lastType, ret);
} }
void TypeCheck::visitVRet(VRet *v_ret) void TypeCheck::visitVRet(VRet *v_ret)
{ {
/* Code For VRet Goes Here */ checkReturn(make_shared<Void>(), v_ret);
} }
void TypeCheck::visitCond(Cond *cond) void TypeCheck::visitCond(Cond *cond)
...@@ -170,8 +174,12 @@ void TypeCheck::visitCond(Cond *cond) ...@@ -170,8 +174,12 @@ void TypeCheck::visitCond(Cond *cond)
/* Code For Cond Goes Here */ /* Code For Cond Goes Here */
cond->expr_->accept(this); cond->expr_->accept(this);
Bool expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, cond->expr_);
}
cond->stmt_->accept(this); cond->stmt_->accept(this);
returnType = nullptr;
} }
void TypeCheck::visitCondElse(CondElse *cond_else) void TypeCheck::visitCondElse(CondElse *cond_else)
...@@ -179,8 +187,22 @@ void TypeCheck::visitCondElse(CondElse *cond_else) ...@@ -179,8 +187,22 @@ void TypeCheck::visitCondElse(CondElse *cond_else)
/* Code For CondElse Goes Here */ /* Code For CondElse Goes Here */
cond_else->expr_->accept(this); cond_else->expr_->accept(this);
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;
returnType = nullptr;
cond_else->stmt_2->accept(this); cond_else->stmt_2->accept(this);
auto ret2 = returnType;
if (ret1 && ret2) {
if (*ret1 != *ret2) {
throw InvalidTypeError(*ret1, {ret2}, cond_else);
}
} else {
returnType = nullptr;
}
} }
...@@ -189,8 +211,12 @@ void TypeCheck::visitWhile(While *while_) ...@@ -189,8 +211,12 @@ void TypeCheck::visitWhile(While *while_)
/* Code For While Goes Here */ /* Code For While Goes Here */
while_->expr_->accept(this); while_->expr_->accept(this);
Bool expect;
if (*lastType != expect) {
throw InvalidTypeError(expect, {lastType}, while_->expr_);
}
while_->stmt_->accept(this); while_->stmt_->accept(this);
returnType = nullptr;
} }
void TypeCheck::visitSExp(SExp *s_exp) void TypeCheck::visitSExp(SExp *s_exp)
...@@ -324,7 +350,7 @@ void TypeCheck::visitEString(EString *e) ...@@ -324,7 +350,7 @@ void TypeCheck::visitEString(EString *e)
auto a = lastType; auto a = lastType;
Str expect; Str expect;
if (*a != expect) { if (*a != expect) {
throw InvalidTypeError(e->lineno, expect, {a}, e); throw InvalidTypeError(expect, {a}, e);
} }
lastType = make_shared<Str>(); lastType = make_shared<Str>();
} }
...@@ -338,7 +364,7 @@ void TypeCheck::visitENewArray(ENewArray *e) ...@@ -338,7 +364,7 @@ void TypeCheck::visitENewArray(ENewArray *e)
auto a = lastType; auto a = lastType;
Array expect(e->type_); Array expect(e->type_);
if (*a != expect) { if (*a != expect) {
throw InvalidTypeError(e->lineno, expect, {a}, e); throw InvalidTypeError(expect, {a}, e);
} }
lastType = make_shared<Array>(e->type_); lastType = make_shared<Array>(e->type_);
} }
...@@ -406,7 +432,7 @@ void TypeCheck::visitNeg(Neg *e) ...@@ -406,7 +432,7 @@ void TypeCheck::visitNeg(Neg *e)
auto a = lastType; auto a = lastType;
Int expect; Int expect;
if (*a != expect) { if (*a != expect) {
throw InvalidTypeError(e->lineno, expect, {a}, e); throw InvalidTypeError(expect, {a}, e);
} }
lastType = make_shared<Int>(); lastType = make_shared<Int>();
} }
...@@ -417,7 +443,7 @@ void TypeCheck::visitNot(Not *e) ...@@ -417,7 +443,7 @@ void TypeCheck::visitNot(Not *e)
auto a = lastType; auto a = lastType;
Bool expect; Bool expect;
if (*a != expect) { if (*a != expect) {
throw InvalidTypeError(e->lineno, expect, {a}, e); throw InvalidTypeError(expect, {a}, e);
} }
lastType = make_shared<Bool>(); lastType = make_shared<Bool>();
} }
...@@ -430,7 +456,7 @@ void TypeCheck::visitEMul(EMul *e) ...@@ -430,7 +456,7 @@ void TypeCheck::visitEMul(EMul *e)
auto b = lastType; auto b = lastType;
Int expect; Int expect;
if (*a != expect || *a != *b) { if (*a != expect || *a != *b) {
throw InvalidTypeError(e->lineno, expect, {a, b}, e); throw InvalidTypeError(expect, {a, b}, e);
} }
lastType = make_shared<Int>(); lastType = make_shared<Int>();
} }
...@@ -443,7 +469,7 @@ void TypeCheck::visitEAdd(EAdd *e) ...@@ -443,7 +469,7 @@ void TypeCheck::visitEAdd(EAdd *e)
auto b = lastType; auto b = lastType;
Int expect; Int expect;
if (*a != expect || *a != *b) { if (*a != expect || *a != *b) {
throw InvalidTypeError(e->lineno, expect, {a, b}, e); throw InvalidTypeError(expect, {a, b}, e);
} }
lastType = make_shared<Int>(); lastType = make_shared<Int>();
} }
...@@ -456,7 +482,7 @@ void TypeCheck::visitERel(ERel *e) ...@@ -456,7 +482,7 @@ void TypeCheck::visitERel(ERel *e)
auto b = lastType; auto b = lastType;
Int expect; Int expect;
if (*a != expect || *a != *b) { if (*a != expect || *a != *b) {
throw InvalidTypeError(e->lineno, expect, {a, b}, e); throw InvalidTypeError(expect, {a, b}, e);
} }
lastType = make_shared<Bool>(); lastType = make_shared<Bool>();
} }
...@@ -469,7 +495,7 @@ void TypeCheck::visitEAnd(EAnd *e) ...@@ -469,7 +495,7 @@ void TypeCheck::visitEAnd(EAnd *e)
auto b = lastType; auto b = lastType;
Bool expect; Bool expect;
if (*a != expect || *a != *b) { if (*a != expect || *a != *b) {
throw InvalidTypeError(e->lineno, expect, {a, b}, e); throw InvalidTypeError(expect, {a, b}, e);
} }
lastType = make_shared<Bool>(); lastType = make_shared<Bool>();
} }
...@@ -482,7 +508,7 @@ void TypeCheck::visitEOr(EOr *e) ...@@ -482,7 +508,7 @@ void TypeCheck::visitEOr(EOr *e)
auto b = lastType; auto b = lastType;
Bool expect; Bool expect;
if (*a != expect || *a != *b) { if (*a != expect || *a != *b) {
throw InvalidTypeError(e->lineno, expect, {a, b}, e); throw InvalidTypeError(expect, {a, b}, e);
} }
lastType = make_shared<Bool>(); lastType = make_shared<Bool>();
} }
...@@ -516,6 +542,7 @@ void TypeCheck::visitListStmt(ListStmt *list_stmt) ...@@ -516,6 +542,7 @@ void TypeCheck::visitListStmt(ListStmt *list_stmt)
for (ListStmt::iterator i = list_stmt->begin() ; i != list_stmt->end() ; ++i) for (ListStmt::iterator i = list_stmt->begin() ; i != list_stmt->end() ; ++i)
{ {
(*i)->accept(this); (*i)->accept(this);
if (returnType) break;
} }
} }
...@@ -576,12 +603,17 @@ void TypeCheck::check(Visitable *v) ...@@ -576,12 +603,17 @@ void TypeCheck::check(Visitable *v)
scope.currentClass = nullptr; scope.currentClass = nullptr;
} }
for (auto f : scope.functions) {
checkFunction(f);
}
} }
void TypeCheck::checkFunction(FunctionInfoPtr f) void TypeCheck::checkFunction(FunctionInfoPtr f)
{ {
scope.currentFunction = f; scope.currentFunction = f;
std::cout << "checking fun " << f->name << " at line " << f->lineLocation << endl;
BindingPtr binding = make_shared<Binding>(nullptr); BindingPtr binding = make_shared<Binding>(nullptr);
f->binding = binding; f->binding = binding;
...@@ -590,6 +622,27 @@ void TypeCheck::checkFunction(FunctionInfoPtr f) ...@@ -590,6 +622,27 @@ void TypeCheck::checkFunction(FunctionInfoPtr f)
} }
f->block->accept(this); f->block->accept(this);
if (*f->type != Void()) {
if (!returnType) {
throw ParseError("Funkcja nie zwróciła wyniku!", f->lineLocation);
}
if (*returnType != *f->type) {
throw InvalidTypeError(*returnType, {&*f->type}, f->block);
}
} else {
if (returnType && *returnType != *f->type) {
throw InvalidTypeError(*returnType, {&*f->type}, f->block);
}
}
scope.currentFunction = nullptr; scope.currentFunction = nullptr;
} }
void TypeCheck::checkReturn(shared_ptr<Type> type, Stmt *stmt) {
lastType = returnType = type;
if (*type != *scope.currentFunction->type) {
throw InvalidTypeError(*scope.currentFunction->type, {type}, stmt);
}
}
\ No newline at end of file
...@@ -16,9 +16,10 @@ class TypeCheck : public Visitor ...@@ -16,9 +16,10 @@ class TypeCheck : public Visitor
} state; } state;
Scope scope; Scope scope;
shared_ptr<Type> lastType; shared_ptr<Type> lastType, returnType;
void checkFunction(FunctionInfoPtr f); void checkFunction(FunctionInfoPtr f);
void checkReturn(shared_ptr<Type> type, Stmt *stmt);
public: public:
TypeCheck(); TypeCheck();
void check(Visitable *v); void check(Visitable *v);
......
...@@ -16,6 +16,7 @@ using ClassInfoPtr = shared_ptr<ClassInfo>; ...@@ -16,6 +16,7 @@ using ClassInfoPtr = shared_ptr<ClassInfo>;
using BindingPtr = shared_ptr<Binding>; using BindingPtr = shared_ptr<Binding>;
class Visitable;
class Program; class Program;
class TopDef; class TopDef;
class FunDef; class FunDef;
......
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