diff options
| author | Mistivia <i@mistivia.com> | 2025-06-28 15:19:26 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-06-28 15:19:26 +0800 |
| commit | 9efc0e78ad1609217752b5aa02fbb389d726e9c7 (patch) | |
| tree | 4fcc801fa760ed9c0796afcc80662b9e9fc927ff /src/builtins.c | |
| parent | 878a056f3accafaa797446eb3a3b1a66b36d0d07 (diff) | |
add builtin funcs
Diffstat (limited to 'src/builtins.c')
| -rw-r--r-- | src/builtins.c | 91 |
1 files changed, 88 insertions, 3 deletions
diff --git a/src/builtins.c b/src/builtins.c index 591dc97..e39dfa4 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -7,6 +7,14 @@ #include <float.h> #include <math.h> +SExpRef builtin_functionp(Interp *interp, SExpRef args) { + if (LENGTH(args) != 1) { + return new_error(interp, "function?: args num error.\n"); + } + return new_boolean(interp, VALTYPE(CAR(args)) == kFuncSExp + || VALTYPE(CAR(args)) == kUserFuncSExp); +} + SExpRef builtin_setnth(Interp *interp, SExpRef args) { if (LENGTH(args) != 3) { return new_error(interp, "set-nth: args num error.\n"); @@ -114,11 +122,11 @@ SExpRef builtin_nconc(Interp *interp, SExpRef args) { SExpRef builtin_logand(Interp *interp, SExpRef args) { if (LENGTH(args) < 1) { - return new_error(interp, "nconc: args num error.\n"); + return new_error(interp, "logand: args num error.\n"); } for (SExpRef l = args; !NILP(l); l = CDR(l)) { if (VALTYPE(CAR(l)) != kIntegerSExp) { - return new_error(interp, "append: type error.\n"); + return new_error(interp, "logand: type error.\n"); } } uint64_t res = 0xffffffffffffffffULL; @@ -128,6 +136,83 @@ SExpRef builtin_logand(Interp *interp, SExpRef args) { return new_integer(interp, res); } +SExpRef builtin_logior(Interp *interp, SExpRef args) { + if (LENGTH(args) < 1) { + return new_error(interp, "logior: args num error.\n"); + } + for (SExpRef l = args; !NILP(l); l = CDR(l)) { + if (VALTYPE(CAR(l)) != kIntegerSExp) { + return new_error(interp, "logior: type error.\n"); + } + } + uint64_t res = 0; + for (SExpRef l = args; !NILP(l); l = CDR(l)) { + res = res | (REF(CAR(l))->integer); + } + return new_integer(interp, res); +} + +SExpRef builtin_logxor(Interp *interp, SExpRef args) { + if (LENGTH(args) < 1) { + return new_error(interp, "logxor: args num error.\n"); + } + for (SExpRef l = args; !NILP(l); l = CDR(l)) { + if (VALTYPE(CAR(l)) != kIntegerSExp) { + return new_error(interp, "logxor: type error.\n"); + } + } + uint64_t res = 0; + for (SExpRef l = args; !NILP(l); l = CDR(l)) { + res = res ^ (REF(CAR(l))->integer); + } + return new_integer(interp, res); +} + +SExpRef builtin_lognot(Interp *interp, SExpRef args) { + if (LENGTH(args) != 1) { + return new_error(interp, "lognot: args num error.\n"); + } + SExpRef x = CAR(args); + if (VALTYPE(x) != kIntegerSExp) { + return new_error(interp, "lognot: type error.\n"); + } + uint64_t res = 0; + res = ~(REF(x)->integer); + return new_integer(interp, res); +} + +SExpRef builtin_lsh(Interp *interp, SExpRef args) { + if (LENGTH(args) != 2) { + return new_error(interp, "lsh: args num error.\n"); + } + SExpRef x = CAR(args), n = CADR(args); + if (VALTYPE(x) != kIntegerSExp) { + return new_error(interp, "lsh: type error.\n"); + } + if (VALTYPE(n) != kIntegerSExp) { + return new_error(interp, "lsh: type error.\n"); + } + uint64_t res = 0; + res = (REF(x)->integer) << (REF(n)->integer); + return new_integer(interp, res); +} + +SExpRef builtin_ash(Interp *interp, SExpRef args) { + if (LENGTH(args) != 2) { + return new_error(interp, "ash: args num error.\n"); + } + SExpRef x = CAR(args), n = CADR(args); + if (VALTYPE(x) != kIntegerSExp) { + return new_error(interp, "ash: type error.\n"); + } + if (VALTYPE(n) != kIntegerSExp) { + return new_error(interp, "ash: type error.\n"); + } + int64_t res = 0; + res = (REF(x)->integer) >> (REF(n)->integer); + return new_integer(interp, res); +} + SExpRef builtin_charp(Interp *interp, SExpRef args) { if (LENGTH(args) != 1) return new_error(interp, "char?: arg num error.\n"); return new_boolean(interp, VALTYPE(CAR(args)) == kCharSExp); @@ -263,7 +348,7 @@ SExpRef builtin_numberp(Interp *interp, SExpRef args) { SExpRef builtin_integerp(Interp *interp, SExpRef args) { if (LENGTH(args) != 1) return new_error(interp, "integer?: arg num error.\n"); - return new_boolean(interp, REF(CAR(args))->type == kNilSExp); + return new_boolean(interp, REF(CAR(args))->type == kIntegerSExp); } SExpRef builtin_floatp(Interp *interp, SExpRef args) { |
