importing and macros can expand to macros

This commit is contained in:
Felix Brendel
2019-05-03 19:12:30 +02:00
parent 0923f36f9c
commit a1fccd29de
10 changed files with 115 additions and 54 deletions
+21 -25
View File
@@ -10,18 +10,17 @@ namespace Parser {
// read-time. This should always be the global environment.
Environment* environment_for_macros;
proc init(Environment* env) -> void {
// NOTE(Felix): it is important to keep the parser environment
// up to date with the global environment. When doing tests,
// or running a programm we have to reload it.
// proc set_environment_for_macros(Environment* env) -> void {
// // NOTE(Felix): it is important to keep the parser environment
// // up to date with the global environment. When doing tests,
// // or running a programm we have to reload it.
// NOTE(Felix): For now we just allow executing built-ins at
// read-time (while creating macros). If later we want to
// change that, we have to define some funcions in this
// environment.
environment_for_macros = env;
standard_in = Memory::create_string("stdin");
}
// // NOTE(Felix): For now we just allow executing built-ins at
// // read-time (while creating macros). If later we want to
// // change that, we have to define some funcions in this
// // environment.
// environment_for_macros = env;
// }
proc inject_scl(Lisp_Object* lo) -> void {
lo->sourceCodeLocation = new(Source_Code_Location);
@@ -364,8 +363,9 @@ namespace Parser {
}
// check if we have to create or delete or run macros
if (Memory::get_type(expression->value.pair.first) == Lisp_Object_Type::Symbol) {
if (string_equal("define-syntax", expression->value.pair.first->value.identifier)) {
while (Memory::get_type(expression->value.pair.first) == Lisp_Object_Type::Symbol) {
Lisp_Object* parsed_symbol = expression->value.pair.first;
if (string_equal("define-syntax", parsed_symbol->value.identifier)) {
// create a new macro
Lisp_Object* arguments = expression->value.pair.rest;
Lisp_Object* body;
@@ -426,7 +426,7 @@ namespace Parser {
// print_environment(environment_for_macros);
return Memory::nil;
} else if (string_equal("delete-syntax", expression->value.pair.first->value.identifier)) {
} else if (string_equal("delete-syntax", parsed_symbol->value.identifier)) {
/* --- deleting an existing macro --- */
// TODO(Felix): this is a hard one because when
// environments will be made from hashmaps, how can we
@@ -446,20 +446,16 @@ namespace Parser {
// if threre is a macro named like this, then macroexpand
// if not it is regular code, dont touch.
for (int i = 0; i < environment_for_macros->next_index; ++i) {
if (string_equal(expression->value.pair.first->value.identifier, environment_for_macros->keys[i]) &&
Memory::get_type(environment_for_macros->values[i]) == Lisp_Object_Type::Function &&
environment_for_macros->values[i]->value.function.type == Function_Type::Macro)
{
try {
expression = eval_expr(expression, environment_for_macros);
}
}
}
Lisp_Object* macro = try_lookup_symbol(parsed_symbol, environment_for_macros);
if (macro &&
Memory::get_type(macro) == Lisp_Object_Type::Function &&
macro->value.function.type == Function_Type::Macro)
{
try expression = eval_expr(expression, environment_for_macros);
} else break;
}
}
return expression;
}