Fixed not copying the default keyword args

This commit is contained in:
FelixBrendel
2018-11-15 15:45:20 +01:00
parent 319d6d2041
commit 3e8f883308
6 changed files with 112 additions and 69 deletions
+9
View File
@@ -126,6 +126,7 @@ typedef enum {
Built_In_Addition,
Built_In_And,
Built_In_Breakpoint,
Built_In_Copy,
Built_In_Define,
Built_In_Division,
Built_In_Equal,
@@ -169,6 +170,7 @@ char* Built_In_Name_to_string(Built_In_Name name) {
case Built_In_Addition: return "+";
case Built_In_And: return "and";
case Built_In_Breakpoint: return "breakpoint";
case Built_In_Copy: return "copy";
case Built_In_Define: return "define";
case Built_In_Division: return "/";
case Built_In_Equal: return "=";
@@ -294,6 +296,7 @@ Ast_Node* create_ast_node_built_in_function(char* name) {
else if (string_equal(name, ">=")) type = Built_In_Greater_Equal;
else if (string_equal(name, "and")) type = Built_In_And;
else if (string_equal(name, "breakpoint")) type = Built_In_Breakpoint;
else if (string_equal(name, "copy")) type = Built_In_Copy;
else if (string_equal(name, "define")) type = Built_In_Define;
else if (string_equal(name, "error")) type = Built_In_Error;
else if (string_equal(name, "eval")) type = Built_In_Eval;
@@ -337,3 +340,9 @@ Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
node->value.pair->rest = rest;
return node;
}
Ast_Node* copy_ast_node(Ast_Node* n) {
Ast_Node* target = new(Ast_Node);
*target = *n;
return target;
}
+63 -63
View File
@@ -6,10 +6,10 @@ typedef enum {
struct Environment {
struct Environment* parent;
Environment_Type type;
Environment_Type type;
int capacity;
int next_index;
int capacity;
int next_index;
// TODO(Felix): Use a hashmap here.
char** keys;
Ast_Node** values;
@@ -22,12 +22,12 @@ Environment* create_child_environment(Environment* parent, Environment_Type type
int start_capacity = 16;
env->type = type;
env->parent = parent;
env->type = type;
env->parent = parent;
env->capacity = start_capacity;
env->next_index = 0;
env->keys = (char**)malloc(start_capacity * sizeof(char*));
env->values = (Ast_Node**)malloc(start_capacity * sizeof(Ast_Node*));
env->keys = (char**)malloc(start_capacity * sizeof(char*));
env->values = (Ast_Node**)malloc(start_capacity * sizeof(Ast_Node*));
return env;
}
@@ -38,12 +38,12 @@ Environment* create_empty_environment(Environment_Type type) {
void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
if (env->type == Environment_Type_Macro) {
// NOTE(Felix): we know we have a parent because every
// environment has a parent except the top level environment.
// However the top level environment is not a let-environment,
// so we would not land here
define_symbol(symbol, value, env->parent);
return;
// NOTE(Felix): we know we have a parent because every
// environment has a parent except the top level environment.
// However the top level environment is not a let-environment,
// so we would not land here
define_symbol(symbol, value, env->parent);
return;
}
// NOTE(Felix): right now we are simply adding the symol at the
@@ -52,9 +52,9 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
// latest defined one first, but a bit messy. Later we should use
// a hashmap here. @refactor
if (env->next_index == env->capacity) {
env->capacity *= 2;
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
env->values = (Ast_Node**)realloc(env->values, env->capacity * sizeof(Ast_Node*));
env->capacity *= 2;
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
env->values = (Ast_Node**)realloc(env->values, env->capacity * sizeof(Ast_Node*));
}
env->keys [env->next_index] = symbol->value.symbol->identifier;
@@ -64,8 +64,8 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
if (env->type != Environment_Type_Macro) {
create_error(Error_Type_Unknown_Error, symbol);
return;
create_error(Error_Type_Unknown_Error, symbol);
return;
}
env->type = Environment_Type_Lambda;
@@ -77,19 +77,19 @@ void print_environment(Environment* env);
Ast_Node* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) {
for (int i = env->next_index - 1; i >= 0; --i)
if (string_equal(env->keys[i], sym->identifier))
return env->values[i];
if (string_equal(env->keys[i], sym->identifier))
return env->values[i];
return nullptr;
}
Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) {
Ast_Node* result;
do {
if (env->type != Environment_Type_Lambda) {
result = lookup_symbol_in_this_envt(sym, env);
if (result) return result;
}
env = env->parent;
if (env->type != Environment_Type_Lambda) {
result = lookup_symbol_in_this_envt(sym, env);
if (result) return result;
}
env = env->parent;
} while (env);
return nullptr;
}
@@ -97,22 +97,22 @@ Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) {
Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) {
Ast_Node* result;
do {
result = lookup_symbol_in_this_envt(sym, env);
if (result) return result;
if (env->type == Environment_Type_Lambda)
break;
result = lookup_symbol_in_this_envt(sym, env);
if (result) return result;
if (env->type == Environment_Type_Lambda)
break;
env = env->parent;
env = env->parent;
} while (env);
if (env) {
do {
if (env->type != Environment_Type_Lambda) {
result = lookup_symbol_in_this_envt(sym, env);
if (result) return result;
}
env = env->parent;
} while (env);
do {
if (env->type != Environment_Type_Lambda) {
result = lookup_symbol_in_this_envt(sym, env);
if (result) return result;
}
env = env->parent;
} while (env);
}
return nullptr;
@@ -123,29 +123,29 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
Ast_Node* result;
result = lookup_symbol_in_this_envt(sym, env);
if (result)
return result;
return result;
if (env->parent) {
if (env->type == Environment_Type_Lambda) {
result = lookup_symbol_from_lambda_env(sym, env->parent);
} else {
result = lookup_symbol_from_let_or_macro_env(sym, env->parent);
}
if (env->type == Environment_Type_Lambda) {
result = lookup_symbol_from_lambda_env(sym, env->parent);
} else {
result = lookup_symbol_from_let_or_macro_env(sym, env->parent);
}
if (result)
return result;
if (result)
return result;
}
if (string_equal(sym->identifier, "nil")) {
return create_ast_node_nil();
return create_ast_node_nil();
}
if (string_equal(sym->identifier, "t")) {
return create_ast_node_t();
return create_ast_node_t();
}
result = create_ast_node_built_in_function(sym->identifier);
if (result)
return result;
return result;
create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil());
/* printf("%s\n", sym->identifier); */
@@ -153,28 +153,28 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
}
void print_indent(int indent) {
for (int i = 0; i < indent; ++i) {
printf(" ");
printf(" ");
}
}
void print_environment_indent(Environment* env, int indent) {
for (int i = 0; i < env->next_index; ++i) {
print_indent(indent);
printf("%s -> ", env->keys[i]);
print(env->values[i]);
printf("\n");
print_indent(indent);
printf("%s -> ", env->keys[i]);
print(env->values[i]);
printf("\n");
}
if (env->parent) {
print_indent(indent);
printf("parent");
if (env->parent->type == Environment_Type_Lambda)
printf(" (lambda)");
else if (env->parent->type == Environment_Type_Macro)
printf(" (macro)");
else if (env->parent->type == Environment_Type_Let)
printf(" (let)");
printf(":\n");
print_environment_indent(env->parent, indent+4);
print_indent(indent);
printf("parent");
if (env->parent->type == Environment_Type_Lambda)
printf(" (lambda)");
else if (env->parent->type == Environment_Type_Macro)
printf(" (macro)");
else if (env->parent->type == Environment_Type_Let)
printf(" (let)");
printf(":\n");
print_environment_indent(env->parent, indent+4);
}
}
+29 -3
View File
@@ -77,7 +77,8 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
// if not set it and then add it to the array list
define_symbol(
create_ast_node_symbol(arguments->value.pair->first->value.keyword->identifier),
arguments->value.pair->rest->value.pair->first, new_env);
arguments->value.pair->rest->value.pair->first,
new_env);
append_to_String_array_list(read_in_keywords, arguments->value.pair->first->value.keyword->identifier);
@@ -115,7 +116,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
if (!was_set) {
define_symbol(
create_ast_node_symbol(defined_keyword),
function->keyword_arguments->values->data[i], new_env);
copy_ast_node(function->keyword_arguments->values->data[i]), new_env);
}
}
}
@@ -151,7 +152,6 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
result = eval_expr(function->body, new_env);
}
free(new_env);
return result;
}
}
@@ -456,8 +456,18 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
printf("Keyword: {");
if (fun->value.function->keyword_arguments->next_index != 0) {
printf("%s", fun->value.function->keyword_arguments->identifiers[0]);
if (fun->value.function->keyword_arguments->values->data[0]) {
printf(" (");
print(fun->value.function->keyword_arguments->values->data[0]);
printf(")");
}
for (int i = 1; i < fun->value.function->keyword_arguments->next_index; ++i) {
printf(", %s", fun->value.function->keyword_arguments->identifiers[i]);
if (fun->value.function->keyword_arguments->values->data[i]) {
printf(" (");
print(fun->value.function->keyword_arguments->values->data[i]);
printf(")");
}
}
}
printf("}\n");
@@ -808,6 +818,22 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
*target = *source;
return target;
}
case Built_In_Copy: {
if (arguments_length != 1)
report_error(Error_Type_Wrong_Number_Of_Arguments);
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil ||
evaluated_arguments->value.pair->first->type == Ast_Node_Type_Keyword)
{
report_error(Error_Type_Type_Missmatch);
}
Ast_Node* target = new(Ast_Node);
Ast_Node* source = evaluated_arguments->value.pair->first;
*target = *source;
return target;
}
case Built_In_Load: {
if (arguments_length != 1)
report_error(Error_Type_Wrong_Number_Of_Arguments);