jak-project/common/goos/Interpreter.h

331 lines
14 KiB
C
Raw Normal View History

#pragma once
2020-08-22 22:30:12 -04:00
/*!
* @file Interpreter.h
* The GOOS Interpreter and implementation of special and "built-in forms"
2020-08-22 22:30:12 -04:00
*/
#include <memory>
2020-11-20 20:17:37 -05:00
#include <optional>
2020-08-22 22:30:12 -04:00
#include "Object.h"
#include "Reader.h"
namespace goos {
class Interpreter {
public:
Interpreter(const std::string& user_profile = "#f");
2020-08-29 19:13:29 -04:00
~Interpreter();
void execute_repl(REPL::Wrapper& repl);
2020-08-22 22:30:12 -04:00
void throw_eval_error(const Object& o, const std::string& err);
Object eval_with_rewind(const Object& obj, const std::shared_ptr<EnvironmentObject>& env);
bool get_global_variable_by_name(const std::string& name, Object* dest);
void set_global_variable_by_name(const std::string& name, const Object& value);
void set_global_variable_to_symbol(const std::string& name, const std::string& value);
void set_global_variable_to_int(const std::string& name, int value);
2020-08-22 22:30:12 -04:00
Object eval(Object obj, const std::shared_ptr<EnvironmentObject>& env);
Object intern(const std::string& name);
InternedSymbolPtr intern_ptr(const std::string& name);
2020-08-22 22:30:12 -04:00
void disable_printfs();
2020-09-06 17:42:20 -04:00
Object eval_symbol(const Object& sym, const std::shared_ptr<EnvironmentObject>& env);
bool eval_symbol(const Object& sym,
const std::shared_ptr<EnvironmentObject>& env,
Object* result);
2020-09-06 17:42:20 -04:00
Arguments get_args(const Object& form, const Object& rest, const ArgumentSpec& spec);
Arguments get_args_no_named(const Object& form, const Object& rest, const ArgumentSpec& spec);
2020-09-06 17:42:20 -04:00
void set_args_in_env(const Object& form,
const Arguments& args,
const ArgumentSpec& arg_spec,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_list_return_last(const Object& form,
Object rest,
const std::shared_ptr<EnvironmentObject>& env);
2020-09-07 13:28:16 -04:00
bool truthy(const Object& o);
2020-08-22 22:30:12 -04:00
void register_form(
const std::string& name,
const std::function<
Object(const Object&, Arguments&, const std::shared_ptr<EnvironmentObject>&)>& form);
void eval_args(Arguments* args, const std::shared_ptr<EnvironmentObject>& env);
2020-08-22 22:30:12 -04:00
Reader reader;
Object global_environment;
Object goal_env;
private:
friend class Goal;
void load_goos_library();
void define_var_in_env(Object& env, const Object& var, const std::string& name);
2020-08-22 22:30:12 -04:00
void expect_env(const Object& form, const Object& o);
void vararg_check(
const Object& form,
const Arguments& args,
2020-11-20 20:17:37 -05:00
const std::vector<std::optional<ObjectType>>& unnamed,
const std::unordered_map<std::string, std::pair<bool, std::optional<ObjectType>>>& named);
2020-08-22 22:30:12 -04:00
Object eval_pair(const Object& o, const std::shared_ptr<EnvironmentObject>& env);
docs: Automatically generate documentation from goal_src code (#2214) This automatically generates documentation from goal_src docstrings, think doxygen/java-docs/rust docs/etc. It mostly supports everything already, but here are the following things that aren't yet complete: - file descriptions - high-level documentation to go along with this (think pure markdown docs describing overall systems that would be co-located in goal_src for organizational purposes) - enums - states - std-lib functions (all have empty strings right now for docs anyway) The job of the new `gen-docs` function is solely to generate a bunch of JSON data which should give you everything you need to generate some decent documentation (outputting markdown/html/pdf/etc). It is not it's responsibility to do that nice formatting -- this is by design to intentionally delegate that responsibility elsewhere. Side-note, this is about 12-15MB of minified json for jak 2 so far :) In our normal "goal_src has changed" action -- we will generate this data, and the website can download it -- use the information to generate the documentation at build time -- and it will be included in the site. Likewise, if we wanted to include docs along with releases for offline viewing, we could do so in a similar fashion (just write a formatting script to generate said documentation). Lastly this work somewhat paves the way for doing more interesting things in the LSP like: - whats the docstring for this symbol? - autocompleting function arguments - type checking function arguments - where is this symbol defined? - etc Fixes #2215
2023-02-20 19:49:37 -05:00
public:
2020-08-22 22:30:12 -04:00
ArgumentSpec parse_arg_spec(const Object& form, Object& rest);
docs: Automatically generate documentation from goal_src code (#2214) This automatically generates documentation from goal_src docstrings, think doxygen/java-docs/rust docs/etc. It mostly supports everything already, but here are the following things that aren't yet complete: - file descriptions - high-level documentation to go along with this (think pure markdown docs describing overall systems that would be co-located in goal_src for organizational purposes) - enums - states - std-lib functions (all have empty strings right now for docs anyway) The job of the new `gen-docs` function is solely to generate a bunch of JSON data which should give you everything you need to generate some decent documentation (outputting markdown/html/pdf/etc). It is not it's responsibility to do that nice formatting -- this is by design to intentionally delegate that responsibility elsewhere. Side-note, this is about 12-15MB of minified json for jak 2 so far :) In our normal "goal_src has changed" action -- we will generate this data, and the website can download it -- use the information to generate the documentation at build time -- and it will be included in the site. Likewise, if we wanted to include docs along with releases for offline viewing, we could do so in a similar fashion (just write a formatting script to generate said documentation). Lastly this work somewhat paves the way for doing more interesting things in the LSP like: - whats the docstring for this symbol? - autocompleting function arguments - type checking function arguments - where is this symbol defined? - etc Fixes #2215
2023-02-20 19:49:37 -05:00
private:
2020-08-22 22:30:12 -04:00
Object quasiquote_helper(const Object& form, const std::shared_ptr<EnvironmentObject>& env);
IntType number_to_integer(const Object& obj);
FloatType number_to_float(const Object& obj);
template <typename T>
T number(const Object& obj);
template <typename T>
Object num_lt(const Object& form, Arguments& args, const std::shared_ptr<EnvironmentObject>& env);
template <typename T>
Object num_gt(const Object& form, Arguments& args, const std::shared_ptr<EnvironmentObject>& env);
template <typename T>
Object num_leq(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
template <typename T>
Object num_geq(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
template <typename T>
Object num_plus(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
template <typename T>
Object num_minus(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
template <typename T>
Object num_divide(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
template <typename T>
Object num_times(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_eval(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_equals(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_exit(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_begin(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_read(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_read_data_file(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
2020-08-22 22:30:12 -04:00
Object eval_read_file(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_load_file(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_try_load_file(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
2020-08-22 22:30:12 -04:00
Object eval_print(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_inspect(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_plus(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_minus(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_times(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_divide(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_numequals(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_lt(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_gt(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_leq(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_geq(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_car(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_cdr(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_set_car(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_set_cdr(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_gensym(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_cons(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_null(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_type(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_format(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_error(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_ref(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_length(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_append(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_starts_with(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_ends_with(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_split(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_substr(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_ash(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_symbol_to_string(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_string_to_symbol(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_int_to_string(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_get_env(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
2020-08-22 22:30:12 -04:00
// specials
Object eval_define(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_quote(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_set(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_lambda(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_cond(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_or(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_and(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_quasiquote(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_macro(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_while(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_let(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_let_star(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_let_common(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env,
bool star);
2020-08-22 22:30:12 -04:00
Object eval_make_string_hash_table(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_hash_table_try_ref(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
Object eval_hash_table_set(const Object& form,
Arguments& args,
const std::shared_ptr<EnvironmentObject>& env);
const Object& true_or_false(bool val);
void init_special_forms(
const std::unordered_map<std::string,
Object (Interpreter::*)(const Object&,
const Object&,
const std::shared_ptr<EnvironmentObject>&)>&
forms);
void init_builtin_forms(
const std::unordered_map<std::string,
Object (Interpreter::*)(const Object&,
Arguments&,
const std::shared_ptr<EnvironmentObject>&)>&
forms);
2020-08-22 22:30:12 -04:00
bool want_exit = false;
bool disable_printing = false;
std::unordered_map<
void*,
Object (Interpreter::*)(const Object&, Arguments&, const std::shared_ptr<EnvironmentObject>&)>
2020-08-22 22:30:12 -04:00
builtin_forms;
std::vector<std::pair<
void*,
std::function<Object(const Object&, Arguments&, const std::shared_ptr<EnvironmentObject>&)>>>
m_custom_forms;
std::vector<std::pair<void*,
Object (Interpreter::*)(const Object& form,
const Object& rest,
const std::shared_ptr<EnvironmentObject>& env)>>
2020-08-22 22:30:12 -04:00
special_forms;
int64_t gensym_id = 0;
std::unordered_map<std::string, ObjectType> string_to_type;
const char* m_false_sym = nullptr;
const char* m_true_sym = nullptr;
Object m_false_object, m_true_object;
2020-08-22 22:30:12 -04:00
};
} // namespace goos