Remove single-quote support for strings.
Add triple-quote support. Switch to structs for handling errors.
This commit is contained in:
parent
49bf4aa1a2
commit
d36f1bf162
17
src/object.c
17
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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
44
src/tokens.c
44
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,11 +99,31 @@ 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') {
|
||||
} 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 {
|
||||
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){
|
||||
*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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue