summaryrefslogtreecommitdiff
path: root/liblali.c
diff options
context:
space:
mode:
Diffstat (limited to 'liblali.c')
-rw-r--r--liblali.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/liblali.c b/liblali.c
index e2239dd..87be3d6 100644
--- a/liblali.c
+++ b/liblali.c
@@ -953,6 +953,36 @@ DEFINE_PRIMITIVE_RELATIONAL(primitiveLess, < , true)
DEFINE_PRIMITIVE_RELATIONAL(primitiveGreater, > , true)
/* DEFINE_PRIMITIVE_RELATIONAL(primitiveGreaterEqual, >=, true) */
+Object *primitiveJoin(Object **args, GC_PARAM) {
+ if ((*args)->car == nil)
+ exception("cannot join an empty list");
+ else if ((*args)->car->type != TYPE_CONS)
+ exceptionWithObject((*args)->car, "is not a list");
+
+ unsigned long i = 1;
+ Object *tmpCons = (*args)->car;
+ for (; tmpCons->cdr != nil; tmpCons = tmpCons->cdr)
+ i += strlen(tmpCons->car->string);
+
+ char symbolResult[i];
+ tmpCons = (*args)->car;
+ unsigned long wordLength = strlen(tmpCons->car->string);
+
+ // first list element
+ for (int j = 0; j < wordLength; j++)
+ symbolResult[j] = tmpCons->car->string[j];
+
+ // rest of list elements
+ for (i = wordLength; tmpCons->cdr != nil; tmpCons = tmpCons->cdr) {
+ wordLength = strlen(tmpCons->cdr->car->string);
+ for (int j = 0; j < wordLength; j++)
+ symbolResult[i+j] = tmpCons->cdr->car->string[j];
+ i += wordLength;
+ }
+
+ return newSymbol(symbolResult, GC_ROOTS);
+}
+
typedef struct Primitive {
char *name;
int nMinArgs, nMaxArgs;
@@ -995,6 +1025,7 @@ Primitive primitives[] = {
/* { "<=", 1, -1, primitiveLessEqual }, */
{ ">", 1, -1, primitiveGreater },
/* { ">=", 1, -1, primitiveGreaterEqual } */
+ { "join", 1, 1, primitiveJoin },
};
// Special forms handled by evalExpr. Must be in the same order as above.