#include #include #include #include #include #include #include #include #include #include #include #include #include #include "../evaluate.h" #include "struct.h" #include "evaluate.h" struct value* application_expression_evaluate( struct expression* super, struct environment* outer_environment, struct booleans* booleans) { ENTER; struct value* result; struct application_expression* this = (void*) super; struct value* left = expression_evaluate(this->left, outer_environment, booleans); struct value* lleft = lazy_value_unlazy(left, booleans); struct value* right = new_lazy_value( /* capture environment: */ outer_environment, /* expression: */ this->right); switch (lleft->kind) { case vk_lambda: { struct lambda_value* lambda = (void*) lleft; struct environment* environment = new_environment(lambda->environment); environment_declare(environment, lambda->variable_name, right); result = expression_evaluate(lambda->body, environment, booleans); free_environment(environment); break; } case vk_builtin_lambda: { struct builtin_lambda_value* lambda = (void*) lleft; assert(lambda->number_of_parameters > 0); if (lambda->number_of_parameters == 1) { result = (lambda->funcptr)(booleans, lambda, right); } else { result = new_builtin_lambda_value( /* name: */ lambda->name, /* funcptr: */ lambda->funcptr, /* number_of_parameters: */ lambda->number_of_parameters - 1, /* value: */ right, /* prev: */ lambda); } break; } case vk_lazy: { TODO; break; } default: { dpvu(lleft->kind); // make some kind of 'error-value'? // that's contagious, like NaN? // maybe error values can link to other error values? // if more than on seperate error was encountered? TODO; exit(1); break; } } free_value(left); free_value(lleft); free_value(right); EXIT; return result; }