#ifndef _UCLISP_LISP_H_ #define _UCLISP_LISP_H_ #include "common.h" #define LISP_FUNC_0(func_name, ucl_name, scope_name) \ static struct ucl_object *func_name##_impl(struct ucl* ucl, struct ucl_scope *scope); \ struct ucl_object *func_name(struct ucl* ucl, struct ucl_scope *scope, struct ucl_object *args) { \ if (args->cell.car != NULL) { \ return NULL; \ } \ return func_name##_impl(ucl, scope); \ } \ static struct ucl_object *func_name##_impl(struct ucl *ucl_name, struct ucl_scope *scope) #define LISP_FUNC_1(func_name, ucl_name, scope_name, arg0_name) \ static struct ucl_object *func_name##_impl(struct ucl* ucl, struct ucl_scope *scope, struct ucl_object *arg0_name); \ struct ucl_object *func_name(struct ucl* ucl, struct ucl_scope *scope, struct ucl_object *args) { \ struct ucl_object *len_obj = ucl_list_length(ucl, args); \ if (len_obj->type != UCL_TYPE_INT) { \ return NULL; \ } \ if (len_obj->integer != 1) { \ return NULL; \ } \ struct ucl_object *arg0 = ucl_car(ucl, args); \ return func_name##_impl(ucl, scope_name, arg0); \ } \ static struct ucl_object *func_name##_impl(struct ucl* ucl_name, struct ucl_scope *scope, struct ucl_object *arg0_name) // TODO: Unroll the args more efficiently, this is O(n^2) #define LISP_FUNC_2(func_name, ucl_name, scope_name, arg0_name, arg1_name) \ static struct ucl_object *func_name##_impl(struct ucl* ucl, struct ucl_scope *scope, struct ucl_object *arg0_name, struct ucl_object *arg1_name); \ struct ucl_object *func_name(struct ucl* ucl, struct ucl_scope *scope, struct ucl_object *args) { \ struct ucl_object *len_obj = ucl_list_length(ucl, args); \ if (len_obj->type != UCL_TYPE_INT) { \ return NULL; \ } \ if (len_obj->integer != 2) { \ return NULL; \ } \ struct ucl_object *arg0 = ucl_list_nth(ucl, args, 0); \ struct ucl_object *arg1 = ucl_list_nth(ucl, args, 1); \ return func_name##_impl(ucl, scope, arg0, arg1); \ } \ static struct ucl_object *func_name##_impl(struct ucl *ucl_name, struct ucl_scope *scope, struct ucl_object *arg0_name, struct ucl_object *arg1_name) // TODO: Unroll the args more efficiently, this is O(n^2) #define LISP_FUNC_3(func_name, ucl_name, scope_name, arg0_name, arg1_name, arg2_name) \ static struct ucl_object *func_name##_impl(struct ucl* ucl, struct ucl_scope *scope, struct ucl_object *arg0_name, struct ucl_object *arg1_name, struct ucl_object *arg2_name); \ struct ucl_object *func_name(struct ucl* ucl, struct ucl_scope *scope, struct ucl_object *args) { \ struct ucl_object *len_obj = ucl_list_length(ucl, args); \ if (len_obj->type != UCL_TYPE_INT) { \ return NULL; \ } \ if (len_obj->integer != 3) { \ return NULL; \ } \ struct ucl_object *arg0 = ucl_list_nth(ucl, args, 0); \ struct ucl_object *arg1 = ucl_list_nth(ucl, args, 1); \ struct ucl_object *arg2 = ucl_list_nth(ucl, args, 2); \ return func_name##_impl(ucl, scope, arg0, arg1, arg2); \ } \ static struct ucl_object *func_name##_impl(struct ucl* ucl_name, struct ucl_scope *scope_name, struct ucl_object *arg0_name, struct ucl_object *arg1_name, struct ucl_object *arg2_name) #endif