diff --git a/src/assert.cpp b/src/assert.cpp index 085ea3a..65c619d 100644 --- a/src/assert.cpp +++ b/src/assert.cpp @@ -1,4 +1,4 @@ -void assert_type (Ast_Node* node, Ast_Node_Type type) { +void assert_type (Lisp_Object* node, Lisp_Object_Type type) { if (!node) create_error(Error_Type::Unknown_Error, nullptr); if (node->type == type) return; diff --git a/src/built_ins.cpp b/src/built_ins.cpp index 018b417..6467cd5 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -1,44 +1,44 @@ -Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length); -int list_length(Ast_Node* node); -Ast_Node* eval_expr(Ast_Node* node, Environment* env); -bool is_truthy (Ast_Node* expression, Environment* env); -void parse_argument_list(Ast_Node* arguments, Function* function); +Lisp_Object* eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length); +int list_length(Lisp_Object* node); +Lisp_Object* eval_expr(Lisp_Object* node, Environment* env); +bool is_truthy (Lisp_Object* expression, Environment* env); +void parse_argument_list(Lisp_Object* arguments, Function* function); -bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { +bool lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) { if (n1 == n2) return true; if (n1->type != n2->type) return false; switch (n1->type) { - case Ast_Node_Type::CFunction: + case Lisp_Object_Type::CFunction: // TODO(Felix): make comparing work again. return false; /* return n1->value.built_in_function->type */ /* == n2->value.built_in_function->type; */ - case Ast_Node_Type::Function: + case Lisp_Object_Type::Function: // if they have the same pointer, true is // returned a few lines above return false; - case Ast_Node_Type::Keyword: + case Lisp_Object_Type::Keyword: return string_equal( n1->value.keyword->identifier, n2->value.keyword->identifier); - case Ast_Node_Type::T: - case Ast_Node_Type::Nil: + case Lisp_Object_Type::T: + case Lisp_Object_Type::Nil: return true; - case Ast_Node_Type::Number: + case Lisp_Object_Type::Number: return n1->value.number->value == n2->value.number->value; - case Ast_Node_Type::Pair: + case Lisp_Object_Type::Pair: create_error(Error_Type::Not_Yet_Implemented, n1->sourceCodeLocation); return false; - case Ast_Node_Type::String: + case Lisp_Object_Type::String: return string_equal( n1->value.string->value, n2->value.string->value); - case Ast_Node_Type::Symbol: + case Lisp_Object_Type::Symbol: return string_equal( n1->value.symbol->identifier, n2->value.symbol->identifier); @@ -48,27 +48,27 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { return false; } -Ast_Node* built_in_equals(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_equals(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); } - if (arguments->type == Ast_Node_Type::Nil) - return create_ast_node_t(); + if (arguments->type == Lisp_Object_Type::Nil) + return create_lisp_object_t(); - Ast_Node* first = arguments->value.pair->first; + Lisp_Object* first = arguments->value.pair->first; - while (arguments->type == Ast_Node_Type::Pair) { - if (!ast_node_equal(arguments->value.pair->first, first)) - return create_ast_node_nil(); + while (arguments->type == Lisp_Object_Type::Pair) { + if (!lisp_object_equal(arguments->value.pair->first, first)) + return create_lisp_object_nil(); arguments = arguments->value.pair->rest; } - return create_ast_node_t(); + return create_lisp_object_t(); } -Ast_Node* built_in_greater(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_greater(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); @@ -76,22 +76,22 @@ Ast_Node* built_in_greater(Ast_Node* arguments, Environment* env) { double last_number = strtod("Inf", NULL); - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } if (arguments->value.pair->first->value.number->value >= last_number) - return create_ast_node_nil(); + return create_lisp_object_nil(); last_number = arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_t(); + return create_lisp_object_t(); } -Ast_Node* built_in_greater_equal(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_greater_equal(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); @@ -99,22 +99,22 @@ Ast_Node* built_in_greater_equal(Ast_Node* arguments, Environment* env) { double last_number = strtod("Inf", NULL); - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } if (arguments->value.pair->first->value.number->value > last_number) - return create_ast_node_nil(); + return create_lisp_object_nil(); last_number = arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_t(); + return create_lisp_object_t(); } -Ast_Node* built_in_less(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_less(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); @@ -122,22 +122,22 @@ Ast_Node* built_in_less(Ast_Node* arguments, Environment* env) { double last_number = strtod("-Inf", NULL); - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } if (arguments->value.pair->first->value.number->value <= last_number) - return create_ast_node_nil(); + return create_lisp_object_nil(); last_number = arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_t(); + return create_lisp_object_t(); } -Ast_Node* built_in_less_equal(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_less_equal(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); @@ -145,109 +145,109 @@ Ast_Node* built_in_less_equal(Ast_Node* arguments, Environment* env) { double last_number = strtod("-Inf", NULL); - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } if (arguments->value.pair->first->value.number->value < last_number) - return create_ast_node_nil(); + return create_lisp_object_nil(); last_number = arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_t(); + return create_lisp_object_t(); } -Ast_Node* built_in_add(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_add(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); } double sum = 0; - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } sum += arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_number(sum); + return create_lisp_object_number(sum); } -Ast_Node* built_in_substract(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_substract(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); } try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } double difference = arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } difference -= arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_number(difference); + return create_lisp_object_number(difference); } -Ast_Node* built_in_multiply(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_multiply(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); } try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } double product = arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } product *= arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_number(product); + return create_lisp_object_number(product); } -Ast_Node* built_in_divide(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_divide(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); } try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } double quotient = arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; - while (arguments->type == Ast_Node_Type::Pair) { + while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } quotient /= arguments->value.pair->first->value.number->value; arguments = arguments->value.pair->rest; } - return create_ast_node_number(quotient); + return create_lisp_object_number(quotient); } -Ast_Node* built_in_exponentiate(Ast_Node* arguments, Environment* env) { +Lisp_Object* built_in_exponentiate(Lisp_Object* arguments, Environment* env) { int arguments_length; try { arguments = eval_arguments(arguments, env, &arguments_length); @@ -259,7 +259,7 @@ Ast_Node* built_in_exponentiate(Ast_Node* arguments, Environment* env) { } try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } double base = arguments->value.pair->first->value.number->value; @@ -267,20 +267,20 @@ Ast_Node* built_in_exponentiate(Ast_Node* arguments, Environment* env) { arguments = arguments->value.pair->rest; try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Number); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); } double exponent = arguments->value.pair->first->value.number->value; - return create_ast_node_number(pow(base, exponent)); + return create_lisp_object_number(pow(base, exponent)); } -Ast_Node* built_in_load(char* file_name, Environment* env) { +Lisp_Object* 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; + Lisp_Object* result = create_lisp_object_nil(); + Lisp_Object_Array_List* program; try { program = Parser::parse_program(file_name, file_content); } @@ -298,18 +298,18 @@ Ast_Node* built_in_load(char* file_name, Environment* env) { void load_built_ins_into_environment(Environment* env) { int arguments_length; - Ast_Node* evaluated_arguments; + Lisp_Object* evaluated_arguments; -#define cLambda [=](Ast_Node* arguments, Environment* env) mutable -> Ast_Node* +#define cLambda [=](Lisp_Object* arguments, Environment* env) mutable -> Lisp_Object* #define report_error(_type) { \ create_error(_type, arguments->sourceCodeLocation); \ return nullptr; \ } - auto defun = [&](char* name, std::function fun) { + auto defun = [&](char* name, std::function fun) { define_symbol( - create_ast_node_symbol(name), - create_ast_node_cfunction(fun), + create_lisp_object_symbol(name), + create_lisp_object_cfunction(fun), env); }; @@ -332,19 +332,19 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* symbol = arguments->value.pair->first; + Lisp_Object* symbol = arguments->value.pair->first; - if (symbol->type == Ast_Node_Type::Pair) { + if (symbol->type == Lisp_Object_Type::Pair) { try { symbol = eval_expr(symbol, env); } } - if (symbol->type != Ast_Node_Type::Symbol) { + if (symbol->type != Lisp_Object_Type::Symbol) { report_error(Error_Type::Type_Missmatch); } - Ast_Node* value = arguments->value.pair->rest->value.pair->first; + Lisp_Object* value = arguments->value.pair->rest->value.pair->first; try { value = eval_expr(value, env); } @@ -362,15 +362,15 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* symbol = arguments->value.pair->first; + Lisp_Object* symbol = arguments->value.pair->first; - if (symbol->type == Ast_Node_Type::Pair) { + if (symbol->type == Lisp_Object_Type::Pair) { try { symbol = eval_expr(symbol, env); } } - if (symbol->type != Ast_Node_Type::Symbol) { + if (symbol->type != Lisp_Object_Type::Symbol) { report_error(Error_Type::Type_Missmatch); } @@ -379,7 +379,7 @@ void load_built_ins_into_environment(Environment* env) { } - Ast_Node* value = arguments->value.pair->rest->value.pair->first; + Lisp_Object* value = arguments->value.pair->rest->value.pair->first; try { value = eval_expr(value, env); } @@ -396,14 +396,14 @@ void load_built_ins_into_environment(Environment* env) { if (arguments_length != 2) 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) + if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil || + evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Keyword) { report_error(Error_Type::Type_Missmatch); } - Ast_Node* target = evaluated_arguments->value.pair->first; - Ast_Node* source = evaluated_arguments->value.pair->rest->value.pair->first; + Lisp_Object* target = evaluated_arguments->value.pair->first; + Lisp_Object* source = evaluated_arguments->value.pair->rest->value.pair->first; *target = *source; return target; @@ -417,16 +417,16 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* condition = arguments->value.pair->first; - Ast_Node* then_part = arguments->value.pair->rest; - Ast_Node* else_part = then_part->value.pair->rest; + Lisp_Object* condition = arguments->value.pair->first; + Lisp_Object* then_part = arguments->value.pair->rest; + Lisp_Object* else_part = then_part->value.pair->rest; bool truthy; try { truthy = is_truthy(condition, env); } - Ast_Node* result; + Lisp_Object* result; if (truthy) try{ @@ -436,7 +436,7 @@ void load_built_ins_into_environment(Environment* env) { try { result = eval_expr(else_part->value.pair->first, env); } - else return create_ast_node_nil(); + else return create_lisp_object_nil(); return result; }); defun("quote", cLambda { @@ -462,15 +462,15 @@ void load_built_ins_into_environment(Environment* env) { // printf("\n"); // recursive lambdas in lambdas yay!! - std::function unquoteSomeExpressions; - unquoteSomeExpressions = [&unquoteSomeExpressions, &env] (Ast_Node* expr) -> Ast_Node* { + std::function unquoteSomeExpressions; + unquoteSomeExpressions = [&unquoteSomeExpressions, &env] (Lisp_Object* expr) -> Lisp_Object* { // if it is an atom, return it - if (expr->type != Ast_Node_Type::Pair) - return copy_ast_node(expr); + if (expr->type != Lisp_Object_Type::Pair) + return copy_lisp_object(expr); // it is a pair! - Ast_Node* originalPair = expr->value.pair->first; - if (originalPair->type == Ast_Node_Type::Symbol && + Lisp_Object* originalPair = expr->value.pair->first; + if (originalPair->type == Lisp_Object_Type::Symbol && string_equal(originalPair->value.symbol->identifier, "unquote")) { // eval replace the stuff @@ -486,35 +486,35 @@ void load_built_ins_into_environment(Environment* env) { // funciton, we can't jsut modify it because otherwise // we modify the body of the function and would bake // in the result... - Ast_Node* newPair = create_ast_node_pair(nullptr, nullptr); - Ast_Node* newPairHead = newPair; - Ast_Node* head = expr; - while (head->type == Ast_Node_Type::Pair) { + Lisp_Object* newPair = create_lisp_object_pair(nullptr, nullptr); + Lisp_Object* newPairHead = newPair; + Lisp_Object* head = expr; + while (head->type == Lisp_Object_Type::Pair) { newPairHead->value.pair->first = unquoteSomeExpressions(head->value.pair->first); - if (head->value.pair->rest->type != Ast_Node_Type::Pair) + if (head->value.pair->rest->type != Lisp_Object_Type::Pair) break; - newPairHead->value.pair->rest = create_ast_node_pair(nullptr, nullptr); + newPairHead->value.pair->rest = create_lisp_object_pair(nullptr, nullptr); newPairHead = newPairHead->value.pair->rest; head = head->value.pair->rest; } - newPairHead->value.pair->rest = create_ast_node_nil(); + newPairHead->value.pair->rest = create_lisp_object_nil(); return newPair; }; - Ast_Node* ret = arguments->value.pair->first; - Ast_Node* head = ret; + Lisp_Object* ret = arguments->value.pair->first; + Lisp_Object* head = ret; ret = unquoteSomeExpressions(ret); return ret; }); defun("and", cLambda { bool result = true; - while (arguments->type != Ast_Node_Type::Nil) { - if (arguments->type != Ast_Node_Type::Pair) { + while (arguments->type != Lisp_Object_Type::Nil) { + if (arguments->type != Lisp_Object_Type::Pair) { report_error(Error_Type::Ill_Formed_List); } try { @@ -522,15 +522,15 @@ void load_built_ins_into_environment(Environment* env) { } arguments = arguments->value.pair->rest; - if (!result) return create_ast_node_nil(); + if (!result) return create_lisp_object_nil(); } - return create_ast_node_t(); + return create_lisp_object_t(); }); defun("or", cLambda { bool result = false; - while (arguments->type != Ast_Node_Type::Nil) { - if (arguments->type != Ast_Node_Type::Pair) { + while (arguments->type != Lisp_Object_Type::Nil) { + if (arguments->type != Lisp_Object_Type::Pair) { report_error(Error_Type::Ill_Formed_List); } try { @@ -538,10 +538,10 @@ void load_built_ins_into_environment(Environment* env) { } arguments = arguments->value.pair->rest; - if (result) return create_ast_node_t(); + if (result) return create_lisp_object_t(); } - return create_ast_node_nil(); + return create_lisp_object_nil(); }); defun("not", cLambda { try { @@ -556,8 +556,8 @@ void load_built_ins_into_environment(Environment* env) { truthy = is_truthy(arguments->value.pair->first, env); } if (truthy) - return create_ast_node_nil(); - return create_ast_node_t(); + return create_lisp_object_nil(); + return create_lisp_object_t(); }); defun("while", cLambda { try { @@ -567,16 +567,16 @@ void load_built_ins_into_environment(Environment* env) { if (arguments_length < 2) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* condition_part = arguments->value.pair->first; - Ast_Node* condition; - Ast_Node* then_part = arguments->value.pair->rest; - Ast_Node* result = create_ast_node_nil(); + Lisp_Object* condition_part = arguments->value.pair->first; + Lisp_Object* condition; + Lisp_Object* then_part = arguments->value.pair->rest; + Lisp_Object* result = create_lisp_object_nil(); while (true) { try { condition = eval_expr(condition_part, env); } - if (condition->type == Ast_Node_Type::Nil) { + if (condition->type == Lisp_Object_Type::Nil) { break; } try { @@ -596,27 +596,27 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); Environment* let_env = create_child_environment(env); - Ast_Node* bindings = arguments->value.pair->first; + Lisp_Object* bindings = arguments->value.pair->first; while (true) { - if (bindings->type == Ast_Node_Type::Nil) { + if (bindings->type == Lisp_Object_Type::Nil) { break; - } else if (bindings->type != Ast_Node_Type::Pair) { + } else if (bindings->type != Lisp_Object_Type::Pair) { report_error(Error_Type::Ill_Formed_Arguments); } - Ast_Node* sym = bindings->value.pair->first->value.pair->first; - if(sym->type != Ast_Node_Type::Symbol) { + Lisp_Object* sym = bindings->value.pair->first->value.pair->first; + if(sym->type != Lisp_Object_Type::Symbol) { report_error(Error_Type::Ill_Formed_Arguments); } - Ast_Node* rest_sym = bindings->value.pair->first->value.pair->rest; - if (rest_sym->type != Ast_Node_Type::Pair) { + Lisp_Object* rest_sym = bindings->value.pair->first->value.pair->rest; + if (rest_sym->type != Lisp_Object_Type::Pair) { report_error(Error_Type::Ill_Formed_Arguments); } - if (rest_sym->value.pair->rest->type != Ast_Node_Type::Nil) { + if (rest_sym->value.pair->rest->type != Lisp_Object_Type::Nil) { report_error(Error_Type::Ill_Formed_Arguments); } - Ast_Node* value = eval_expr(rest_sym->value.pair->first, env); + Lisp_Object* value = eval_expr(rest_sym->value.pair->first, env); define_symbol(sym, value, let_env); @@ -625,12 +625,12 @@ void load_built_ins_into_environment(Environment* env) { arguments = arguments->value.pair->rest; - Ast_Node* evaluated_arguments; + Lisp_Object* evaluated_arguments; try { evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length); } - if (evaluated_arguments->type == Ast_Node_Type::Nil) + if (evaluated_arguments->type == Lisp_Object_Type::Nil) return evaluated_arguments; // skip to the last evaluated operand and return it, @@ -638,7 +638,7 @@ void load_built_ins_into_environment(Environment* env) { // manually, because we want to increase code reuse, // but at the cost that we have to find the end of the // list again - while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type::Pair) { + while (evaluated_arguments->value.pair->rest->type == Lisp_Object_Type::Pair) { evaluated_arguments = evaluated_arguments->value.pair->rest; } return evaluated_arguments->value.pair->first; @@ -660,9 +660,9 @@ void load_built_ins_into_environment(Environment* env) { function->type = Function_Type::Lambda; // if parameters were specified - if (arguments->value.pair->first->type != Ast_Node_Type::Nil) { + if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Pair); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair); } try { parse_argument_list(arguments->value.pair->first, function); @@ -675,7 +675,7 @@ void load_built_ins_into_environment(Environment* env) { arguments = arguments->value.pair->rest; // if there is a docstring, use it - if (arguments->value.pair->first->type == Ast_Node_Type::String) { + if (arguments->value.pair->first->type == Lisp_Object_Type::String) { function->docstring = arguments->value.pair->first->value.string->value; arguments = arguments->value.pair->rest; } else { @@ -684,12 +684,12 @@ void load_built_ins_into_environment(Environment* env) { // we are now in the function body, just wrap it in an // implicit prog - function->body = create_ast_node_pair( - create_ast_node_symbol("prog"), + function->body = create_lisp_object_pair( + create_lisp_object_symbol("prog"), arguments); - Ast_Node* ret = new(Ast_Node); - ret->type = Ast_Node_Type::Function; + Lisp_Object* ret = new(Lisp_Object); + ret->type = Lisp_Object_Type::Function; ret->value.function = function; return ret; }); @@ -710,9 +710,9 @@ void load_built_ins_into_environment(Environment* env) { function->type = Function_Type::Special_Lambda; // if parameters were specified - if (arguments->value.pair->first->type != Ast_Node_Type::Nil) { + if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Pair); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair); } try { parse_argument_list(arguments->value.pair->first, function); @@ -725,7 +725,7 @@ void load_built_ins_into_environment(Environment* env) { arguments = arguments->value.pair->rest; // if there is a docstring, use it - if (arguments->value.pair->first->type == Ast_Node_Type::String) { + if (arguments->value.pair->first->type == Lisp_Object_Type::String) { function->docstring = arguments->value.pair->first->value.string->value; arguments = arguments->value.pair->rest; } else { @@ -734,12 +734,12 @@ void load_built_ins_into_environment(Environment* env) { // we are now in the function body, just wrap it in an // implicit prog - function->body = create_ast_node_pair( - create_ast_node_symbol("prog"), + function->body = create_lisp_object_pair( + create_lisp_object_symbol("prog"), arguments); - Ast_Node* ret = new(Ast_Node); - ret->type = Ast_Node_Type::Function; + Lisp_Object* ret = new(Lisp_Object); + ret->type = Lisp_Object_Type::Function; ret->value.function = function; return ret; }); @@ -750,7 +750,7 @@ void load_built_ins_into_environment(Environment* env) { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* result; + Lisp_Object* result; try { result = eval_expr(evaluated_arguments->value.pair->first, env); } @@ -763,7 +763,7 @@ void load_built_ins_into_environment(Environment* env) { evaluated_arguments = eval_arguments(arguments, env, &arguments_length); } - if (evaluated_arguments->type == Ast_Node_Type::Nil) + if (evaluated_arguments->type == Lisp_Object_Type::Nil) return evaluated_arguments; // skip to the last evaluated operand and return it, @@ -771,7 +771,7 @@ void load_built_ins_into_environment(Environment* env) { // manually, because we want to increase code reuse, // but at the cost that we have to find the end of the // list again - while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type::Pair) { + while (evaluated_arguments->value.pair->rest->type == Lisp_Object_Type::Pair) { evaluated_arguments = evaluated_arguments->value.pair->rest; } return evaluated_arguments->value.pair->first; @@ -790,7 +790,7 @@ void load_built_ins_into_environment(Environment* env) { if (arguments_length != 2) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - return create_ast_node_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first); + return create_lisp_object_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first); }); defun("first", cLambda { try { @@ -799,9 +799,9 @@ void load_built_ins_into_environment(Environment* env) { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil) - return create_ast_node_nil(); - if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::Pair) + if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) + return create_lisp_object_nil(); + if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) report_error(Error_Type::Type_Missmatch); return evaluated_arguments->value.pair->first->value.pair->first; @@ -813,9 +813,9 @@ void load_built_ins_into_environment(Environment* env) { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil) - return create_ast_node_nil(); - if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::Pair) + if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) + return create_lisp_object_nil(); + if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) report_error(Error_Type::Type_Missmatch); return evaluated_arguments->value.pair->first->value.pair->rest; @@ -828,28 +828,28 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node_Type type = evaluated_arguments->value.pair->first->type; + Lisp_Object_Type type = evaluated_arguments->value.pair->first->type; switch (type) { - case Ast_Node_Type::CFunction: return create_ast_node_keyword("cfunction"); - case Ast_Node_Type::Function: { + case Lisp_Object_Type::CFunction: return create_lisp_object_keyword("cfunction"); + case Lisp_Object_Type::Function: { Function* fun = evaluated_arguments->value.pair->first->value.function; if (fun->type == Function_Type::Lambda) - return create_ast_node_keyword("lambda"); + return create_lisp_object_keyword("lambda"); else if (fun->type == Function_Type::Special_Lambda) - return create_ast_node_keyword("special-lambda"); + return create_lisp_object_keyword("special-lambda"); else if (fun->type == Function_Type::Macro) - return create_ast_node_keyword("macro"); - else return create_ast_node_keyword("unknown"); - } - 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"); - case Ast_Node_Type::Symbol: return create_ast_node_keyword("symbol"); - } - return create_ast_node_keyword("unknown"); + return create_lisp_object_keyword("macro"); + else return create_lisp_object_keyword("unknown"); + } + case Lisp_Object_Type::Keyword: return create_lisp_object_keyword("keyword"); + case Lisp_Object_Type::Nil: return create_lisp_object_keyword("nil"); + case Lisp_Object_Type::T: return create_lisp_object_keyword("t"); + case Lisp_Object_Type::Number: return create_lisp_object_keyword("number"); + case Lisp_Object_Type::Pair: return create_lisp_object_keyword("pair"); + case Lisp_Object_Type::String: return create_lisp_object_keyword("string"); + case Lisp_Object_Type::Symbol: return create_lisp_object_keyword("symbol"); + } + return create_lisp_object_keyword("unknown"); }); defun("info", cLambda { try { @@ -862,10 +862,10 @@ void load_built_ins_into_environment(Environment* env) { print(arguments->value.pair->first); - Ast_Node* type = eval_expr( - create_ast_node_pair( - create_ast_node_symbol("type"), - create_ast_node_pair(arguments->value.pair->first, create_ast_node_nil())), + Lisp_Object* type = eval_expr( + create_lisp_object_pair( + create_lisp_object_symbol("type"), + create_lisp_object_pair(arguments->value.pair->first, create_lisp_object_nil())), env); if (type) { @@ -874,12 +874,12 @@ void load_built_ins_into_environment(Environment* env) { printf("\n\n"); // TODO(Felix): Maybe don't compare strings here?? Wtf - if (type->type == Ast_Node_Type::Keyword && + if (type->type == Lisp_Object_Type::Keyword && (string_equal(type->value.keyword->identifier, "lambda") || string_equal(type->value.keyword->identifier, "special-lambda") || string_equal(type->value.keyword->identifier, "macro"))) { - Ast_Node* fun = eval_expr(arguments->value.pair->first, env); + Lisp_Object* fun = eval_expr(arguments->value.pair->first, env); if (fun->value.function->docstring) printf("Docstring:\n==========\n%s\n\n", fun->value.function->docstring); @@ -924,7 +924,7 @@ void load_built_ins_into_environment(Environment* env) { delete_error(); } - return create_ast_node_nil(); + return create_lisp_object_nil(); }); defun("print", cLambda { try { @@ -935,7 +935,7 @@ void load_built_ins_into_environment(Environment* env) { } print(evaluated_arguments->value.pair->first); // printf("\n"); - return create_ast_node_nil(); + return create_lisp_object_nil(); }); defun("read", cLambda { try { @@ -947,14 +947,14 @@ void load_built_ins_into_environment(Environment* env) { } if (arguments_length == 1) { - Ast_Node* prompt = evaluated_arguments->value.pair->first; - /* if (prompt->type == Ast_Node_Type::String) */ + Lisp_Object* prompt = evaluated_arguments->value.pair->first; + /* if (prompt->type == Lisp_Object_Type::String) */ /* printf("%s", prompt->value.string->value); */ /* else */ print(evaluated_arguments->value.pair->first); } char* line = read_line(); - return create_ast_node_string(line, (int)strlen(line)); + return create_lisp_object_string(line, (int)strlen(line)); }); defun("exit", cLambda { try { @@ -966,8 +966,8 @@ void load_built_ins_into_environment(Environment* env) { } if (arguments_length == 1) { - Ast_Node* error_code = evaluated_arguments->value.pair->first; - if (error_code->type != Ast_Node_Type::Number) + Lisp_Object* error_code = evaluated_arguments->value.pair->first; + if (error_code->type != Lisp_Object_Type::Number) report_error(Error_Type::Type_Missmatch); exit((int)error_code->value.number->value); @@ -979,7 +979,7 @@ void load_built_ins_into_environment(Environment* env) { if_debug { __debugbreak(); } - return create_ast_node_nil(); + return create_lisp_object_nil(); }); defun("try", cLambda { try { @@ -990,9 +990,9 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* try_part = arguments->value.pair->first; - Ast_Node* catch_part = arguments->value.pair->rest->value.pair->first; - Ast_Node* result; + Lisp_Object* try_part = arguments->value.pair->first; + Lisp_Object* catch_part = arguments->value.pair->rest->value.pair->first; + Lisp_Object* result; result = eval_expr(try_part, env); if (error) { @@ -1011,10 +1011,10 @@ void load_built_ins_into_environment(Environment* env) { if (arguments_length != 1) report_error(Error_Type::Wrong_Number_Of_Arguments); - if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::String) + if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::String) report_error(Error_Type::Type_Missmatch); - Ast_Node* result; + Lisp_Object* result; try { result = built_in_load( evaluated_arguments->value.pair->first->value.string->value, env); @@ -1033,14 +1033,14 @@ void load_built_ins_into_environment(Environment* env) { 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) + if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil || + evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Keyword) { report_error(Error_Type::Type_Missmatch); } - Ast_Node* target = new(Ast_Node); - Ast_Node* source = evaluated_arguments->value.pair->first; + Lisp_Object* target = new(Lisp_Object); + Lisp_Object* source = evaluated_arguments->value.pair->first; *target = *source; return target; @@ -1068,13 +1068,13 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* source = evaluated_arguments->value.pair->first; + Lisp_Object* source = evaluated_arguments->value.pair->first; - if (source->type != Ast_Node_Type::String) { + if (source->type != Lisp_Object_Type::String) { report_error(Error_Type::Type_Missmatch); } - return create_ast_node_symbol(_strdup(source->value.string->value)); + return create_lisp_object_symbol(_strdup(source->value.string->value)); }); defun("symbol->string", cLambda { try { @@ -1085,14 +1085,14 @@ void load_built_ins_into_environment(Environment* env) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Ast_Node* source = evaluated_arguments->value.pair->first; + Lisp_Object* source = evaluated_arguments->value.pair->first; - if (source->type != Ast_Node_Type::Symbol) { + if (source->type != Lisp_Object_Type::Symbol) { report_error(Error_Type::Type_Missmatch); } // TODO(Felix): this is not really fast what we are doing here: - return create_ast_node_string(_strdup(source->value.symbol->identifier), (int)strlen(source->value.symbol->identifier)); + return create_lisp_object_string(_strdup(source->value.symbol->identifier), (int)strlen(source->value.symbol->identifier)); }); defun("concat-strings", cLambda { try { @@ -1105,11 +1105,11 @@ void load_built_ins_into_environment(Environment* env) { int resulting_string_len = 0; - Ast_Node* head = evaluated_arguments; + Lisp_Object* head = evaluated_arguments; - while (head->type == Ast_Node_Type::Pair) { + while (head->type == Lisp_Object_Type::Pair) { try { - assert_type(head->value.pair->first, Ast_Node_Type::String); + assert_type(head->value.pair->first, Lisp_Object_Type::String); } resulting_string_len += head->value.pair->first->value.string->length; @@ -1121,7 +1121,7 @@ void load_built_ins_into_environment(Environment* env) { char* resulting_string = (char*)malloc(resulting_string_len * sizeof(char)) + 1; int index_in_string = 0; - while (head->type == Ast_Node_Type::Pair) { + while (head->type == Lisp_Object_Type::Pair) { strcpy(resulting_string+index_in_string, head->value.pair->first->value.string->value); index_in_string += head->value.pair->first->value.string->length; head = head->value.pair->rest; @@ -1129,7 +1129,7 @@ void load_built_ins_into_environment(Environment* env) { resulting_string[index_in_string] = '\0'; - return create_ast_node_string(resulting_string, resulting_string_len); + return create_lisp_object_string(resulting_string, resulting_string_len); }); #undef report_error diff --git a/src/env.cpp b/src/env.cpp index e3205a2..49e3389 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -5,7 +5,7 @@ struct Environment { int next_index; // TODO(Felix): Use a hashmap here. char** keys; - Ast_Node** values; + Lisp_Object** values; }; Environment* create_child_environment(Environment* parent) { @@ -17,7 +17,7 @@ Environment* create_child_environment(Environment* 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->values = (Lisp_Object**)malloc(start_capacity * sizeof(Lisp_Object*)); return env; } @@ -26,7 +26,7 @@ Environment* create_empty_environment() { return create_child_environment(nullptr); } -void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { +void define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) { // NOTE(Felix): right now we are simply adding the symol at the // back of the list without checking if it already exists but are // also searching for thesymbol from the back, so we will find the @@ -35,7 +35,7 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { 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->values = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*)); } env->keys [env->next_index] = symbol->value.symbol->identifier; @@ -45,17 +45,17 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { void print_environment(Environment* env); -Ast_Node* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) { +Lisp_Object* 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]; return nullptr; } -Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) { +Lisp_Object* lookup_symbol(Lisp_Object* node, Environment* env) { // first check current environment Symbol* sym = node->value.symbol; - Ast_Node* result; + Lisp_Object* result; result = lookup_symbol_in_this_envt(sym, env); if (result) return result; @@ -68,10 +68,10 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) { } if (string_equal(sym->identifier, "nil")) { - return create_ast_node_nil(); + return create_lisp_object_nil(); } if (string_equal(sym->identifier, "t")) { - return create_ast_node_t(); + return create_lisp_object_t(); } create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation); diff --git a/src/eval.cpp b/src/eval.cpp index c0228df..dbbc1f7 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -1,16 +1,16 @@ -Ast_Node* eval_expr(Ast_Node*, Environment*); +Lisp_Object* eval_expr(Lisp_Object*, Environment*); -Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) { +Lisp_Object* apply_arguments_to_function(Lisp_Object* arguments, Function* function) { Environment* new_env = create_child_environment(function->parent_environment); // positional arguments for (int i = 0; i < function->positional_arguments->next_index; ++i) { - if (arguments->type == Ast_Node_Type::Pair) { - // TODO(Felix): here we create new ast_node_symbols from + if (arguments->type == Lisp_Object_Type::Pair) { + // TODO(Felix): here we create new lisp_object_symbols from // their identifiers but before we converted them to // strings from symbols... Wo maybe just use the symbols? define_symbol( - create_ast_node_symbol(function->positional_arguments->identifiers[i]), + create_lisp_object_symbol(function->positional_arguments->identifiers[i]), arguments->value.pair->first, new_env); } else { @@ -22,14 +22,14 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) { String_Array_List* read_in_keywords = create_String_array_list(16); - if (arguments->type == Ast_Node_Type::Nil) + if (arguments->type == Lisp_Object_Type::Nil) goto checks; // keyword arguments: use all given ones and keep track of the // added ones (array list), if end of parameters in encountered or // something that is not a keyword is encountered or a keyword // that is not recognized is encoutered, jump out of the loop. - while (arguments->value.pair->first->type == Ast_Node_Type::Keyword) { + while (arguments->value.pair->first->type == Lisp_Object_Type::Keyword) { // check if this one is even an accepted keyword bool accepted = false; for (int i = 0; i < function->keyword_arguments->next_index; ++i) { @@ -64,14 +64,14 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) { // okay so we found a keyword that has to be read in and was // not already read in, is there a next element to actually // set it to? - if (arguments->value.pair->rest->type != Ast_Node_Type::Pair) { + if (arguments->value.pair->rest->type != Lisp_Object_Type::Pair) { create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); return nullptr; } // 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), + create_lisp_object_symbol(arguments->value.pair->first->value.keyword->identifier), arguments->value.pair->rest->value.pair->first, new_env); @@ -80,7 +80,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) { // overstep both for next one arguments = arguments->value.pair->rest->value.pair->rest; - if (arguments->type == Ast_Node_Type::Nil) { + if (arguments->type == Lisp_Object_Type::Nil) { break; } } @@ -110,23 +110,23 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) { // to use it or if the user supplied his own if (!was_set) { define_symbol( - create_ast_node_symbol(defined_keyword), - copy_ast_node(function->keyword_arguments->values->data[i]), new_env); + create_lisp_object_symbol(defined_keyword), + copy_lisp_object(function->keyword_arguments->values->data[i]), new_env); } } } - if (arguments->type == Ast_Node_Type::Nil) { + if (arguments->type == Lisp_Object_Type::Nil) { if (function->rest_argument) { define_symbol( - create_ast_node_symbol(function->rest_argument), - create_ast_node_nil(), new_env); + create_lisp_object_symbol(function->rest_argument), + create_lisp_object_nil(), new_env); } } else { if (function->rest_argument) { define_symbol( - create_ast_node_symbol(function->rest_argument), + create_lisp_object_symbol(function->rest_argument), arguments, new_env); } else { // rest was not declared but additional arguments were found @@ -136,7 +136,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) { } - Ast_Node* result; + Lisp_Object* result; try { result = eval_expr(function->body, new_env); } @@ -162,15 +162,15 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) { positional_arguments, keyword_arguments and rest_argument and filling it in */ -void parse_argument_list(Ast_Node* arguments, Function* function) { +void parse_argument_list(Lisp_Object* arguments, Function* function) { // first init the fields function->positional_arguments = create_positional_argument_list(16); function->keyword_arguments = create_keyword_argument_list(16); function->rest_argument = nullptr; // okay let's try to read some positional arguments - while (arguments->type == Ast_Node_Type::Pair) { - if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) { + while (arguments->type == Lisp_Object_Type::Pair) { + if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword) { if (string_equal(arguments->value.pair->first->value.keyword->identifier, "keys") || string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) break; @@ -180,7 +180,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { } } - if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) { + if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } @@ -195,25 +195,25 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { // okay we are done with positional arguments, lets check for // keywords, - if (arguments->type != Ast_Node_Type::Pair) { - if (arguments->type != Ast_Node_Type::Nil) + if (arguments->type != Lisp_Object_Type::Pair) { + if (arguments->type != Lisp_Object_Type::Nil) create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } - if (arguments->value.pair->first->type == Ast_Node_Type::Keyword && + if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword && string_equal(arguments->value.pair->first->value.keyword->identifier, "keys")) { arguments = arguments->value.pair->rest; - if (arguments->type != Ast_Node_Type::Pair || - arguments->value.pair->first->type != Ast_Node_Type::Symbol) + if (arguments->type != Lisp_Object_Type::Pair || + arguments->value.pair->first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } - while (arguments->type == Ast_Node_Type::Pair) { - if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) { + while (arguments->type == Lisp_Object_Type::Pair) { + if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword) { if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) break; else { @@ -222,7 +222,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { } } - if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) { + if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } @@ -230,16 +230,16 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { // we found a symbol (arguments->value.pair->first) for // the keyword args! Let's check if the next arguement is // :defaults-to - Ast_Node* next = arguments->value.pair->rest; - if (next->type == Ast_Node_Type::Pair && - next->value.pair->first->type == Ast_Node_Type::Keyword && + Lisp_Object* next = arguments->value.pair->rest; + if (next->type == Lisp_Object_Type::Pair && + next->value.pair->first->type == Lisp_Object_Type::Keyword && string_equal(next->value.pair->first->value.keyword->identifier, "defaults-to")) { // check if there is a next argument too, otherwise it // would be an error next = next->value.pair->rest; - if (next->type == Ast_Node_Type::Pair) { + if (next->type == Lisp_Object_Type::Pair) { append_to_keyword_argument_list(function->keyword_arguments, arguments->value.pair->first->value.symbol->identifier, next->value.pair->first); @@ -261,24 +261,24 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { // Now we are also done with keyword arguments, lets check for // if there is a rest argument - if (arguments->type != Ast_Node_Type::Pair) { - if (arguments->type != Ast_Node_Type::Nil) + if (arguments->type != Lisp_Object_Type::Pair) { + if (arguments->type != Lisp_Object_Type::Nil) create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } - if (arguments->value.pair->first->type == Ast_Node_Type::Keyword && + if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword && string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) { arguments = arguments->value.pair->rest; - if (arguments->type != Ast_Node_Type::Pair || - arguments->value.pair->first->type != Ast_Node_Type::Symbol) + if (arguments->type != Lisp_Object_Type::Pair || + arguments->value.pair->first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } function->rest_argument = arguments->value.pair->first->value.symbol->identifier; - if (arguments->value.pair->rest->type != Ast_Node_Type::Nil) { + if (arguments->value.pair->rest->type != Lisp_Object_Type::Nil) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); } } else { @@ -288,20 +288,20 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { } -int list_length(Ast_Node* node) { - if (node->type == Ast_Node_Type::Nil) +int list_length(Lisp_Object* node) { + if (node->type == Lisp_Object_Type::Nil) return 0; - if (node->type != Ast_Node_Type::Pair) { + if (node->type != Lisp_Object_Type::Pair) { create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation); return 0; } int len = 0; - while (node->type == Ast_Node_Type::Pair) { + while (node->type == Lisp_Object_Type::Pair) { ++len; node = node->value.pair->rest; - if (node->type == Ast_Node_Type::Nil) + if (node->type == Lisp_Object_Type::Nil) return len; } @@ -309,9 +309,9 @@ int list_length(Ast_Node* node) { return 0; } -bool is_truthy (Ast_Node* expression, Environment* env); +bool is_truthy (Lisp_Object* expression, Environment* env); -Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) { +Lisp_Object* extract_keyword_value(char* keyword, Parsed_Arguments* args) { // NOTE(Felix): This will be a hashmap lookup later for (int i = 0; i < args->keyword_keys->next_index; ++i) { if (string_equal(args->keyword_keys->data[i]->value.keyword->identifier, keyword)) @@ -320,26 +320,26 @@ Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) { return nullptr; } -Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) { +Lisp_Object* eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) { int my_out_arguments_length = 0; - if (arguments->type == Ast_Node_Type::Nil) { + if (arguments->type == Lisp_Object_Type::Nil) { return arguments; } - Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr); - Ast_Node* evaluated_arguments_head = evaluated_arguments; - Ast_Node* current_head = arguments; - while (current_head->type == Ast_Node_Type::Pair) { + Lisp_Object* evaluated_arguments = create_lisp_object_pair(nullptr, nullptr); + Lisp_Object* evaluated_arguments_head = evaluated_arguments; + Lisp_Object* current_head = arguments; + while (current_head->type == Lisp_Object_Type::Pair) { try { evaluated_arguments_head->value.pair->first = eval_expr(current_head->value.pair->first, env); } current_head = current_head->value.pair->rest; - if (current_head->type == Ast_Node_Type::Pair) { - evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr); + if (current_head->type == Lisp_Object_Type::Pair) { + evaluated_arguments_head->value.pair->rest = create_lisp_object_pair(nullptr, nullptr); evaluated_arguments_head = evaluated_arguments_head->value.pair->rest; - } else if (current_head->type == Ast_Node_Type::Nil) { + } else if (current_head->type == Lisp_Object_Type::Nil) { evaluated_arguments_head->value.pair->rest = current_head; } else { create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); @@ -351,7 +351,7 @@ Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_argumen return evaluated_arguments; } -Ast_Node* eval_expr(Ast_Node* node, Environment* env) { +Lisp_Object* eval_expr(Lisp_Object* node, Environment* env) { #define report_error(_type) { \ create_error(_type, node->sourceCodeLocation); \ return nullptr; \ @@ -360,26 +360,26 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { if (error) return nullptr; - Ast_Node* ret = new(Ast_Node); + Lisp_Object* ret = new(Lisp_Object); switch (node->type) { - case Ast_Node_Type::T: - case Ast_Node_Type::Nil: + case Lisp_Object_Type::T: + case Lisp_Object_Type::Nil: return node; - case Ast_Node_Type::Symbol: { - Ast_Node* symbol; + case Lisp_Object_Type::Symbol: { + Lisp_Object* symbol; try { symbol = lookup_symbol(node, env); } return symbol; } - case Ast_Node_Type::Number: - case Ast_Node_Type::Keyword: - case Ast_Node_Type::String: + case Lisp_Object_Type::Number: + case Lisp_Object_Type::Keyword: + case Lisp_Object_Type::String: return node; - case Ast_Node_Type::Pair: { - Ast_Node* lispOperator; - if (node->value.pair->first->type != Ast_Node_Type::CFunction && - node->value.pair->first->type != Ast_Node_Type::Function) + case Lisp_Object_Type::Pair: { + Lisp_Object* lispOperator; + if (node->value.pair->first->type != Lisp_Object_Type::CFunction && + node->value.pair->first->type != Lisp_Object_Type::Function) { try { lispOperator = eval_expr(node->value.pair->first, env); @@ -388,17 +388,17 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { lispOperator = node->value.pair->first; } - Ast_Node* arguments = node->value.pair->rest; + Lisp_Object* arguments = node->value.pair->rest; int arguments_length; // check for c function - if (lispOperator->type == Ast_Node_Type::CFunction) { - Ast_Node* result = lispOperator->value.cfunction->function(arguments, env); + if (lispOperator->type == Lisp_Object_Type::CFunction) { + Lisp_Object* result = lispOperator->value.cfunction->function(arguments, env); return result; } // check for lisp function - if (lispOperator->type == Ast_Node_Type::Function) { + if (lispOperator->type == Lisp_Object_Type::Function) { // only for lambdas we evaluate the arguments before // apllying if (lispOperator->value.function->type == Function_Type::Lambda) { @@ -407,7 +407,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { } } - Ast_Node* result; + Lisp_Object* result; try { result = apply_arguments_to_function(arguments, lispOperator->value.function); } @@ -421,12 +421,12 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { #undef report_error } -bool is_truthy (Ast_Node* expression, Environment* env) { - Ast_Node* result; +bool is_truthy (Lisp_Object* expression, Environment* env) { + Lisp_Object* result; try { result = eval_expr(expression, env); } - if (result->type == Ast_Node_Type::Nil) + if (result->type == Lisp_Object_Type::Nil) return false; return true; diff --git a/src/io.cpp b/src/io.cpp index dd8eb41..342feb0 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -38,27 +38,27 @@ void panic(char* message) { exit(1); } -void print(Ast_Node* node) { +void print(Lisp_Object* node) { switch (node->type) { - case (Ast_Node_Type::Nil): { + case (Lisp_Object_Type::Nil): { printf("nil"); } break; - case (Ast_Node_Type::T): { + case (Lisp_Object_Type::T): { printf("t"); } break; - case (Ast_Node_Type::Number): { + case (Lisp_Object_Type::Number): { printf("%f", node->value.number->value); } break; - case (Ast_Node_Type::String): { + case (Lisp_Object_Type::String): { printf("\"%s\"", node->value.string->value); } break; - case (Ast_Node_Type::Symbol): { + case (Lisp_Object_Type::Symbol): { printf("%s", node->value.symbol->identifier); } break; - case (Ast_Node_Type::Keyword): { + case (Lisp_Object_Type::Keyword): { printf(":%s", node->value.keyword->identifier); } break; - case (Ast_Node_Type::Function): { + case (Lisp_Object_Type::Function): { if (node->value.function->type == Function_Type::Lambda) printf("[lambda]"); else if (node->value.function->type == Function_Type::Special_Lambda) @@ -68,11 +68,11 @@ void print(Ast_Node* node) { else assert(false); } break; - case (Ast_Node_Type::CFunction): { + case (Lisp_Object_Type::CFunction): { printf("[C-function]"); } break; - case (Ast_Node_Type::Pair): { - Ast_Node* head = node; + case (Lisp_Object_Type::Pair): { + Lisp_Object* head = node; printf("("); // NOTE(Felix): We cold do a while true here, however in case @@ -83,12 +83,12 @@ void print(Ast_Node* node) { head = head->value.pair->rest; if (!head) return; - if (head->type != Ast_Node_Type::Pair) + if (head->type != Lisp_Object_Type::Pair) break; printf(" "); } - if (head->type != Ast_Node_Type::Nil) { + if (head->type != Lisp_Object_Type::Nil) { printf(" . "); print(head); } @@ -99,27 +99,27 @@ void print(Ast_Node* node) { } // XXX(Felix): obv code dublicate -void fprint(FILE* f, Ast_Node* node) { +void fprint(FILE* f, Lisp_Object* node) { switch (node->type) { - case (Ast_Node_Type::Nil): { + case (Lisp_Object_Type::Nil): { fprintf(f, "nil"); } break; - case (Ast_Node_Type::T): { + case (Lisp_Object_Type::T): { fprintf(f, "t"); } break; - case (Ast_Node_Type::Number): { + case (Lisp_Object_Type::Number): { fprintf(f, "%f", node->value.number->value); } break; - case (Ast_Node_Type::String): { + case (Lisp_Object_Type::String): { fprintf(f, "\"%s\"", node->value.string->value); } break; - case (Ast_Node_Type::Symbol): { + case (Lisp_Object_Type::Symbol): { fprintf(f, "%s", node->value.symbol->identifier); } break; - case (Ast_Node_Type::Keyword): { + case (Lisp_Object_Type::Keyword): { fprintf(f, ":%s", node->value.keyword->identifier); } break; - case (Ast_Node_Type::Function): { + case (Lisp_Object_Type::Function): { if (node->value.function->type == Function_Type::Lambda) fprintf(f, "[lambda]"); else if (node->value.function->type == Function_Type::Special_Lambda) @@ -129,11 +129,11 @@ void fprint(FILE* f, Ast_Node* node) { else assert(false); } break; - case (Ast_Node_Type::CFunction): { + case (Lisp_Object_Type::CFunction): { fprintf(f, "[C-function]"); } break; - case (Ast_Node_Type::Pair): { - Ast_Node* head = node; + case (Lisp_Object_Type::Pair): { + Lisp_Object* head = node; fprintf(f, "("); // NOTE(Felix): We cold do a while true here, however in case @@ -144,12 +144,12 @@ void fprint(FILE* f, Ast_Node* node) { head = head->value.pair->rest; if (!head) return; - if (head->type != Ast_Node_Type::Pair) + if (head->type != Lisp_Object_Type::Pair) break; fprintf(f, " "); } - if (head->type != Ast_Node_Type::Nil) { + if (head->type != Lisp_Object_Type::Nil) { fprintf(f, " . "); print(head); } diff --git a/src/ast.cpp b/src/lisp_object.cpp similarity index 57% rename from src/ast.cpp rename to src/lisp_object.cpp index da317a5..07c755b 100644 --- a/src/ast.cpp +++ b/src/lisp_object.cpp @@ -1,8 +1,8 @@ -struct Ast_Node; +struct Lisp_Object; -define_array_list(Ast_Node*, Ast_Node); +define_array_list(Lisp_Object*, Lisp_Object); -enum struct Ast_Node_Type { +enum struct Lisp_Object_Type { Nil, T, Symbol, @@ -14,17 +14,17 @@ enum struct Ast_Node_Type { CFunction, }; -char* Ast_Node_Type_to_string(Ast_Node_Type type) { +char* Lisp_Object_Type_to_string(Lisp_Object_Type type) { switch (type) { - case(Ast_Node_Type::Nil): return "nil"; - case(Ast_Node_Type::T): return "t"; - case(Ast_Node_Type::Number): return "number"; - case(Ast_Node_Type::String): return "string"; - case(Ast_Node_Type::Symbol): return "symbol"; - case(Ast_Node_Type::Keyword): return "keyword"; - case(Ast_Node_Type::Function): return "function"; - case(Ast_Node_Type::CFunction): return "C-function"; - case(Ast_Node_Type::Pair): return "pair"; + case(Lisp_Object_Type::Nil): return "nil"; + case(Lisp_Object_Type::T): return "t"; + case(Lisp_Object_Type::Number): return "number"; + case(Lisp_Object_Type::String): return "string"; + case(Lisp_Object_Type::Symbol): return "symbol"; + case(Lisp_Object_Type::Keyword): return "keyword"; + case(Lisp_Object_Type::Function): return "function"; + case(Lisp_Object_Type::CFunction): return "C-function"; + case(Lisp_Object_Type::Pair): return "pair"; } return "unknown"; } @@ -47,12 +47,12 @@ struct String { }; struct Pair { - Ast_Node* first; - Ast_Node* rest; + Lisp_Object* first; + Lisp_Object* rest; }; struct Positional_Arguments { - // TODO(Felix) use Ast_Node_symbols here instead, so we don't have + // TODO(Felix) use Lisp_Object_symbols here instead, so we don't have // to convert them to strings and back to symbols char** identifiers; int next_index; @@ -63,7 +63,7 @@ struct Keyword_Arguments { char** identifiers; // NOTE(Felix): values[i] will be nullptr if no defalut value was // declared for key identifiers[i] - Ast_Node_Array_List* values; + Lisp_Object_Array_List* values; int next_index; int length; }; @@ -88,7 +88,7 @@ void append_to_positional_argument_list(Positional_Arguments* args, char* identi Keyword_Arguments* create_keyword_argument_list(int initial_capacity) { Keyword_Arguments* ret = new(Keyword_Arguments); ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*)); - ret->values = create_Ast_Node_array_list(initial_capacity); + ret->values = create_Lisp_Object_array_list(initial_capacity); ret->next_index = 0; ret->length = initial_capacity; return ret; @@ -96,7 +96,7 @@ Keyword_Arguments* create_keyword_argument_list(int initial_capacity) { void append_to_keyword_argument_list(Keyword_Arguments* args, char* identifier, - struct Ast_Node* default_value) + struct Lisp_Object* default_value) { if (args->next_index == args->length) { args->length *= 2; @@ -104,7 +104,7 @@ void append_to_keyword_argument_list(Keyword_Arguments* args, } args->identifiers[args->next_index++] = identifier; - append_to_Ast_Node_array_list(args->values, default_value); + append_to_Lisp_Object_array_list(args->values, default_value); } struct Environment; @@ -122,18 +122,18 @@ struct Function { Keyword_Arguments* keyword_arguments; // rest_argument will be nullptr if no rest argument is declared char* rest_argument; - Ast_Node* body; // implicit prog + Lisp_Object* body; // implicit prog Environment* parent_environment; // we are doing closures now!! }; struct CFunction { - std::function function; + std::function function; }; -struct Ast_Node { +struct Lisp_Object { Source_Code_Location* sourceCodeLocation; - Ast_Node_Type type; + Lisp_Object_Type type; union { Symbol* symbol; Keyword* keyword; @@ -146,85 +146,85 @@ struct Ast_Node { }; struct Parsed_Arguments { - Ast_Node_Array_List* positional_arguments; + Lisp_Object_Array_List* positional_arguments; // TODO(Felix): Really use hashmap (keyword[sting] -> - // value[Ast_Node*]) here - Ast_Node_Array_List* keyword_keys; - Ast_Node_Array_List* keyword_values; + // value[Lisp_Object*]) here + Lisp_Object_Array_List* keyword_keys; + Lisp_Object_Array_List* keyword_values; }; -Ast_Node* create_ast_node() { - Ast_Node* node = new(Ast_Node); +Lisp_Object* create_lisp_object() { + Lisp_Object* node = new(Lisp_Object); node->sourceCodeLocation = nullptr; return node; } -Ast_Node* create_ast_node_nil() { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::Nil; +Lisp_Object* create_lisp_object_nil() { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::Nil; node->value.pair = nullptr; return node; } -Ast_Node* create_ast_node_t() { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::T; +Lisp_Object* create_lisp_object_t() { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::T; node->value.pair = nullptr; return node; } -Ast_Node* create_ast_node_number(double number) { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::Number; +Lisp_Object* create_lisp_object_number(double number) { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::Number; node->value.number = new(Number); node->value.number->value = number; return node; } -Ast_Node* create_ast_node_string(char* str, int length) { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::String; +Lisp_Object* create_lisp_object_string(char* str, int length) { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::String; node->value.string = new(String); node->value.string->value = str; node->value.string->length = length; return node; } -Ast_Node* create_ast_node_symbol(char* identifier) { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::Symbol; +Lisp_Object* create_lisp_object_symbol(char* identifier) { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::Symbol; node->value.symbol = new(Symbol); node->value.symbol->identifier = identifier; return node; } -Ast_Node* create_ast_node_keyword(char* keyword) { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::Keyword; +Lisp_Object* create_lisp_object_keyword(char* keyword) { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::Keyword; node->value.keyword = new(Keyword); node->value.keyword->identifier = keyword; return node; } -Ast_Node* create_ast_node_cfunction(std::function function) { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::CFunction; +Lisp_Object* create_lisp_object_cfunction(std::function function) { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::CFunction; node->value.cfunction = new(CFunction); node->value.cfunction->function = function; return node; } -Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) { - Ast_Node* node = create_ast_node(); - node->type = Ast_Node_Type::Pair; +Lisp_Object* create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) { + Lisp_Object* node = create_lisp_object(); + node->type = Lisp_Object_Type::Pair; node->value.pair = new(Pair); node->value.pair->first = first; node->value.pair->rest = rest; return node; } -Ast_Node* copy_ast_node(Ast_Node* n) { - Ast_Node* target = create_ast_node(); +Lisp_Object* copy_lisp_object(Lisp_Object* n) { + Lisp_Object* target = create_lisp_object(); *target = *n; return target; } diff --git a/src/main.cpp b/src/main.cpp index 62a65b9..026a714 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,7 @@ #include #include "./helpers.cpp" -#include "./ast.cpp" +#include "./lisp_object.cpp" #include "./error.cpp" #include "./io.cpp" #include "./assert.cpp" @@ -19,7 +19,7 @@ #include "./eval.cpp" #include "./testing.cpp" -Ast_Node* interprete_file (char* file_name) { +Lisp_Object* interprete_file (char* file_name) { char* file_content = read_entire_file(file_name); if (!file_content) { create_error(Error_Type::Unknown_Error, nullptr); @@ -34,12 +34,12 @@ Ast_Node* interprete_file (char* file_name) { built_in_load("pre.slime", env); } - Ast_Node_Array_List* program; + Lisp_Object_Array_List* program; try { program = Parser::parse_program(file_name, file_content); } - Ast_Node* result = create_ast_node_nil(); + Lisp_Object* result = create_lisp_object_nil(); for (int i = 0; i < program->next_index; ++i) { try { result = eval_expr(program->data[i], env); @@ -64,7 +64,7 @@ int interprete_stdin () { delete_error(); } - Ast_Node* parsed, * evaluated; + Lisp_Object* parsed, * evaluated; while (true) { printf(">"); line = read_expression(); diff --git a/src/parse.cpp b/src/parse.cpp index 814234b..011e902 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -1,8 +1,8 @@ // forward decls -- start void load_built_ins_into_environment(Environment*); -Ast_Node* eval_expr(Ast_Node*, Environment*); -void parse_argument_list(Ast_Node*, Function*); -int list_length(Ast_Node*); +Lisp_Object* eval_expr(Lisp_Object*, Environment*); +void parse_argument_list(Lisp_Object*, Function*); +int list_length(Lisp_Object*); // forward decls -- end @@ -109,34 +109,34 @@ namespace Parser { return atom; } - Ast_Node* parse_number(char* text, int* index_in_text) { + Lisp_Object* parse_number(char* text, int* index_in_text) { double number; char* str_number = read_atom(text, index_in_text); sscanf(str_number, "%lf", &number); - Ast_Node* ret = create_ast_node_number(number); + Lisp_Object* ret = create_lisp_object_number(number); inject_scl(ret); return ret; } - Ast_Node* parse_keyword(char* text, int* index_in_text) { + Lisp_Object* parse_keyword(char* text, int* index_in_text) { // we are now on the colon ++(*index_in_text); ++parser_col; char* str_keyword = read_atom(text, index_in_text); - Ast_Node* ret = create_ast_node_keyword(str_keyword); + Lisp_Object* ret = create_lisp_object_keyword(str_keyword); inject_scl(ret); return ret; } - Ast_Node* parse_symbol(char* text, int* index_in_text) { + Lisp_Object* parse_symbol(char* text, int* index_in_text) { // we are now at the first char of the symbol char* str_symbol = read_atom(text, index_in_text); - Ast_Node* ret = create_ast_node_symbol(str_symbol); + Lisp_Object* ret = create_lisp_object_symbol(str_symbol); inject_scl(ret); return ret; } - Ast_Node* parse_string(char* text, int* index_in_text) { + Lisp_Object* parse_string(char* text, int* index_in_text) { // the first character is the '"' ++(*index_in_text); ++parser_col; @@ -146,7 +146,7 @@ namespace Parser { if (text[*index_in_text] == '"') { char* str = new(char); *str = '\0'; - Ast_Node* ret = create_ast_node_string(str, 0); + Lisp_Object* ret = create_lisp_object_string(str, 0); inject_scl(ret); // plus one because we want to go after the quotes @@ -187,12 +187,12 @@ namespace Parser { *index_in_text += string_length +1; // plus one because we want to // go after the quotes - Ast_Node* ret = create_ast_node_string(string, string_length); + Lisp_Object* ret = create_lisp_object_string(string, string_length); inject_scl(ret); return ret; } - Ast_Node* parse_atom(char* text, int* index_in_text) { + Lisp_Object* parse_atom(char* text, int* index_in_text) { // numbers if ((text[*index_in_text] <= 57 && // if number text[*index_in_text] >= 48) @@ -220,7 +220,7 @@ namespace Parser { return parse_symbol(text, index_in_text); } - Ast_Node* parse_expression(char* text, int* index_in_text) { + Lisp_Object* parse_expression(char* text, int* index_in_text) { // if it is quoted if (text[*index_in_text] == '\'' || @@ -230,7 +230,7 @@ namespace Parser { char quoteType = text[*index_in_text]; ++(*index_in_text); ++parser_col; - Ast_Node* result; + Lisp_Object* result; if (text[*index_in_text] == '(' || text[*index_in_text] == '\'' || text[*index_in_text] == '`' || @@ -246,17 +246,17 @@ namespace Parser { } if (quoteType == '\'') - return create_ast_node_pair( - create_ast_node_symbol("quote"), - create_ast_node_pair(result, create_ast_node_nil())); + return create_lisp_object_pair( + create_lisp_object_symbol("quote"), + create_lisp_object_pair(result, create_lisp_object_nil())); else if (quoteType == '`') - return create_ast_node_pair( - create_ast_node_symbol("quasiquote"), - create_ast_node_pair(result, create_ast_node_nil())); + return create_lisp_object_pair( + create_lisp_object_symbol("quasiquote"), + create_lisp_object_pair(result, create_lisp_object_nil())); // it has to be an unquote - return create_ast_node_pair( - create_ast_node_symbol("unquote"), - create_ast_node_pair(result, create_ast_node_nil())); + return create_lisp_object_pair( + create_lisp_object_symbol("unquote"), + create_lisp_object_pair(result, create_lisp_object_nil())); } @@ -271,14 +271,14 @@ namespace Parser { if (text[(*index_in_text)] == ')') { ++(*index_in_text); ++parser_col; - return create_ast_node_nil(); + return create_lisp_object_nil(); } // okay there is something - Ast_Node* head = new(Ast_Node); - head->type = Ast_Node_Type::Pair; + Lisp_Object* head = new(Lisp_Object); + head->type = Lisp_Object_Type::Pair; head->value.pair = new(Pair); - Ast_Node* expression = head; + Lisp_Object* expression = head; while (true) { if (text[*index_in_text] == '(' || @@ -303,7 +303,7 @@ namespace Parser { if (text[(*index_in_text)] == ')') { - head->value.pair->rest = create_ast_node_nil(); + head->value.pair->rest = create_lisp_object_nil(); ++parser_col; ++(*index_in_text); break; @@ -325,16 +325,16 @@ namespace Parser { ++(*index_in_text); break; } else { - head->value.pair->rest = create_ast_node_pair(nullptr, nullptr); + head->value.pair->rest = create_lisp_object_pair(nullptr, nullptr); head = head->value.pair->rest; } } // check if we have to create or delete or run macros - if (expression->value.pair->first->type == Ast_Node_Type::Symbol) { + if (expression->value.pair->first->type == Lisp_Object_Type::Symbol) { if (string_equal("define-syntax", expression->value.pair->first->value.symbol->identifier)) { // create a new macro - Ast_Node* arguments = expression->value.pair->rest; + Lisp_Object* arguments = expression->value.pair->rest; int arguments_length; // HACK(Felix): almost code duplicate from @@ -349,13 +349,13 @@ namespace Parser { return nullptr; } - if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) { + if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Type_Missmatch, expression->sourceCodeLocation); return nullptr; } // extract the name - Ast_Node* symbol_for_macro = arguments->value.pair->first; + Lisp_Object* symbol_for_macro = arguments->value.pair->first; arguments = arguments->value.pair->rest; Function* function = new(Function); @@ -363,9 +363,9 @@ namespace Parser { function->type = Function_Type::Macro; // if parameters were specified - if (arguments->value.pair->first->type != Ast_Node_Type::Nil) { + if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) { try { - assert_type(arguments->value.pair->first, Ast_Node_Type::Pair); + assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair); } try { parse_argument_list(arguments->value.pair->first, function); @@ -378,7 +378,7 @@ namespace Parser { arguments = arguments->value.pair->rest; // if there is a docstring, use it - if (arguments->value.pair->first->type == Ast_Node_Type::String) { + if (arguments->value.pair->first->type == Lisp_Object_Type::String) { function->docstring = arguments->value.pair->first->value.string->value; arguments = arguments->value.pair->rest; } else { @@ -387,17 +387,17 @@ namespace Parser { // we are now in the function body, just wrap it in an // implicit prog - function->body = create_ast_node_pair( - create_ast_node_symbol("prog"), + function->body = create_lisp_object_pair( + create_lisp_object_symbol("prog"), arguments); - Ast_Node* macro = new(Ast_Node); - macro->type = Ast_Node_Type::Function; + Lisp_Object* macro = new(Lisp_Object); + macro->type = Lisp_Object_Type::Function; macro->value.function = function; define_symbol(symbol_for_macro, macro, environment_for_macros); // print_environment(environment_for_macros); - return create_ast_node_nil(); + return create_lisp_object_nil(); } else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) { /* --- deleting an existing macro --- */ @@ -420,7 +420,7 @@ namespace Parser { for (int i = 0; i < environment_for_macros->next_index; ++i) { if (string_equal(expression->value.pair->first->value.symbol->identifier, environment_for_macros->keys[i]) && - environment_for_macros->values[i]->type == Ast_Node_Type::Function && + environment_for_macros->values[i]->type == Lisp_Object_Type::Function && environment_for_macros->values[i]->value.function->type == Function_Type::Macro) { try { @@ -444,16 +444,16 @@ namespace Parser { return expression; } - Ast_Node* parse_single_expression(char* text) { + Lisp_Object* parse_single_expression(char* text) { parser_file = "stdin"; parser_line = 1; parser_col = 1; int index_in_text = 0; - Ast_Node* result; + Lisp_Object* result; eat_until_code(text, &index_in_text); if (text[(index_in_text)] == '\0') - return create_ast_node_nil(); + return create_lisp_object_nil(); if (text[index_in_text] == '(' || text[index_in_text] == '\'' || text[index_in_text] == '`' || @@ -474,7 +474,7 @@ namespace Parser { return nullptr; } - void write_expanded_file(char* file_name, Ast_Node_Array_List* program) { + void write_expanded_file(char* file_name, Lisp_Object_Array_List* program) { char* ext = ".expanded"; char* newName = (char*)calloc(4 + strlen(file_name), sizeof(char)); strcpy(newName, file_name); @@ -488,7 +488,7 @@ namespace Parser { for (int i = 0; i < program->next_index; ++i) { // a macro will parse as nil for now, so we skip those - if (program->data[i]->type == Ast_Node_Type::Nil) + if (program->data[i]->type == Lisp_Object_Type::Nil) continue; fprint(f, program->data[i]); fprintf(f, "\n\n"); @@ -497,24 +497,24 @@ namespace Parser { fclose(f); } - Ast_Node_Array_List* parse_program(char* file_name, char* text) { + Lisp_Object_Array_List* parse_program(char* file_name, char* text) { parser_file = (char*)malloc(strlen(file_name) * sizeof(char) + 1); strcpy(parser_file, file_name); parser_line = 1; parser_col = 0; - Ast_Node_Array_List* program = create_Ast_Node_array_list(16); + Lisp_Object_Array_List* program = create_Lisp_Object_array_list(16); int index_in_text = 0; while (text[index_in_text] != '\0') { switch (text[index_in_text]) { case '(': { - Ast_Node* parsed; + Lisp_Object* parsed; try { parsed = parse_expression(text, &index_in_text); } - append_to_Ast_Node_array_list(program, parsed); + append_to_Lisp_Object_array_list(program, parsed); } break; case ';': case ' ': diff --git a/src/testing.cpp b/src/testing.cpp index 1e86a10..c876486 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -57,8 +57,8 @@ #define assert_equal_type(node, _type) \ if (node->type != _type) { \ print_assert_equal_fail( \ - Ast_Node_Type_to_string(node->type), \ - Ast_Node_Type_to_string(_type), char*, "%s"); \ + Lisp_Object_Type_to_string(node->type), \ + Lisp_Object_Type_to_string(_type), char*, "%s"); \ return fail; \ } \ @@ -87,33 +87,33 @@ testresult test_eval_operands() { char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))"; - Ast_Node* operands = Parser::parse_single_expression(operands_string); + Lisp_Object* operands = Parser::parse_single_expression(operands_string); int operands_length; operands = eval_arguments(operands, create_built_ins_environment(), &operands_length); assert_no_error(error); assert_equal_int(list_length(operands), 4); - assert_equal_type(operands, Ast_Node_Type::Pair); - assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number); + assert_equal_type(operands, Lisp_Object_Type::Pair); + assert_equal_type(operands->value.pair->first, Lisp_Object_Type::Number); assert_equal_double(operands->value.pair->first->value.number->value, 1); operands = operands->value.pair->rest; - assert_equal_type(operands, Ast_Node_Type::Pair); - assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number); + assert_equal_type(operands, Lisp_Object_Type::Pair); + assert_equal_type(operands->value.pair->first, Lisp_Object_Type::Number); assert_equal_double(operands->value.pair->first->value.number->value, 3); operands = operands->value.pair->rest; - assert_equal_type(operands, Ast_Node_Type::Pair); - assert_equal_type(operands->value.pair->first, Ast_Node_Type::String); + assert_equal_type(operands, Lisp_Object_Type::Pair); + assert_equal_type(operands->value.pair->first, Lisp_Object_Type::String); assert_equal_string(operands->value.pair->first->value.string->value, "okay"); operands = operands->value.pair->rest; - assert_equal_type(operands, Ast_Node_Type::Pair); - assert_equal_type(operands->value.pair->first, Ast_Node_Type::Keyword); + assert_equal_type(operands, Lisp_Object_Type::Pair); + assert_equal_type(operands->value.pair->first, Lisp_Object_Type::Keyword); assert_equal_string(operands->value.pair->first->value.keyword->identifier, "haha"); return pass; @@ -128,48 +128,48 @@ testresult test_parse_atom() { "sym +"; // symbols // test numbers - Ast_Node* result = Parser::parse_atom(string, &index_in_text); + Lisp_Object* result = Parser::parse_atom(string, &index_in_text); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, 123); ++index_in_text; result = Parser::parse_atom(string, &index_in_text); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, -1.23e-2); // test strings ++index_in_text; result = Parser::parse_atom(string, &index_in_text); - assert_equal_type(result, Ast_Node_Type::String); + assert_equal_type(result, Lisp_Object_Type::String); assert_equal_string(result->value.string->value, "asd"); // test keywords ++index_in_text; result = Parser::parse_atom(string, &index_in_text); - assert_equal_type(result, Ast_Node_Type::Keyword); + assert_equal_type(result, Lisp_Object_Type::Keyword); assert_equal_string(result->value.keyword->identifier, "key1"); ++index_in_text; result = Parser::parse_atom(string, &index_in_text); - assert_equal_type(result, Ast_Node_Type::Keyword); + assert_equal_type(result, Lisp_Object_Type::Keyword); assert_equal_string(result->value.keyword->identifier, "key:2"); // test symbols ++index_in_text; result = Parser::parse_atom(string, &index_in_text); - assert_equal_type(result, Ast_Node_Type::Symbol); + assert_equal_type(result, Lisp_Object_Type::Symbol); assert_equal_string(result->value.symbol->identifier, "sym"); ++index_in_text; result = Parser::parse_atom(string, &index_in_text); - assert_equal_type(result, Ast_Node_Type::Symbol); + assert_equal_type(result, Lisp_Object_Type::Symbol); assert_equal_string(result->value.symbol->identifier, "+"); return pass; @@ -179,28 +179,28 @@ testresult test_parse_expression() { int index_in_text = 0; char string[] = "(fun + 12)"; - Ast_Node* result = Parser::parse_expression(string, &index_in_text); + Lisp_Object* result = Parser::parse_expression(string, &index_in_text); assert_no_error(error); - assert_equal_type(result, Ast_Node_Type::Pair); - assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); + assert_equal_type(result, Lisp_Object_Type::Pair); + assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol); assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); result = result->value.pair->rest; - assert_equal_type(result, Ast_Node_Type::Pair); - assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); + assert_equal_type(result, Lisp_Object_Type::Pair); + assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol); assert_equal_string(result->value.pair->first->value.symbol->identifier, "+"); result = result->value.pair->rest; - assert_equal_type(result, Ast_Node_Type::Pair); - assert_equal_type(result->value.pair->first, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Pair); + assert_equal_type(result->value.pair->first, Lisp_Object_Type::Number); assert_equal_double(result->value.pair->first->value.number->value, 12); result = result->value.pair->rest; - assert_equal_type(result, Ast_Node_Type::Nil); + assert_equal_type(result, Lisp_Object_Type::Nil); char string2[] = "(define fun (lambda (x) (+ 5 (* x x ))))"; index_in_text = 0; @@ -208,21 +208,21 @@ testresult test_parse_expression() { result = Parser::parse_expression(string2, &index_in_text); assert_no_error(error); - assert_equal_type(result, Ast_Node_Type::Pair); - assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); + assert_equal_type(result, Lisp_Object_Type::Pair); + assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol); assert_equal_string(result->value.pair->first->value.symbol->identifier, "define"); result = result->value.pair->rest; - assert_equal_type(result, Ast_Node_Type::Pair); - assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); + assert_equal_type(result, Lisp_Object_Type::Pair); + assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol); assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); result = result->value.pair->rest; - assert_equal_type(result, Ast_Node_Type::Pair); - assert_equal_type(result->value.pair->first, Ast_Node_Type::Pair); - assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_Type::Symbol); + assert_equal_type(result, Lisp_Object_Type::Pair); + assert_equal_type(result->value.pair->first, Lisp_Object_Type::Pair); + assert_equal_type(result->value.pair->first->value.pair->first, Lisp_Object_Type::Symbol); assert_equal_string(result->value.pair->first->value.pair->first->value.symbol->identifier, "lambda"); result = result->value.pair->rest; @@ -232,12 +232,12 @@ testresult test_parse_expression() { testresult test_built_in_add() { char exp_string[] = "(+ 10 4)"; - Ast_Node* expression = Parser::parse_single_expression(exp_string); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, 14); return pass; @@ -245,12 +245,12 @@ testresult test_built_in_add() { testresult test_built_in_substract() { char exp_string[] = "(- 10 4)"; - Ast_Node* expression = Parser::parse_single_expression(exp_string); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, 6); return pass; @@ -259,12 +259,12 @@ testresult test_built_in_substract() { testresult test_built_in_multiply() { char exp_string[] = "(* 10 4)"; - Ast_Node* expression = Parser::parse_single_expression(exp_string); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, 40); return pass; @@ -273,12 +273,12 @@ testresult test_built_in_multiply() { testresult test_built_in_divide() { char exp_string[] = "(/ 20 4)"; - Ast_Node* expression = Parser::parse_single_expression(exp_string); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); assert_null(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, 5); return pass; @@ -287,12 +287,12 @@ testresult test_built_in_divide() { testresult test_built_in_if() { char exp_string1[] = "(if 1 4 5)"; - Ast_Node* expression = Parser::parse_single_expression(exp_string1); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string1); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, 4); char exp_string2[] = "(if () 4 5)"; @@ -301,7 +301,7 @@ testresult test_built_in_if() { assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Number); + assert_equal_type(result, Lisp_Object_Type::Number); assert_equal_double(result->value.number->value, 5); return pass; @@ -309,12 +309,12 @@ testresult test_built_in_if() { testresult test_built_in_and() { char exp_string1[] = "(and 1 \"asd\" 4)"; - Ast_Node* expression = Parser::parse_single_expression(exp_string1); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string1); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::T); + assert_equal_type(result, Lisp_Object_Type::T); // a false case char exp_string2[] = "(and () \"asd\" 4)"; @@ -323,19 +323,19 @@ testresult test_built_in_and() { assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Nil); + assert_equal_type(result, Lisp_Object_Type::Nil); return pass; } testresult test_built_in_or() { char exp_string1[] = "(or \"asd\" nil)"; - Ast_Node* expression = Parser::parse_single_expression(exp_string1); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string1); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::T); + assert_equal_type(result, Lisp_Object_Type::T); // a false case char exp_string2[] = "(or () ())"; @@ -344,7 +344,7 @@ testresult test_built_in_or() { assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Nil); + assert_equal_type(result, Lisp_Object_Type::Nil); return pass; } @@ -352,13 +352,13 @@ testresult test_built_in_or() { testresult test_built_in_not() { char exp_string1[] = "(not ())"; - Ast_Node* expression = Parser::parse_single_expression(exp_string1); - Ast_Node* result = eval_expr(expression, create_built_ins_environment()); + Lisp_Object* expression = Parser::parse_single_expression(exp_string1); + Lisp_Object* result = eval_expr(expression, create_built_ins_environment()); // a true case assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::T); + assert_equal_type(result, Lisp_Object_Type::T); // a false case char exp_string2[] = "(not \"asd xD\")"; @@ -367,7 +367,7 @@ testresult test_built_in_not() { assert_no_error(error); assert_not_null(result); - assert_equal_type(result, Ast_Node_Type::Nil); + assert_equal_type(result, Lisp_Object_Type::Nil); return pass; }