Commit 7734538e authored by zygzagZ's avatar zygzagZ

WIP dziala sporo

parent b860fd23
...@@ -2903,11 +2903,13 @@ bool Fun::isEqual(Type const *other) const { ...@@ -2903,11 +2903,13 @@ bool Fun::isEqual(Type const *other) const {
bool ClassT::isEqual(Type const *other) const { bool ClassT::isEqual(Type const *other) const {
if (const ClassT* casted = dynamic_cast<const ClassT*>(other)) { if (const ClassT* casted = dynamic_cast<const ClassT*>(other)) {
BindingPtr ba = binding.lock(), bb = casted->binding.lock(); auto v1 = pident_->var.lock(), v2 = casted->pident_->var.lock();
if (!ba || !bb) { return v1 && v1 == v2;
throw std::runtime_error("Binding nie znaleziony na typie klasy!"); // BindingPtr ba = binding.lock(), bb = casted->binding.lock();
} // if (!ba || !bb) {
return ba->classes[pident_] == bb->classes[pident_]; // throw std::runtime_error("Binding nie znaleziony na typie klasy!");
// }
// return ba->classes[pident_] == bb->classes[pident_];
} }
return false; return false;
} }
...@@ -29,12 +29,10 @@ ClassInfo::ClassInfo(PIdent *ident, BindingPtr parent /*= nullptr*/) ...@@ -29,12 +29,10 @@ ClassInfo::ClassInfo(PIdent *ident, BindingPtr parent /*= nullptr*/)
{ {
type = make_shared<ClassT>(ident->clone()); type = make_shared<ClassT>(ident->clone());
type->binding = parent; type->binding = parent;
}; };
Scope::Scope() Scope::Scope()
: currentClass() : currentClass()
{ {
} }
...@@ -52,6 +52,7 @@ public: ...@@ -52,6 +52,7 @@ public:
weak_ptr<Binding> parent; weak_ptr<Binding> parent;
Binding(BindingPtr parent = nullptr); Binding(BindingPtr parent = nullptr);
virtual ~Binding() {};
BindingPtr getParent() const { return parent.lock(); }; BindingPtr getParent() const { return parent.lock(); };
}; };
......
...@@ -20,6 +20,8 @@ void usage() { ...@@ -20,6 +20,8 @@ void usage() {
printf("\t-v (files)\tVerbose mode. Parse content of files verbosely.\n"); printf("\t-v (files)\tVerbose mode. Parse content of files verbosely.\n");
} }
const int CONTEXT_LINES = 3;
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
FILE *input; FILE *input;
...@@ -47,8 +49,14 @@ int main(int argc, char ** argv) ...@@ -47,8 +49,14 @@ int main(int argc, char ** argv)
} }
} else input = stdin; } else input = stdin;
string source;
while (int c = fgetc(input)) {
if (c == EOF) break;
source += c;
}
/* The default entry point is used. For other options see Parser.H */ /* The default entry point is used. For other options see Parser.H */
Program *parse_tree = pProgram(input); Program *parse_tree = pProgram(source.data());
if (!parse_tree) { if (!parse_tree) {
fprintf(stderr, "Parser error, invalid syntax!\n"); fprintf(stderr, "Parser error, invalid syntax!\n");
return 1; return 1;
...@@ -71,6 +79,26 @@ int main(int argc, char ** argv) ...@@ -71,6 +79,26 @@ int main(int argc, char ** argv)
checker.check(parse_tree); checker.check(parse_tree);
} catch (ParseError const &e) { } catch (ParseError const &e) {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
if (e.line != -1) {
auto ss = std::stringstream{source};
int l = 1;
int ll = max(max(to_string(e.line - CONTEXT_LINES).length(), to_string(e.line + CONTEXT_LINES).length()), 3lu);
cout << "ll: " << ll << endl;
for (std::string line; std::getline(ss, line, '\n');l++) {
auto diff = abs(e.line - l);
if (diff <= CONTEXT_LINES) {
if (!diff) {
cout << "--> ";
for (int i = 2; i < ll; i++) cout << ' ';
cout << line << endl;
} else {
cout << to_string(l) << ": ";
for (int i = to_string(l).length(); i < ll; i++) cout << ' ';
cout << line << endl;
}
}
}
}
return 1; return 1;
} }
std::cout << "OK!" << endl; std::cout << "OK!" << endl;
......
...@@ -17,6 +17,7 @@ ParseError::ParseError(string reason, Visitable *expr) : runtime_error("ParseErr ...@@ -17,6 +17,7 @@ ParseError::ParseError(string reason, Visitable *expr) : runtime_error("ParseErr
ParseError::ParseError(string reason, VarInfo &var) : runtime_error("ParseError") { ParseError::ParseError(string reason, VarInfo &var) : runtime_error("ParseError") {
msg = reason + "\nIn " + var.describe(); msg = reason + "\nIn " + var.describe();
line = var.lineLocation;
} }
RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) { RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) {
......
...@@ -13,13 +13,16 @@ using namespace std; ...@@ -13,13 +13,16 @@ using namespace std;
class ParseError : std::runtime_error { class ParseError : std::runtime_error {
protected: protected:
string msg; string msg;
int line;
ParseError() : runtime_error("ParseError") {} ParseError() : runtime_error("ParseError") {}
public: public:
int line;
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(string reason, VarInfo &var);
ParseError(const ParseError &e, Visitable *expr) : ParseError(e.what(), expr) {};
ParseError(const ParseError &e, Visitable *param) : ParseError(e.what(), param) { if (e.line != -1) line = e.line; };
ParseError(const ParseError &e, VarInfo &param) : ParseError(e.what(), param) { if (e.line != -1) line = e.line; };
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(); }
}; };
......
...@@ -17,6 +17,8 @@ void TypeCheck::visitClassDef(ClassDef *t) { ...@@ -17,6 +17,8 @@ void TypeCheck::visitClassDef(ClassDef *t) {
parent = scope; parent = scope;
} }
auto c = make_shared<ClassInfo>(t->getName(), parent); auto c = make_shared<ClassInfo>(t->getName(), parent);
static_pointer_cast<ClassT>(c->type)->pident_->var = c;
t->getName()->var = c;
scope->classes << c; scope->classes << c;
scope->currentBinding = scope->currentClass = c; scope->currentBinding = scope->currentClass = c;
...@@ -30,6 +32,10 @@ void TypeCheck::visitPIdent(PIdent *p_ident) ...@@ -30,6 +32,10 @@ void TypeCheck::visitPIdent(PIdent *p_ident)
auto var = scope->currentBinding->variables[p_ident]; auto var = scope->currentBinding->variables[p_ident];
p_ident->var = var; p_ident->var = var;
lastType = var->type; lastType = var->type;
if (auto ptr = dynamic_pointer_cast<ClassT>(lastType)) {
if (!ptr->pident_ || !ptr->pident_->var.lock())
throw ParseError("chuj");
}
} }
void TypeCheck::visitProg(Prog *prog) void TypeCheck::visitProg(Prog *prog)
...@@ -222,14 +228,13 @@ void TypeCheck::visitForEach(ForEach *for_each) ...@@ -222,14 +228,13 @@ 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_);
auto arrType = evalExpr<Array>(for_each->expr_); auto arrType = evalExpr<Array>(for_each->expr_);
if (*arrType != expect) { if (*arrType != expect) {
throw InvalidTypeError(expect, {lastType}, for_each->expr_); throw InvalidTypeError(expect, {arrType}, for_each->expr_);
} }
VarInfoPtr var = make_shared<VarInfo>(for_each->pident_, lastType); VarInfoPtr var = make_shared<VarInfo>(for_each->pident_, for_each->type_->clone());
binding->variables << var; binding->variables << var;
scope->currentBinding = binding; scope->currentBinding = binding;
...@@ -301,9 +306,18 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr) ...@@ -301,9 +306,18 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
} }
throw ParseError("Class expected", e_cls_mmbr->expr_); throw ParseError("Class expected", e_cls_mmbr->expr_);
} }
ClassInfoPtr klass = scope->currentBinding->classes[type->pident_]; ClassInfoPtr klass = scope->classes[type->pident_];
if (klass != type->pident_->var.lock()) {
throw ParseError("ej lol inny var");
}
VarInfoPtr var = klass->variables.local(e_cls_mmbr->pident_->string_); VarInfoPtr var = klass->variables.local(e_cls_mmbr->pident_->string_);
if (!var) { while (!var && klass) {
klass = dynamic_pointer_cast<ClassInfo>(klass->getParent());
if (klass) {
var = klass->variables.local(e_cls_mmbr->pident_->string_);
}
}
if (!var || var == scope->variables.local(e_cls_mmbr->pident_->string_)) {
cout << "undef clsmmbr !var" << endl; cout << "undef clsmmbr !var" << endl;
throw UndefinedError(e_cls_mmbr->pident_); throw UndefinedError(e_cls_mmbr->pident_);
} }
...@@ -314,7 +328,8 @@ void TypeCheck::visitEApp(EApp *e_app) ...@@ -314,7 +328,8 @@ void TypeCheck::visitEApp(EApp *e_app)
{ {
shared_ptr<Fun> type = evalExpr<Fun>(e_app->expr_); shared_ptr<Fun> type = evalExpr<Fun>(e_app->expr_);
if (type->listtype_->size() != e_app->listexpr_->size()) { if (type->listtype_->size() != e_app->listexpr_->size()) {
throw ParseError("Expected " + to_string(type->listtype_->size()) + " arguments, " + to_string(e_app->listexpr_->size()) + " given", e_app); string msg = "Expected " + to_string(type->listtype_->size()) + " arguments, " + to_string(e_app->listexpr_->size()) + " given";
throw ParseError(msg, e_app);
} }
for (unsigned int i = 0; i < type->listtype_->size(); i++) { for (unsigned int i = 0; i < type->listtype_->size(); i++) {
try { try {
...@@ -325,7 +340,10 @@ void TypeCheck::visitEApp(EApp *e_app) ...@@ -325,7 +340,10 @@ void TypeCheck::visitEApp(EApp *e_app)
throw InvalidTypeError(*expect, {exprType}, expr); throw InvalidTypeError(*expect, {exprType}, expr);
} }
} catch (const ParseError &e) { } catch (const ParseError &e) {
throw ParseError(string(e.what()) + "\nIn argument " + to_string(i+1) + " of function call:", e_app); string msg = string(e.what()) + "\nIn argument " + to_string(i+1) + " of function call:";
ParseError ctx(msg, e_app);
ctx.line = e.line;
throw e;
} }
} }
...@@ -370,6 +388,9 @@ void TypeCheck::visitENewClass(ENewClass *e_new_class) ...@@ -370,6 +388,9 @@ void TypeCheck::visitENewClass(ENewClass *e_new_class)
{ {
// e_new_class->pident_->accept(this); // e_new_class->pident_->accept(this);
lastType = evalExpr<ClassT>(e_new_class->pident_); lastType = evalExpr<ClassT>(e_new_class->pident_);
// if (!e_new_class->pident_->var.lock()) {
// }
// ClassInfoPtr klass = dynamic_pointer_cast<ClassInfo>(e_new_class->pident_->var.lock()); // ClassInfoPtr klass = dynamic_pointer_cast<ClassInfo>(e_new_class->pident_->var.lock());
// if (!klass) { // if (!klass) {
// throw ParseError("Class expected", e_new_class->pident_); // throw ParseError("Class expected", e_new_class->pident_);
...@@ -554,7 +575,7 @@ void TypeCheck::check(Visitable *v) ...@@ -554,7 +575,7 @@ void TypeCheck::check(Visitable *v)
checkFunction(f); checkFunction(f);
} }
} catch (const ParseError &e) { } catch (const ParseError &e) {
throw ParseError(e.what(), *c); throw ParseError(e, *c);
} }
...@@ -604,7 +625,7 @@ void TypeCheck::checkFunction(FunctionInfoPtr f) ...@@ -604,7 +625,7 @@ void TypeCheck::checkFunction(FunctionInfoPtr f)
scope->currentFunction = nullptr; scope->currentFunction = nullptr;
} catch (const ParseError &e) { } catch (const ParseError &e) {
throw ParseError(e.what(), *f); throw ParseError(e, *f);
} }
} }
......
#!/bin/bash #!/bin/bash
t=0 t=0
RED='\033[0;31m'
GREEN='\033[0;32m'
NONE='\033[0m'
function red {
echo -e "${RED}$@${NONE}"
}
function green {
echo -e "${GREEN}$@${NONE}"
}
make -j8 && for i in lat/lattests/good/*.lat; do make -j8 && for i in lat/lattests/good/*.lat; do
t=$((t+1)) t=$((t+1))
(./latc "$i" &>/dev/null); (./latc "$i" &>/dev/null);
if ! [ $? -eq 0 ]; then if ! [ $? -eq 0 ]; then
echo $i; red "FAIL $i";
./latc "$i" ./latc "$i"
exit 1; exit 1;
fi fi
done && for i in lat/lattests/bad/*.lat; do done && green good OK && for i in lat/lattests/bad/*.lat; do
t=$((t+1)) t=$((t+1))
(./latc "$i" &>/dev/null); (./latc "$i" &>/dev/null);
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo $i; red "FAIL $i";
./latc "$i" ./latc "$i"
exit 1; exit 1;
fi fi
done && echo OK: $t tests passed! done && green "OK: $t tests passed!" && for ext in `ls lat/lattests/extensions`; do
\ No newline at end of file ok=1
for i in lat/lattests/extensions/$ext/*.lat; do
(./latc "$i" &>/dev/null);
if ! [ $? -eq 0 ]; then
red "$ext fails on $i";
./latc "$i"
ok=0;
break;
fi
done
if [ $ok -eq 1 ]; then
green "OK: $ext passed!"
fi
done
\ No newline at end of file
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