mirror of
https://github.com/open-goal/jak-project
synced 2026-07-08 22:45:00 -04:00
[compiler] fix compile_condition not attempting macro expansion (#3030)
Ancient bug! Resulted in a 1%-2% decrease in code object file size (and more importantly the asm is more readable). Fixes #3029
This commit is contained in:
@@ -40,21 +40,25 @@ Condition Compiler::compile_condition(const goos::Object& condition, Env* env, b
|
||||
{">", ConditionKind::GT}, {"<", ConditionKind::LT},
|
||||
{">=", ConditionKind::GEQ}, {"<=", ConditionKind::LEQ}};
|
||||
|
||||
// we may have gotten a macro as a condition, expand it first.
|
||||
// note : use the `condition` arg for errors still so that the user can actually tell what code
|
||||
// went wrong!
|
||||
auto new_c = expand_macro_completely(condition, env);
|
||||
|
||||
// possibly a form with an optimizable condition?
|
||||
if (condition.is_pair()) {
|
||||
auto first = pair_car(condition);
|
||||
auto rest = pair_cdr(condition);
|
||||
if (new_c.is_pair()) {
|
||||
auto& first = pair_car(new_c);
|
||||
auto& rest = pair_cdr(new_c);
|
||||
|
||||
if (first.is_symbol()) {
|
||||
auto fas = first.as_symbol();
|
||||
|
||||
// if there's a not, we can just try again to get an optimization with the invert flipped.
|
||||
if (fas->name == "not") {
|
||||
auto arg = pair_car(rest);
|
||||
if (!pair_cdr(rest).is_empty_list()) {
|
||||
throw_compiler_error(condition, "A condition with \"not\" can have only one argument");
|
||||
}
|
||||
return compile_condition(arg, env, !invert);
|
||||
return compile_condition(pair_car(rest), env, !invert);
|
||||
}
|
||||
|
||||
auto& conditions = invert ? conditions_inverted : conditions_normal;
|
||||
|
||||
@@ -17,7 +17,7 @@ bool Compiler::try_getting_macro_from_goos(const goos::Object& macro_name, goos:
|
||||
got_macro = true;
|
||||
}
|
||||
|
||||
if (got_macro) {
|
||||
if (got_macro && dest) {
|
||||
*dest = macro_obj;
|
||||
}
|
||||
return got_macro;
|
||||
@@ -266,15 +266,16 @@ Val* Compiler::compile_mlet(const goos::Object& form, const goos::Object& rest,
|
||||
}
|
||||
|
||||
Val* Compiler::compile_macro_expand(const goos::Object& form, const goos::Object& rest, Env* env) {
|
||||
auto macro = pair_car(rest);
|
||||
goos::Object macro_obj;
|
||||
if (!try_getting_macro_from_goos(pair_car(macro), ¯o_obj)) {
|
||||
throw_compiler_error(form, "{} is not a macro.", pair_car(macro).print());
|
||||
auto& macro = pair_car(rest);
|
||||
auto& macro_name = pair_car(macro);
|
||||
if (!try_getting_macro_from_goos(macro_name, nullptr)) {
|
||||
throw_compiler_error(form, "invalid argument to `macro-expand`: {} does not exist as a macro",
|
||||
macro_name.print());
|
||||
}
|
||||
// the pretty printer doesn't support macro objects, so we use the pair
|
||||
auto result = goos::Object(macro);
|
||||
while (expand_macro_once(result, &result, env)) {
|
||||
if (!pair_cdr(rest).is_empty_list()) {
|
||||
throw_compiler_error(form, "too many arguments to `macro-expand`");
|
||||
}
|
||||
auto result = expand_macro_completely(macro, env);
|
||||
auto code = pretty_print::to_string(result);
|
||||
lg::print("{}\n", code);
|
||||
return get_none();
|
||||
@@ -285,8 +286,8 @@ bool Compiler::expand_macro_once(const goos::Object& src, goos::Object* out, Env
|
||||
return false;
|
||||
}
|
||||
|
||||
auto first = src.as_pair()->car;
|
||||
auto rest = src.as_pair()->cdr;
|
||||
auto& first = src.as_pair()->car;
|
||||
auto& rest = src.as_pair()->cdr;
|
||||
if (!first.is_symbol()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user