Add iteration (dotimes, dolist, while)
This commit is contained in:
@@ -25,9 +25,6 @@ int main(int argc, const char **argv) {
|
|||||||
ucl_scope_put(scope, "and", ucl_special_create(ucl_special_and));
|
ucl_scope_put(scope, "and", ucl_special_create(ucl_special_and));
|
||||||
ucl_scope_put(scope, "or", ucl_special_create(ucl_special_or));
|
ucl_scope_put(scope, "or", ucl_special_create(ucl_special_or));
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// - iteration
|
|
||||||
|
|
||||||
ucl_scope_put(scope, "print", ucl_builtin_create(ucl_builtin_print));
|
ucl_scope_put(scope, "print", ucl_builtin_create(ucl_builtin_print));
|
||||||
ucl_scope_put(scope, "printl", ucl_builtin_create(ucl_builtin_printl));
|
ucl_scope_put(scope, "printl", ucl_builtin_create(ucl_builtin_printl));
|
||||||
// TODO:
|
// TODO:
|
||||||
@@ -65,6 +62,10 @@ int main(int argc, const char **argv) {
|
|||||||
ucl_scope_put(scope, "mapcar", ucl_builtin_create(ucl_builtin_mapcar));
|
ucl_scope_put(scope, "mapcar", ucl_builtin_create(ucl_builtin_mapcar));
|
||||||
ucl_scope_put(scope, "equal", ucl_builtin_create(ucl_builtin_mapcar));
|
ucl_scope_put(scope, "equal", ucl_builtin_create(ucl_builtin_mapcar));
|
||||||
|
|
||||||
|
ucl_scope_put(scope, "dotimes", ucl_special_create(ucl_special_dotimes));
|
||||||
|
ucl_scope_put(scope, "dolist", ucl_special_create(ucl_special_dolist));
|
||||||
|
ucl_scope_put(scope, "while", ucl_special_create(ucl_special_while));
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - reduce
|
// - reduce
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "lisp.h"
|
#include "lisp.h"
|
||||||
|
#include "uclisp.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@@ -84,6 +85,69 @@ struct ucl_object *ucl_special_lambda(struct ucl_scope *scope, struct ucl_object
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ucl_object *ucl_special_dotimes(struct ucl_scope *scope, struct ucl_object *args) {
|
||||||
|
// TODO: Check arguments
|
||||||
|
struct ucl_object *assignment = ucl_car(args);
|
||||||
|
struct ucl_object *body = ucl_cdr(args);
|
||||||
|
|
||||||
|
struct ucl_object *var = ucl_car(assignment);
|
||||||
|
struct ucl_object *times = ucl_evaluate(scope, ucl_list_nth(assignment, 1));
|
||||||
|
|
||||||
|
UCL_COND_OR_RET_ERROR(var->type == UCL_TYPE_SYMBOL, "'var' argument to dotimes must be an symbol");
|
||||||
|
UCL_COND_OR_RET_ERROR(times->type == UCL_TYPE_INT, "'times' argument to dotimes must be an int");
|
||||||
|
|
||||||
|
struct ucl_scope *let_scope = ucl_scope_create_child(scope);
|
||||||
|
|
||||||
|
for (int i = 0; i < times->integer; i++) {
|
||||||
|
ucl_scope_put(let_scope, var->symbol, ucl_int_create(i));
|
||||||
|
struct ucl_object *iterval = ucl_progn(let_scope, body);
|
||||||
|
UCL_RET_IF_ERROR(iterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ucl_nil_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ucl_object *ucl_special_dolist(struct ucl_scope *scope, struct ucl_object *args) {
|
||||||
|
// TODO: Check arguments
|
||||||
|
struct ucl_object *assignment = ucl_car(args);
|
||||||
|
struct ucl_object *body = ucl_cdr(args);
|
||||||
|
|
||||||
|
struct ucl_object *var = ucl_car(assignment);
|
||||||
|
struct ucl_object *list = ucl_evaluate(scope, ucl_list_nth(assignment, 1));
|
||||||
|
|
||||||
|
UCL_COND_OR_RET_ERROR(var->type == UCL_TYPE_SYMBOL, "'var' argument to dolist must be an symbol");
|
||||||
|
UCL_COND_OR_RET_ERROR(list->type == UCL_TYPE_CELL, "'list' argument to dolist must be a list");
|
||||||
|
|
||||||
|
struct ucl_scope *let_scope = ucl_scope_create_child(scope);
|
||||||
|
|
||||||
|
FOREACH_LIST(list, iter, item) {
|
||||||
|
ucl_scope_put(let_scope, var->symbol, item);
|
||||||
|
struct ucl_object *iterval = ucl_progn(let_scope, body);
|
||||||
|
if (iterval->type == UCL_TYPE_ERROR) {
|
||||||
|
ucl_scope_delete(let_scope);
|
||||||
|
}
|
||||||
|
UCL_RET_IF_ERROR(iterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ucl_nil_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ucl_object *ucl_special_while(struct ucl_scope *scope, struct ucl_object *args) {
|
||||||
|
// TODO: Check arguments
|
||||||
|
struct ucl_object *condition = ucl_car(args);
|
||||||
|
struct ucl_object *body = ucl_cdr(args);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
struct ucl_object* cond_val = ucl_evaluate(scope, condition);
|
||||||
|
UCL_RET_IF_ERROR(cond_val);
|
||||||
|
if (!ucl_truthy_bool(cond_val)) {
|
||||||
|
return ucl_nil_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ucl_object *val = ucl_progn(scope, body);
|
||||||
|
UCL_RET_IF_ERROR(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ucl_object *ucl_special_setq(struct ucl_scope *scope, struct ucl_object *args) {
|
struct ucl_object *ucl_special_setq(struct ucl_scope *scope, struct ucl_object *args) {
|
||||||
// TODO: Check arguments
|
// TODO: Check arguments
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ struct ucl_object *ucl_special_let(struct ucl_scope *scope, struct ucl_object *a
|
|||||||
struct ucl_object *ucl_special_if(struct ucl_scope *scope, struct ucl_object *args);
|
struct ucl_object *ucl_special_if(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
struct ucl_object *ucl_special_defun(struct ucl_scope *scope, struct ucl_object *args);
|
struct ucl_object *ucl_special_defun(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
struct ucl_object *ucl_special_lambda(struct ucl_scope *scope, struct ucl_object *args);
|
struct ucl_object *ucl_special_lambda(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
|
struct ucl_object *ucl_special_dotimes(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
|
struct ucl_object *ucl_special_dolist(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
|
struct ucl_object *ucl_special_while(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
struct ucl_object *ucl_special_setq(struct ucl_scope *scope, struct ucl_object *args);
|
struct ucl_object *ucl_special_setq(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
struct ucl_object *ucl_special_progn(struct ucl_scope *scope, struct ucl_object *args);
|
struct ucl_object *ucl_special_progn(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
struct ucl_object *ucl_special_quote(struct ucl_scope *scope, struct ucl_object *args);
|
struct ucl_object *ucl_special_quote(struct ucl_scope *scope, struct ucl_object *args);
|
||||||
|
|||||||
Reference in New Issue
Block a user