mirror of
https://github.com/ProgramSnail/lang_modes_check.git
synced 2025-12-06 00:58:42 +00:00
type checker arrow type fix and type check test
This commit is contained in:
parent
ec04e05b7b
commit
8ca733934f
3 changed files with 57 additions and 8 deletions
|
|
@ -231,7 +231,7 @@ struct Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
// private: // TODO: temporary, to beautify type checker output
|
||||||
size_t first_unused_generic_id = 0;
|
size_t first_unused_generic_id = 0;
|
||||||
|
|
||||||
vector<Type> types;
|
vector<Type> types;
|
||||||
|
|
|
||||||
50
src/main.cpp
50
src/main.cpp
|
|
@ -19,11 +19,19 @@ auto make_program_2(bool uniq) {
|
||||||
using namespace nodes;
|
using namespace nodes;
|
||||||
return make_expr<Let>(
|
return make_expr<Let>(
|
||||||
Arg("f"),
|
Arg("f"),
|
||||||
lambda2(Arg("x", uniq ? types::Mode(types::Mode::Uniq::UNIQUE) : types::Mode()), Arg("y"),
|
lambda2(Arg("x", uniq ? types::Mode(types::Mode::Uniq::UNIQUE)
|
||||||
|
: types::Mode()),
|
||||||
|
Arg("y"),
|
||||||
operator_call("+", make_expr<Var>("x"), make_expr<Var>("y"))),
|
operator_call("+", make_expr<Var>("x"), make_expr<Var>("y"))),
|
||||||
make_expr<Var>("f"));
|
make_expr<Var>("f"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto make_program_3() {
|
||||||
|
using namespace nodes;
|
||||||
|
return make_expr<Let>(Arg("f"), lambda1(Arg("x"), make_expr<Var>("x")),
|
||||||
|
make_expr<Var>("f"));
|
||||||
|
}
|
||||||
|
|
||||||
void add_builtin_functions_types(type_check::State &state, bool uniq) {
|
void add_builtin_functions_types(type_check::State &state, bool uniq) {
|
||||||
auto sum_type = state.type_storage.add(types::make_operator(
|
auto sum_type = state.type_storage.add(types::make_operator(
|
||||||
state.type_storage.get_int_type(
|
state.type_storage.get_int_type(
|
||||||
|
|
@ -83,13 +91,47 @@ void run_example(const auto& make_program, bool arg_uniq, bool sum_uniq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "\x1b[1;92mPROGRAM IS CORRECT\x1b[0m\n";
|
std::cout << "\x1b[1;92mPROGRAM IS CORRECT\x1b[0m\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_example_2() {
|
||||||
|
const auto program = make_program_3();
|
||||||
|
|
||||||
|
std::cout << "\n\x1b[1;34m--- TYPE CHECK ---\x1b[0m\n";
|
||||||
|
std::cout << "\x1b[1;34mPROGRAM:\x1b[0m \x1b[1;90m" << *program
|
||||||
|
<< "\x1b[0m\n\n";
|
||||||
|
|
||||||
|
try {
|
||||||
|
type_check::State state;
|
||||||
|
|
||||||
|
std::cout << "expression type is " << type_check::check_expr(program, state).get().type.index()
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
for (auto &type : state.type_storage.types) {
|
||||||
|
std::cout << type.type.index();
|
||||||
|
if (auto *arrow_type = get_if<types::ArrowType>(&type.type);
|
||||||
|
arrow_type != nullptr) {
|
||||||
|
std::cout << "[-";
|
||||||
|
for (const auto &arg : arrow_type->types) {
|
||||||
|
std::cout << arg.get().type.index() << "-";
|
||||||
|
}
|
||||||
|
std::cout << "]";
|
||||||
|
}
|
||||||
|
std::cout << ' ';
|
||||||
|
}
|
||||||
|
} catch (utils::Error error) {
|
||||||
|
print_error("\x1b[1;31mTYPE CHECK ERROR:\x1b[0m", error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "\n\n\x1b[1;34m--- END ---\x1b[0m\n";
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
for (size_t n = 0; n < 8; ++n) {
|
for (size_t n = 0; n < 8; ++n) {
|
||||||
std::cout << "\n\x1b[1;34m--- START TEST ---\x1b[0m\n";
|
std::cout << "\n\x1b[1;34m--- TEST ---\x1b[0m\n";
|
||||||
run_example(n / 4 == 0 ? &make_program_1 : &make_program_2, n % 2 == 1, (n / 2) % 2 ==1);
|
run_example(n / 4 == 0 ? &make_program_1 : &make_program_2, n % 2 == 1,
|
||||||
std::cout << "\n\x1b[1;34m--- END TEST ---\x1b[0m\n";
|
(n / 2) % 2 == 1);
|
||||||
|
std::cout << "\n\x1b[1;34m--- END ---\x1b[0m\n";
|
||||||
}
|
}
|
||||||
|
run_example_2();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,20 @@ types::TypeID check_let(nodes::Let &expr, State &state) {
|
||||||
types::TypeID check_lambda(nodes::Lambda &expr, State &state) {
|
types::TypeID check_lambda(nodes::Lambda &expr, State &state) {
|
||||||
Context context(state.manager);
|
Context context(state.manager);
|
||||||
|
|
||||||
|
ArrowType lambda_arrow_type;
|
||||||
|
|
||||||
|
lambda_arrow_type.types.reserve(expr.args.size() + 1);
|
||||||
for (auto &arg : expr.args) {
|
for (auto &arg : expr.args) {
|
||||||
types::TypeID new_type = state.type_storage.introduce_new_generic(arg.name, arg.mode_hint);
|
types::TypeID new_type = state.type_storage.introduce_new_generic(arg.name, arg.mode_hint);
|
||||||
arg.type = new_type;
|
arg.type = new_type;
|
||||||
|
lambda_arrow_type.types.push_back(new_type);
|
||||||
state.manager.add_var(arg.name, new_type);
|
state.manager.add_var(arg.name, new_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
types::TypeID lambda_type = check_expr(expr.expr, state);
|
types::TypeID ret_type = check_expr(expr.expr, state);
|
||||||
|
lambda_arrow_type.types.push_back(ret_type);
|
||||||
|
|
||||||
|
types::TypeID lambda_type = state.type_storage.add(lambda_arrow_type);
|
||||||
return (expr.type = lambda_type).value();
|
return (expr.type = lambda_type).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue