mirror of
https://github.com/open-goal/jak-project
synced 2026-09-03 18:23:39 -04:00
[goalc] add a build system (#704)
* add first attempt at build system * fix stupid bug * try again
This commit is contained in:
@@ -72,7 +72,8 @@ Interpreter::Interpreter() {
|
||||
{"string-ref", &Interpreter::eval_string_ref},
|
||||
{"string-length", &Interpreter::eval_string_length},
|
||||
{"string-append", &Interpreter::eval_string_append},
|
||||
{"ash", &Interpreter::eval_ash}};
|
||||
{"ash", &Interpreter::eval_ash},
|
||||
{"symbol->string", &Interpreter::eval_symbol_to_string}};
|
||||
|
||||
string_to_type = {{"empty-list", ObjectType::EMPTY_LIST},
|
||||
{"integer", ObjectType::INTEGER},
|
||||
@@ -90,6 +91,17 @@ Interpreter::Interpreter() {
|
||||
load_goos_library();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a user defined special form. The given function will be called with unevaluated arguments.
|
||||
* Lookup from these forms occurs after special/builtin, but before any env lookups.
|
||||
*/
|
||||
void Interpreter::register_form(
|
||||
const std::string& name,
|
||||
const std::function<
|
||||
Object(const Object&, Arguments&, const std::shared_ptr<EnvironmentObject>&)>& form) {
|
||||
m_custom_forms[name] = form;
|
||||
}
|
||||
|
||||
Interpreter::~Interpreter() {
|
||||
// There are some circular references that prevent shared_ptrs from cleaning up if we
|
||||
// don't do this.
|
||||
@@ -191,6 +203,19 @@ bool Interpreter::get_global_variable_by_name(const std::string& name, Object* d
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the variable to the value. Overwrites an existing value, or creates a new global.
|
||||
*/
|
||||
void Interpreter::set_global_variable_by_name(const std::string& name, const Object& value) {
|
||||
auto sym = SymbolObject::make_new(reader.symbolTable, name).as_symbol();
|
||||
global_environment.as_env()->vars[sym] = value;
|
||||
}
|
||||
|
||||
void Interpreter::set_global_variable_to_symbol(const std::string& name, const std::string& value) {
|
||||
auto sym = SymbolObject::make_new(reader.symbolTable, value);
|
||||
set_global_variable_by_name(name, sym);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get arguments being passed to a form. Don't evaluate them. There are two modes, "varargs" and
|
||||
* "not varargs". With varargs enabled, any number of unnamed and named arguments can be given.
|
||||
@@ -525,6 +550,13 @@ Object Interpreter::eval_pair(const Object& obj, const std::shared_ptr<Environme
|
||||
return ((*this).*(kv_b->second))(obj, args, env);
|
||||
}
|
||||
|
||||
// try custom forms next
|
||||
auto kv_u = m_custom_forms.find(head_sym->name);
|
||||
if (kv_u != m_custom_forms.end()) {
|
||||
Arguments args = get_args(obj, rest, make_varargs());
|
||||
return (kv_u->second)(obj, args, env);
|
||||
}
|
||||
|
||||
// try macros next
|
||||
Object macro_obj;
|
||||
if (try_symbol_lookup(head, env, ¯o_obj) && macro_obj.is_macro()) {
|
||||
@@ -1586,10 +1618,17 @@ Object Interpreter::eval_ash(const Object& form,
|
||||
if (sa >= 0 && sa < 64) {
|
||||
return Object::make_integer(val << sa);
|
||||
} else if (sa > -64) {
|
||||
return Object::make_integer(val >> sa);
|
||||
return Object::make_integer(val >> -sa);
|
||||
} else {
|
||||
throw_eval_error(form, fmt::format("Shift amount {} is out of range", sa));
|
||||
return EmptyListObject::make_new();
|
||||
}
|
||||
}
|
||||
|
||||
Object Interpreter::eval_symbol_to_string(const Object& form,
|
||||
Arguments& args,
|
||||
const std::shared_ptr<EnvironmentObject>&) {
|
||||
vararg_check(form, args, {ObjectType::SYMBOL}, {});
|
||||
return StringObject::make_new(args.unnamed.at(0).as_symbol()->name);
|
||||
}
|
||||
} // namespace goos
|
||||
|
||||
Reference in New Issue
Block a user