From bac1790b6c10024bae9930c92c9d7c2b4d4d7823 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Mon, 25 Apr 2022 14:11:28 -0400 Subject: [PATCH] Allow for multiple strings of lambda documentation. Still trying to see a good way to base testing off of this. --- src/examples/lib.pbl | 2 ++ src/object.c | 26 ++++++++++++++++++-------- src/object.h | 2 +- src/pebblisp.c | 10 ++-------- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/examples/lib.pbl b/src/examples/lib.pbl index efc943f..d9f3cd7 100644 --- a/src/examples/lib.pbl +++ b/src/examples/lib.pbl @@ -95,6 +95,7 @@ (def max (fn (...values) "Return the largest of the given values" + "(max 1 5 3) => 3" (reduce values _max (first values)) )) @@ -102,6 +103,7 @@ (def min (fn (...values) "Return the smallest of the given values" + "(min 2 1 6) => 1" (reduce values _min (first values)) )) diff --git a/src/object.c b/src/object.c index 587d035..c68f043 100644 --- a/src/object.c +++ b/src/object.c @@ -719,7 +719,7 @@ inline Object withLen(size_t len, enum Type type) return o; } -inline Object constructLambda(const Object* params, const Object* docs, const Object* body, struct Environment* env) +inline Object constructLambda(const Object* params, const Object* body, struct Environment* env) { if (!params || !body) { return errorObject(NULL_LAMBDA_LIST); @@ -728,12 +728,17 @@ inline Object constructLambda(const Object* params, const Object* docs, const Ob if (params->type != TYPE_LIST) { throw(LAMBDA_ARGS_NOT_LIST, "fn params must be TYPE_LIST, but is %s", getTypeName(params)); } + + const Object* docs = body; + size_t docLength = 0; + while (body->type == TYPE_STRING) { + docLength += sizeof(char) * (strlen(body->string) + 1); + body = body->forward; + } + if (body->type != TYPE_LIST) { throw(LAMBDA_ARGS_NOT_LIST, "fn body must be TYPE_LIST, but is %s", getTypeName(body)); } - if (docs && docs->type != TYPE_STRING) { - throw(BAD_TYPE, "fn docstring must be TYPE_STRING, but is %s", getTypeName(docs)); - } Object o = newObject(TYPE_LAMBDA); o.lambda = malloc(sizeof(struct Lambda)); @@ -741,11 +746,16 @@ inline Object constructLambda(const Object* params, const Object* docs, const Ob o.lambda->body = cloneList(body); lambdaRefs(&o) = 1; - if (docs) { - lambdaDocs(&o) = malloc(sizeof(char) * (strlen(docs->string) + 1)); - strcpy(lambdaDocs(&o), docs->string); - } else { + if (docLength == 0) { lambdaDocs(&o) = NULL; + } else { + lambdaDocs(&o) = malloc(docLength + 1); + char* docText = lambdaDocs(&o); + while (docs->type == TYPE_STRING) { + const char* data = docs->string; + docText += sprintf(docText, "%s\n", data); + docs = docs->forward; + } } Object* dest = &o.lambda->body; diff --git a/src/object.h b/src/object.h index 8f4b4fb..c4469d7 100644 --- a/src/object.h +++ b/src/object.h @@ -317,7 +317,7 @@ Object errorWithAllocatedContextLineNo(enum errorCode code, char* context, int l struct Error noError(); -Object constructLambda(const Object* params, const Object* docs, const Object* body, struct Environment* env); +Object constructLambda(const Object* params, const Object* body, struct Environment* env); #ifdef STANDALONE diff --git a/src/pebblisp.c b/src/pebblisp.c index 48a6f9a..e95266b 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -268,14 +268,8 @@ Object evalList(const Object* obj, struct Environment* env) if (strcmp(first_form->string, "fn") == 0) { Object* params = first_form->forward; - Object* doc = NULL; - Object* body = NULL; - if (params) { - int twoParams = params->forward && params->forward->forward; - doc = twoParams ? params->forward : NULL; - body = twoParams ? params->forward->forward : params->forward; - } - return constructLambda(params, doc, body, env); + Object* body = params->forward; + return constructLambda(params, body, env); } if (strcmp(first_form->string, "struct") == 0) {