#pragma once #include "lexer.h" #include #include #include #include #include #include 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(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 pointed; }; using stack_element = std::variant; using interpreter_stack = std::stack; struct generate_context; struct operation { [[nodiscard]] virtual std::string name() const = 0; [[nodiscard]] virtual std::vector argument_types() const = 0; [[nodiscard]] virtual std::vector return_types() const = 0; [[nodiscard]] virtual std::vector generate(const parser_context&, const lexed_output& lexer_data) const = 0; [[nodiscard]] virtual std::vector 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 _args; std::vector _rets; std::vector _instructions; std::function _executable; primitive_operation(std::string name, std::vector args, std::vector rets, std::vector body, std::function executable) : _name(std::forward(name)) , _args(std::forward>(args)) , _rets(std::forward>(rets)) , _instructions(std::forward>(body)) , _executable(std::move(executable)) {} [[nodiscard]] std::string name() const final { return _name; } [[nodiscard]] std::vector argument_types() const final { return _args; } [[nodiscard]] std::vector return_types() const final { return _rets; } [[nodiscard]] std::vector generate(const parser_context&, const lexed_output& lexer_data) const final { return {}; } [[nodiscard]] std::vector 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 _args; std::vector _rets; std::vector _body; std::vector> _simple_sub_bodies; procedure_operation(std::string name, std::vector args, std::vector rets, std::vector body, std::vector> sub_bodies) : _name(std::forward(name)) , _args(std::forward>(args)) , _rets(std::forward>(rets)) , _body(std::forward>(body)) , _simple_sub_bodies(std::forward>>(sub_bodies)) {} [[nodiscard]] std::string name() const final { return _name; } [[nodiscard]] std::vector argument_types() const final { return _args; } [[nodiscard]] std::vector return_types() const final { return _rets; } [[nodiscard]] std::vector generate(const parser_context&, const lexed_output& lexer_data) const final; [[nodiscard]] std::vector 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(); } }