|
|
- #pragma once
-
- #include "lexer.h"
- #include <functional>
- #include <memory>
- #include <stack>
- #include <string>
- #include <variant>
- #include <vector>
- namespace molasses {
-
- struct type {
- [[nodiscard]] virtual std::string name() const = 0;
- [[nodiscard]] virtual size_t byte_size() const = 0;
- };
-
- inline auto operator<=>(const type& lhs, const type& rhs) {
- return lhs.name() <=> rhs.name();
- }
-
- struct primitive_type : public type {
- std::string _name;
- size_t _byte_size;
-
- primitive_type(std::string name, size_t byte_size)
- : _name(std::forward<std::string>(name))
- , _byte_size(byte_size)
- {}
-
- [[nodiscard]] std::string name() const final {
- return _name;
- }
- [[nodiscard]] size_t byte_size() const final {
- return _byte_size;
- };
- };
-
- struct parser_context;
-
- struct ptr_type{
- void* ptr;
- std::shared_ptr<type> pointed;
- };
-
- using stack_element = std::variant<int32_t, int64_t, ptr_type>;
-
- using interpreter_stack = std::stack<stack_element>;
-
- struct generate_context;
-
- struct operation {
- [[nodiscard]] virtual std::string name() const = 0;
- [[nodiscard]] virtual std::vector<std::string> argument_types() const = 0;
- [[nodiscard]] virtual std::vector<std::string> return_types() const = 0;
- [[nodiscard]] virtual std::vector<std::string> generate(const parser_context&, const lexed_output& lexer_data) const = 0;
- [[nodiscard]] virtual std::vector<std::string> emit(const parser_context&) const = 0;
- virtual void execute(const generate_context&, interpreter_stack&) const = 0;
- };
-
- struct primitive_operation : public operation {
- std::string _name;
- std::vector<std::string> _args;
- std::vector<std::string> _rets;
- std::vector<std::string> _instructions;
- std::function<void(const generate_context&, interpreter_stack&)> _executable;
-
- primitive_operation(std::string name, std::vector<std::string> args, std::vector<std::string> rets, std::vector<std::string> body, std::function<void(const generate_context&,interpreter_stack&)> executable)
- : _name(std::forward<std::string>(name))
- , _args(std::forward<std::vector<std::string>>(args))
- , _rets(std::forward<std::vector<std::string>>(rets))
- , _instructions(std::forward<std::vector<std::string>>(body))
- , _executable(std::move(executable))
- {}
-
- [[nodiscard]] std::string name() const final {
- return _name;
- }
- [[nodiscard]] std::vector<std::string> argument_types() const final {
- return _args;
- }
- [[nodiscard]] std::vector<std::string> return_types() const final {
- return _rets;
- }
- [[nodiscard]] std::vector<std::string> generate(const parser_context&, const lexed_output& lexer_data) const final {
- return {};
- }
- [[nodiscard]] std::vector<std::string> emit(const parser_context&) const final {
- return _instructions;
- }
-
- void execute(const generate_context& ctx, interpreter_stack& stack) const override {
- _executable(ctx, stack);
- };
- };
-
- struct procedure_operation : public operation {
- std::string _name;
- std::vector<std::string> _args;
- std::vector<std::string> _rets;
- std::vector<symbol> _body;
- std::vector<std::pair<size_t, size_t>> _simple_sub_bodies;
-
- procedure_operation(std::string name, std::vector<std::string> args, std::vector<std::string> rets, std::vector<symbol> body, std::vector<std::pair<size_t, size_t>> sub_bodies)
- : _name(std::forward<std::string>(name))
- , _args(std::forward<std::vector<std::string>>(args))
- , _rets(std::forward<std::vector<std::string>>(rets))
- , _body(std::forward<std::vector<symbol>>(body))
- , _simple_sub_bodies(std::forward<std::vector<std::pair<size_t, size_t>>>(sub_bodies))
- {}
-
- [[nodiscard]] std::string name() const final {
- return _name;
- }
- [[nodiscard]] std::vector<std::string> argument_types() const final {
- return _args;
- }
- [[nodiscard]] std::vector<std::string> return_types() const final {
- return _rets;
- }
- [[nodiscard]] std::vector<std::string> generate(const parser_context&, const lexed_output& lexer_data) const final;
- [[nodiscard]] std::vector<std::string> emit(const parser_context&) const final;
- void execute(const generate_context&, interpreter_stack&) const final;
- };
-
- inline auto operator<=>(const operation& lhs, const operation& rhs) {
- return lhs.name() <=> rhs.name();
- }
- }
|