Remove single-quote support for strings.

Add triple-quote support.
Switch to structs for handling errors.
This commit is contained in:
Sage Vaillancourt 2021-12-13 10:47:35 -05:00 committed by Sage Vaillancourt
parent 49bf4aa1a2
commit d36f1bf162
5 changed files with 54 additions and 24 deletions

View File

@ -218,7 +218,9 @@ static const char *errorText[] = {
"NOT_A_LIST", "NOT_A_LIST",
"SCRIPT_NOT_FOUND", "SCRIPT_NOT_FOUND",
"NO_CLONE_SPECIFIED", "NO_CLONE_SPECIFIED",
"CAN_ONLY_EVAL_STRINGS" "CAN_ONLY_EVAL_STRINGS",
"UNEXPECTED_EOF",
"INDEX_PAST_END"
}; };
#endif #endif
@ -772,16 +774,16 @@ inline enum errorCode getErrorCode(const Object obj)
inline void errorAddContext(Object *o, const char* context) inline void errorAddContext(Object *o, const char* context)
{ {
printf("o: %p\n", o); 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); printf("o->error->context: %s\n", o->error->context);
o->error->context = calloc(sizeof(char), RESULT_LENGTH); o->error->context = calloc(sizeof(char), RESULT_LENGTH);
printf("context: %p\n", context); printf("context: %p\n", context);
strncpy(o->error->context, context, RESULT_LENGTH); 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) { if (context) {
errorAddContext(&o, context); errorAddContext(&o, context);
} }
@ -789,6 +791,13 @@ inline Object errorWithContext(enum errorCode err, const char* context)
} }
#endif #endif
struct Error noError()
{
struct Error err;
err.context = NULL;
return err;
}
inline Object toBool(const Object test) inline Object toBool(const Object test)
{ {
if(test.number == 0) if(test.number == 0)

View File

@ -52,6 +52,7 @@ enum errorCode {
SCRIPT_NOT_FOUND, SCRIPT_NOT_FOUND,
NO_CLONE_SPECIFIED, NO_CLONE_SPECIFIED,
CAN_ONLY_EVAL_STRINGS, CAN_ONLY_EVAL_STRINGS,
UNEXPECTED_EOF,
INDEX_PAST_END, INDEX_PAST_END,
}; };
@ -72,12 +73,10 @@ struct Lambda;
struct Environment; struct Environment;
struct Slice; struct Slice;
struct Other; struct Other;
#ifndef SIMPLE_ERRORS
struct Error { struct Error {
enum errorCode code; enum errorCode code;
char* context; char* context;
}; };
#endif
struct Object { struct Object {
Type type; Type type;
@ -163,6 +162,7 @@ enum errorCode getErrorCode(const Object obj);
Object errorWithContext(enum errorCode err, const char* context); Object errorWithContext(enum errorCode err, const char* context);
void errorAddContext(Object *o, const char* context); void errorAddContext(Object *o, const char* context);
#endif #endif
struct Error noError();
Object constructLambda(const Object *params, const Object *body); Object constructLambda(const Object *params, const Object *body);

View File

@ -733,11 +733,12 @@ Object parseAtom(struct Slice *s)
Object parseEval(const char *input, struct Environment *env) Object parseEval(const char *input, struct Environment *env)
{ {
char *err; struct Error err = noError();
struct Slice *tokens = nf_tokenize(input, &err); struct Slice *tokens = nf_tokenize(input, &err);
if(err) { if(err.context != NULL) {
Object o = errorWithContext(MISMATCHED_PARENS, err); Object o = errorWithContext(err.code, err.context);
free(err); free(err.context);
return o; return o;
} }
if(!tokens->text) { if(!tokens->text) {

View File

@ -25,7 +25,7 @@
*/ */
// Is the char a standalone token? // Is the char a standalone token?
static const char singleTokens[] = "()+-*/="; static const char singleTokens[] = "()+-*/='";
int isSingle(const char c) { int isSingle(const char c) {
int i = 0; int i = 0;
while(singleTokens[i] != '\0'){ while(singleTokens[i] != '\0'){
@ -53,11 +53,11 @@ int notWhitespace(const char c) {
} }
// Return needs to be freed, if not null // 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) { if(!input) {
*err = malloc(sizeof(char) * ERR_LEN); err->context = malloc(sizeof(char) * ERR_LEN);
strcpy(*err, "no input"); strcpy(err->context, "no input");
return NULL; return NULL;
} }
@ -86,9 +86,10 @@ struct Slice *nf_tokenize(const char *input, char **err)
} else if (input[i] == ')') { } else if (input[i] == ')') {
parens--; parens--;
if(parens < 0) { 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; int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(*err, &input[start], ERR_LEN); strncpy(err->context, &input[start], ERR_LEN);
free(slices); free(slices);
return NULL; return NULL;
} }
@ -98,11 +99,31 @@ struct Slice *nf_tokenize(const char *input, char **err)
if(isSingle(input[i])) { if(isSingle(input[i])) {
i++; i++;
} else if(input[i] == '"' || input[i] == '\'') { } else if(input[i] == '"') {
const char quote = input[i]; if(input[i + 1] == '"' && input [i + 2] == '"') {
while(input[++i] != quote && input[i] != '\0') { // 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++; l++;
} }
}
i++; i++;
} else { } else {
while(!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '\0') { while(!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '\0') {
@ -115,9 +136,9 @@ struct Slice *nf_tokenize(const char *input, char **err)
} }
if(parens != 0){ 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; int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(*err, &input[start], ERR_LEN); strncpy(err->context, &input[start], ERR_LEN);
free(slices); free(slices);
return NULL; return NULL;
} }
@ -125,6 +146,5 @@ struct Slice *nf_tokenize(const char *input, char **err)
slices[slice].text = NULL; slices[slice].text = NULL;
slices[slice].length = 0; slices[slice].length = 0;
*err = NULL;
return slices; return slices;
} }

View File

@ -6,6 +6,6 @@
int isSingle(const char c); int isSingle(const char c);
int isDigit(const char c); int isDigit(const char c);
int isHex(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 #endif