From 716b72ff0f5995b43cec437eab3e43e53c97c850 Mon Sep 17 00:00:00 2001 From: Felix Brendel Date: Mon, 29 Oct 2018 12:54:23 +0100 Subject: [PATCH] linux fixes --- build.sh | 4 +- src/built_ins.c | 183 ++++++++++++++++++++++++------------------------ src/env.c | 130 +++++++++++++++++----------------- src/eval.c | 28 ++++---- 4 files changed, 175 insertions(+), 170 deletions(-) diff --git a/build.sh b/build.sh index c12e420..ee7b0dd 100755 --- a/build.sh +++ b/build.sh @@ -2,5 +2,7 @@ clang src/main.c -g -o ./bin/slime --std=c99 || exit 1 echo "" echo "--- Output Start ---" -./bin/slime +pushd bin +./slime +popd echo "--- Output End ---" diff --git a/src/built_ins.c b/src/built_ins.c index c9fa399..1da9ca5 100644 --- a/src/built_ins.c +++ b/src/built_ins.c @@ -2,39 +2,40 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env); bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { if (n1 == n2) - return true; + return true; if (n1->type != n2->type) - return false; + return false; switch (n1->type) { case Ast_Node_Type_Built_In_Function: - return n1->value.built_in_function->type - == n2->value.built_in_function->type; + return n1->value.built_in_function->type + == n2->value.built_in_function->type; case Ast_Node_Type_Function: - // if they have the same pointer, true is - // returned a few lines above - return false; + // if they have the same pointer, true is + // returned a few lines above + return false; case Ast_Node_Type_Keyword: - return string_equal( - n1->value.keyword->identifier, - n2->value.keyword->identifier); + return string_equal( + n1->value.keyword->identifier, + n2->value.keyword->identifier); + case Ast_Node_Type_T: case Ast_Node_Type_Nil: - return true; + return true; case Ast_Node_Type_Number: - return - n1->value.number->value == - n2->value.number->value; + return + n1->value.number->value == + n2->value.number->value; case Ast_Node_Type_Pair: - create_error(Error_Type_Not_Yet_Implemented, n1); - return false; + create_error(Error_Type_Not_Yet_Implemented, n1); + return false; case Ast_Node_Type_String: - return string_equal( - n1->value.string->value, - n2->value.string->value); + return string_equal( + n1->value.string->value, + n2->value.string->value); case Ast_Node_Type_Symbol: - return string_equal( - n1->value.symbol->identifier, - n2->value.symbol->identifier); + return string_equal( + n1->value.symbol->identifier, + n2->value.symbol->identifier); } // we should never reach here @@ -43,32 +44,32 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { Ast_Node* built_in_equals(Ast_Node* operands) { if (operands->type == Ast_Node_Type_Nil) - return create_ast_node_t(); + return create_ast_node_t(); Ast_Node* first = operands->value.pair->first; while (operands->type == Ast_Node_Type_Pair) { - if (!ast_node_equal(operands->value.pair->first, first)) - return create_ast_node_nil(); - operands = operands->value.pair->rest; + if (!ast_node_equal(operands->value.pair->first, first)) + return create_ast_node_nil(); + operands = operands->value.pair->rest; } - return create_ast_node_t(); + return create_ast_node_t(); } Ast_Node* built_in_greater(Ast_Node* operands) { double last_number = strtod("Inf", NULL); while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } - if (operands->value.pair->first->value.number->value >= last_number) - return create_ast_node_nil(); + if (operands->value.pair->first->value.number->value >= last_number) + return create_ast_node_nil(); - last_number = operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + last_number = operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_t(); @@ -78,15 +79,15 @@ Ast_Node* built_in_greater_equal(Ast_Node* operands) { double last_number = strtod("Inf", NULL); while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } - if (operands->value.pair->first->value.number->value > last_number) - return create_ast_node_nil(); + if (operands->value.pair->first->value.number->value > last_number) + return create_ast_node_nil(); - last_number = operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + last_number = operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_t(); @@ -96,15 +97,15 @@ Ast_Node* built_in_less(Ast_Node* operands) { double last_number = strtod("-Inf", NULL); while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } - if (operands->value.pair->first->value.number->value <= last_number) - return create_ast_node_nil(); + if (operands->value.pair->first->value.number->value <= last_number) + return create_ast_node_nil(); - last_number = operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + last_number = operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_t(); @@ -114,15 +115,15 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) { double last_number = strtod("-Inf", NULL); while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } - if (operands->value.pair->first->value.number->value < last_number) - return create_ast_node_nil(); + if (operands->value.pair->first->value.number->value < last_number) + return create_ast_node_nil(); - last_number = operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + last_number = operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_t(); @@ -131,11 +132,11 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) { Ast_Node* built_in_add(Ast_Node* operands) { double sum = 0; while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } - sum += operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } + sum += operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_number(sum); @@ -143,54 +144,54 @@ Ast_Node* built_in_add(Ast_Node* operands) { Ast_Node* built_in_substract(Ast_Node* operands) { try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); + assert_type(operands->value.pair->first, Ast_Node_Type_Number); } double difference = operands->value.pair->first->value.number->value; operands = operands->value.pair->rest; while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } - difference -= operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + difference -= operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_number(difference); } Ast_Node* built_in_multiply(Ast_Node* operands) { try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); + assert_type(operands->value.pair->first, Ast_Node_Type_Number); } double product = operands->value.pair->first->value.number->value; operands = operands->value.pair->rest; while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } - product *= operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + product *= operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_number(product); } Ast_Node* built_in_divide(Ast_Node* operands) { try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); + assert_type(operands->value.pair->first, Ast_Node_Type_Number); } double quotient = operands->value.pair->first->value.number->value; operands = operands->value.pair->rest; while (operands->type == Ast_Node_Type_Pair) { - try { - assert_type(operands->value.pair->first, Ast_Node_Type_Number); - } + try { + assert_type(operands->value.pair->first, Ast_Node_Type_Number); + } - quotient /= operands->value.pair->first->value.number->value; - operands = operands->value.pair->rest; + quotient /= operands->value.pair->first->value.number->value; + operands = operands->value.pair->rest; } return create_ast_node_number(quotient); } @@ -199,19 +200,19 @@ Ast_Node* built_in_divide(Ast_Node* operands) { Ast_Node* built_in_load(char* file_name, Environment* env) { char* file_content = read_entire_file(file_name); if (file_content) { - Ast_Node* result = create_ast_node_nil(); - Ast_Node_Array_List* program; - try { - program = parse_program(file_content); - } - for (int i = 0; i < program->next_index; ++i) { - try { - result = eval_expr(program->data[i], env); - } - } - return result; + Ast_Node* result = create_ast_node_nil(); + Ast_Node_Array_List* program; + try { + program = parse_program(file_content); + } + for (int i = 0; i < program->next_index; ++i) { + try { + result = eval_expr(program->data[i], env); + } + } + return result; } else { - create_error(Error_Type_Unknown_Error, create_ast_node_nil()); - return nullptr; + create_error(Error_Type_Unknown_Error, create_ast_node_nil()); + return nullptr; } } diff --git a/src/env.c b/src/env.c index e6e2bb7..791228b 100644 --- a/src/env.c +++ b/src/env.c @@ -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; @@ -63,9 +63,9 @@ 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; + if (env->type != Environment_Type_Macro) { + 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 (result) - return result; + 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 (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); } } diff --git a/src/eval.c b/src/eval.c index 7b1aed5..e920782 100644 --- a/src/eval.c +++ b/src/eval.c @@ -139,20 +139,21 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E } } - eval_time: - Ast_Node* result; + eval_time: { + Ast_Node* result; - // don't have to check every time if it is macro environment or - // not - if (function->is_macro) - new_env->type = Environment_Type_Macro; + // don't have to check every time if it is macro environment or + // not + if (function->is_macro) + new_env->type = Environment_Type_Macro; - try { - result = eval_expr(function->body, new_env); - } + try { + result = eval_expr(function->body, new_env); + } - free(new_env); - return result; + free(new_env); + return result; + } } /* @@ -433,8 +434,8 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { // just make sure type was not redefined and // returns something that is not a keyword if (type->type == Ast_Node_Type_Keyword && - string_equal(type->value.keyword->identifier, "dynamic-function") || - string_equal(type->value.keyword->identifier, "dynamic-macro")) + (string_equal(type->value.keyword->identifier, "dynamic-function") || + string_equal(type->value.keyword->identifier, "dynamic-macro"))) { Ast_Node* fun = eval_expr(arguments->value.pair->first, env); printf("\nMacro? %s\n", (fun->value.function->is_macro) ? "yes" : "no"); @@ -866,6 +867,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { } case Ast_Node_Type_Keyword: return create_ast_node_keyword("keyword"); case Ast_Node_Type_Nil: return create_ast_node_keyword("nil"); + case Ast_Node_Type_T: return create_ast_node_keyword("t"); case Ast_Node_Type_Number: return create_ast_node_keyword("number"); case Ast_Node_Type_Pair: return create_ast_node_keyword("pair"); case Ast_Node_Type_String: return create_ast_node_keyword("string");