update stuff
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
add_library(caioc_compiler STATIC
|
||||
parser.cxx
|
||||
)
|
||||
|
||||
target_sources(caioc_compiler
|
||||
PUBLIC
|
||||
FILE_SET caioc_compiler_modules TYPE CXX_MODULES FILES
|
||||
declaration.ixx
|
||||
expression.ixx
|
||||
parser.ixx
|
||||
program.ixx
|
||||
statement.ixx
|
||||
token.ixx
|
||||
|
||||
)
|
||||
target_compile_options(caioc_compiler PUBLIC -freflection -fcontracts -fcontract-evaluation-semantic=enforce)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
export module caioc.declaration;
|
||||
|
||||
import std;
|
||||
|
||||
import caioc.statement;
|
||||
import caioc.expression;
|
||||
|
||||
namespace caioc {
|
||||
|
||||
export struct declaration {
|
||||
virtual ~declaration() = default;
|
||||
};
|
||||
|
||||
export struct function_declaration : declaration {
|
||||
struct argument {
|
||||
std::string name;
|
||||
std::string type_name;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<argument> arguments;
|
||||
std::string return_type;
|
||||
std::unique_ptr<block_statement> body;
|
||||
};
|
||||
|
||||
} // namespace caioc
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::function_declaration> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::function_declaration& d, std::format_context& ctx) const {
|
||||
auto out = std::format_to(ctx.out(), "Function({}, args: [", d.name);
|
||||
bool first = true;
|
||||
for (const auto& arg : d.arguments) {
|
||||
if (!first) {
|
||||
out = std::format_to(out, ", ");
|
||||
}
|
||||
first = false;
|
||||
out = std::format_to(out, "{}", arg);
|
||||
}
|
||||
out = std::format_to(out, "], return_type: {}", d.return_type);
|
||||
out = d.body ? std::format_to(out, ", body: {}", *d.body) : std::format_to(out, ", body: <null>");
|
||||
return std::format_to(out, ")");
|
||||
}
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::declaration> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::declaration& d, std::format_context& ctx) const {
|
||||
if (auto* p = dynamic_cast<const caioc::function_declaration*>(&d)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
return std::format_to(ctx.out(), "<unknown declaration>");
|
||||
}
|
||||
};
|
||||
|
||||
+83
-2
@@ -5,7 +5,7 @@ import std;
|
||||
namespace caioc {
|
||||
|
||||
export struct expression {
|
||||
virtual expression() = default;
|
||||
virtual ~expression() = default;
|
||||
};
|
||||
|
||||
export struct int_literal_expression : expression {
|
||||
@@ -20,7 +20,7 @@ export struct string_literal_expression : expression {
|
||||
|
||||
export struct identifier_expression : expression {
|
||||
std::string name;
|
||||
}
|
||||
};
|
||||
|
||||
export struct call_expression : expression {
|
||||
std::unique_ptr<expression> callee;
|
||||
@@ -28,3 +28,84 @@ export struct call_expression : expression {
|
||||
};
|
||||
|
||||
} // namespace caioc
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::int_literal_expression> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::int_literal_expression& e, std::format_context& ctx) const {
|
||||
return std::format_to(ctx.out(), "IntLiteral({})", e.value);
|
||||
}
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::bool_literal_expression> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::bool_literal_expression& e, std::format_context& ctx) const {
|
||||
return std::format_to(ctx.out(), "BoolLiteral({})", e.value);
|
||||
}
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::string_literal_expression> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::string_literal_expression& e, std::format_context& ctx) const {
|
||||
return std::format_to(ctx.out(), "StringLiteral(\"{}\")", e.value);
|
||||
}
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::identifier_expression> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::identifier_expression& e, std::format_context& ctx) const {
|
||||
return std::format_to(ctx.out(), "Identifier({})", e.name);
|
||||
}
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::expression> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
std::format_context::iterator format(const caioc::expression& e, std::format_context& ctx) const;
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::call_expression> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
std::format_context::iterator format(const caioc::call_expression& e, std::format_context& ctx) const;
|
||||
};
|
||||
|
||||
inline std::format_context::iterator std::formatter<caioc::expression>::format(const caioc::expression& e,
|
||||
std::format_context& ctx) const {
|
||||
if (auto* p = dynamic_cast<const caioc::int_literal_expression*>(&e)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::bool_literal_expression*>(&e)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::string_literal_expression*>(&e)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::identifier_expression*>(&e)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::call_expression*>(&e)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
return std::format_to(ctx.out(), "<unknown expression>");
|
||||
}
|
||||
|
||||
inline std::format_context::iterator std::formatter<caioc::call_expression>::format(const caioc::call_expression& e,
|
||||
std::format_context& ctx) const {
|
||||
auto out = std::format_to(ctx.out(), "Call(");
|
||||
out = e.callee ? std::format_to(out, "{}", *e.callee) : std::format_to(out, "<null>");
|
||||
for (const auto& arg : e.args) {
|
||||
out = std::format_to(out, ", ");
|
||||
out = arg ? std::format_to(out, "{}", *arg) : std::format_to(out, "<null>");
|
||||
}
|
||||
return std::format_to(out, ")");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
module caioc.parser;
|
||||
|
||||
import std;
|
||||
|
||||
import caioc.program;
|
||||
import caioc.token;
|
||||
|
||||
namespace caioc {
|
||||
|
||||
class parser {};
|
||||
|
||||
program_module parse(std::span<const token> tokens) { return {}; }
|
||||
|
||||
} // namespace caioc
|
||||
@@ -0,0 +1,10 @@
|
||||
export module caioc.parser;
|
||||
|
||||
import std;
|
||||
|
||||
import caioc.program;
|
||||
import caioc.token;
|
||||
|
||||
namespace caioc {
|
||||
export [[nodiscard]] program_module parse(std::span<const token> tokens);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
export module caioc.program;
|
||||
|
||||
import std;
|
||||
|
||||
import caioc.declaration;
|
||||
|
||||
namespace caioc {
|
||||
|
||||
export struct program_module {
|
||||
std::vector<std::unique_ptr<declaration>> declarations;
|
||||
};
|
||||
|
||||
} // namespace caioc
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::program_module> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::program_module& s, std::format_context& ctx) const {}
|
||||
};
|
||||
@@ -0,0 +1,157 @@
|
||||
export module caioc.statement;
|
||||
|
||||
import std;
|
||||
|
||||
import caioc.expression;
|
||||
|
||||
namespace caioc {
|
||||
export struct statement {
|
||||
virtual ~statement() = default;
|
||||
};
|
||||
|
||||
export struct return_statement : statement {
|
||||
std::unique_ptr<expression> value;
|
||||
};
|
||||
|
||||
export struct expression_statement : statement {
|
||||
std::unique_ptr<expression> value;
|
||||
};
|
||||
|
||||
export struct block_statement : statement {
|
||||
std::vector<std::unique_ptr<statement>> statements;
|
||||
};
|
||||
|
||||
export struct if_statement : statement {
|
||||
std::unique_ptr<expression> condition;
|
||||
std::unique_ptr<statement> then_branch;
|
||||
std::unique_ptr<statement> else_branch;
|
||||
};
|
||||
|
||||
export struct while_statement : statement {
|
||||
std::unique_ptr<expression> condition;
|
||||
std::unique_ptr<statement> body;
|
||||
};
|
||||
|
||||
export struct let_statement : statement {
|
||||
std::string name;
|
||||
std::string type_name;
|
||||
std::unique_ptr<expression> init;
|
||||
};
|
||||
|
||||
} // namespace caioc
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::return_statement> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::return_statement& s, std::format_context& ctx) const {
|
||||
return s.value ? std::format_to(ctx.out(), "Return({})", *s.value) : std::format_to(ctx.out(), "Return()");
|
||||
}
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::expression_statement> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::expression_statement& s, std::format_context& ctx) const {
|
||||
return s.value ? std::format_to(ctx.out(), "ExprStmt({})", *s.value)
|
||||
: std::format_to(ctx.out(), "ExprStmt(<null>)");
|
||||
}
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::let_statement> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
auto format(const caioc::let_statement& s, std::format_context& ctx) const {
|
||||
auto out = std::format_to(ctx.out(), "Let({}: {}", s.name, s.type_name);
|
||||
out = s.init ? std::format_to(out, " = {}", *s.init) : out;
|
||||
return std::format_to(out, ")");
|
||||
}
|
||||
};
|
||||
|
||||
// --- mutually-referencing cluster: declared here, defined out-of-line below ---
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::statement> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
std::format_context::iterator format(const caioc::statement& s, std::format_context& ctx) const;
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::block_statement> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
std::format_context::iterator format(const caioc::block_statement& s, std::format_context& ctx) const;
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::if_statement> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
std::format_context::iterator format(const caioc::if_statement& s, std::format_context& ctx) const;
|
||||
};
|
||||
|
||||
export template <>
|
||||
struct std::formatter<caioc::while_statement> {
|
||||
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||
|
||||
std::format_context::iterator format(const caioc::while_statement& s, std::format_context& ctx) const;
|
||||
};
|
||||
|
||||
inline std::format_context::iterator std::formatter<caioc::statement>::format(const caioc::statement& s,
|
||||
std::format_context& ctx) const {
|
||||
if (auto* p = dynamic_cast<const caioc::return_statement*>(&s)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::expression_statement*>(&s)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::block_statement*>(&s)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::if_statement*>(&s)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::while_statement*>(&s)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
if (auto* p = dynamic_cast<const caioc::let_statement*>(&s)) {
|
||||
return std::format_to(ctx.out(), "{}", *p);
|
||||
}
|
||||
return std::format_to(ctx.out(), "<unknown statement>");
|
||||
}
|
||||
|
||||
inline std::format_context::iterator std::formatter<caioc::block_statement>::format(const caioc::block_statement& s,
|
||||
std::format_context& ctx) const {
|
||||
auto out = std::format_to(ctx.out(), "Block[");
|
||||
bool first = true;
|
||||
for (const auto& stmt : s.statements) {
|
||||
if (!first) {
|
||||
out = std::format_to(out, ", ");
|
||||
}
|
||||
first = false;
|
||||
out = stmt ? std::format_to(out, "{}", *stmt) : std::format_to(out, "<null>");
|
||||
}
|
||||
return std::format_to(out, "]");
|
||||
}
|
||||
|
||||
inline std::format_context::iterator std::formatter<caioc::if_statement>::format(const caioc::if_statement& s,
|
||||
std::format_context& ctx) const {
|
||||
auto out = std::format_to(ctx.out(),
|
||||
"If({}, then: ", s.condition ? std::format("{}", *s.condition) : std::string("<null>"));
|
||||
out = s.then_branch ? std::format_to(out, "{}", *s.then_branch) : std::format_to(out, "<null>");
|
||||
if (s.else_branch) {
|
||||
out = std::format_to(out, ", else: {}", *s.else_branch);
|
||||
}
|
||||
return std::format_to(out, ")");
|
||||
}
|
||||
|
||||
inline std::format_context::iterator std::formatter<caioc::while_statement>::format(const caioc::while_statement& s,
|
||||
std::format_context& ctx) const {
|
||||
auto out =
|
||||
std::format_to(ctx.out(), "While({}, ", s.condition ? std::format("{}", *s.condition) : std::string("<null>"));
|
||||
out = s.body ? std::format_to(out, "{}", *s.body) : std::format_to(out, "<null>");
|
||||
return std::format_to(out, ")");
|
||||
}
|
||||
|
||||
+4
-1
@@ -2,6 +2,7 @@ import std;
|
||||
|
||||
import caioc.utils;
|
||||
import caioc.frontend.tokenizer;
|
||||
import caioc.parser;
|
||||
|
||||
auto main(int argc, char** argv) -> int {
|
||||
if (argc < 2) {
|
||||
@@ -20,9 +21,11 @@ auto main(int argc, char** argv) -> int {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (const auto token : tokens) {
|
||||
for (const auto& token : tokens) {
|
||||
std::println("{}: {} @ {}:{}", caioc::enum_to_string(token.type), token.backing, token.line, token.column);
|
||||
}
|
||||
|
||||
const auto program = caioc::parse(tokens);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user