#include "uclisp.h" #include "internal.h" #include "utility.h" #include #include #include 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; }