Commit 7734538e authored by zygzagZ's avatar zygzagZ

WIP dziala sporo

parent b860fd23
......@@ -2903,11 +2903,13 @@ bool Fun::isEqual(Type const *other) const {
bool ClassT::isEqual(Type const *other) const {
if (const ClassT* casted = dynamic_cast<const ClassT*>(other)) {
BindingPtr ba = binding.lock(), bb = casted->binding.lock();
if (!ba || !bb) {
throw std::runtime_error("Binding nie znaleziony na typie klasy!");
}
return ba->classes[pident_] == bb->classes[pident_];
auto v1 = pident_->var.lock(), v2 = casted->pident_->var.lock();
return v1 && v1 == v2;
// BindingPtr ba = binding.lock(), bb = casted->binding.lock();
// if (!ba || !bb) {
// throw std::runtime_error("Binding nie znaleziony na typie klasy!");
// }
// return ba->classes[pident_] == bb->classes[pident_];
}
return false;
}
......@@ -29,12 +29,10 @@ ClassInfo::ClassInfo(PIdent *ident, BindingPtr parent /*= nullptr*/)
{
type = make_shared<ClassT>(ident->clone());
type->binding = parent;
};
Scope::Scope()
: currentClass()
{
}
......@@ -52,6 +52,7 @@ public:
weak_ptr<Binding> parent;
Binding(BindingPtr parent = nullptr);
virtual ~Binding() {};
BindingPtr getParent() const { return parent.lock(); };
};
......
......@@ -20,6 +20,8 @@ void usage() {
printf("\t-v (files)\tVerbose mode. Parse content of files verbosely.\n");
}
const int CONTEXT_LINES = 3;
int main(int argc, char ** argv)
{
FILE *input;
......@@ -47,8 +49,14 @@ int main(int argc, char ** argv)
}
} 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 */
Program *parse_tree = pProgram(input);
Program *parse_tree = pProgram(source.data());
if (!parse_tree) {
fprintf(stderr, "Parser error, invalid syntax!\n");
return 1;
......@@ -71,6 +79,26 @@ int main(int argc, char ** argv)
checker.check(parse_tree);
} catch (ParseError const &e) {
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;
}
std::cout << "OK!" << endl;
......
......@@ -17,6 +17,7 @@ ParseError::ParseError(string reason, Visitable *expr) : runtime_error("ParseErr
ParseError::ParseError(string reason, VarInfo &var) : runtime_error("ParseError") {
msg = reason + "\nIn " + var.describe();
line = var.lineLocation;
}
RedefinedError::RedefinedError(PIdent *ident, VarInfoPtr orig) {
......
......@@ -13,13 +13,16 @@ using namespace std;
class ParseError : std::runtime_error {
protected:
string msg;
int line;
ParseError() : runtime_error("ParseError") {}
public:
int line;
ParseError(string reason, int line = -1);
ParseError(string reason, Visitable *expr);
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(); }
};
......@@ -41,4 +44,4 @@ public:
InvalidTypeError(Type &expected, vector<Type*> received, Visitable *expr = NULL);
};
#endif
\ No newline at end of file
#endif
......@@ -17,6 +17,8 @@ void TypeCheck::visitClassDef(ClassDef *t) {
parent = scope;
}
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->currentBinding = scope->currentClass = c;
......@@ -30,6 +32,10 @@ void TypeCheck::visitPIdent(PIdent *p_ident)
auto var = scope->currentBinding->variables[p_ident];
p_ident->var = var;
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)
......@@ -222,14 +228,13 @@ void TypeCheck::visitForEach(ForEach *for_each)
{
BindingPtr binding = make_shared<Binding>(scope->currentBinding);
for_each->type_->accept(this);
Type &iterType = *lastType;
Array expect(for_each->type_);
auto arrType = evalExpr<Array>(for_each->expr_);
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;
scope->currentBinding = binding;
......@@ -301,9 +306,18 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
}
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_);
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;
throw UndefinedError(e_cls_mmbr->pident_);
}
......@@ -314,7 +328,8 @@ void TypeCheck::visitEApp(EApp *e_app)
{
shared_ptr<Fun> type = evalExpr<Fun>(e_app->expr_);
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++) {
try {
......@@ -325,7 +340,10 @@ void TypeCheck::visitEApp(EApp *e_app)
throw InvalidTypeError(*expect, {exprType}, expr);
}
} 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)
{
// e_new_class->pident_->accept(this);
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());
// if (!klass) {
// throw ParseError("Class expected", e_new_class->pident_);
......@@ -554,7 +575,7 @@ void TypeCheck::check(Visitable *v)
checkFunction(f);
}
} catch (const ParseError &e) {
throw ParseError(e.what(), *c);
throw ParseError(e, *c);
}
......@@ -604,7 +625,7 @@ void TypeCheck::checkFunction(FunctionInfoPtr f)
scope->currentFunction = nullptr;
} catch (const ParseError &e) {
throw ParseError(e.what(), *f);
throw ParseError(e, *f);
}
}
......
#!/bin/bash
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
t=$((t+1))
(./latc "$i" &>/dev/null);
if ! [ $? -eq 0 ]; then
echo $i;
red "FAIL $i";
./latc "$i"
exit 1;
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))
(./latc "$i" &>/dev/null);
if [ $? -eq 0 ]; then
echo $i;
red "FAIL $i";
./latc "$i"
exit 1;
fi
done && echo OK: $t tests passed!
\ No newline at end of file
done && green "OK: $t tests passed!" && for ext in `ls lat/lattests/extensions`; do
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