diff --git a/src/examples/lib.pbl b/src/examples/lib.pbl index d9f3cd7..de746d2 100644 --- a/src/examples/lib.pbl +++ b/src/examples/lib.pbl @@ -57,11 +57,28 @@ (def split (fn (txt splitter) "Split a string at each instance of splitter" ( (def i (indexOf txt splitter)) + (def split-len (slen splitter)) (if (< i 0) (txt) - (pre (split (substr (+ 1 i) 9999999 txt) splitter) (substr 0 i txt)) + (pre (split (substr (+ split-len i) 9999999 txt) splitter) (substr 0 i txt)) ) ))) +(def not (fn (bool) (if bool F T))) + +(def _doc-test (fn (docstring) ( + (def halves (split docstring " => ")) + (if (not (= 2 (len halves))) () ( + (def '(test expected) halves) + (def actual (string (eval test))) + (if (= actual expected) (prnl "Test passed!") (prnl "Test failed! Expected " expected " but received " actual))) + ) + "" +))) + +(def doc-test (fn (docstring) ( + (for-each _doc-test (split docstring nl)) +))) + (def loadfile (fn (file-name) "Read and immediately evaluate the file with the given path." ( (eval (rf file-name)) @@ -95,7 +112,7 @@ (def max (fn (...values) "Return the largest of the given values" - "(max 1 5 3) => 3" + "(max 1 5 3) => 5" (reduce values _max (first values)) )) diff --git a/src/object.c b/src/object.c index c68f043..6fa3ad4 100644 --- a/src/object.c +++ b/src/object.c @@ -282,10 +282,12 @@ int stringNObj(struct string* s, const Object* obj) break; case TYPE_LAMBDA: { #if defined(STANDALONE) && !defined(DEBUG) - const char* docString = lambdaDocs(obj); - if (docString) { - inflate(s, strlen(docString)); - appendf(s, "%s\n", docString); + char** docStrings = lambdaDocs(obj); + if (docStrings) { + for (; *docStrings; docStrings++) { + inflate(s, strlen(*docStrings)); + appendf(s, "%s\n", *docStrings); + } } stringNObj(s, &obj->lambda->params); appendf(s, " -> "); @@ -732,7 +734,7 @@ inline Object constructLambda(const Object* params, const Object* body, struct E const Object* docs = body; size_t docLength = 0; while (body->type == TYPE_STRING) { - docLength += sizeof(char) * (strlen(body->string) + 1); + docLength++; body = body->forward; } @@ -749,13 +751,14 @@ inline Object constructLambda(const Object* params, const Object* body, struct E if (docLength == 0) { lambdaDocs(&o) = NULL; } else { - lambdaDocs(&o) = malloc(docLength + 1); - char* docText = lambdaDocs(&o); + lambdaDocs(&o) = malloc(sizeof(char*) * (docLength + 1)); + char** docTexts = lambdaDocs(&o); while (docs->type == TYPE_STRING) { - const char* data = docs->string; - docText += sprintf(docText, "%s\n", data); + *docTexts = strdup(docs->string); docs = docs->forward; + docTexts++; } + *docTexts = NULL; } Object* dest = &o.lambda->body; diff --git a/src/object.h b/src/object.h index c4469d7..20f7ef1 100644 --- a/src/object.h +++ b/src/object.h @@ -158,7 +158,7 @@ struct Object { union { Object* forward; - char* docString; + char** docStrings; int refs; }; }; @@ -180,7 +180,7 @@ struct StructObject { struct Object* fields; // Order should match that in the definition. }; -#define lambdaDocs(LAMBDA_OBJECT) (LAMBDA_OBJECT)->lambda->params.docString +#define lambdaDocs(LAMBDA_OBJECT) (LAMBDA_OBJECT)->lambda->params.docStrings #define lambdaRefs(LAMBDA_OBJECT) (LAMBDA_OBJECT)->lambda->body.refs struct Lambda { /// params.docstring can contain details about the constructed lambda.