85 lines
2 KiB
C
85 lines
2 KiB
C
|
|
#include <assert.h>
|
|
|
|
#include <debug.h>
|
|
|
|
#include <value/struct.h>
|
|
#include <value/integer/new.h>
|
|
|
|
#include <gc/dec_external_refcount.h>
|
|
|
|
#include "../defines/BUILTIN_PARAMETER_DECLARATION.h"
|
|
|
|
#include "sub.h"
|
|
|
|
struct value* builtin_sub(
|
|
BUILTIN_PARAMETER_DECLARATION)
|
|
{
|
|
struct value* retval = NULL;
|
|
ENTER;
|
|
|
|
if (arguments->kind == vk_null)
|
|
{
|
|
TODO;
|
|
}
|
|
else
|
|
{
|
|
assert(arguments->kind == vk_list);
|
|
|
|
struct list_value* arguments_lv = &arguments->subclass.list;
|
|
|
|
struct value* first = evalfunc(arguments_lv->first, environment, gc);
|
|
|
|
switch (first->kind)
|
|
{
|
|
case vk_integer:
|
|
{
|
|
intmax_t sub = first->subclass.integer.value;
|
|
|
|
for (struct value* link = arguments_lv->rest;
|
|
link->kind == vk_list;
|
|
link = link->subclass.list.rest)
|
|
{
|
|
struct value* element = link->subclass.list.first;
|
|
|
|
struct value* evaluated = evalfunc(element, environment, gc);
|
|
|
|
if (evaluated->kind != vk_integer)
|
|
{
|
|
TODO;
|
|
}
|
|
|
|
dpvlu(evaluated->subclass.integer.value);
|
|
|
|
sub -= evaluated->subclass.integer.value;
|
|
|
|
gc_dec_external_refcount(gc, evaluated);
|
|
}
|
|
|
|
dpvlu(sub);
|
|
|
|
retval = new_integer_value(gc, sub);
|
|
|
|
break;
|
|
}
|
|
|
|
case vk_string:
|
|
TODO;
|
|
break;
|
|
|
|
case vk_list:
|
|
TODO;
|
|
break;
|
|
|
|
default:
|
|
TODO;
|
|
break;
|
|
}
|
|
|
|
gc_dec_external_refcount(gc, first);
|
|
}
|
|
|
|
EXIT;
|
|
return retval;
|
|
}
|
|
|