A bit of cleanup/simplification.
This commit is contained in:
parent
1c52cb0ff1
commit
20f2d02f77
44
src/object.c
44
src/object.c
|
@ -49,30 +49,14 @@ int listLength(const Object* listObj)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a pointer to the Object at the given index in a given list
|
|
||||||
* @param listObj The list to fetch an Object from
|
|
||||||
* @param n The index to to fetch from the list
|
|
||||||
* @return A pointer to the Object, if it is found, or NULL on an error
|
|
||||||
*/
|
|
||||||
Object* itemAt(const Object* listObj, int n)
|
|
||||||
{
|
|
||||||
FOR_POINTER_IN_LIST(listObj) {
|
|
||||||
if (n-- == 0) {
|
|
||||||
return POINTER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a pointer to the last Object in the given list.
|
* Returns a pointer to the last Object in the given list.
|
||||||
* @param listObj The list to find the tail of
|
* @param listObj The list to find the tail of.
|
||||||
* @return A pointer to the last Object if it is found, or NULL on an error
|
* @return A pointer to the last Object if it is found, or NULL on an error
|
||||||
*/
|
*/
|
||||||
Object* tail(const Object* listObj)
|
Object* tail(const Object* listObj)
|
||||||
{
|
{
|
||||||
if (!listObj || !isListy(*listObj)) {
|
if (!isListy(*listObj)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +268,7 @@ int stringNObj(struct string* s, const Object* obj)
|
||||||
inflate(s, 128);
|
inflate(s, 128);
|
||||||
if (obj->error->context && obj->error->context[0] != '\0') {
|
if (obj->error->context && obj->error->context[0] != '\0') {
|
||||||
appendf(s, "%s: %s", errorText[code],
|
appendf(s, "%s: %s", errorText[code],
|
||||||
obj->error->context);
|
obj->error->context);
|
||||||
} else if (code >= 0 && code <= INDEX_PAST_END) {
|
} else if (code >= 0 && code <= INDEX_PAST_END) {
|
||||||
appendf(s, "%s", errorText[code]);
|
appendf(s, "%s", errorText[code]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -374,7 +358,7 @@ const char* getTypeName(const Object* obj)
|
||||||
void _printObj(const Object* obj, int newline)
|
void _printObj(const Object* obj, int newline)
|
||||||
{
|
{
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
printf(newline ? "\n" : "");
|
printf(newline ? "<null>\n" : "<null>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t length;
|
size_t length;
|
||||||
|
@ -421,18 +405,18 @@ void cleanObject(Object* target)
|
||||||
if ((target->string[-1] -= 1) == 0) {
|
if ((target->string[-1] -= 1) == 0) {
|
||||||
free(target->string - 1);
|
free(target->string - 1);
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
case TYPE_SLIST:
|
case TYPE_SLIST:
|
||||||
deleteList(target);
|
deleteList(target);
|
||||||
break;
|
return;
|
||||||
case TYPE_HASH_TABLE:
|
case TYPE_HASH_TABLE:
|
||||||
target->table->refs -= 1;
|
target->table->refs -= 1;
|
||||||
if (!target->table->refs) {
|
if (!target->table->refs) {
|
||||||
deleteTable(&target->table->table);
|
deleteTable(&target->table->table);
|
||||||
free(target->table);
|
free(target->table);
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
case TYPE_LAMBDA:
|
case TYPE_LAMBDA:
|
||||||
lambdaRefs(target) -= 1;
|
lambdaRefs(target) -= 1;
|
||||||
if (!lambdaRefs(target)) {
|
if (!lambdaRefs(target)) {
|
||||||
|
@ -441,29 +425,29 @@ void cleanObject(Object* target)
|
||||||
free(lambdaDocs(target));
|
free(lambdaDocs(target));
|
||||||
free(target->lambda);
|
free(target->lambda);
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
case TYPE_STRUCT:
|
case TYPE_STRUCT:
|
||||||
for (int i = 0; i < getStructAt(target->structObject->definition)->fieldCount; i++) {
|
for (int i = 0; i < getStructAt(target->structObject->definition)->fieldCount; i++) {
|
||||||
cleanObject(&target->structObject->fields[i]);
|
cleanObject(&target->structObject->fields[i]);
|
||||||
}
|
}
|
||||||
free(target->structObject->fields);
|
free(target->structObject->fields);
|
||||||
free(target->structObject);
|
free(target->structObject);
|
||||||
break;
|
return;
|
||||||
case TYPE_PROMISE:
|
case TYPE_PROMISE:
|
||||||
cleanPromise(target->promise);
|
cleanPromise(target->promise);
|
||||||
break;
|
return;
|
||||||
case TYPE_ERROR:
|
case TYPE_ERROR:
|
||||||
#ifndef SIMPLE_ERRORS
|
#ifndef SIMPLE_ERRORS
|
||||||
free(target->error->plContext);
|
free(target->error->plContext);
|
||||||
free(target->error->context);
|
free(target->error->context);
|
||||||
free(target->error);
|
free(target->error);
|
||||||
#endif
|
#endif
|
||||||
break;
|
return;
|
||||||
case TYPE_OTHER:
|
case TYPE_OTHER:
|
||||||
if (target->other->cleanup) {
|
if (target->other->cleanup) {
|
||||||
target->other->cleanup(target);
|
target->other->cleanup(target);
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
case TYPE_STATIC_FUNC:
|
case TYPE_STATIC_FUNC:
|
||||||
if ((target->staticF->refs -= 1) == 0) {
|
if ((target->staticF->refs -= 1) == 0) {
|
||||||
for (int i = 0; i < target->staticF->argCount; i++) {
|
for (int i = 0; i < target->staticF->argCount; i++) {
|
||||||
|
@ -471,11 +455,11 @@ void cleanObject(Object* target)
|
||||||
}
|
}
|
||||||
free(target->staticF);
|
free(target->staticF);
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
case TYPE_NUMBER:
|
case TYPE_NUMBER:
|
||||||
case TYPE_FUNC:
|
case TYPE_FUNC:
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,8 +232,6 @@ void deleteList(Object* dest);
|
||||||
|
|
||||||
int listLength(const Object* listObj);
|
int listLength(const Object* listObj);
|
||||||
|
|
||||||
Object* itemAt(const Object* listObj, int n);
|
|
||||||
|
|
||||||
void cleanObject(Object* target);
|
void cleanObject(Object* target);
|
||||||
|
|
||||||
void printAndClean(Object* target);
|
void printAndClean(Object* target);
|
||||||
|
|
|
@ -230,7 +230,9 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
if (first_form->type == TYPE_SYMBOL) {
|
if (first_form->type == TYPE_SYMBOL) {
|
||||||
if (strcmp(first_form->string, "if") == 0) {
|
if (strcmp(first_form->string, "if") == 0) {
|
||||||
return evalIfArgs(first_form->forward, env);
|
return evalIfArgs(first_form->forward, env);
|
||||||
} else if (strcmp(first_form->string, "fn") == 0) {
|
}
|
||||||
|
|
||||||
|
if (strcmp(first_form->string, "fn") == 0) {
|
||||||
Object* params = first_form->forward;
|
Object* params = first_form->forward;
|
||||||
Object* doc = NULL;
|
Object* doc = NULL;
|
||||||
Object* body = NULL;
|
Object* body = NULL;
|
||||||
|
@ -240,7 +242,9 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
body = twoParams ? params->forward->forward : params->forward;
|
body = twoParams ? params->forward->forward : params->forward;
|
||||||
}
|
}
|
||||||
return constructLambda(params, doc, body, env);
|
return constructLambda(params, doc, body, env);
|
||||||
} else if (strcmp(first_form->string, "struct") == 0) {
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,19 +374,21 @@ Result parse(struct Slice* slices)
|
||||||
r.obj.type = TYPE_SLIST;
|
r.obj.type = TYPE_SLIST;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} else if (token->text[0] == '(') {
|
|
||||||
return readSeq(rest);
|
|
||||||
} else {
|
|
||||||
Result r = parseAtom(token);
|
|
||||||
r.slices = &r.slices[1];
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token->text[0] == '(') {
|
||||||
|
return readSeq(rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result r = parseAtom(token);
|
||||||
|
r.slices = &r.slices[1];
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_SUGAR
|
#ifndef NO_SUGAR
|
||||||
#define sugar(_desc, _code) _code
|
#define sugar(_code) _code
|
||||||
#else
|
#else
|
||||||
#define sugar(_desc, _code) ;
|
#define sugar(_code) do { } while (0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Result readSeq(struct Slice* tokens)
|
Result readSeq(struct Slice* tokens)
|
||||||
|
@ -396,15 +402,17 @@ Result readSeq(struct Slice* tokens)
|
||||||
return (Result) { res, rest };
|
return (Result) { res, rest };
|
||||||
}
|
}
|
||||||
Result r = parse(tokens);
|
Result r = parse(tokens);
|
||||||
sugar("(? fil) => (? 'fil')" // or,
|
|
||||||
"(def yee 10) => (def 'yee' 10)",
|
|
||||||
if (forceString && r.obj.type == TYPE_SYMBOL) {
|
|
||||||
r.obj.type = TYPE_STRING;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if (r.obj.type == TYPE_ERROR) {
|
if (r.obj.type == TYPE_ERROR) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
sugar(
|
||||||
|
// (? fil) => (? 'fil') // or,
|
||||||
|
// (def yee 10) => (def 'yee' 10)
|
||||||
|
// (set yee 10) => (set 'yee' 10)
|
||||||
|
if (forceString && r.obj.type == TYPE_SYMBOL) {
|
||||||
|
r.obj.type = TYPE_STRING;
|
||||||
|
}
|
||||||
|
)
|
||||||
nf_addToList(&res, cloneObject(r.obj));
|
nf_addToList(&res, cloneObject(r.obj));
|
||||||
tokens = r.slices;
|
tokens = r.slices;
|
||||||
cleanObject(&r.obj);
|
cleanObject(&r.obj);
|
||||||
|
|
27
src/plfunc.c
27
src/plfunc.c
|
@ -101,7 +101,14 @@ Object at(Object* params, unused int length, unused struct Environment* env)
|
||||||
Object index = params[0];
|
Object index = params[0];
|
||||||
Object list = params[1];
|
Object list = params[1];
|
||||||
|
|
||||||
const Object* found = itemAt(&list, index.number);
|
const Object* found = NULL;
|
||||||
|
int n = index.number;
|
||||||
|
FOR_POINTER_IN_LIST(&list) {
|
||||||
|
if (n-- == 0) {
|
||||||
|
found = POINTER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
return cloneObject(*found);
|
return cloneObject(*found);
|
||||||
|
@ -116,22 +123,20 @@ Object rest(Object* params, unused int length, unused struct Environment* env)
|
||||||
Object list = params[0];
|
Object list = params[0];
|
||||||
|
|
||||||
BuildListNamed(ret);
|
BuildListNamed(ret);
|
||||||
Object* l = &list;
|
if (list.list) {
|
||||||
FOR_POINTER_IN_LIST(l) {
|
for (Object* _element = list.list->forward; _element != NULL; _element = _element->forward) {
|
||||||
if (POINTER == l->list) {
|
addToList(ret, cloneObject(*POINTER));
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
addToList(ret, cloneObject(*POINTER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object reverse(Object* params, unused int length, unused struct Environment* ignore2)
|
Object reverse(Object* params, unused int length, unused struct Environment* ignore2)
|
||||||
{
|
{
|
||||||
checkTypes(reverse)
|
checkTypes(reverse)
|
||||||
Object _list = params[0];
|
const Object* list = ¶ms[0];
|
||||||
|
|
||||||
const Object* list = &_list;
|
|
||||||
Object rev = listObject();
|
Object rev = listObject();
|
||||||
|
|
||||||
Object* tail = NULL;
|
Object* tail = NULL;
|
||||||
|
@ -301,7 +306,8 @@ Object parseEvalO(Object* params, unused int length, struct Environment* env)
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
return parseEval(text.string, env);
|
return parseEval(text.string, env);
|
||||||
default:
|
default:
|
||||||
throw(CAN_ONLY_EVAL_STRINGS, "Tried to (eval) a %s, instead of a string or symbol list", getTypeName(&text));
|
throw(CAN_ONLY_EVAL_STRINGS, "Tried to (eval) a %s, instead of a string or symbol list",
|
||||||
|
getTypeName(&text));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +336,6 @@ Object catObjects(Object* params, int length, unused struct Environment* env)
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Object len(Object* params, unused int length, unused struct Environment* env)
|
Object len(Object* params, unused int length, unused struct Environment* env)
|
||||||
{
|
{
|
||||||
checkTypes(len)
|
checkTypes(len)
|
||||||
|
@ -382,7 +387,7 @@ int areEqual(const Object* obj1, const Object* obj2)
|
||||||
const long n2 = obj2->number;
|
const long n2 = obj2->number;
|
||||||
|
|
||||||
if (bothAre(TYPE_STRING, obj1, obj2)) {
|
if (bothAre(TYPE_STRING, obj1, obj2)) {
|
||||||
return !strcmp(obj1->string, obj2->string);
|
return obj1->string == obj2->string || strcmp(obj1->string, obj2->string) == 0;
|
||||||
}
|
}
|
||||||
if (bothAre(TYPE_LIST, obj1, obj2)) {
|
if (bothAre(TYPE_LIST, obj1, obj2)) {
|
||||||
return listEquality(obj1, obj2);
|
return listEquality(obj1, obj2);
|
||||||
|
|
Loading…
Reference in New Issue