Skip to content

Commit

Permalink
Update syntactic_environment::identify to receive only identifier
Browse files Browse the repository at this point in the history
Signed-off-by: yamacir-kit <[email protected]>
  • Loading branch information
yamacir-kit committed Dec 24, 2024
1 parent c7ea03c commit f697396
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 75 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ Then, select one of the following targets and `make` it according to your purpos

| Target | Description
|-------------|-------------
| `all` | Build shared-library `libmeevax.0.5.308.so` and executable `meevax`.
| `all` | Build shared-library `libmeevax.0.5.309.so` and executable `meevax`.
| `install` | Copy files into `/usr/local` directly.
| `package` | Generate debian package `meevax_0.5.308_amd64.deb` (only Ubuntu). The generated package can be installed by `sudo apt install build/meevax_0.5.308_amd64.deb`.
| `package` | Generate debian package `meevax_0.5.309_amd64.deb` (only Ubuntu). The generated package can be installed by `sudo apt install build/meevax_0.5.309_amd64.deb`.
| `test` | Test executable `meevax`. This target requires Valgrind to be installed.
| `uninstall` | Remove files copied to `/usr/local` directly by target `install`.

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.5.308
0.5.309
153 changes: 81 additions & 72 deletions include/meevax/kernel/syntactic_environment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ namespace meevax::inline kernel

static GENERATOR(set)
{
assert(car(form).is_also<identifier>());

if (let const& identity = generator.identify(car(form), bound_variables); identity.is<relative>())
{
return generator.generate(cadr(form),
Expand Down Expand Up @@ -685,6 +687,8 @@ namespace meevax::inline kernel

assert(not car(form).is<pair>()); // This has been checked on previous passes.

assert(car(form).is_also<identifier>());

return generator.generate(cdr(form) ? cadr(form) : unspecified,
bound_variables,
cons(make(instruction::store_absolute), generator.identify(car(form), bound_variables),
Expand All @@ -693,6 +697,8 @@ namespace meevax::inline kernel

static GENERATOR(define_syntax)
{
assert(car(form).is_also<identifier>());

let identity = generator.identify(car(form), unit);

cdr(identity) = make<transformer>(Environment().execute(generator.generate(cadr(form),
Expand Down Expand Up @@ -787,6 +793,7 @@ namespace meevax::inline kernel

inline auto define(object const& variable, object const& value = undefined) -> void
{
assert(variable.is_also<identifier>());
assert(identify(variable, unit).template is<absolute>());
cdr(identify(variable, unit)) = value;
}
Expand Down Expand Up @@ -818,6 +825,8 @@ namespace meevax::inline kernel
{
if (form.is<syntactic_closure>())
{
assert(form.is_also<identifier>());

if (let const& identity = identify(form, bound_variables); identity == f)
{
return form.as<syntactic_closure>().expand(bound_variables, rename);
Expand All @@ -826,38 +835,42 @@ namespace meevax::inline kernel

return form.is_also<identifier>() ? rename(form) : form;
}
else if (let const& identity = identify(car(form), bound_variables); identity.is<absolute>())
else if (car(form).is_also<identifier>())
{
if (cdr(identity).is<transformer>())
{
/*
Scheme programs can define and use new derived expression types,
called macros. Program-defined expression types have the syntax
(<keyword> <datum>...)
where <keyword> is an identifier that uniquely determines the
expression type. This identifier is called the syntactic keyword,
or simply keyword, of the macro. The number of the <datum>s, and
their syntax, depends on the expression type.
Each instance of a macro is called a use of the macro. The set of
rules that specifies how a use of a macro is transcribed into a
more primitive expression is called the transformer of the macro.
*/
assert(cadr(identity).is<closure>());
assert(cddr(identity).is<syntactic_environment>());

return expand(Environment().apply(cadr(identity),
form,
make<syntactic_environment>(bound_variables, second),
cddr(identity)),
bound_variables,
rename);
}
else if (cdr(identity).is<syntax>())
if (let const& identity = identify(car(form), bound_variables); identity.is<absolute>())
{
return cdr(identity).as<syntax>().expand(*this, form, bound_variables, rename);
if (cdr(identity).is<transformer>())
{
/*
Scheme programs can define and use new derived expression types,
called macros. Program-defined expression types have the syntax
(<keyword> <datum>...)
where <keyword> is an identifier that uniquely determines the
expression type. This identifier is called the syntactic
keyword, or simply keyword, of the macro. The number of the
<datum>s, and their syntax, depends on the expression type.
Each instance of a macro is called a use of the macro. The set
of rules that specifies how a use of a macro is transcribed into
a more primitive expression is called the transformer of the
macro.
*/
assert(cadr(identity).is<closure>());
assert(cddr(identity).is<syntactic_environment>());

return expand(Environment().apply(cadr(identity),
form,
make<syntactic_environment>(bound_variables, second),
cddr(identity)),
bound_variables,
rename);
}
else if (cdr(identity).is<syntax>())
{
return cdr(identity).as<syntax>().expand(*this, form, bound_variables, rename);
}
}
}

Expand All @@ -878,7 +891,7 @@ namespace meevax::inline kernel
{
if (form.is_also<identifier>())
{
assert(form.is<symbol>() or form.is<syntactic_closure>());
assert(form.is_also<identifier>());

if (let const& identity = identify(form, bound_variables); identity.is<relative>())
{
Expand All @@ -899,14 +912,15 @@ namespace meevax::inline kernel
return cons(make(instruction::load_constant), form, continuation);
}
}
else if (let const& identity = std::as_const(*this).identify(car(form), bound_variables); identity.is<absolute>() and cdr(identity).is<syntax>())
{
return cdr(identity).as<syntax>().generate(*this, cdr(form), bound_variables, continuation, tail);
}
else
else if (car(form).is_also<identifier>())
{
return generator::call(*this, form, bound_variables, continuation, tail);
if (let const& identity = std::as_const(*this).identify(car(form), bound_variables); identity.is<absolute>() and cdr(identity).is<syntax>())
{
return cdr(identity).as<syntax>().generate(*this, cdr(form), bound_variables, continuation, tail);
}
}

return generator::call(*this, form, bound_variables, continuation, tail);
}
catch (error & e)
{
Expand All @@ -917,51 +931,46 @@ namespace meevax::inline kernel
inline auto identify(object const& variable,
object const& bound_variables) const -> object
{
if (not variable.is_also<identifier>())
{
return f;
}
else
assert(variable.is_also<identifier>());

auto i = 0;

for (auto outer = bound_variables; outer.is<pair>(); ++i, outer = cdr(outer))
{
auto i = 0;
auto j = 0;

for (auto outer = bound_variables; outer.is<pair>(); ++i, outer = cdr(outer))
for (auto inner = outer.is<pair>() ? car(outer) : unit; not inner.is<null>(); ++j, inner = inner.is<pair>() ? cdr(inner) : unit)
{
auto j = 0;

for (auto inner = outer.is<pair>() ? car(outer) : unit; not inner.is<null>(); ++j, inner = inner.is<pair>() ? cdr(inner) : unit)
if (inner.is<pair>())
{
if (inner.is<pair>())
if (car(inner).is<absolute>() and eq(caar(inner), variable))
{
if (car(inner).is<absolute>() and eq(caar(inner), variable))
{
return car(inner);
}
else if (eq(car(inner), variable))
{
return make<relative>(make<std::int32_t>(i), make<std::int32_t>(j));
}
return car(inner);
}
else if (inner.is_also<identifier>() and eq(inner, variable))
else if (eq(car(inner), variable))
{
return make<variadic>(make<std::int32_t>(i), make<std::int32_t>(j));
return make<relative>(make<std::int32_t>(i), make<std::int32_t>(j));
}
}
else if (inner.is_also<identifier>() and eq(inner, variable))
{
return make<variadic>(make<std::int32_t>(i), make<std::int32_t>(j));
}
}
}

if (variable.is<syntactic_closure>()) // Resolve alias
{
return variable.as<syntactic_closure>()
.environment
.template as<syntactic_environment>()
.identify(variable.as<syntactic_closure>().form,
unify(car(variable.as<syntactic_closure>().environment),
bound_variables));
}
else
{
return assq(variable, second);
}
if (variable.is<syntactic_closure>()) // Resolve alias
{
return variable.as<syntactic_closure>()
.environment
.template as<syntactic_environment>()
.identify(variable.as<syntactic_closure>().form,
unify(car(variable.as<syntactic_closure>().environment),
bound_variables));
}
else
{
return assq(variable, second);
}
}

Expand Down Expand Up @@ -1003,7 +1012,7 @@ namespace meevax::inline kernel
object const& bound_variables,
object const& binding_specs = unit) const -> pair
{
if (form.is<pair>() and car(form).is<pair>())
if (form.is<pair>() and car(form).is<pair>() and caar(form).is_also<identifier>())
{
if (let const& identity = identify(caar(form), bound_variables); identity.is<absolute>())
{
Expand Down

0 comments on commit f697396

Please sign in to comment.