aboutsummaryrefslogtreecommitdiff
path: root/src/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/builtins.c')
-rw-r--r--src/builtins.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/builtins.c b/src/builtins.c
index fe14b8f..48cb4f0 100644
--- a/src/builtins.c
+++ b/src/builtins.c
@@ -6,6 +6,110 @@
#include <float.h>
#include <math.h>
+SExpRef builtin_string(Interp *interp, SExpRef args) {
+ for (SExpRef i = args; !NILP(i); i = CDR(i)) {
+ SExpRef x = CAR(i);
+ if (VALTYPE(x) != kIntegerSExp && VALTYPE(x) != kCharSExp) {
+ return new_error(interp, "string: type error.\n");
+ }
+ }
+ str_builder_t sb;
+ init_str_builder(&sb);
+ for (SExpRef i = args; !NILP(i); i = CDR(i)) {
+ SExpRef x = CAR(i);
+ if (VALTYPE(x) == kIntegerSExp) {
+ str_builder_append_char(&sb, REF(x)->integer);
+ } else {
+ str_builder_append_char(&sb, REF(x)->character);
+ }
+ }
+ str_builder_append_char(&sb, '\0');
+ SExpRef ret = new_string(interp, sb.buf);
+ free(sb.buf);
+ return ret;
+}
+
+SExpRef builtin_string_eq(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 2) return new_error(interp, "string=: arg num error.\n");
+ SExpRef s1 = CAR(args), s2 = CADR(args);
+ if (VALTYPE(s1) != kStringSExp || VALTYPE(s2) != kStringSExp) {
+ return new_error(interp, "string=: type error.\n");
+ }
+ return new_boolean(interp, strcmp(REF(s1)->str, REF(s2)->str) == 0);
+}
+
+SExpRef builtin_string_gt(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 2) return new_error(interp, "string>: arg num error.\n");
+ SExpRef s1 = CAR(args), s2 = CADR(args);
+ if (VALTYPE(s1) != kStringSExp || VALTYPE(s2) != kStringSExp) {
+ return new_error(interp, "string>: type error.\n");
+ }
+ return new_boolean(interp, strcmp(REF(s1)->str, REF(s2)->str) > 0);
+
+}
+
+SExpRef builtin_string_lt(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 2) return new_error(interp, "string<: arg num error.\n");
+ SExpRef s1 = CAR(args), s2 = CADR(args);
+ if (VALTYPE(s1) != kStringSExp || VALTYPE(s2) != kStringSExp) {
+ return new_error(interp, "string<: type error.\n");
+ }
+ return new_boolean(interp, strcmp(REF(s1)->str, REF(s2)->str) < 0);
+}
+
+SExpRef builtin_string_ge(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 2) return new_error(interp, "string>=: arg num error.\n");
+ SExpRef s1 = CAR(args), s2 = CADR(args);
+ if (VALTYPE(s1) != kStringSExp || VALTYPE(s2) != kStringSExp) {
+ return new_error(interp, "string>=: type error.\n");
+ }
+ return new_boolean(interp, strcmp(REF(s1)->str, REF(s2)->str) >= 0);
+}
+
+SExpRef builtin_string_le(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 2) return new_error(interp, "string<=: arg num error.\n");
+ SExpRef s1 = CAR(args), s2 = CADR(args);
+ if (VALTYPE(s1) != kStringSExp || VALTYPE(s2) != kStringSExp) {
+ return new_error(interp, "string<=: type error.\n");
+ }
+ return new_boolean(interp, strcmp(REF(s1)->str, REF(s2)->str) <= 0);
+}
+
+SExpRef builtin_string_neq(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 2) return new_error(interp, "string/=: arg num error.\n");
+ SExpRef s1 = CAR(args), s2 = CADR(args);
+ if (VALTYPE(s1) != kStringSExp || VALTYPE(s2) != kStringSExp) {
+ return new_error(interp, "string/=: type error.\n");
+ }
+ return new_boolean(interp, strcmp(REF(s1)->str, REF(s2)->str) != 0);
+}
+
+SExpRef builtin_split_string(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 2) return new_error(interp, "split-string: arg num error.\n");
+ SExpRef s1 = CAR(args), s2 = CADR(args);
+ if (VALTYPE(s1) != kStringSExp || VALTYPE(s2) != kCharSExp) {
+ return new_error(interp, "split-string: type error.\n");
+ }
+ char **ss;
+ ss = str_split((char*)REF(s1)->str, REF(s2)->character);
+ SExpRef lst = NIL;
+ for (char **i = ss; *i != NULL; i++) {
+ lst = CONS(new_string(interp, *i), lst);
+ }
+ destroy_str_list(ss);
+ return lisp_nreverse(interp, lst);
+}
+
+SExpRef builtin_strip_string(Interp *interp, SExpRef args) {
+ if (LENGTH(args) != 1) return new_error(interp, "strip-string: arg num error.\n");
+ SExpRef s = CAR(args);
+ if (VALTYPE(s) != kStringSExp) return new_error(interp, "strip-string: type error.\n");
+ char *news = str_strip((char*)REF(s)->str);
+ SExpRef ret = new_string(interp, news);
+ free(news);
+ return ret;
+}
+
SExpRef builtin_alwaysgc(Interp *interp, SExpRef args) {
if (LENGTH(args) != 1) return new_error(interp, "_alwaysgc: arg num error.\n");
SExpRef arg = CAR(args);