fixes splicing of nil and macros dont expand at parse time fr now

This commit is contained in:
Felix Brendel
2019-06-06 13:40:47 +02:00
parent 89fa56c720
commit c0e79075bc
9 changed files with 99 additions and 52 deletions
+30 -13
View File
@@ -496,8 +496,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
// funciton, we can't just modify it because otherwise
// we modify the body of the function and would bake
// in the result...
Lisp_Object* newPair;
try newPair = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
Lisp_Object* newPair = Memory::nil;
Lisp_Object* newPairHead = newPair;
Lisp_Object* head = expr;
while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
@@ -509,25 +508,43 @@ proc load_built_ins_into_environment(Environment* env) -> void {
{
Lisp_Object* spliced = unquoteSomeExpressions(head->value.pair.first);
try assert_type(spliced, Lisp_Object_Type::Pair);
newPairHead->value.pair.first = spliced->value.pair.first;
newPairHead->value.pair.rest = spliced->value.pair.rest;
if (spliced == Memory::nil) {
head = head->value.pair.rest;
continue;
}
// now skip to the end
while (newPairHead->value.pair.rest != Memory::nil) {
try assert_type(spliced, Lisp_Object_Type::Pair);
if (newPair == Memory::nil) {
try newPair = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
newPairHead = newPair;
} else {
try newPairHead->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
newPairHead->value.pair.first = spliced->value.pair.first;
newPairHead->value.pair.rest = spliced->value.pair.rest;
// now skip to the end
while (newPairHead->value.pair.rest != Memory::nil) {
newPairHead = newPairHead->value.pair.rest;
}
}
} else {
if (newPair == Memory::nil) {
try newPair = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
newPairHead = newPair;
} else {
try newPairHead->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
newPairHead = newPairHead->value.pair.rest;
}
} else {
newPairHead->value.pair.first = unquoteSomeExpressions(head->value.pair.first);
}
if (Memory::get_type(head->value.pair.rest) != Lisp_Object_Type::Pair)
break;
// if (Memory::get_type(head->value.pair.rest) != Lisp_Object_Type::Pair) {
// break;
// }
try newPairHead->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
newPairHead = newPairHead->value.pair.rest;
head = head->value.pair.rest;
}
newPairHead->value.pair.rest = Memory::nil;
+5
View File
@@ -67,6 +67,11 @@ proc print_indent(int indent) -> void {
}
proc print_environment_indent(Environment* env, int indent) -> void {
// if(env == Globals::root_environment) {
// print_indent(indent);
// printf("[built-ins]-Environment (%lld)\n", (long long)env);
// return;
// }
for (int i = 0; i < env->next_index; ++i) {
print_indent(indent);
print(env->values[i]);
+13
View File
@@ -418,6 +418,19 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
Lisp_Object* result;
try result = apply_arguments_to_function(arguments, &lispOperator->value.function);
// NOTE(Felix): The parser does not understnad (import ..)
// so it cannot expand imported macros at read time
// (because at read time, they are not imported yet, this
// is done at runtime...). That is why we sometimes have
// stray macros fying around, in that case, we expand them
// and bake them in, so they do not have to be expanded
// later again.
if (lispOperator->value.function.type == Function_Type::Macro) {
*node = *result;
try result = eval_expr(result, env);
}
return result;
}
}
+17 -1
View File
@@ -449,16 +449,32 @@ namespace Parser {
} else {
// if threre is a macro named like this, then macroexpand
// if not it is regular code, dont touch.
break;
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)
{
// printf("Found macro: ") ;
// printf("pretending to expand macro at %s %d %d: ",
// Memory::get_c_str(parser_file),
// parser_line, parser_col);
// print(parsed_symbol);
// printf("\n");
// NOTE(Felix): Execute it as a special lambda,
// because if we keep it as a macro, the evaluator
// will think it is a stray macro that was not yet
// expanded, and attempt to evaluate it twice (1.
// for expanding, and 2. for evaluating)
macro->value.function.type = Function_Type::Special_Lambda;
// NOTE(Felix): deferred so even if eval expr
// fails, and returns, the type will be be
// resetted to macro.
defer {
macro->value.function.type = Function_Type::Macro;
};
try expression = eval_expr(expression, environment_for_macros);
break;
} else break;
}
}