Add a simple assert() macro.

assert() is disabled when calling make release
Support negative numbers!
This commit is contained in:
Sage Vaillancourt 2022-04-27 16:44:00 -04:00 committed by Sage Vaillancourt
parent 5ab7a638af
commit 139e912548
7 changed files with 65 additions and 56 deletions

View File

@ -26,7 +26,7 @@ val: notest
./tests.sh -val
release_notest:
gcc -O3 $(GCC_ARGS) $(file_libs) && strip ./$(exe)
gcc -O3 $(GCC_ARGS) -D RELEASE $(file_libs) && strip ./$(exe)
release: release_notest
echo && ./tests.sh

View File

@ -8,14 +8,16 @@
size_t addStripped(struct ObjectTable* table, char* name, struct StrippedObject object);
char* ERROR_ARRAY[1] = {"ERROR THIS VALUE SHOULD BE IGNORED"};
Object deStrip(struct StrippedObject object)
{
// Garbage .forward data may be safe here, but since usage of that data is
// currently in flux, it should take the more cautious route for now.
// Garbage .forward/.docStrings data may be safe here.
// Usage of that data is currently in flux, so it has a very noisy value for now.
return (Object) {
.type = object.type,
.string = object.data,
.forward = NULL,
.docStrings = ERROR_ARRAY,
};
}
@ -130,6 +132,7 @@ static size_t hash(unused const char* str, struct ObjectTable* table)
*/
size_t addStripped(struct ObjectTable* table, char* name, struct StrippedObject object)
{
assert(table);
extendTable(table);
size_t initial = hash(name, table);
size_t h = initial % table->capacity;
@ -171,12 +174,13 @@ Object buildHashTable(Object* params, int length, struct Environment* env)
capacity = params[0].number;
}
Object table = newObject(TYPE_HASH_TABLE);
table.table = malloc(sizeof(struct ObjectTableObject));
table.table->table = buildTable(capacity);
table.table->refs = 1;
struct ObjectTableObject* table = malloc(sizeof(struct ObjectTableObject));
table->table = buildTable(capacity);
table->refs = 1;
return table;
Object tableObject = newObject(TYPE_HASH_TABLE);
tableObject.data = table;
return tableObject;
}
Object addToHashTable(Object* params, int length, struct Environment* env)

View File

