diff --git a/src/object.c b/src/object.c index 1828454..42093ae 100644 --- a/src/object.c +++ b/src/object.c @@ -218,7 +218,9 @@ static const char *errorText[] = { "NOT_A_LIST", "SCRIPT_NOT_FOUND", "NO_CLONE_SPECIFIED", - "CAN_ONLY_EVAL_STRINGS" + "CAN_ONLY_EVAL_STRINGS", + "UNEXPECTED_EOF", + "INDEX_PAST_END" }; #endif @@ -772,16 +774,16 @@ inline enum errorCode getErrorCode(const Object obj) inline void errorAddContext(Object *o, const char* context) { printf("o: %p\n", o); - printf("o->error: %s\n", o->error); + //printf("o->error: %s\n", o->error); printf("o->error->context: %s\n", o->error->context); o->error->context = calloc(sizeof(char), RESULT_LENGTH); printf("context: %p\n", context); strncpy(o->error->context, context, RESULT_LENGTH); } -inline Object errorWithContext(enum errorCode err, const char* context) +inline Object errorWithContext(enum errorCode code, const char* context) { - Object o = errorObject(err); + Object o = errorObject(code); if (context) { errorAddContext(&o, context); } @@ -789,6 +791,13 @@ inline Object errorWithContext(enum errorCode err, const char* context) } #endif +struct Error noError() +{ + struct Error err; + err.context = NULL; + return err; +} + inline Object toBool(const Object test) { if(test.number == 0) diff --git a/src/object.h b/src/object.h index db1adf8..ace6b20 100644 --- a/src/object.h +++ b/src/object.h @@ -52,6 +52,7 @@ enum errorCode { SCRIPT_NOT_FOUND, NO_CLONE_SPECIFIED, CAN_ONLY_EVAL_STRINGS, + UNEXPECTED_EOF, INDEX_PAST_END, }; @@ -72,12 +73,10 @@ struct Lambda; struct Environment; struct Slice; struct Other; -#ifndef SIMPLE_ERRORS struct Error { enum errorCode code; char* context; }; -#endif struct Object { Type type; @@ -163,6 +162,7 @@ enum errorCode getErrorCode(const Object obj); Object errorWithContext(enum errorCode err, const char* context); void errorAddContext(Object *o, const char* context); #endif +struct Error noError(); Object constructLambda(const Object *params, const Object *body); diff --git a/src/pebblisp.c b/src/pebblisp.c index e17de84..645f9b6 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -733,11 +733,12 @@ Object parseAtom(struct Slice *s) Object parseEval(const char *input, struct Environment *env) { - char *err; + struct Error err = noError(); + struct Slice *tokens = nf_tokenize(input, &err); - if(err) { - Object o = errorWithContext(MISMATCHED_PARENS, err); - free(err); + if(err.context != NULL) { + Object o = errorWithContext(err.code, err.context); + free(err.context); return o; } if(!tokens->text) { diff --git a/src/tokens.c b/src/tokens.c index 9e4863e..fb1a543 100644 --- a/src/tokens.c +++ b/src/tokens.c @@ -25,7 +25,7 @@ */ // Is the char a standalone token? -static const char singleTokens[] = "()+-*/="; +static const char singleTokens[] = "()+-*/='"; int isSingle(const char c) { int i = 0; while(singleTokens[i] != '\0'){ @@ -53,11 +53,11 @@ int notWhitespace(const char c) { } // Return needs to be freed, if not null -struct Slice *nf_tokenize(const char *input, char **err) +struct Slice *nf_tokenize(const char *input, struct Error *err) { if(!input) { - *err = malloc(sizeof(char) * ERR_LEN); - strcpy(*err, "no input"); + err->context = malloc(sizeof(char) * ERR_LEN); + strcpy(err->context, "no input"); return NULL; } @@ -86,9 +86,10 @@ struct Slice *nf_tokenize(const char *input, char **err) } else if (input[i] == ')') { parens--; if(parens < 0) { - *err = malloc(sizeof(char) * ERR_LEN); + err->context = malloc(sizeof(char) * ERR_LEN + 1); + err->code = MISMATCHED_PARENS; int start = i > ERR_LEN ? i - ERR_LEN : 0; - strncpy(*err, &input[start], ERR_LEN); + strncpy(err->context, &input[start], ERR_LEN); free(slices); return NULL; } @@ -98,10 +99,30 @@ struct Slice *nf_tokenize(const char *input, char **err) if(isSingle(input[i])) { i++; - } else if(input[i] == '"' || input[i] == '\'') { - const char quote = input[i]; - while(input[++i] != quote && input[i] != '\0') { - l++; + } else if(input[i] == '"') { + if(input[i + 1] == '"' && input [i + 2] == '"') { + // Triple-quoted block + i += 2; + slices[slice].text += 2; + for(;;) { + i++; + if(input[i] == '"' && input[i + 1] == '"' && input[i + 2] == '"') { + break; + } + if(input[i] == '\0' || input[i + 1] == '\0' || input[i + 2] == '\0') { + err->context = malloc(sizeof(char) * ERR_LEN + 1); + err->code = UNEXPECTED_EOF; + int start = i > ERR_LEN ? i - ERR_LEN : 0; + strncpy(err->context, &input[start], ERR_LEN); + free(slices); + return NULL; + } + } + } else { + // Simple string + while(input[++i] != '"' && input[i] != '\0') { + l++; + } } i++; } else { @@ -115,9 +136,9 @@ struct Slice *nf_tokenize(const char *input, char **err) } if(parens != 0){ - *err = malloc(sizeof(char) * ERR_LEN); + err->context = malloc(sizeof(char) * ERR_LEN); int start = i > ERR_LEN ? i - ERR_LEN : 0; - strncpy(*err, &input[start], ERR_LEN); + strncpy(err->context, &input[start], ERR_LEN); free(slices); return NULL; } @@ -125,6 +146,5 @@ struct Slice *nf_tokenize(const char *input, char **err) slices[slice].text = NULL; slices[slice].length = 0; - *err = NULL; return slices; } diff --git a/src/tokens.h b/src/tokens.h index a4c50c7..1e526e6 100644 --- a/src/tokens.h +++ b/src/tokens.h @@ -6,6 +6,6 @@ int isSingle(const char c); int isDigit(const char c); int isHex(const char c); -struct Slice *nf_tokenize(const char *input, char **err); +struct Slice *nf_tokenize(const char *input, struct Error *err); #endif