diff options
author | Daniel Cerqueira <dan.git@lispclub.com> | 2025-05-29 11:54:21 +0100 |
---|---|---|
committer | Daniel Cerqueira <dan.git@lispclub.com> | 2025-05-29 11:54:21 +0100 |
commit | f1fe930de080baede6951b2414c7631abe6b4860 (patch) | |
tree | c47685013a897fe7796eaa013c4e239c33ccc2a4 /liblali.c | |
parent | 1c217ee6ac5aacd2f37b1d0e69a71ac94afd5acd (diff) |
add join primitive
Diffstat (limited to 'liblali.c')
-rw-r--r-- | liblali.c | 31 |
1 files changed, 31 insertions, 0 deletions
@@ -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. |