Fix no-context error-handling.

Centralize parts of number-parsing.
This commit is contained in:
Sage Vaillancourt 2022-04-14 16:04:17 -04:00 committed by Sage Vaillancourt
parent 3f4d8fd7af
commit 83b1b9212e
4 changed files with 74 additions and 64 deletions

View File

@ -824,6 +824,9 @@ errorWithAllocatedContextLineNo(enum errorCode code, char* context, int lineNo,
inline Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName)
{
if (!context) {
context = "";
}
char* copiedContext = malloc(sizeof(char) * ERR_LEN);
strcpy(copiedContext, context);
return errorWithAllocatedContextLineNo(code, copiedContext, lineNo, fileName);

View File

@ -328,7 +328,10 @@ Object structAccess(Object* params, unused int length, unused struct Environment
Result parse(struct Slice* slices)
{
struct Slice* token = slices;
if (token && token->text) {
if (!token || !token->text) {
return (Result) { errorObject(NULL_PARSE), NULL };
}
struct Slice* rest = &slices[1];
if (token->text[0] == '\'' && token->text[1] == '(') {
Result r = readSeq(&slices[2]);
@ -343,9 +346,6 @@ Result parse(struct Slice* slices)
r.slices = &r.slices[1];
return r;
}
} else {
return (Result) { errorObject(NULL_PARSE), NULL };
}
}
#ifndef NO_SUGAR
@ -382,33 +382,47 @@ Result readSeq(struct Slice* tokens)
}
}
Object parseDecimal(struct Slice* s)
int hexChar(char c)
{
int num = 0;
for (int i = 0; i < s->length; i++) {
if (!isDigit(s->text[i])) {
return errorObject(BAD_NUMBER);
if (isDigit(c)) {
return c - '0';
}
num *= 10;
num += s->text[i] - '0';
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
return numberObject(num);
if (c >= 'A' && c <= 'F'){
return c - 'A' + 10;
}
return -1;
}
Object parseHex(struct Slice* s)
int binChar(char c)
{
if (c == '0' || c == '1') {
return c - '0';
}
return -1;
}
int decChar(char c)
{
if (isDigit(c)) {
return c - '0';
}
return -1;
}
Object parseNum(int base, const char* text, int length, int (*func)(char))
{
int num = 0;
for (int i = 2; i < s->length; i++) {
const char c = s->text[i];
if (!isHex(c)) {
return errorObject(BAD_NUMBER);
}
num *= 16;
if (isDigit(c)) {
num += c - '0';
} else /* is hex */ {
num += c - 'a' + 10;
for (int i = 0; i < length; i++) {
const char c = text[i];
int value = func(c);
if (value < 0) {
throw(BAD_NUMBER, "at %s", text);
}
num *= base;
num += value;
}
return numberObject(num);
}
@ -440,30 +454,28 @@ Result parseAtom(struct Slice* s)
const char c = s->text[0];
if (isDigit(c)) {
if (c != '0' || s->length == 1) {
return (Result) { parseDecimal(s), s };
return (Result) { parseNum(10, s->text, s->length, decChar), s };
}
#ifndef LOW_MEM
} else if (s->text[1] == 'x') {
return (Result) { parseHex(s), s };
} else if (s->text[1] == 'b') {
return (Result) { parseBin(s), s };
if (s->text[1] == 'x') {
return (Result) { parseNum(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 };
}
#endif
} else {
return (Result) { errorWithContext(UNSUPPORTED_NUMBER_TYPE, s->text), s };
}
} else if (s->length == 1 && c == 'T') {
if (s->length == 1 && c == 'T') {
return (Result) { trueObject(), s };
} else if (s->length == 1 && c == 'F') {
}
if (s->length == 1 && c == 'F') {
return (Result) { falseObject(), s };
} else if (c == '"'/* || c == '\''*/) {
}
if (c == '"') {
return (Result) { objFromSlice(s->text, s->length), s };
} else if (s->text[s->length] == '.') {
/*
struct InlinedFunction f ={
.func = structAccess,
.arguments = malloc(sizeof(Object) * 2),
.argCount = 2,
};
f.arguments[0] = symFromSlice(s->text, s->length);
}
if (s->text[s->length] == '.') {
struct Slice* next = s + 2;
f.arguments[1] = stringFromSlice(next->text, next->length);
@ -523,7 +535,7 @@ Object parseEval(const char* input, struct Environment* env)
cleanObject(&obj);
Object parsed = parse(tok).obj;
if (parsed.type == TYPE_ERROR) {
obj = parsed; // TODO Check necessity
obj = parsed;
#ifdef STANDALONE
obj.error->plContext = malloc(sizeof(struct Slice));
*obj.error->plContext = *lastOpen;

View File

@ -107,7 +107,7 @@ Object at(Object* params, unused int length, unused struct Environment* env)
return cloneObject(*found);
}
return errorObject(INDEX_PAST_END);
throw(INDEX_PAST_END, "Tried to access index %ld from list of len %d", index.number, listLength(&list));
}
Object rest(Object* params, unused int length, unused struct Environment* env)

View File

@ -18,7 +18,7 @@ int isSingle(const char c)
int i = 0;
while (singleTokens[i] != '\0') {
if (singleTokens[i] == c) {
return singleTokens[i];
return 1;
}
i++;
}
@ -30,11 +30,6 @@ int isDigit(const char c)
return c >= '0' && c <= '9';
}
int isHex(const char c)
{
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}
int isWhitespace(const char c)
{
return c == ' ' || c == '\t' || c == '\n';