Commit f608a142 authored by zygzagZ's avatar zygzagZ

arguments check in Fun Type compare, check const integer overflow, check void: arg, declaration

parent 519005ca
......@@ -2896,7 +2896,12 @@ bool Fun::isEqual(Type const *other, bool sub) const {
if (!type_->isEqual(casted->type_, sub) || listtype_->size() != casted->listtype_->size()) {
return false;
}
// TODO: czy sprawdzać argumenty?
for (unsigned int i = 0; i < listtype_->size(); i++) {
if (!casted->listtype_->at(i)->isEqual(listtype_->at(i), true)) {
return false;
}
}
return true;
}
return false;
}
......
......@@ -9,7 +9,7 @@
/******************** TypeDef Section ********************/
typedef int Integer;
typedef long long int Integer;
typedef char Char;
typedef double Double;
typedef std::string String;
......@@ -229,6 +229,8 @@ public:
virtual Type *clone() const = 0;
virtual std::string printName() const = 0;
virtual bool isEqual(Type const *f, bool sub = false) const = 0;
template<typename T>
bool isEqual(shared_ptr<T> f, bool sub = false) const { return isEqual((T*)&*f, sub); };
bool operator==(Type const & f) const { return isEqual(&f); }
bool operator!=(Type const & f) const { return !isEqual(&f); }
};
......
......@@ -1137,7 +1137,7 @@ YY_BUFFER_APPEND(yytext); BEGIN STRING;
case 60:
YY_RULE_SETUP
#line 90 "Grammar.l"
yylval.int_ = atoi(yytext); return _INTEGER_;
yylval.int_ = ((strlen(yytext) > 18) ? (1ll<<60) : atoll(yytext)); return _INTEGER_;
YY_BREAK
case 61:
/* rule 61 can match eol */
......
......@@ -6,7 +6,9 @@ using namespace std;
ParseError::ParseError(string reason, int line) : runtime_error("ParseError"), line(line)
{
msg = reason + "\nAt line " + to_string(line);
msg = reason;
if (line != -1)
msg += "\nAt line " + to_string(line);
}
ParseError::ParseError(string reason, Visitable *expr) : runtime_error("ParseError")
......
......@@ -262,7 +262,7 @@ union YYSTYPE
{
#line 100 "Grammar.y"
int int_;
long long int int_;
char char_;
double double_;
char* string_;
......
......@@ -30,7 +30,7 @@ class RelOp;
typedef union
{
int int_;
long long int int_;
char char_;
double double_;
char* string_;
......
......@@ -3,6 +3,7 @@
#include <stdexcept>
#include <iostream>
#include "Printer.h"
#include <climits>
void TypeCheck::visitClassDef(ClassDef *t) {
const string name = t->getName()->string_;
......@@ -134,11 +135,15 @@ void TypeCheck::visitDecl(Decl *decl)
Type* type = decl->type_;
type->accept(this);
if (dynamic_cast<Void*>(type)) {
throw ParseError("Void variable", type);
}
for (Item * el : *decl->listitem_) {
// el->accept(this); // nie trzeba bo el to tylko ident = expr
if (el->expr_) {
auto exprType = evalExpr(el->expr_);
if (!type->isEqual(&*exprType, true)) {
if (!type->isEqual(exprType, true)) {
throw InvalidTypeError(*type, {exprType}, el->expr_);
}
}
......@@ -153,7 +158,7 @@ void TypeCheck::visitAss(Ass *ass)
{
auto a = evalExpr(ass->expr_1);
auto b = evalExpr(ass->expr_2);
if (!a->isEqual(&*b, true)) {
if (!a->isEqual(b, true)) {
throw InvalidTypeError(*a, {b}, ass->expr_1);
}
}
......@@ -214,7 +219,10 @@ void TypeCheck::visitWhile(While *while_)
{
evalExpr<Bool>(while_->expr_);
while_->stmt_->accept(this);
if (!dynamic_cast<ELitTrue*>(while_->expr_)) {
returnType = nullptr;
}
}
void TypeCheck::visitSExp(SExp *s_exp)
......@@ -228,7 +236,7 @@ void TypeCheck::visitForEach(ForEach *for_each)
for_each->type_->accept(this);
Array expect(for_each->type_);
auto arrType = evalExpr<Array>(for_each->expr_);
if (*arrType != expect) {
if (!expect.isEqual(&*arrType, true)) {
throw InvalidTypeError(expect, {arrType}, for_each->expr_);
}
......@@ -328,7 +336,7 @@ void TypeCheck::visitEApp(EApp *e_app)
Expr *expr = e_app->listexpr_->at(i);
auto exprType = evalExpr(expr);
auto *expect = type->listtype_->at(i);
if (*expect != *exprType) {
if (!expect->isEqual(exprType, true)) {
throw InvalidTypeError(*expect, {exprType}, expr);
}
} catch (const ParseError &e) {
......@@ -345,6 +353,9 @@ void TypeCheck::visitEApp(EApp *e_app)
void TypeCheck::visitELitInt(ELitInt *e_lit_int)
{
visitInteger(e_lit_int->integer_);
if (e_lit_int->integer_ > INT_MAX || e_lit_int->integer_ < INT_MIN) {
throw ParseError("constant too big", e_lit_int->lineno);
}
lastType = make_shared<Int>();
}
......@@ -369,7 +380,7 @@ void TypeCheck::visitENewArray(ENewArray *e)
evalExpr<Int>(e->expr_);
e->type_->accept(this);
if (dynamic_cast<Void*>(e->type_)) {
throw ParseError("Tablica typu void!", e);
throw ParseError("Void table", e);
}
auto ret = make_shared<Array>(e->type_->clone()); // make type
ret->type_->binding = scope->currentBinding;
......@@ -437,7 +448,7 @@ void TypeCheck::visitERel(ERel *e)
auto a = evalExpr(e->expr_1);
auto b = evalExpr(e->expr_2);
if (dynamic_cast<EQU*>(e->relop_) || dynamic_cast<NE*>(e->relop_)) {
if (*a != *b) {
if (!a->isEqual(b, true) && !b->isEqual(a, true)) {
throw InvalidTypeError(*a, {b}, e);
}
} else {
......@@ -591,6 +602,16 @@ void TypeCheck::check(Visitable *v)
for (auto f : scope->functions) {
checkFunction(f);
}
if (FunctionInfoPtr main = scope->functions.local("main")) {
Fun expected(new Int(), new ListType());
if (!main->type->isEqual(&expected, false)) {
throw InvalidTypeError(expected, {main->type}, main->ident);
}
} else {
throw ParseError("No \"main\" function declared");
}
}
void TypeCheck::checkReturnStatement(shared_ptr<Type> type, Stmt *stmt) {
......@@ -600,7 +621,7 @@ void TypeCheck::checkReturnStatement(shared_ptr<Type> type, Stmt *stmt) {
if (!funType) throw runtime_error("FunctionInfo " + f->name + ":" + to_string(f->lineLocation) + " nie ma typu Fun!");
auto funRet = funType->type_;
if (*type != *funRet) {
if (!funRet->isEqual(type, true)) {
throw InvalidTypeError(*funRet, {type}, stmt);
}
}
......@@ -648,11 +669,11 @@ void TypeCheck::checkFunctionRet() {
if (!returnType || returnType == nullptr) {
throw ParseError("Function " + f->name + " did not return!", f->lineLocation);
}
if (*returnType != *funRet) {
if (!funRet->isEqual(returnType, true)) {
throw InvalidTypeError(*returnType, {funRet}, f->block);
}
} else {
if (returnType && *returnType != *funRet) {
if (returnType && !funRet->isEqual(returnType, true)) {
throw InvalidTypeError(*returnType, {funRet}, f->block);
}
}
......
......@@ -147,7 +147,12 @@ protected:
void visitEmpty(Empty *p) {};
void visitNoInit(NoInit *p) { };
void visitInit(Init *p) { };
void visitAr(Ar *p) { p->type_->accept(this); };
void visitAr(Ar *p) {
p->type_->accept(this);
if (dynamic_cast<Void*>(p->type_)) {
throw ParseError("Void argument", p->type_);
}
};
// exprs
void visitPlus(Plus *p) {};
......
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