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",
|
"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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
46
src/tokens.c
46
src/tokens.c
|
@ -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,10 +99,30 @@ 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
|
||||||
l++;
|
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++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue