From d6ecda99f6df43db6a61b64aee4b5ce577c5d4e6 Mon Sep 17 00:00:00 2001 From: FelixBrendel Date: Fri, 15 Mar 2019 15:37:35 +0100 Subject: [PATCH] I think I did Lisp_Object SSO --- bin/tests/lexical_scope.slime.expanded | 2 +- src/built_ins.cpp | 408 ++++++++++++------------- src/env.cpp | 16 +- src/eval.cpp | 106 +++---- src/io.cpp | 115 ++----- src/memory.cpp | 33 +- src/parse.cpp | 89 +++--- src/structs.cpp | 17 +- src/testing.cpp | 90 +++--- todo.org | 11 + 10 files changed, 386 insertions(+), 501 deletions(-) diff --git a/bin/tests/lexical_scope.slime.expanded b/bin/tests/lexical_scope.slime.expanded index aa6a62c..ec91232 100644 --- a/bin/tests/lexical_scope.slime.expanded +++ b/bin/tests/lexical_scope.slime.expanded @@ -1,4 +1,4 @@ -(define (make-counter) (let ((var 0.000000)) (lambda nil (mutate var (+ 1.000000 var)) var))) +(define (make-counter) (let ((var 0.000000)) (lambda () (mutate var (+ 1.000000 var)) var))) (define counter1 (make-counter)) diff --git a/src/built_ins.cpp b/src/built_ins.cpp index 0f094b6..7fead60 100644 --- a/src/built_ins.cpp +++ b/src/built_ins.cpp @@ -16,24 +16,20 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { return false; case Lisp_Object_Type::Keyword: return string_equal( - n1->value.keyword->identifier, - n2->value.keyword->identifier); + n1->value.identifier, + n2->value.identifier); case Lisp_Object_Type::T: case Lisp_Object_Type::Nil: return true; case Lisp_Object_Type::Number: - return - n1->value.number->value == - n2->value.number->value; + return n1->value.number == n2->value.number; case Lisp_Object_Type::Pair: create_error(Error_Type::Not_Yet_Implemented, n1->sourceCodeLocation); return false; case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string); case Lisp_Object_Type::Symbol: - return string_equal( - n1->value.symbol->identifier, - n2->value.symbol->identifier); + return string_equal(n1->value.identifier, n2->value.identifier); } // we should never reach here @@ -80,43 +76,49 @@ proc load_built_ins_into_environment(Environment* env) -> void { env); }; - proc parse_lambda_starting_from_args = [&](Lisp_Object* arguments, Environment* env) -> Lisp_Object* { - Function* function = new(Function); - function->parent_environment = env; - function->type = Function_Type::Lambda; + proc parse_lambda_starting_from_args = [&](Lisp_Object* arguments, Environment* env, bool is_special = false) -> Lisp_Object* { + // Function* function = new(Function); + Lisp_Object* ret = Memory::create_lisp_object(); + ret->type = Lisp_Object_Type::Function; + + ret->value.function.parent_environment = env; + + if (is_special) + ret->value.function.type = Function_Type::Special_Lambda; + else + ret->value.function.type = Function_Type::Lambda; // if parameters were specified - if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) { + if (arguments->value.pair.first->type != Lisp_Object_Type::Nil) { try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair); } try { - parse_argument_list(arguments->value.pair->first, function); + parse_argument_list(arguments->value.pair.first, &ret->value.function); } } else { - function->positional_arguments = create_positional_argument_list(1); - function->keyword_arguments = create_keyword_argument_list(1); - function->rest_argument = nullptr; + ret->value.function.positional_arguments = create_positional_argument_list(1); + ret->value.function.keyword_arguments = create_keyword_argument_list(1); + ret->value.function.rest_argument = nullptr; } - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; // if there is a docstring, use it - if (arguments->value.pair->first->type == Lisp_Object_Type::String) { - function->docstring = arguments->value.pair->first->value.string; - arguments = arguments->value.pair->rest; + if (arguments->value.pair.first->type == Lisp_Object_Type::String) { + ret->value.function.docstring = arguments->value.pair.first->value.string; + arguments = arguments->value.pair.rest; } else { - function->docstring = nullptr; + ret->value.function.docstring = nullptr; } // we are now in the function body, just wrap it in an // implicit prog - function->body = Memory::create_lisp_object_pair( + ret->value.function.body = Memory::create_lisp_object_pair( Memory::get_or_create_lisp_object_symbol("prog"), arguments); - Lisp_Object* ret = Memory::create_lisp_object(); - ret->type = Lisp_Object_Type::Function; - ret->value.function = function; + + // ret->value.function = function; return ret; }; @@ -129,12 +131,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments->type == Lisp_Object_Type::Nil) return Memory::t; - Lisp_Object* first = arguments->value.pair->first; + Lisp_Object* first = arguments->value.pair.first; while (arguments->type == Lisp_Object_Type::Pair) { - if (!lisp_object_equal(arguments->value.pair->first, first)) + if (!lisp_object_equal(arguments->value.pair.first, first)) return Memory::nil; - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; } return Memory::t; @@ -149,14 +151,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - if (arguments->value.pair->first->value.number->value >= last_number) + if (arguments->value.pair.first->value.number >= last_number) return Memory::nil; - last_number = arguments->value.pair->first->value.number->value; - arguments = arguments->value.pair->rest; + last_number = arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::t; @@ -171,14 +173,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - if (arguments->value.pair->first->value.number->value > last_number) + if (arguments->value.pair.first->value.number > last_number) return Memory::nil; - last_number = arguments->value.pair->first->value.number->value; - arguments = arguments->value.pair->rest; + last_number = arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::t; @@ -193,14 +195,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - if (arguments->value.pair->first->value.number->value <= last_number) + if (arguments->value.pair.first->value.number <= last_number) return Memory::nil; - last_number = arguments->value.pair->first->value.number->value; - arguments = arguments->value.pair->rest; + last_number = arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::t; @@ -215,14 +217,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - if (arguments->value.pair->first->value.number->value < last_number) + if (arguments->value.pair.first->value.number < last_number) return Memory::nil; - last_number = arguments->value.pair->first->value.number->value; - arguments = arguments->value.pair->rest; + last_number = arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::t; @@ -236,10 +238,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { double sum = 0; while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_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; + sum += arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::create_lisp_object_number(sum); @@ -251,18 +253,18 @@ proc load_built_ins_into_environment(Environment* env) -> void { } try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - double difference = arguments->value.pair->first->value.number->value; + double difference = arguments->value.pair.first->value.number; - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_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; + difference -= arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::create_lisp_object_number(difference); }); @@ -273,18 +275,18 @@ proc load_built_ins_into_environment(Environment* env) -> void { } try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - double product = arguments->value.pair->first->value.number->value; + double product = arguments->value.pair.first->value.number; - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_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; + product *= arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::create_lisp_object_number(product); }); @@ -295,18 +297,18 @@ proc load_built_ins_into_environment(Environment* env) -> void { } try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - double quotient = arguments->value.pair->first->value.number->value; + double quotient = arguments->value.pair.first->value.number; - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; while (arguments->type == Lisp_Object_Type::Pair) { try { - assert_type(arguments->value.pair->first, Lisp_Object_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; + quotient /= arguments->value.pair.first->value.number; + arguments = arguments->value.pair.rest; } return Memory::create_lisp_object_number(quotient); }); @@ -322,18 +324,18 @@ proc load_built_ins_into_environment(Environment* env) -> void { } try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - double base = arguments->value.pair->first->value.number->value; + double base = arguments->value.pair.first->value.number; - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Number); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); } - double exponent = arguments->value.pair->first->value.number->value; + double exponent = arguments->value.pair.first->value.number; return Memory::create_lisp_object_number(pow(base, exponent)); }); @@ -348,7 +350,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - if (is_truthy(arguments->value.pair->first, env)) + if (is_truthy(arguments->value.pair.first, env)) return Memory::t; report_error(Error_Type::Assertion_Error); @@ -363,7 +365,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* symbol = arguments->value.pair->first; + Lisp_Object* symbol = arguments->value.pair.first; Lisp_Object* value; if (symbol->type == Lisp_Object_Type::Pair) { @@ -386,15 +388,15 @@ proc load_built_ins_into_environment(Environment* env) -> void { f(3) x */ - Lisp_Object* real_symbol = symbol->value.pair->first; + Lisp_Object* real_symbol = symbol->value.pair.first; try { assert_type(real_symbol, Lisp_Object_Type::Symbol); } Lisp_Object* fake_lambda = Memory::create_lisp_object_pair( - symbol ->value.pair->rest, - arguments->value.pair->rest); + symbol ->value.pair.rest, + arguments->value.pair.rest); value = parse_lambda_starting_from_args(fake_lambda, env); symbol = real_symbol; @@ -406,7 +408,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Type_Missmatch); } - value = arguments->value.pair->rest->value.pair->first; + value = arguments->value.pair.rest->value.pair.first; try { value = eval_expr(value, env); } @@ -425,7 +427,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { // report_error(Error_Type::Wrong_Number_Of_Arguments); // } - // Lisp_Object* symbol = arguments->value.pair->first; + // Lisp_Object* symbol = arguments->value.pair.first; // if (symbol->type == Lisp_Object_Type::Pair) { // try { @@ -442,7 +444,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { // } - // Lisp_Object* value = arguments->value.pair->rest->value.pair->first; + // Lisp_Object* value = arguments->value.pair.rest->value.pair.first; // try { // value = eval_expr(value, env); // } @@ -459,14 +461,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 2) report_error(Error_Type::Wrong_Number_Of_Arguments); - if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil || - evaluated_arguments->value.pair->first->type == Lisp_Object_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); } - Lisp_Object* target = evaluated_arguments->value.pair->first; - Lisp_Object* 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; @@ -480,9 +482,9 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* condition = arguments->value.pair->first; - Lisp_Object* then_part = arguments->value.pair->rest; - Lisp_Object* 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 { @@ -493,11 +495,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (truthy) try{ - result = eval_expr(then_part->value.pair->first, env); + result = eval_expr(then_part->value.pair.first, env); } else if (arguments_length == 3) try { - result = eval_expr(else_part->value.pair->first, env); + result = eval_expr(else_part->value.pair.first, env); } else return Memory::nil; return result; @@ -511,7 +513,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - return arguments->value.pair->first; + return arguments->value.pair.first; }); defun("quasiquote", cLambda { try { @@ -535,12 +537,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { return Memory::copy_lisp_object(expr); // it is a pair! - Lisp_Object* originalPair = expr->value.pair->first; + Lisp_Object* originalPair = expr->value.pair.first; if (originalPair->type == Lisp_Object_Type::Symbol && - string_equal(originalPair->value.symbol->identifier, "unquote")) + string_equal(originalPair->value.identifier, "unquote")) { // eval replace the stuff - return eval_expr(expr->value.pair->rest->value.pair->first, env); + return eval_expr(expr->value.pair.rest->value.pair.first, env); } // it is a list but not starting with the symbol @@ -556,22 +558,22 @@ proc load_built_ins_into_environment(Environment* env) -> void { Lisp_Object* newPairHead = newPair; Lisp_Object* head = expr; while (head->type == Lisp_Object_Type::Pair) { - newPairHead->value.pair->first = unquoteSomeExpressions(head->value.pair->first); + newPairHead->value.pair.first = unquoteSomeExpressions(head->value.pair.first); - if (head->value.pair->rest->type != Lisp_Object_Type::Pair) + if (head->value.pair.rest->type != Lisp_Object_Type::Pair) break; - newPairHead->value.pair->rest = Memory::create_lisp_object_pair(nullptr, nullptr); + newPairHead->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr); - newPairHead = newPairHead->value.pair->rest; - head = head->value.pair->rest; + newPairHead = newPairHead->value.pair.rest; + head = head->value.pair.rest; } - newPairHead->value.pair->rest = Memory::nil; + newPairHead->value.pair.rest = Memory::nil; return newPair; }; - Lisp_Object* ret = arguments->value.pair->first; + Lisp_Object* ret = arguments->value.pair.first; Lisp_Object* head = ret; ret = unquoteSomeExpressions(ret); @@ -584,9 +586,9 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Ill_Formed_List); } try { - result &= is_truthy(arguments->value.pair->first, env); + result &= is_truthy(arguments->value.pair.first, env); } - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; if (!result) return Memory::nil; } @@ -600,9 +602,9 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Ill_Formed_List); } try { - result |= is_truthy(arguments->value.pair->first, env); + result |= is_truthy(arguments->value.pair.first, env); } - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; if (result) return Memory::t; } @@ -619,7 +621,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { } bool truthy; try { - truthy = is_truthy(arguments->value.pair->first, env); + truthy = is_truthy(arguments->value.pair.first, env); } if (truthy) return Memory::nil; @@ -633,9 +635,9 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length < 2) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* condition_part = arguments->value.pair->first; + Lisp_Object* condition_part = arguments->value.pair.first; Lisp_Object* condition; - Lisp_Object* then_part = arguments->value.pair->rest; + Lisp_Object* then_part = arguments->value.pair.rest; Lisp_Object* result = Memory::nil; while (true) { @@ -646,7 +648,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { break; } try { - result = eval_expr(then_part->value.pair->first, env); + result = eval_expr(then_part->value.pair.first, env); } } return result; @@ -662,7 +664,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); Environment* let_env = Memory::create_child_environment(env); - Lisp_Object* bindings = arguments->value.pair->first; + Lisp_Object* bindings = arguments->value.pair.first; while (true) { if (bindings->type == Lisp_Object_Type::Nil) { break; @@ -670,29 +672,29 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Ill_Formed_Arguments); } - Lisp_Object* sym = bindings->value.pair->first->value.pair->first; + Lisp_Object* sym = bindings->value.pair.first->value.pair.first; if(sym->type != Lisp_Object_Type::Symbol) { report_error(Error_Type::Ill_Formed_Arguments); } - Lisp_Object* rest_sym = bindings->value.pair->first->value.pair->rest; + 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 != Lisp_Object_Type::Nil) { + if (rest_sym->value.pair.rest->type != Lisp_Object_Type::Nil) { report_error(Error_Type::Ill_Formed_Arguments); } - Lisp_Object* value = eval_expr(rest_sym->value.pair->first, env); + Lisp_Object* value = eval_expr(rest_sym->value.pair.first, env); // NOTE(Felix): We have to copy the value here because // if the let body modifies the value, it would bake // in... bad bad... define_symbol(sym, Memory::copy_lisp_object(value), let_env); - bindings = bindings->value.pair->rest; + bindings = bindings->value.pair.rest; } - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; Lisp_Object* evaluated_arguments; try { @@ -707,10 +709,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { // 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 == Lisp_Object_Type::Pair) { - evaluated_arguments = evaluated_arguments->value.pair->rest; + while (evaluated_arguments->value.pair.rest->type == Lisp_Object_Type::Pair) { + evaluated_arguments = evaluated_arguments->value.pair.rest; } - return evaluated_arguments->value.pair->first; + return evaluated_arguments->value.pair.first; }); defun("lambda", cLambda { /* TODO(Felix): first one crashes @@ -742,43 +744,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length == 0) report_error(Error_Type::Wrong_Number_Of_Arguments); - Function* function = new(Function); - function->parent_environment = env; - function->type = Function_Type::Special_Lambda; - - // if parameters were specified - if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) { - try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair); - } - try { - parse_argument_list(arguments->value.pair->first, function); - } - } else { - function->positional_arguments = create_positional_argument_list(1); - function->keyword_arguments = create_keyword_argument_list(1); - function->rest_argument = nullptr; - } - - arguments = arguments->value.pair->rest; - // if there is a docstring, use it - if (arguments->value.pair->first->type == Lisp_Object_Type::String) { - function->docstring = arguments->value.pair->first->value.string; - arguments = arguments->value.pair->rest; - } else { - function->docstring = nullptr; - } + Lisp_Object* function = parse_lambda_starting_from_args(arguments, env, true); + // parse lambda starting from arguments - // we are now in the function body, just wrap it in an - // implicit prog - function->body = Memory::create_lisp_object_pair( - Memory::get_or_create_lisp_object_symbol("prog"), - arguments); - Lisp_Object* ret = Memory::create_lisp_object(); - ret->type = Lisp_Object_Type::Function; - ret->value.function = function; - return ret; + return function; }); defun("eval", cLambda { try { @@ -789,7 +759,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { } Lisp_Object* result; try { - result = eval_expr(evaluated_arguments->value.pair->first, env); + result = eval_expr(evaluated_arguments->value.pair.first, env); } return result; }); @@ -808,10 +778,10 @@ proc load_built_ins_into_environment(Environment* env) -> void { // 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 == Lisp_Object_Type::Pair) { - evaluated_arguments = evaluated_arguments->value.pair->rest; + while (evaluated_arguments->value.pair.rest->type == Lisp_Object_Type::Pair) { + evaluated_arguments = evaluated_arguments->value.pair.rest; } - return evaluated_arguments->value.pair->first; + return evaluated_arguments->value.pair.first; }); defun("list", cLambda { try { @@ -827,7 +797,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 2) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - return Memory::create_lisp_object_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first); + return Memory::create_lisp_object_pair(evaluated_arguments->value.pair.first, evaluated_arguments->value.pair.rest->value.pair.first); }); defun("first", cLambda { try { @@ -836,12 +806,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) + if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil) return Memory::nil; - if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) + 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; + return evaluated_arguments->value.pair.first->value.pair.first; }); defun("rest", cLambda { try { @@ -850,12 +820,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) + if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil) return Memory::nil; - if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) + 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; + return evaluated_arguments->value.pair.first->value.pair.rest; }); defun("set-type", cLambda { try { @@ -865,14 +835,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* object = evaluated_arguments->value.pair->first; - Lisp_Object* type = evaluated_arguments->value.pair->rest->value.pair->first; + Lisp_Object* object = evaluated_arguments->value.pair.first; + Lisp_Object* type = evaluated_arguments->value.pair.rest->value.pair.first; try { assert_type(type, Lisp_Object_Type::Keyword); } - evaluated_arguments->value.pair->first->userType = type; + evaluated_arguments->value.pair.first->userType = type; return type; }); defun("delete-type", cLambda { @@ -882,7 +852,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - evaluated_arguments->value.pair->first->userType = nullptr; + evaluated_arguments->value.pair.first->userType = nullptr; return Memory::t; }); defun("type", cLambda { @@ -893,15 +863,15 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - if (evaluated_arguments->value.pair->first->userType) { - return evaluated_arguments->value.pair->first->userType; + if (evaluated_arguments->value.pair.first->userType) { + return evaluated_arguments->value.pair.first->userType; } - Lisp_Object_Type type = evaluated_arguments->value.pair->first->type; + Lisp_Object_Type type = evaluated_arguments->value.pair.first->type; switch (type) { case Lisp_Object_Type::CFunction: return Memory::get_or_create_lisp_object_keyword("cfunction"); case Lisp_Object_Type::Function: { - Function* fun = evaluated_arguments->value.pair->first->value.function; + Function* fun = &evaluated_arguments->value.pair.first->value.function; if (fun->type == Function_Type::Lambda) return Memory::get_or_create_lisp_object_keyword("lambda"); else if (fun->type == Function_Type::Special_Lambda) @@ -929,12 +899,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - print(arguments->value.pair->first); + print(arguments->value.pair.first); Lisp_Object* type = eval_expr( Memory::create_lisp_object_pair( Memory::get_or_create_lisp_object_symbol("type"), - Memory::create_lisp_object_pair(arguments->value.pair->first, Memory::nil)), + Memory::create_lisp_object_pair(arguments->value.pair.first, Memory::nil)), env); if (type) { @@ -944,52 +914,52 @@ proc load_built_ins_into_environment(Environment* env) -> void { // TODO(Felix): Maybe don't compare strings here?? Wtf 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"))) + (string_equal(type->value.identifier, "lambda") || + string_equal(type->value.identifier, "special-lambda") || + string_equal(type->value.identifier, "macro"))) { - Lisp_Object* 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", Memory::get_c_str(fun->value.function->docstring)); + if (fun->value.function.docstring) + printf("Docstring:\n==========\n%s\n\n", Memory::get_c_str(fun->value.function.docstring)); else printf("No docstring avaliable\n"); printf("Arguments:\n==========\n"); printf("Postitional: {"); - if (fun->value.function->positional_arguments->next_index != 0) { + if (fun->value.function.positional_arguments->next_index != 0) { printf("%s", - Memory::get_c_str(fun->value.function->positional_arguments->identifiers[0])); - for (int i = 1; i < fun->value.function->positional_arguments->next_index; ++i) { + Memory::get_c_str(fun->value.function.positional_arguments->identifiers[0])); + for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) { printf(", %s", - Memory::get_c_str(fun->value.function->positional_arguments->identifiers[i])); + Memory::get_c_str(fun->value.function.positional_arguments->identifiers[i])); } } printf("}\n"); printf("Keyword: {"); - if (fun->value.function->keyword_arguments->next_index != 0) { + if (fun->value.function.keyword_arguments->next_index != 0) { printf("%s", - Memory::get_c_str(fun->value.function->keyword_arguments->identifiers[0])); - if (fun->value.function->keyword_arguments->values->data[0]) { + Memory::get_c_str(fun->value.function.keyword_arguments->identifiers[0])); + if (fun->value.function.keyword_arguments->values->data[0]) { printf(" ("); - print(fun->value.function->keyword_arguments->values->data[0]); + print(fun->value.function.keyword_arguments->values->data[0]); printf(")"); } - for (int i = 1; i < fun->value.function->keyword_arguments->next_index; ++i) { + for (int i = 1; i < fun->value.function.keyword_arguments->next_index; ++i) { printf(", %s", - Memory::get_c_str(fun->value.function->keyword_arguments->identifiers[i])); - if (fun->value.function->keyword_arguments->values->data[i]) { + Memory::get_c_str(fun->value.function.keyword_arguments->identifiers[i])); + if (fun->value.function.keyword_arguments->values->data[i]) { printf(" ("); - print(fun->value.function->keyword_arguments->values->data[i]); + print(fun->value.function.keyword_arguments->values->data[i]); printf(")"); } } } printf("}\n"); printf("Rest: {"); - if (fun->value.function->rest_argument) + if (fun->value.function.rest_argument) printf("%s", - Memory::get_c_str(fun->value.function->rest_argument)); + Memory::get_c_str(fun->value.function.rest_argument)); printf("}\n"); } @@ -1007,12 +977,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Function) { + if (evaluated_arguments->value.pair.first->type != Lisp_Object_Type::Function) { report_error(Error_Type::Type_Missmatch); } puts("body:\n"); - print(evaluated_arguments->value.pair->first->value.function->body); + print(evaluated_arguments->value.pair.first->value.function.body); puts("\n"); return Memory::nil; @@ -1024,7 +994,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 1) { report_error(Error_Type::Wrong_Number_Of_Arguments); } - print(evaluated_arguments->value.pair->first); + print(evaluated_arguments->value.pair.first); // printf("\n"); return Memory::nil; }); @@ -1038,11 +1008,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { } if (arguments_length == 1) { - Lisp_Object* prompt = evaluated_arguments->value.pair->first; + 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); + print(evaluated_arguments->value.pair.first); } char* line = read_line(); String* strLine = Memory::create_string(line); @@ -1059,11 +1029,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { } if (arguments_length == 1) { - Lisp_Object* error_code = evaluated_arguments->value.pair->first; + 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); + exit((int)error_code->value.number); } exit(0); }); @@ -1085,8 +1055,8 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* try_part = arguments->value.pair->first; - Lisp_Object* catch_part = arguments->value.pair->rest->value.pair->first; + 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); @@ -1106,12 +1076,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 1) report_error(Error_Type::Wrong_Number_Of_Arguments); - if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::String) + if (evaluated_arguments->value.pair.first->type != Lisp_Object_Type::String) report_error(Error_Type::Type_Missmatch); Lisp_Object* result; try { - result = built_in_load(evaluated_arguments->value.pair->first->value.string, env); + result = built_in_load(evaluated_arguments->value.pair.first->value.string, env); } return result; @@ -1127,14 +1097,14 @@ proc load_built_ins_into_environment(Environment* env) -> void { if (arguments_length != 1) report_error(Error_Type::Wrong_Number_Of_Arguments); - if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil || - evaluated_arguments->value.pair->first->type == Lisp_Object_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); } Lisp_Object* target = Memory::create_lisp_object(); - Lisp_Object* source = evaluated_arguments->value.pair->first; + Lisp_Object* source = evaluated_arguments->value.pair.first; *target = *source; return target; @@ -1157,13 +1127,13 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* source = evaluated_arguments->value.pair->first; + Lisp_Object* source = evaluated_arguments->value.pair.first; if (source->type != Lisp_Object_Type::Symbol) { report_error(Error_Type::Type_Missmatch); } - return Memory::get_or_create_lisp_object_keyword(source->value.symbol->identifier); + return Memory::get_or_create_lisp_object_keyword(source->value.identifier); }); defun("string->symbol", cLambda { @@ -1178,7 +1148,7 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* source = evaluated_arguments->value.pair->first; + Lisp_Object* source = evaluated_arguments->value.pair.first; if (source->type != Lisp_Object_Type::String) { report_error(Error_Type::Type_Missmatch); @@ -1195,12 +1165,12 @@ proc load_built_ins_into_environment(Environment* env) -> void { report_error(Error_Type::Wrong_Number_Of_Arguments); } - Lisp_Object* source = evaluated_arguments->value.pair->first; + Lisp_Object* source = evaluated_arguments->value.pair.first; if (source->type != Lisp_Object_Type::Symbol) { report_error(Error_Type::Type_Missmatch); } - return Memory::create_lisp_object_string(Memory::duplicate_string(source->value.symbol->identifier)); + return Memory::create_lisp_object_string(Memory::duplicate_string(source->value.identifier)); }); defun("concat-strings", cLambda { try { @@ -1217,11 +1187,11 @@ proc load_built_ins_into_environment(Environment* env) -> void { while (head->type == Lisp_Object_Type::Pair) { try { - assert_type(head->value.pair->first, Lisp_Object_Type::String); + assert_type(head->value.pair.first, Lisp_Object_Type::String); } - resulting_string_len += head->value.pair->first->value.string->length; + resulting_string_len += head->value.pair.first->value.string->length; - head = head->value.pair->rest; + head = head->value.pair.rest; } head = evaluated_arguments; @@ -1231,9 +1201,9 @@ proc load_built_ins_into_environment(Environment* env) -> void { while (head->type == Lisp_Object_Type::Pair) { strcpy((&resulting_string->data)+index_in_string, - Memory::get_c_str(head->value.pair->first->value.string)); - index_in_string += head->value.pair->first->value.string->length; - head = head->value.pair->rest; + Memory::get_c_str(head->value.pair.first->value.string)); + index_in_string += head->value.pair.first->value.string->length; + head = head->value.pair.rest; } return Memory::create_lisp_object_string(resulting_string); diff --git a/src/env.cpp b/src/env.cpp index 56d1989..1d5ad12 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -11,23 +11,23 @@ proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) -> env->values = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*)); } - env->keys [env->next_index] = Memory::get_c_str(symbol->value.symbol->identifier); + env->keys [env->next_index] = Memory::get_c_str(symbol->value.identifier); env->values[env->next_index] = value; ++env->next_index; } -proc lookup_symbol_in_this_envt(Symbol* sym, Environment* env) -> Lisp_Object* { +proc lookup_symbol_in_this_envt(String* identifier, Environment* env) -> Lisp_Object* { for (int i = env->next_index - 1; i >= 0; --i) - if (string_equal(env->keys[i], Memory::get_c_str(sym->identifier))) + if (string_equal(env->keys[i], Memory::get_c_str(identifier))) return env->values[i]; return nullptr; } proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { // first check current environment - Symbol* sym = node->value.symbol; + String* identifier = node->value.identifier; Lisp_Object* result; - result = lookup_symbol_in_this_envt(sym, env); + result = lookup_symbol_in_this_envt(identifier, env); if (result) return result; @@ -38,15 +38,15 @@ proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* { return result; } - if (string_equal(Memory::get_c_str(sym->identifier), "nil")) { + if (string_equal(Memory::get_c_str(identifier), "nil")) { return Memory::nil; } - if (string_equal(Memory::get_c_str(sym->identifier), "t")) { + if (string_equal(Memory::get_c_str(identifier), "t")) { return Memory::t; } + printf("%s\n", Memory::get_c_str(identifier)); create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation); - printf("%s\n", Memory::get_c_str(sym->identifier)); return nullptr; } diff --git a/src/eval.cpp b/src/eval.cpp index 4dd580c..4d80d02 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -11,13 +11,13 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> // strings from symbols... Wo maybe just use the symbols? define_symbol( Memory::get_or_create_lisp_object_symbol(function->positional_arguments->identifiers[i]), - arguments->value.pair->first, new_env); + arguments->value.pair.first, new_env); } else { create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); return nullptr; } - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; } String_Array_List* read_in_keywords = create_String_array_list(); @@ -29,12 +29,12 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> // 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 == Lisp_Object_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) { if (string_equal( - arguments->value.pair->first->value.keyword->identifier, + arguments->value.pair.first->value.identifier, function->keyword_arguments->identifiers[i])) { accepted = true; @@ -54,7 +54,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> // check if it was already read in for (int i = 0; i < read_in_keywords->next_index; ++i) { if (string_equal( - arguments->value.pair->first->value.keyword->identifier, + arguments->value.pair.first->value.identifier, read_in_keywords->data[i])) { // TODO(Felix): if we are actually done with all the @@ -69,21 +69,21 @@ proc apply_arguments_to_function(Lisp_Object* 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 != Lisp_Object_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( - Memory::get_or_create_lisp_object_symbol(arguments->value.pair->first->value.keyword->identifier), - arguments->value.pair->rest->value.pair->first, + Memory::get_or_create_lisp_object_symbol(arguments->value.pair.first->value.identifier), + arguments->value.pair.rest->value.pair.first, new_env); - append_to_array_list(read_in_keywords, arguments->value.pair->first->value.keyword->identifier); + append_to_array_list(read_in_keywords, arguments->value.pair.first->value.identifier); // overstep both for next one - arguments = arguments->value.pair->rest->value.pair->rest; + arguments = arguments->value.pair.rest->value.pair.rest; if (arguments->type == Lisp_Object_Type::Nil) { break; @@ -175,9 +175,9 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { // okay let's try to read some positional arguments 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")) + if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword) { + if (string_equal(arguments->value.pair.first->value.identifier, "keys") || + string_equal(arguments->value.pair.first->value.identifier, "rest")) break; else { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); @@ -185,7 +185,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { } } - if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) { + if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } @@ -193,9 +193,9 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { // okay wow we found an actual symbol append_to_positional_argument_list( function->positional_arguments, - arguments->value.pair->first->value.symbol->identifier); + arguments->value.pair.first->value.identifier); - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; } // okay we are done with positional arguments, lets check for @@ -206,20 +206,20 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { return; } - if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword && - string_equal(arguments->value.pair->first->value.keyword->identifier, "keys")) + if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword && + string_equal(arguments->value.pair.first->value.identifier, "keys")) { - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; if (arguments->type != Lisp_Object_Type::Pair || - arguments->value.pair->first->type != Lisp_Object_Type::Symbol) + arguments->value.pair.first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } 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")) + if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword) { + if (string_equal(arguments->value.pair.first->value.identifier, "rest")) break; else { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); @@ -227,7 +227,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { } } - if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) { + if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; } @@ -235,20 +235,20 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { // we found a symbol (arguments->value.pair->first) for // the keyword args! Let's check if the next arguement is // :defaults-to - Lisp_Object* next = arguments->value.pair->rest; + 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, + next->value.pair.first->type == Lisp_Object_Type::Keyword && + string_equal(next->value.pair.first->value.identifier, "defaults-to")) { // check if there is a next argument too, otherwise it // would be an error - next = next->value.pair->rest; + next = next->value.pair.rest; 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); - arguments = next->value.pair->rest; + arguments->value.pair.first->value.identifier, + next->value.pair.first); + arguments = next->value.pair.rest; } else { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); return; @@ -256,7 +256,7 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { } else { // No :defaults-to, so just add it to the list append_to_keyword_argument_list(function->keyword_arguments, - arguments->value.pair->first->value.symbol->identifier, + arguments->value.pair.first->value.identifier, nullptr); arguments = next; } @@ -272,18 +272,18 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void { return; } - if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword && - string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) + if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword && + string_equal(arguments->value.pair.first->value.identifier, "rest")) { - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; if (arguments->type != Lisp_Object_Type::Pair || - arguments->value.pair->first->type != Lisp_Object_Type::Symbol) + 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 != Lisp_Object_Type::Nil) { + function->rest_argument = arguments->value.pair.first->value.identifier; + if (arguments->value.pair.rest->type != Lisp_Object_Type::Nil) { create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); } } else { @@ -305,7 +305,7 @@ proc list_length(Lisp_Object* node) -> int { int len = 0; while (node->type == Lisp_Object_Type::Pair) { ++len; - node = node->value.pair->rest; + node = node->value.pair.rest; if (node->type == Lisp_Object_Type::Nil) return len; } @@ -317,7 +317,7 @@ proc list_length(Lisp_Object* node) -> int { proc extract_keyword_value(char* keyword, Parsed_Arguments* args) -> Lisp_Object* { // 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)) + if (string_equal(args->keyword_keys->data[i]->value.identifier, keyword)) return args->keyword_values->data[i]; } return nullptr; @@ -335,17 +335,17 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_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); + evaluated_arguments_head->value.pair.first = + eval_expr(current_head->value.pair.first, env); } - evaluated_arguments_head->value.pair->first->sourceCodeLocation = current_head->value.pair->first->sourceCodeLocation; - current_head = current_head->value.pair->rest; + evaluated_arguments_head->value.pair.first->sourceCodeLocation = current_head->value.pair.first->sourceCodeLocation; + current_head = current_head->value.pair.rest; if (current_head->type == Lisp_Object_Type::Pair) { - evaluated_arguments_head->value.pair->rest = Memory::create_lisp_object_pair(nullptr, nullptr); - evaluated_arguments_head = evaluated_arguments_head->value.pair->rest; + evaluated_arguments_head->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr); + evaluated_arguments_head = evaluated_arguments_head->value.pair.rest; } else if (current_head->type == Lisp_Object_Type::Nil) { - evaluated_arguments_head->value.pair->rest = current_head; + evaluated_arguments_head->value.pair.rest = current_head; } else { create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); return nullptr; @@ -375,17 +375,17 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* { current_source_code_location = node->sourceCodeLocation; Lisp_Object* lispOperator; - if (node->value.pair->first->type != Lisp_Object_Type::CFunction && - node->value.pair->first->type != Lisp_Object_Type::Function) + 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); + lispOperator = eval_expr(node->value.pair.first, env); } } else { - lispOperator = node->value.pair->first; + lispOperator = node->value.pair.first; } - Lisp_Object* arguments = node->value.pair->rest; + Lisp_Object* arguments = node->value.pair.rest; int arguments_length; // check for c function @@ -398,7 +398,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* { if (lispOperator->type == Lisp_Object_Type::Function) { // only for lambdas we evaluate the arguments before // apllying - if (lispOperator->value.function->type == Function_Type::Lambda) { + if (lispOperator->value.function.type == Function_Type::Lambda) { try { arguments = eval_arguments(arguments, env, &arguments_length); } @@ -406,7 +406,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* { Lisp_Object* result; try { - result = apply_arguments_to_function(arguments, lispOperator->value.function); + result = apply_arguments_to_function(arguments, &lispOperator->value.function); } return result; } diff --git a/src/io.cpp b/src/io.cpp index eb6ca38..e518f0e 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -227,129 +227,58 @@ proc panic(char* message) -> void { exit(1); } -proc print(Lisp_Object* node, bool print_quotes = false) -> void { +proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) -> void { + switch (node->type) { - case (Lisp_Object_Type::Nil): { - printf("()"); - } break; - case (Lisp_Object_Type::T): { - printf("t"); - } break; - case (Lisp_Object_Type::Number): { - printf("%f", node->value.number->value); - } break; + case (Lisp_Object_Type::Nil): fprintf(file, "()"); break; + case (Lisp_Object_Type::T): fprintf(file, "t"); break; + case (Lisp_Object_Type::Number): fprintf(file, "%f", node->value.number); break; + case (Lisp_Object_Type::Symbol): fprintf(file, "%s", Memory::get_c_str(node->value.identifier)); break; + case (Lisp_Object_Type::Keyword): fprintf(file, ":%s", Memory::get_c_str(node->value.identifier)); break; + case (Lisp_Object_Type::CFunction): fprintf(file, "[C-function]"); break; case (Lisp_Object_Type::String): { if (print_quotes) - printf("\"%s\"", Memory::get_c_str(node->value.string)); + fprintf(file, "\"%s\"", Memory::get_c_str(node->value.string)); else - printf("%s", Memory::get_c_str(node->value.string)); - } break; - case (Lisp_Object_Type::Symbol): { - printf("%s", Memory::get_c_str(node->value.symbol->identifier)); - } break; - case (Lisp_Object_Type::Keyword): { - printf(":%s", Memory::get_c_str(node->value.keyword->identifier)); + fprintf(file, "%s", Memory::get_c_str(node->value.string)); } break; 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) - printf("[special-lambda]"); - else if (node->value.function->type == Function_Type::Macro) - printf("[macro]"); + if (node->value.function.type == Function_Type::Lambda) + fprintf(file, "[lambda]"); + else if (node->value.function.type == Function_Type::Special_Lambda) + fprintf(file, "[special-lambda]"); + else if (node->value.function.type == Function_Type::Macro) + fprintf(file, "[macro]"); else assert(false); } break; - case (Lisp_Object_Type::CFunction): { - printf("[C-function]"); - } break; case (Lisp_Object_Type::Pair): { Lisp_Object* head = node; - printf("("); + fprintf(file, "("); // NOTE(Felix): We cold do a while true here, however in case // we want to print a broken list (for logging the error) we // should do mo checks. while (head) { - print(head->value.pair->first); - head = head->value.pair->rest; + print(head->value.pair.first, print_quotes, file); + head = head->value.pair.rest; if (!head) return; if (head->type != Lisp_Object_Type::Pair) break; - printf(" "); + fprintf(file, " "); } if (head->type != Lisp_Object_Type::Nil) { - printf(" . "); + fprintf(file, " . "); print(head); } - printf(")"); + fprintf(file, ")"); } break; } } -// XXX(Felix): obv code dublicate -proc fprint(FILE* f, Lisp_Object* node) -> void { - switch (node->type) { - case (Lisp_Object_Type::Nil): { - fprintf(f, "nil"); - } break; - case (Lisp_Object_Type::T): { - fprintf(f, "t"); - } break; - case (Lisp_Object_Type::Number): { - fprintf(f, "%f", node->value.number->value); - } break; - case (Lisp_Object_Type::String): { - fprintf(f, "\"%s\"", Memory::get_c_str(node->value.string)); - } break; - case (Lisp_Object_Type::Symbol): { - fprintf(f, "%s", Memory::get_c_str(node->value.symbol->identifier)); - } break; - case (Lisp_Object_Type::Keyword): { - fprintf(f, ":%s", Memory::get_c_str(node->value.keyword->identifier)); - } break; - 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) - fprintf(f, "[special-lambda]"); - else if (node->value.function->type == Function_Type::Macro) - fprintf(f, "[macro]"); - else - assert(false); - } break; - case (Lisp_Object_Type::CFunction): { - fprintf(f, "[C-function]"); - } break; - case (Lisp_Object_Type::Pair): { - Lisp_Object* head = node; - fprintf(f, "("); - - // NOTE(Felix): We cold do a while true here, however in case - // we want to print a broken list (for logging the error) we - // should do mo checks. - while (head) { - fprint(f, head->value.pair->first); - head = head->value.pair->rest; - if (!head) - return; - if (head->type != Lisp_Object_Type::Pair) - break; - fprintf(f, " "); - } - - if (head->type != Lisp_Object_Type::Nil) { - fprintf(f, " . "); - print(head); - } - - fprintf(f, ")"); - } break; - } -} proc print_error_location() -> void { if (error->location) { diff --git a/src/memory.cpp b/src/memory.cpp index 1eda2ed..deac8ae 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -114,33 +114,16 @@ namespace Memory { // init nil nil = create_lisp_object(); nil->type = Lisp_Object_Type::Nil; - nil->value.pair = nullptr; // init t t = create_lisp_object(); t->type = Lisp_Object_Type::T; - t->value.pair = nullptr; } - // proc get_lisp_object_nil() -> Lisp_Object* { - // Lisp_Object* node = create_lisp_object(); - // node->type = Lisp_Object_Type::Nil; - // node->value.pair = nullptr; - // return node; - // } - - // proc get_lisp_object_t() -> Lisp_Object* { - // Lisp_Object* node = create_lisp_object(); - // node->type = Lisp_Object_Type::T; - // node->value.pair = nullptr; - // return node; - // } - proc create_lisp_object_number(double number) -> Lisp_Object* { Lisp_Object* node = create_lisp_object(); node->type = Lisp_Object_Type::Number; - node->value.number = new(Number); - node->value.number->value = number; + node->value.number = number; return node; } @@ -163,8 +146,8 @@ namespace Memory { // reuse it and dont create new one Lisp_Object* node = create_lisp_object(); node->type = Lisp_Object_Type::Symbol; - node->value.symbol = new(Symbol); - node->value.symbol->identifier = identifier; + // node->value.symbol = new(Symbol); + node->value.identifier = identifier; return node; } @@ -178,8 +161,8 @@ namespace Memory { // reuse it and dont create new one Lisp_Object* node = create_lisp_object(); node->type = Lisp_Object_Type::Keyword; - node->value.keyword = new(Keyword); - node->value.keyword->identifier = keyword; + // node->value.keyword = new(Keyword); + node->value.identifier = keyword; return node; } @@ -200,9 +183,9 @@ namespace Memory { proc create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) -> Lisp_Object* { 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; + // node->value.pair = new(Pair); + node->value.pair.first = first; + node->value.pair.rest = rest; return node; } diff --git a/src/parse.cpp b/src/parse.cpp index d799d9d..24f1cd4 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -293,7 +293,7 @@ namespace Parser { // okay there is something Lisp_Object* head = Memory::create_lisp_object(); head->type = Lisp_Object_Type::Pair; - head->value.pair = new(Pair); + // head->value.pair = new(Pair); Lisp_Object* expression = head; while (true) { @@ -304,11 +304,11 @@ namespace Parser { text[*index_in_text] == ',') { try { - head->value.pair->first = parse_expression(text, index_in_text); + head->value.pair.first = parse_expression(text, index_in_text); } } else { try { - head->value.pair->first = parse_atom(text, index_in_text); + head->value.pair.first = parse_atom(text, index_in_text); } } @@ -320,7 +320,7 @@ namespace Parser { if (text[(*index_in_text)] == ')') { - head->value.pair->rest = Memory::nil; + head->value.pair.rest = Memory::nil; ++parser_col; ++(*index_in_text); break; @@ -330,9 +330,9 @@ namespace Parser { eat_until_code(text, index_in_text); if (text[(*index_in_text)] == '(') - head->value.pair->rest = parse_expression(text, index_in_text); + head->value.pair.rest = parse_expression(text, index_in_text); else - head->value.pair->rest = parse_atom(text, index_in_text); + head->value.pair.rest = parse_atom(text, index_in_text); eat_until_code(text, index_in_text); @@ -342,16 +342,16 @@ namespace Parser { ++(*index_in_text); break; } else { - head->value.pair->rest = Memory::create_lisp_object_pair(nullptr, nullptr); - head = head->value.pair->rest; + head->value.pair.rest = Memory::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 == Lisp_Object_Type::Symbol) { - if (string_equal("define-syntax", expression->value.pair->first->value.symbol->identifier)) { + if (expression->value.pair.first->type == Lisp_Object_Type::Symbol) { + if (string_equal("define-syntax", expression->value.pair.first->value.identifier)) { // create a new macro - Lisp_Object* arguments = expression->value.pair->rest; + Lisp_Object* arguments = expression->value.pair.rest; int arguments_length; // HACK(Felix): almost code duplicate from @@ -366,57 +366,57 @@ namespace Parser { return nullptr; } - if (arguments->value.pair->first->type != Lisp_Object_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 - Lisp_Object* symbol_for_macro = arguments->value.pair->first; - arguments = arguments->value.pair->rest; + Lisp_Object* symbol_for_macro = arguments->value.pair.first; + arguments = arguments->value.pair.rest; - Function* function = new(Function); - function->parent_environment = environment_for_macros; - function->type = Function_Type::Macro; + // Function* function = new(Function); + Lisp_Object* macro = Memory::create_lisp_object(); + macro->type = Lisp_Object_Type::Function; + macro->value.function.parent_environment = environment_for_macros; + macro->value.function.type = Function_Type::Macro; // if parameters were specified - if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) { + if (arguments->value.pair.first->type != Lisp_Object_Type::Nil) { try { - assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair); } try { - parse_argument_list(arguments->value.pair->first, function); + parse_argument_list(arguments->value.pair.first, ¯o->value.function); } } else { - function->positional_arguments = create_positional_argument_list(1); - function->keyword_arguments = create_keyword_argument_list(1); - function->rest_argument = nullptr; + macro->value.function.positional_arguments = create_positional_argument_list(1); + macro->value.function.keyword_arguments = create_keyword_argument_list(1); + macro->value.function.rest_argument = nullptr; } - arguments = arguments->value.pair->rest; + arguments = arguments->value.pair.rest; // if there is a docstring, use it - if (arguments->value.pair->first->type == Lisp_Object_Type::String) { - function->docstring = arguments->value.pair->first->value.string; - arguments = arguments->value.pair->rest; + if (arguments->value.pair.first->type == Lisp_Object_Type::String) { + macro->value.function.docstring = arguments->value.pair.first->value.string; + arguments = arguments->value.pair.rest; } else { - function->docstring = nullptr; + macro->value.function.docstring = nullptr; } // we are now in the function body, just wrap it in an // implicit prog - function->body = Memory::create_lisp_object_pair( + macro->value.function.body = Memory::create_lisp_object_pair( Memory::get_or_create_lisp_object_symbol("prog"), arguments); - Lisp_Object* macro = Memory::create_lisp_object(); - macro->type = Lisp_Object_Type::Function; - macro->value.function = function; + // macro->value.function = function; define_symbol(symbol_for_macro, macro, environment_for_macros); // print_environment(environment_for_macros); return Memory::nil; - } else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) { + } else if (string_equal("delete-syntax", expression->value.pair.first->value.identifier)) { /* --- deleting an existing macro --- */ // TODO(Felix): this is a hard one because when // environments will be made from hashmaps, how can we @@ -436,21 +436,12 @@ namespace Parser { // if not it is regular code, dont touch. for (int i = 0; i < environment_for_macros->next_index; ++i) { - if (string_equal(expression->value.pair->first->value.symbol->identifier, environment_for_macros->keys[i]) && + if (string_equal(expression->value.pair.first->value.identifier, environment_for_macros->keys[i]) && environment_for_macros->values[i]->type == Lisp_Object_Type::Function && - environment_for_macros->values[i]->value.function->type == Function_Type::Macro) + environment_for_macros->values[i]->value.function.type == Function_Type::Macro) { try { - // if (string_equal(environment_for_macros->keys[i], "when")) { - // printf("invoking macro for %s in %s:%d to:\n\t", environment_for_macros->keys[i], parser_file, parser_line); - // print(environment_for_macros->values[i]->value.function->body); - // } expression = eval_expr(expression, environment_for_macros); - // if (string_equal(environment_for_macros->keys[i], "when")) { - // printf("\nresult: \n\t"); - // print(expression); - // printf("\n\n"); - // } } } } @@ -536,6 +527,11 @@ namespace Parser { strcat(newName, ext); FILE *f = fopen(newName, "w"); + defer { + fclose(f); + free(newName); + }; + if (f == NULL) { printf("Error opening file!\n"); exit(1); @@ -545,12 +541,9 @@ namespace Parser { // a macro will parse as nil for now, so we skip those if (program->data[i]->type == Lisp_Object_Type::Nil) continue; - fprint(f, program->data[i]); + print(program->data[i], true, f); fprintf(f, "\n\n"); } - - fclose(f); - free(newName); } proc parse_program(String* file_name, char* text) -> Lisp_Object_Array_List* { diff --git a/src/structs.cpp b/src/structs.cpp index bbc6f80..1c92f3e 100644 --- a/src/structs.cpp +++ b/src/structs.cpp @@ -73,9 +73,9 @@ struct Keyword { String* identifier; }; -struct Number { - double value; -}; +// struct Number { +// double value; +// }; struct Pair { Lisp_Object* first; @@ -119,12 +119,11 @@ struct Lisp_Object { Lisp_Object_Type type; Lisp_Object* userType; union { - Symbol* symbol; - Keyword* keyword; - Number* number; - String* string; - Pair* pair; - Function* function; + String* identifier; // used for symbols and keywords + double number; + String* string; + Pair pair; + Function function; cFunction* cFunction; } value; }; diff --git a/src/testing.cpp b/src/testing.cpp index 09fdd3e..14b4f27 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -105,26 +105,26 @@ proc test_eval_operands() -> testresult { assert_equal_int(list_length(operands), 4); 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); + assert_equal_type(operands->value.pair.first, Lisp_Object_Type::Number); + assert_equal_double(operands->value.pair.first->value.number, 1); - operands = operands->value.pair->rest; + operands = operands->value.pair.rest; 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); + assert_equal_type(operands->value.pair.first, Lisp_Object_Type::Number); + assert_equal_double(operands->value.pair.first->value.number, 3); - operands = operands->value.pair->rest; + operands = operands->value.pair.rest; 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, "okay"); + assert_equal_type(operands->value.pair.first, Lisp_Object_Type::String); + assert_equal_string(operands->value.pair.first->value.string, "okay"); - operands = operands->value.pair->rest; + operands = operands->value.pair.rest; 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"); + assert_equal_type(operands->value.pair.first, Lisp_Object_Type::Keyword); + assert_equal_string(operands->value.pair.first->value.identifier, "haha"); return pass; } @@ -141,13 +141,13 @@ proc test_parse_atom() -> testresult { Lisp_Object* result = Parser::parse_atom(string, &index_in_text); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, 123); + assert_equal_double(result->value.number, 123); ++index_in_text; result = Parser::parse_atom(string, &index_in_text); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, -1.23e-2); + assert_equal_double(result->value.number, -1.23e-2); // test strings ++index_in_text; @@ -161,26 +161,26 @@ proc test_parse_atom() -> testresult { result = Parser::parse_atom(string, &index_in_text); assert_equal_type(result, Lisp_Object_Type::Keyword); - assert_equal_string(result->value.keyword->identifier, "key1"); + assert_equal_string(result->value.identifier, "key1"); ++index_in_text; result = Parser::parse_atom(string, &index_in_text); assert_equal_type(result, Lisp_Object_Type::Keyword); - assert_equal_string(result->value.keyword->identifier, "key:2"); + assert_equal_string(result->value.identifier, "key:2"); // test symbols ++index_in_text; result = Parser::parse_atom(string, &index_in_text); assert_equal_type(result, Lisp_Object_Type::Symbol); - assert_equal_string(result->value.symbol->identifier, "sym"); + assert_equal_string(result->value.identifier, "sym"); ++index_in_text; result = Parser::parse_atom(string, &index_in_text); assert_equal_type(result, Lisp_Object_Type::Symbol); - assert_equal_string(result->value.symbol->identifier, "+"); + assert_equal_string(result->value.identifier, "+"); return pass; } @@ -193,22 +193,22 @@ proc test_parse_expression() -> testresult { assert_no_error(); 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"); + assert_equal_type(result->value.pair.first, Lisp_Object_Type::Symbol); + assert_equal_string(result->value.pair.first->value.identifier, "fun"); - result = result->value.pair->rest; + result = result->value.pair.rest; 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, "+"); + assert_equal_type(result->value.pair.first, Lisp_Object_Type::Symbol); + assert_equal_string(result->value.pair.first->value.identifier, "+"); - result = result->value.pair->rest; + result = result->value.pair.rest; 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); + assert_equal_type(result->value.pair.first, Lisp_Object_Type::Number); + assert_equal_double(result->value.pair.first->value.number, 12); - result = result->value.pair->rest; + result = result->value.pair.rest; assert_equal_type(result, Lisp_Object_Type::Nil); @@ -219,23 +219,23 @@ proc test_parse_expression() -> testresult { assert_no_error(); 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"); + assert_equal_type(result->value.pair.first, Lisp_Object_Type::Symbol); + assert_equal_string(result->value.pair.first->value.identifier, "define"); - result = result->value.pair->rest; + result = result->value.pair.rest; 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"); + assert_equal_type(result->value.pair.first, Lisp_Object_Type::Symbol); + assert_equal_string(result->value.pair.first->value.identifier, "fun"); - result = result->value.pair->rest; + result = result->value.pair.rest; 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"); + 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.identifier, "lambda"); - result = result->value.pair->rest; + result = result->value.pair.rest; return pass; } @@ -248,7 +248,7 @@ proc test_built_in_add() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, 14); + assert_equal_double(result->value.number, 14); return pass; } @@ -261,7 +261,7 @@ proc test_built_in_substract() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, 6); + assert_equal_double(result->value.number, 6); return pass; } @@ -275,7 +275,7 @@ proc test_built_in_multiply() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, 40); + assert_equal_double(result->value.number, 40); return pass; } @@ -289,7 +289,7 @@ proc test_built_in_divide() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, 5); + assert_equal_double(result->value.number, 5); return pass; } @@ -303,7 +303,7 @@ proc test_built_in_if() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, 4); + assert_equal_double(result->value.number, 4); char exp_string2[] = "(if () 4 5)"; expression = Parser::parse_single_expression(exp_string2); @@ -312,7 +312,7 @@ proc test_built_in_if() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Number); - assert_equal_double(result->value.number->value, 5); + assert_equal_double(result->value.number, 5); return pass; } @@ -393,7 +393,7 @@ proc test_built_in_type() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Keyword); - assert_equal_string(result->value.keyword->identifier, "number"); + assert_equal_string(result->value.identifier, "number"); // setting user type char exp_string2[] = "(prog (set-type a :my-type)(type a))"; @@ -403,7 +403,7 @@ proc test_built_in_type() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Keyword); - assert_equal_string(result->value.keyword->identifier, "my-type"); + assert_equal_string(result->value.identifier, "my-type"); // trying to set invalid user type char exp_string3[] = "(prog (set-type a \"wrong tpye\")(type a))"; @@ -421,7 +421,7 @@ proc test_built_in_type() -> testresult { assert_no_error(); assert_not_null(result); assert_equal_type(result, Lisp_Object_Type::Keyword); - assert_equal_string(result->value.keyword->identifier, "number"); + assert_equal_string(result->value.identifier, "number"); return pass; } diff --git a/todo.org b/todo.org index 044bb9d..85d6b22 100644 --- a/todo.org +++ b/todo.org @@ -13,3 +13,14 @@ ;; should output 6 ;; outputs 0 #+END_SRC +* SSO + +#+begin_src c +Symbol* symbol; // { String* identifier } +Keyword* keyword; // { String* identifier } +Number* number; // { double value } +String* string; // has to stay a pointer +Pair* pair; // { Lisp_Object* first; Lisp_Object* rest } +Function* function; // +cFunction* cFunction; // has to stay a pointer +#+end_src