Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

128 rindas
4.7 KiB

#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();
}
}