aboutsummaryrefslogtreecommitdiff
path: root/src/builtins.c
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-06-28 15:19:26 +0800
committerMistivia <i@mistivia.com>2025-06-28 15:19:26 +0800
commit9efc0e78ad1609217752b5aa02fbb389d726e9c7 (patch)
tree4fcc801fa760ed9c0796afcc80662b9e9fc927ff /src/builtins.c
parent878a056f3accafaa797446eb3a3b1a66b36d0d07 (diff)
add builtin funcs
Diffstat (limited to 'src/builtins.c')
-rw-r--r--src/builtins.c91
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) {