Implement simple fn docstrings.

Adds usage of this new feature for pebblisp.pbl's (alias).
This commit is contained in:
Sage Vaillancourt 2022-04-08 00:36:12 -04:00
parent 9abec12d99
commit 056ea9eb13
5 changed files with 33 additions and 8 deletions

View File

@ -409,9 +409,10 @@ Object help(Object* params, int length, struct Environment* env)
return text;
}
}
Object* object = fetch(symbol, env);
if (object) {
size_t len;
size_t len = 0;
char* string = stringObj(object, &len);
Object text = stringFromSlice(string, len);
free(string);

View File

@ -35,9 +35,10 @@
(Alias "r" "(reloadConfig)")
))
(def alias (fn () (
(reduce (map (fn (a) (cat nl a.name " -> " a.value)) aliases) cat "")
)))
(def alias (fn ()
"Get a string that lists all current aliases." (
(reduce (map (fn (a) (cat nl a.name " -> " a.value)) aliases) cat "")
)))
(def commRunning F)

View File

@ -294,6 +294,11 @@ int stringNObj(struct string* s, const Object* obj)
#ifdef DEBUG
s->cursor += sprintf(s->cursor, "\\x%d", obj->number);
#endif
char* docString = obj->lambda->params.docString;
if (docString) {
inflate(s, strlen(docString));
s->cursor += sprintf(s->cursor, "%s\n", docString);
}
stringNObj(s, &obj->lambda->params);
s->cursor += sprintf(s->cursor, " -> ");
stringNObj(s, &obj->lambda->body);
@ -418,6 +423,7 @@ void cleanObject(Object* target)
cleanObject(&target->lambda->params);
cleanObject(&target->lambda->body);
free(target->lambda);
free(target->lambda->params.docString);
}
break;
case TYPE_STRUCT:
@ -728,7 +734,7 @@ inline Object withLen(size_t len, enum Type type)
return o;
}
inline Object constructLambda(const Object* params, const Object* body, struct Environment* env)
inline Object constructLambda(const Object* params, const Object* docs, const Object* body, struct Environment* env)
{
if (!params || !body) {
return errorObject(NULL_LAMBDA_LIST);
@ -738,12 +744,23 @@ inline Object constructLambda(const Object* params, const Object* body, struct E
return errorObject(LAMBDA_ARGS_NOT_LIST);
}
if (docs && docs->type != TYPE_STRING) {
return errorWithContext(BAD_TYPE, "fn docstring must be a string");
}
Object o = newObject(TYPE_LAMBDA);
o.lambda = malloc(sizeof(struct Lambda));
o.lambda->params = copyList(params);
o.lambda->body = copyList(body);
o.lambda->refs = 1;
if (docs) {
o.lambda->params.docString = malloc(sizeof(char) * (strlen(docs->string) + 1));
strcpy(o.lambda->params.docString, docs->string);
} else {
o.lambda->params.docString = NULL;
}
Object* dest = &o.lambda->body;
FOR_POINTER_IN_LIST(dest) {
if (POINTER->type == TYPE_SYMBOL) {

View File

@ -125,6 +125,7 @@ struct StructObject {
struct Lambda {
int refs;
/// Note: params.docstring can contain details about the constructed lambda.
Object params;
Object body;
};
@ -250,7 +251,7 @@ void errorAddContext(Object* o, const char* context, int lineNo, const char* fil
struct Error noError();
Object constructLambda(const Object* params, const Object* body, struct Environment* env);
Object constructLambda(const Object* params, const Object* docs, const Object* body, struct Environment* env);
#ifdef STANDALONE

View File

@ -226,8 +226,13 @@ Object evalList(const Object* obj, struct Environment* env)
return evalIfArgs(first_form->forward, env);
} else if (strcmp(first_form->string, "fn") == 0) {
Object* params = first_form->forward;
Object* body = params ? params->forward : NULL;
return constructLambda(params, body, env);
Object* doc = NULL;
Object* body = NULL;
if (params) {
doc = params->forward && params->forward->forward ? params->forward : NULL;
body = doc ? params->forward->forward : params->forward;
}
return constructLambda(params, doc, body, env);
} else if (strcmp(first_form->string, "struct") == 0) {
return evalStructArgs(first_form->forward, first_form->forward->forward, env);
}