2024-04-21 07:33:14 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <optional>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <variant>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
#include "utils.hpp"
|
|
|
|
|
#include "types.hpp"
|
2024-04-21 07:33:14 +03:00
|
|
|
|
|
|
|
|
namespace nodes {
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct NodeInfo {
|
|
|
|
|
optional<types::TypeID> type = std::nullopt;
|
|
|
|
|
optional<types::Mode> mode = std::nullopt;
|
2024-04-21 07:33:14 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct Expr;
|
|
|
|
|
using ExprPtr = shared_ptr<Expr>;
|
|
|
|
|
using ExprPtrV = std::vector<ExprPtr>;
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct Arg : public NodeInfo {
|
|
|
|
|
Arg(string name) : name(std::move(name)) {}
|
|
|
|
|
|
2024-04-21 07:33:14 +03:00
|
|
|
string name;
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct Const : public NodeInfo {
|
|
|
|
|
Const(int value) : value(value) {}
|
|
|
|
|
|
2024-04-21 07:33:14 +03:00
|
|
|
int value;
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct Var : public NodeInfo {
|
|
|
|
|
Var(string name) : name(std::move(name)) {}
|
|
|
|
|
|
2024-04-21 07:33:14 +03:00
|
|
|
string name;
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct Let : public NodeInfo {
|
|
|
|
|
Let(Arg name, ExprPtr body, ExprPtr where)
|
|
|
|
|
: name(std::move(name)), body(body), where(where) {}
|
|
|
|
|
|
2024-04-21 07:33:14 +03:00
|
|
|
Arg name;
|
|
|
|
|
ExprPtr body;
|
|
|
|
|
ExprPtr where;
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct Lambda : public NodeInfo {
|
|
|
|
|
Lambda(vector<Arg> args, ExprPtr expr) : args(std::move(args)), expr(expr) {}
|
2024-04-21 07:33:14 +03:00
|
|
|
|
|
|
|
|
vector<Arg> args;
|
|
|
|
|
ExprPtr expr;
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct Call : public NodeInfo {
|
|
|
|
|
Call(ExprPtr func, vector<ExprPtr> args)
|
|
|
|
|
: func(func), args(std::move(args)) {}
|
|
|
|
|
|
2024-04-21 07:33:14 +03:00
|
|
|
ExprPtr func;
|
|
|
|
|
vector<ExprPtr> args;
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
struct Condition : public NodeInfo {
|
|
|
|
|
Condition(ExprPtr condition, ExprPtr then_case, ExprPtr else_case)
|
|
|
|
|
: condition(condition), then_case(then_case), else_case(else_case) {}
|
|
|
|
|
|
2024-04-21 07:33:14 +03:00
|
|
|
ExprPtr condition;
|
|
|
|
|
ExprPtr then_case;
|
|
|
|
|
ExprPtr else_case;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// struct FunctionDecl {
|
|
|
|
|
// string name;
|
|
|
|
|
// vector<Arg> args;
|
|
|
|
|
// ExprPtr expr;
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
struct Expr {
|
|
|
|
|
variant<Const, Var, Let, Lambda, Call, Condition> value;
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
template <typename T, typename... Args> ExprPtr make_expr(Args &&...args) {
|
|
|
|
|
return std::make_shared<Expr>(T(std::forward<Args>(args)...));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T> inline T with_type(T node, types::Type type) {
|
|
|
|
|
node.type = std::move(type);
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T> inline T with_mode(T node, types::Mode mode) {
|
|
|
|
|
node.mode = std::move(mode);
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T> inline T with_unique(T node) {
|
|
|
|
|
return with_mode(node, types::Mode(types::Mode::Uniq::UNIQUE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline ExprPtr make_var(std::string name, types::Mode mode = types::Mode()) {
|
|
|
|
|
return make_expr<Var>(with_mode(Var(std::move(name)), mode));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline ExprPtr lambda1(string var, ExprPtr expr) {
|
|
|
|
|
return make_expr<Lambda>(vector<Arg>{Arg(var)}, std::move(expr));
|
2024-04-21 07:33:14 +03:00
|
|
|
}
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
inline ExprPtr lambda1(Arg var, ExprPtr expr) {
|
|
|
|
|
return make_expr<Lambda>(vector<Arg>{var}, std::move(expr));
|
2024-04-21 07:33:14 +03:00
|
|
|
}
|
|
|
|
|
|
2024-04-21 14:09:38 +03:00
|
|
|
inline ExprPtr operator_call(string name, ExprPtr left, ExprPtr right,
|
|
|
|
|
types::Mode mode = types::Mode()) {
|
|
|
|
|
return make_expr<Call>(make_var(name, mode), ExprPtrV{left, right});
|
2024-04-21 07:33:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: all constructors
|
|
|
|
|
|
|
|
|
|
} // namespace nodes
|