Commit 08a16dd0 authored by zygzagZ's avatar zygzagZ

lineno do kazdego visitable

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