mirror of
https://github.com/ProgramSnail/lang_modes_check.git
synced 2025-12-06 00:58:42 +00:00
better test formatting, etc.
This commit is contained in:
parent
06ccf59e45
commit
ec04e05b7b
3 changed files with 124 additions and 28 deletions
|
|
@ -1,13 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "utils.hpp"
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
namespace nodes {
|
namespace nodes {
|
||||||
|
|
||||||
|
|
@ -22,10 +23,10 @@ using ExprPtr = shared_ptr<Expr>;
|
||||||
using ExprPtrV = std::vector<ExprPtr>;
|
using ExprPtrV = std::vector<ExprPtr>;
|
||||||
|
|
||||||
struct Arg : public NodeInfo {
|
struct Arg : public NodeInfo {
|
||||||
Arg(string name, types::Mode mode_hint = {}) : name(std::move(name)), mode_hint(mode_hint) {}
|
Arg(string name, types::Mode mode_hint = {})
|
||||||
|
: name(std::move(name)), mode_hint(mode_hint) {}
|
||||||
|
|
||||||
string name;
|
string name;
|
||||||
|
|
||||||
types::Mode mode_hint;
|
types::Mode mode_hint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -110,6 +111,10 @@ inline ExprPtr lambda1(Arg var, ExprPtr expr) {
|
||||||
return make_expr<Lambda>(vector<Arg>{var}, std::move(expr));
|
return make_expr<Lambda>(vector<Arg>{var}, std::move(expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ExprPtr lambda2(Arg var1, Arg var2, ExprPtr expr) {
|
||||||
|
return make_expr<Lambda>(vector<Arg>{var1, var2}, std::move(expr));
|
||||||
|
}
|
||||||
|
|
||||||
inline ExprPtr operator_call(string name, ExprPtr left, ExprPtr right) {
|
inline ExprPtr operator_call(string name, ExprPtr left, ExprPtr right) {
|
||||||
return make_expr<Call>(make_expr<Var>(name), ExprPtrV{left, right});
|
return make_expr<Call>(make_expr<Var>(name), ExprPtrV{left, right});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
76
include/printers.hpp
Normal file
76
include/printers.hpp
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "parsing_tree.hpp"
|
||||||
|
|
||||||
|
using namespace nodes;
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &, const Expr &);
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Arg &expr) {
|
||||||
|
out << expr.name << (expr.mode_hint.uniq == types::Mode::Uniq::UNIQUE ? "<unique>" : ""); // TODO: all modes
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Const &expr) {
|
||||||
|
out << expr.value;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Var &expr) {
|
||||||
|
out << expr.name;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Let &expr) {
|
||||||
|
out << "let " << expr.name << " = " << *expr.body << " in " << *expr.where;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Lambda &expr) {
|
||||||
|
out << "\\";
|
||||||
|
for (const auto &arg : expr.args) {
|
||||||
|
out << arg << " ";
|
||||||
|
}
|
||||||
|
out << "-> " << *expr.expr;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Call &expr) {
|
||||||
|
out << *expr.func;
|
||||||
|
for (const auto &arg : expr.args) {
|
||||||
|
out << " " << *arg;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Condition &expr) {
|
||||||
|
out << "if " << *expr.condition << " then " << *expr.then_case << " else "
|
||||||
|
<< *expr.else_case;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const Expr &expr) {
|
||||||
|
switch (expr.value.index()) {
|
||||||
|
case 0: // Const
|
||||||
|
out << std::get<0>(expr.value);
|
||||||
|
break;
|
||||||
|
case 1: // Var
|
||||||
|
out << std::get<1>(expr.value);
|
||||||
|
break;
|
||||||
|
case 2: // Let
|
||||||
|
out << std::get<2>(expr.value);
|
||||||
|
break;
|
||||||
|
case 3: // Lambda
|
||||||
|
out << std::get<3>(expr.value);
|
||||||
|
break;
|
||||||
|
case 4: // Call
|
||||||
|
out << std::get<4>(expr.value);
|
||||||
|
break;
|
||||||
|
case 5: // Condition
|
||||||
|
out << std::get<5>(expr.value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
utils::unreachable();
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
65
src/main.cpp
65
src/main.cpp
|
|
@ -1,28 +1,41 @@
|
||||||
#include "mode_check.hpp"
|
#include "mode_check.hpp"
|
||||||
#include "parsing_tree.hpp"
|
#include "parsing_tree.hpp"
|
||||||
|
#include "printers.hpp"
|
||||||
#include "type_check.hpp"
|
#include "type_check.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
auto make_program(bool uniq) {
|
auto make_program_1(bool uniq) {
|
||||||
using namespace nodes;
|
using namespace nodes;
|
||||||
return make_expr<Let>(
|
return make_expr<Let>(
|
||||||
Arg("f"),
|
Arg("f"),
|
||||||
lambda1(Arg("x", uniq ? types::Mode(types::Mode::Uniq::UNIQUE) : types::Mode()),
|
lambda1(Arg("x", uniq ? types::Mode(types::Mode::Uniq::UNIQUE)
|
||||||
|
: types::Mode()),
|
||||||
operator_call("+", make_expr<Var>("x"), make_expr<Var>("x"))),
|
operator_call("+", make_expr<Var>("x"), make_expr<Var>("x"))),
|
||||||
make_expr<Var>("f"));
|
make_expr<Var>("f"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto make_program_2(bool uniq) {
|
||||||
|
using namespace nodes;
|
||||||
|
return make_expr<Let>(
|
||||||
|
Arg("f"),
|
||||||
|
lambda2(Arg("x", uniq ? types::Mode(types::Mode::Uniq::UNIQUE) : types::Mode()), Arg("y"),
|
||||||
|
operator_call("+", make_expr<Var>("x"), make_expr<Var>("y"))),
|
||||||
|
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(uniq ? types::Mode(types::Mode::Uniq::UNIQUE) : types::Mode()),
|
state.type_storage.get_int_type(
|
||||||
state.type_storage.get_int_type(uniq ? types::Mode(types::Mode::Uniq::UNIQUE) : types::Mode()),
|
uniq ? types::Mode(types::Mode::Uniq::UNIQUE) : types::Mode()),
|
||||||
|
state.type_storage.get_int_type(
|
||||||
|
uniq ? types::Mode(types::Mode::Uniq::UNIQUE) : types::Mode()),
|
||||||
state.type_storage.get_int_type()));
|
state.type_storage.get_int_type()));
|
||||||
state.manager.add_var("+", sum_type);
|
state.manager.add_var("+", sum_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_builtin_functions_modes(mode_check::State &state) {
|
void add_builtin_functions_modes(mode_check::State &state) {
|
||||||
state.add_var("+"); // mode ??
|
state.add_var("+");
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_error(const std::string &general_message,
|
void print_error(const std::string &general_message,
|
||||||
|
|
@ -30,12 +43,22 @@ void print_error(const std::string &general_message,
|
||||||
std::cerr << general_message << " "
|
std::cerr << general_message << " "
|
||||||
<< "file: " << error.location.file_name() << "("
|
<< "file: " << error.location.file_name() << "("
|
||||||
<< error.location.line() << ":" << error.location.column() << ") `"
|
<< error.location.line() << ":" << error.location.column() << ") `"
|
||||||
<< error.location.function_name() << "`: " << error.message << std::endl;
|
<< error.location.function_name() << "`: " << error.message
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_example(bool arg_uniq, bool sum_uniq) {
|
void run_example(const auto& make_program, bool arg_uniq, bool sum_uniq) {
|
||||||
const auto program = make_program(arg_uniq);
|
const auto program = make_program(arg_uniq);
|
||||||
|
|
||||||
|
std::cout << "\x1b[1;34mPROGRAM:\x1b[0m \x1b[1;90m" << *program
|
||||||
|
<< "\x1b[0m\n";
|
||||||
|
if (sum_uniq) {
|
||||||
|
std::cout << "+: int<unique> -> int<unique> -> int\n";
|
||||||
|
} else {
|
||||||
|
std::cout << "+: int -> int -> int\n";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
type_check::State state;
|
type_check::State state;
|
||||||
|
|
||||||
|
|
@ -44,8 +67,8 @@ int run_example(bool arg_uniq, bool sum_uniq) {
|
||||||
type_check::check_expr(program, state);
|
type_check::check_expr(program, state);
|
||||||
|
|
||||||
} catch (utils::Error error) {
|
} catch (utils::Error error) {
|
||||||
print_error("TYPE CHECK ERROR:", error);
|
print_error("\x1b[1;31mTYPE CHECK ERROR:\x1b[0m", error);
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -55,26 +78,18 @@ int run_example(bool arg_uniq, bool sum_uniq) {
|
||||||
|
|
||||||
mode_check::check_expr(program, state);
|
mode_check::check_expr(program, state);
|
||||||
} catch (utils::Error error) {
|
} catch (utils::Error error) {
|
||||||
print_error("MODE CHECK ERROR:", error);
|
print_error("\x1b[1;31mMODE CHECK ERROR:\x1b[0m", error);
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "CHECK DONE\n";
|
std::cout << "\x1b[1;92mPROGRAM IS CORRECT\x1b[0m\n";
|
||||||
|
return;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int n = 0;
|
for (size_t n = 0; n < 8; ++n) {
|
||||||
|
std::cout << "\n\x1b[1;34m--- START TEST ---\x1b[0m\n";
|
||||||
while(true) {
|
run_example(n / 4 == 0 ? &make_program_1 : &make_program_2, n % 2 == 1, (n / 2) % 2 ==1);
|
||||||
std::cout << "--- START TEST ---\n";
|
std::cout << "\n\x1b[1;34m--- END TEST ---\x1b[0m\n";
|
||||||
std::cout << "TEST ID (0 - 3): ";
|
|
||||||
std::cin >> n;
|
|
||||||
if (n < 0 or n >= 4) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
run_example(n % 2 == 1, n / 4 == 1);
|
|
||||||
std::cout << "--- END TEST ---\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue