lambda-calculus/expression/application/evaluate.c
2025-01-13 20:36:07 -06:00

117 lines
2.6 KiB
C

#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <environment/new.h>
#include <environment/declare.h>
#include <environment/free.h>
#include <value/struct.h>
#include <value/lambda/struct.h>
#include <value/builtin_lambda/struct.h>
#include <value/builtin_lambda/new.h>
#include <value/lazy/new.h>
#include <value/lazy/unlazy.h>
#include <value/free.h>
#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);
TODO;
exit(1);
break;
}
}
free_value(left);
free_value(lleft);
free_value(right);
EXIT;
return result;
}