Files
uclisp/src/utility.c

112 lines
2.7 KiB
C

#include "uclisp.h"
#include "internal.h"
#include "utility.h"
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
struct ucl_object *ucl_car(struct ucl_object *list) {
UCL_COND_OR_RET_ERROR(
list != NULL && list->type == UCL_TYPE_CELL,
"Invalid type of argument 0 to 'ucl_car'");
struct ucl_object *car = list->cell.car;
if (car == NULL) {
return ucl_nil_create();
}
return car;
}
struct ucl_object *ucl_cdr(struct ucl_object *list) {
UCL_COND_OR_RET_ERROR(
list != NULL && list->type == UCL_TYPE_CELL,
"Invalid type of argument 0 to 'ucl_cdr'");
struct ucl_object *cdr = list->cell.cdr;
if (cdr == NULL) {
return ucl_nil_create();
}
return cdr;
}
struct ucl_object *ucl_nil_create() {
return ucl_cell_create(NULL, NULL);
}
struct ucl_object *ucl_t_create() {
return ucl_symbol_create(strdup("t"));
}
struct ucl_object *ucl_predicate(bool value) {
if (value) {
return ucl_t_create();
} else {
return ucl_nil_create();
}
}
struct ucl_object *ucl_list_length(struct ucl_object *list) {
UCL_COND_OR_RET_ERROR(
list != NULL && list->type == UCL_TYPE_CELL,
"Invalid type of argument 0 to 'ucl_list_length'");
struct ucl_object *node = list;
if (list->cell.car == NULL) {
return ucl_int_create(0);
}
int length = 1;
while (node->cell.cdr != NULL) {
node = node->cell.cdr;
length++;
}
return ucl_int_create(length);
}
struct ucl_object *ucl_list_nth(struct ucl_object *list, int n) {
UCL_COND_OR_RET_ERROR(
list != NULL && list->type == UCL_TYPE_CELL,
"Invalid type of argument 0 to 'ucl_list_'");
int length = ucl_list_length(list)->integer;
UCL_COND_OR_RET_ERROR(length > n, "Position n >= list length in ucl_list_nth");
struct ucl_object *node = list;
for (int i = 0; i < n; i++) {
node = node->cell.cdr;
}
return node->cell.car;
}
struct ucl_object *ucl_truthy(struct ucl_object *obj) {
// TODO: Implement me
return ucl_error_create("Unimplemented function 'ucl_truthy'");
}
struct ucl_object *ucl_tuple_create(struct ucl_object *obj0, struct ucl_object *obj1) {
struct ucl_object *tuple = ucl_cell_create(obj0, NULL);
ucl_list_append(tuple, obj1);
return tuple;
}
struct ucl_object *ucl_list_append(struct ucl_object *list, struct ucl_object *obj) {
struct ucl_object *iter = list;
if (list->cell.car == NULL) {
list->cell.car = obj;
return list;
}
while (iter->cell.cdr != NULL) {
iter = iter->cell.cdr;
}
iter->cell.cdr = ucl_cell_create(obj, NULL);
return list;
}