@ -102,15 +102,17 @@ void repl(struct Environment* env)
}
add_history(buf);
if (buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' ') {
int isCd = strncmp("cd ", buf, 3);
int isHelp = buf[0] == '?' && (buf[1] == ' ' || buf[1] == '\0');
if (isCd || isHelp) {
char* oldBuf = buf;
if (isCd) {
buf = malloc(sizeof(char) * strlen(buf + 3) + 8);
sprintf(buf, "(cd \"%s\")", oldBuf + 3);
free(oldBuf);
} else if (buf[0] == '?' && (buf[1] == ' ' || buf[1] == '\0')) {
char* oldBuf = buf;
} else {
buf = malloc(sizeof(char) * (strlen(buf) + 3));
sprintf(buf, "(%s)", oldBuf);
}
free(oldBuf);
}

View File

@ -42,6 +42,7 @@ void* scalloc(size_t size, size_t count)
*/
int listLength(const Object* listObj)
{
assert(isListy(*listObj));
int len = 0;
FOR_POINTER_IN_LIST(listObj) {
len++;
@ -56,10 +57,7 @@ int listLength(const Object* listObj)
*/
Object* tail(const Object* listObj)
{
if (!isListy(*listObj)) {
return NULL;
}
assert(isListy(*listObj));
Object* tail = NULL;
FOR_POINTER_IN_LIST(listObj) {
tail = POINTER;
@ -491,6 +489,8 @@ void printAndClean(Object* target)
*/
void deleteList(Object* dest)
{
assert(isListy(*dest));
Object* march = dest->list;
while (march != NULL) {
Object* prevMarch = march;
@ -511,6 +511,8 @@ void deleteList(Object* dest)
*/
Object cloneList(const Object* src)
{
assert(isListy(*src));
Object BuildListNamed(list);
FOR_POINTER_IN_LIST(src) {
addToList(list, cloneObject(*POINTER));
@ -647,6 +649,7 @@ inline Object cloneObject(const Object src)
Object cloneStruct(const Object src)
{
assert(src.type == TYPE_STRUCT);
Object structo = structObject(src.structObject->definition);
struct StructObject* so = structo.structObject;
for (int i = 0; i < getStructAt(so->definition)->fieldCount; i++) {

View File

@ -19,6 +19,12 @@
#define printd(...) do { } while (0)
#endif
#ifdef RELEASE
#define assert(...) do { } while (0)
#else
#define assert(...) do {if (!(__VA_ARGS__)) {eprintf("\nassertion '" # __VA_ARGS__ "' at %s:%d failed!\nBailing!\n", __FILE__, __LINE__); int* X = NULL; unused int Y = *X;}} while (0)
#endif
#define MAX_TOK_CNT 2048
#define FOR_POINTER_IN_LIST(_list) \

View File

@ -203,9 +203,8 @@ Object listEvalLambda(Object* lambda, const Object* passedArguments, int evalLen
deleteEnv(&newEnv);
cleanObject(lambda);
Object* t = tail(&ret);
if (t) {
Object o = cloneObject(*t);
if (isListy(ret)) {
Object o = cloneObject(*tail(&ret));
cleanObject(&ret);
return o;
}
@ -223,19 +222,14 @@ Object listEvalLambda(Object* lambda, const Object* passedArguments, int evalLen
Object funcyEval(Object* funcy, const Object* passedArguments, int evalLength,
struct Environment* env)
{
if (!funcy) {
eprintf("HIGHLY ILLEGAL NULL FUNC-LIKE!!!\n");
throw(BAD_TYPE, "Expected func-like object, but received null");
}
switch (funcy->type) {
case TYPE_LAMBDA:
assert(funcy != NULL);
assert(isFuncy(*funcy));
if (funcy->type == TYPE_LAMBDA) {
return listEvalLambda(funcy, passedArguments, evalLength, env);
case TYPE_FUNC:
return listEvalFunc(funcy, passedArguments, evalLength, env);
default:
eprintf("HIGHLY ILLEGAL NOT-FUNC IN funcyEval()!!!\n");
throw(BAD_TYPE, "Expected func-like object, but received %s", getTypeName(funcy));
}
return listEvalFunc(funcy, passedArguments, evalLength, env);
}
/**
@ -390,11 +384,10 @@ Object structAccess(Object* params, unused int length, unused struct Environment
Result parse(struct Slice* slices)
{
struct Slice* token = slices;
if (!token || !token->text) {
return (Result) { errorObject(NULL_PARSE), NULL };
}
assert(slices);
assert(slices->text);
struct Slice* token = slices;
struct Slice* rest = &slices[1];
if (token->text[0] == '\'' && token->text[1] == '(') {
Result r = readSeq(&slices[2]);
@ -480,7 +473,7 @@ int decChar(char c)
return -1;
}
Object parseNum(int base, const char* text, int length, int (* func)(char))
Object parseNum(int sign, int base, const char* text, int length, int (* func)(char))
{
int num = 0;
for (int i = 0; i < length; i++) {
@ -492,7 +485,7 @@ Object parseNum(int base, const char* text, int length, int (* func)(char))
num *= base;
num += value;
}
return numberObject(num);
return numberObject(num * sign);
}
Object optimize(Object (* func)(Object*, int, struct Environment*), int argCount, Object args[])
@ -516,17 +509,24 @@ Object optimize(Object (* func)(Object*, int, struct Environment*), int argCount
Result parseAtom(struct Slice* s)
{
const char c = s->text[0];
if (isDigit(c)) {
char c = s->text[0];
if (isDigit(c) || (c == '-' && isDigit(s->text[1]))) {
int sign = 1;
if (c == '-') {
s->text = &s->text[1];
s->length -= 1;
c = s->text[0];
sign = -1;
}
if (c != '0' || s->length == 1) {
return (Result) { parseNum(10, s->text, s->length, decChar), s };
return (Result) { parseNum(sign, 10, s->text, s->length, decChar), s };
}
#ifndef LOW_MEM
if (s->text[1] == 'x') {
return (Result) { parseNum(16, s->text + 2, s->length - 2, hexChar), s };
return (Result) { parseNum(sign, 16, s->text + 2, s->length - 2, hexChar), s };
}
if (s->text[1] == 'b') {
return (Result) { parseNum(2, s->text + 2, s->length - 2, binChar), s };
return (Result) { parseNum(sign, 2, s->text + 2, s->length - 2, binChar), s };
}
#endif
return (Result) { errorWithContext(UNSUPPORTED_NUMBER_TYPE, s->text), s };

View File

@ -81,19 +81,13 @@ Object at(Object* params, unused int length, unused struct Environment* env)
Object index = params[0];
Object list = params[1];
const Object* found = NULL;
int n = index.number;
FOR_POINTER_IN_LIST(&list) {
if (n-- == 0) {
found = POINTER;
break;
return cloneObject(*POINTER);
}
}
if (found) {
return cloneObject(*found);
}
throw(INDEX_PAST_END, "Tried to access index %ld from list of len %d", index.number, listLength(&list));
}
@ -298,7 +292,7 @@ Object equ(Object* params, int length, unused struct Environment* env)
Object or(Object* params, int length, unused struct Environment* env)
{
if (length < 2) {
return errorObject(NOT_ENOUGH_ARGUMENTS);
throw(NOT_ENOUGH_ARGUMENTS, "`|` requires at least two arguments");
}
for (int i = 0; i < length - 1; i++) {
@ -313,7 +307,7 @@ Object or(Object* params, int length, unused struct Environment* env)
Object NAME(Object* params, int length, struct Environment* env) \
{ \
if (length < 2) { \
return errorObject(NOT_ENOUGH_ARGUMENTS); \
throw(NOT_ENOUGH_ARGUMENTS, "`" # OP "` requires at least two arguments"); \
} \
\
for (int i = 0; i < length - 1; i++) { \