Implement simple fn docstrings.
Adds usage of this new feature for pebblisp.pbl's (alias).
This commit is contained in:
parent
9abec12d99
commit
056ea9eb13
|
@ -409,9 +409,10 @@ Object help(Object* params, int length, struct Environment* env)
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object* object = fetch(symbol, env);
|
Object* object = fetch(symbol, env);
|
||||||
if (object) {
|
if (object) {
|
||||||
size_t len;
|
size_t len = 0;
|
||||||
char* string = stringObj(object, &len);
|
char* string = stringObj(object, &len);
|
||||||
Object text = stringFromSlice(string, len);
|
Object text = stringFromSlice(string, len);
|
||||||
free(string);
|
free(string);
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
(Alias "r" "(reloadConfig)")
|
(Alias "r" "(reloadConfig)")
|
||||||
))
|
))
|
||||||
|
|
||||||
(def alias (fn () (
|
(def alias (fn ()
|
||||||
|
"Get a string that lists all current aliases." (
|
||||||
(reduce (map (fn (a) (cat nl a.name " -> " a.value)) aliases) cat "")
|
(reduce (map (fn (a) (cat nl a.name " -> " a.value)) aliases) cat "")
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
|
19
src/object.c
19
src/object.c
|
@ -294,6 +294,11 @@ int stringNObj(struct string* s, const Object* obj)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
s->cursor += sprintf(s->cursor, "\\x%d", obj->number);
|
s->cursor += sprintf(s->cursor, "\\x%d", obj->number);
|
||||||
#endif
|
#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);
|
stringNObj(s, &obj->lambda->params);
|
||||||
s->cursor += sprintf(s->cursor, " -> ");
|
s->cursor += sprintf(s->cursor, " -> ");
|
||||||
stringNObj(s, &obj->lambda->body);
|
stringNObj(s, &obj->lambda->body);
|
||||||
|
@ -418,6 +423,7 @@ void cleanObject(Object* target)
|
||||||
cleanObject(&target->lambda->params);
|
cleanObject(&target->lambda->params);
|
||||||
cleanObject(&target->lambda->body);
|
cleanObject(&target->lambda->body);
|
||||||
free(target->lambda);
|
free(target->lambda);
|
||||||
|
free(target->lambda->params.docString);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_STRUCT:
|
case TYPE_STRUCT:
|
||||||
|
@ -728,7 +734,7 @@ inline Object withLen(size_t len, enum Type type)
|
||||||
return o;
|
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) {
|
if (!params || !body) {
|
||||||
return errorObject(NULL_LAMBDA_LIST);
|
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);
|
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);
|
Object o = newObject(TYPE_LAMBDA);
|
||||||
o.lambda = malloc(sizeof(struct Lambda));
|
o.lambda = malloc(sizeof(struct Lambda));
|
||||||
o.lambda->params = copyList(params);
|
o.lambda->params = copyList(params);
|
||||||
o.lambda->body = copyList(body);
|
o.lambda->body = copyList(body);
|
||||||
o.lambda->refs = 1;
|
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;
|
Object* dest = &o.lambda->body;
|
||||||
FOR_POINTER_IN_LIST(dest) {
|
FOR_POINTER_IN_LIST(dest) {
|
||||||
if (POINTER->type == TYPE_SYMBOL) {
|
if (POINTER->type == TYPE_SYMBOL) {
|
||||||
|
|
|
@ -125,6 +125,7 @@ struct StructObject {
|
||||||
|
|
||||||
struct Lambda {
|
struct Lambda {
|
||||||
int refs;
|
int refs;
|
||||||
|
/// Note: params.docstring can contain details about the constructed lambda.
|
||||||
Object params;
|
Object params;
|
||||||
Object body;
|
Object body;
|
||||||
};
|
};
|
||||||
|
@ -250,7 +251,7 @@ void errorAddContext(Object* o, const char* context, int lineNo, const char* fil
|
||||||
|
|
||||||
struct Error noError();
|
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
|
#ifdef STANDALONE
|
||||||
|
|
||||||
|
|
|
@ -226,8 +226,13 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
return evalIfArgs(first_form->forward, env);
|
return evalIfArgs(first_form->forward, env);
|
||||||
} else if (strcmp(first_form->string, "fn") == 0) {
|
} else if (strcmp(first_form->string, "fn") == 0) {
|
||||||
Object* params = first_form->forward;
|
Object* params = first_form->forward;
|
||||||
Object* body = params ? params->forward : NULL;
|
Object* doc = NULL;
|
||||||
return constructLambda(params, body, env);
|
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) {
|
} else if (strcmp(first_form->string, "struct") == 0) {
|
||||||
return evalStructArgs(first_form->forward, first_form->forward->forward, env);
|
return evalStructArgs(first_form->forward, first_form->forward->forward, env);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue