Start dropping support for semicolon separators.

Simplify some error functions.
Oh, right. strdup() exists.
This commit is contained in:
Sage Vaillancourt 2022-04-14 00:31:51 -04:00
parent e326af38f8
commit 3f4d8fd7af
8 changed files with 76 additions and 81 deletions

View File

@ -89,9 +89,7 @@ void addToEnv(struct Environment* env, const char* name, const Object obj)
existing->data = o.data;
return;
}
char* symbol = malloc(sizeof(char) * (strlen(name) + 1));
strcpy(symbol, name);
addToTable(&env->table, symbol, cloneObject(obj));
addToTable(&env->table, strdup(name), cloneObject(obj));
}
/**

View File

@ -69,8 +69,7 @@ char* completionGenerator(const char* text, int state)
struct ObjectTable* table = &global()->table;
for (; i < table->capacity; i++) {
if (table->elements[i].symbol && strncmp(table->elements[i].symbol, text, completionLength) == 0) {
char* symbol = malloc(sizeof(char) * (strlen(table->elements[i].symbol) + 1));
strcpy(symbol, table->elements[i].symbol);
char* symbol = strdup(table->elements[i].symbol);
i++;
return symbol;
}

View File

@ -813,23 +813,20 @@ inline Object errorObject(enum errorCode err)
#ifndef SIMPLE_ERRORS
inline void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName)
inline Object
errorWithAllocatedContextLineNo(enum errorCode code, char* context, int lineNo, const char* fileName)
{
o->error->context = malloc(sizeof(char) * RESULT_LENGTH);
char* cursor = o->error->context;
cursor += sprintf(cursor, "%s", context);
if (fileName) {
sprintf(cursor, " %s:%d", fileName, lineNo);
}
Object o = errorObject(code);
sprintf(context + strlen(context), " %s:%d", fileName, lineNo);
o.error->context = context;
return o;
}
inline Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName)
{
Object o = errorObject(code);
if (context) {
errorAddContext(&o, context, lineNo, fileName);
}
return o;
char* copiedContext = malloc(sizeof(char) * ERR_LEN);
strcpy(copiedContext, context);
return errorWithAllocatedContextLineNo(code, copiedContext, lineNo, fileName);
}
#endif

View File

@ -10,6 +10,8 @@
#else
#define ERR_LEN 256
#ifdef DEBUG
#define printd(...) printf(__VA_ARGS__)
#else
@ -248,17 +250,17 @@ Object errorObject(enum errorCode err);
Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName);
Object errorWithAllocatedContextLineNo(enum errorCode code, char* context, int lineNo, const char* fileName);
#ifdef SIMPLE_ERRORS
#define errorWithContext(code, context) errorObject(code)
#define errorAddContext(x, y, z, a) ;
#define throw(_code, ...) return errorObject(_code)
#else
char ERROR_CONTEXT[128];
#define throw(_code, ...) sprintf(ERROR_CONTEXT, __VA_ARGS__); return errorWithContext(_code, ERROR_CONTEXT)
#define throw(_code, ...) do { char* ERROR_CONTEXT = malloc(sizeof(char) * ERR_LEN); sprintf(ERROR_CONTEXT, __VA_ARGS__); \
return errorWithAllocatedContextLineNo(_code, ERROR_CONTEXT, __LINE__, __FILE__); } while (0)
#define errorWithContext(_code, _context) errorWithContextLineNo(_code, _context, __LINE__, __FILE__)
void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName);
#endif
struct Error noError();

View File

@ -50,16 +50,14 @@ Object evalStructArgs(const Object* symbol, const Object* fields, unused struct
int fieldCount = listLength(fields);
struct StructDef def = {
.name = malloc(sizeof(char) * (strlen(name) + 1)),
.name = strdup(name),
.fieldCount = fieldCount,
.names = malloc(sizeof(char*) * fieldCount),
};
strcpy(def.name, name);
int i = 0;
FOR_POINTER_IN_LIST(fields) {
def.names[i] = malloc(sizeof(char) * (strlen(POINTER->string) + 1));
strcpy(def.names[i], POINTER->string);
def.names[i] = strdup(POINTER->string);
i++;
}
@ -317,12 +315,14 @@ Object structAccess(Object* params, unused int length, unused struct Environment
}
if (isNumber(field)) {
if (structDef->fieldCount < field.number || field.number < 0) {
throw(NULL_PARSE, "Could not find struct field at index %ld. Struct `%s` has %d fields.", field.number, structDef->name, structDef->fieldCount);
throw(NULL_PARSE, "Could not find struct field at index %ld. Struct `%s` has %d fields.", field.number,
structDef->name, structDef->fieldCount);
}
return cloneObject(structo.structObject->fields[field.number]);
}
throw(BAD_PARAMS, "Struct fields should be indexed with a string or a number, but received a %s", getTypeName(&field));
throw(BAD_PARAMS, "Struct fields should be indexed with a string or a number, but received a %s",
getTypeName(&field));
}
Result parse(struct Slice* slices)
@ -429,6 +429,7 @@ Object parseBin(struct Slice* s)
struct InlinedFunction {
Object (* func)(Object*, int, struct Environment*);
Object* arguments;
int argCount;
//struct Environment* env;
@ -514,7 +515,11 @@ Object parseEval(const char* input, struct Environment* env)
parens--;
}
if (parens == 0) {
if (parens != 0) {
i++;
continue;
}
cleanObject(&obj);
Object parsed = parse(tok).obj;
if (parsed.type == TYPE_ERROR) {
@ -525,6 +530,7 @@ Object parseEval(const char* input, struct Environment* env)
#endif
break;
}
if (tok[i].text[0] == ')') {
// Skip `tok` past end of list that just closed
tok = &tok[i + 1];
@ -536,7 +542,6 @@ Object parseEval(const char* input, struct Environment* env)
obj = eval(&parsed, env);
cleanObject(&parsed);
}
}
i++;
}

View File

@ -167,9 +167,8 @@ check "MinRight" "(min 8429 192449)" "8429"
check "MinLeft" "(min 17294722 17294721)" "17294721"
title "Lambdas"
check "Multi-Statement" "(def yee (fn (a) (* 10 a))) ; (yee 5)" "50"
check "Multi-Statement, No Semicolon" "(def yee (fn (a) (* 10 a)))(yee 5)" "50"
check "Pre-Defined Map" "(def yee (fn (a) (* 10 a))) ; (map yee (5 10 2 (+ 12 0)))" "( 50 100 20 120 )"
check "Multi-Statement" "(def yee (fn (a) (* 10 a))) (yee 5)" "50"
check "Pre-Defined Map" "(def yee (fn (a) (* 10 a))) (map yee (5 10 2 (+ 12 0)))" "( 50 100 20 120 )"
check "AnonymousLambda" "\
(map (fn (a) (* a a)) (5 6 7))" "( 25 36 49 )"
check "FbnciSeq" "\
@ -177,17 +176,17 @@ check "FbnciSeq" "\
(if (< a 2) \
a \
(+ (fib (- a 1)) (fib (- a 2))) \
)));\
)))\
(fib 11)" "89"
check "Factorial" "\
(def fac (fn (a) \
(if (= a 1) \
1 \
(* a (fac (- a 1)) ) \
)));\
)))\
(fac 11)" "39916800"
check "Lambda Clone" "(def y (fn (a) (* 10 a))) (def b y) (def y 12345) ((b 5) y)" "( 50 12345 )"
check "Duplicate" "(def dupe (fn (a) (() (a a a))));(dupe (* 10 10))" "( 100 100 100 )"
check "Duplicate" "(def dupe (fn (a) (() (a a a)))) (dupe (* 10 10))" "( 100 100 100 )"
title "Cat"
check "Basic Cat" '(cat "Big" " Kitty")' "Big Kitty"

View File

@ -2,8 +2,6 @@
#include <string.h>
#define ERR_LEN 256
/*
* Grammar:
* token
@ -42,11 +40,18 @@ int isWhitespace(const char c)
return c == ' ' || c == '\t' || c == '\n';
}
void buildErrFromInput(struct Error* err, enum errorCode code, int i, const char* input)
{
err->context = malloc(sizeof(char) * ERR_LEN + 1);
err->code = code;
int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(err->context, &input[start], ERR_LEN);
}
struct Slice* nf_tokenize(const char* input, struct Error* err)
{
if (!input) {
err->context = malloc(sizeof(char) * ERR_LEN);
strcpy(err->context, "no input");
err->context = strdup("no input");
return NULL;
}
@ -63,8 +68,8 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
int parens = 0;
while (input[i] != '\0') {
int l = 1;
if (isWhitespace(input[i]) || input[i] == ';') {
int length = 1;
if (isWhitespace(input[i])) {
if (input[i] == '\n') {
lineNumber++;
}
@ -77,10 +82,7 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
} else if (input[i] == ')') {
parens--;
if (parens < 0) {
err->context = malloc(sizeof(char) * ERR_LEN + 1);
err->code = MISMATCHED_PARENS;
int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(err->context, &input[start], ERR_LEN);
buildErrFromInput(err, MISMATCHED_PARENS, i, input);
//free(slices);
return NULL;
}
@ -104,12 +106,9 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
if (input[i] == '\n') {
lineNumber++;
}
l++;
length++;
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);
buildErrFromInput(err, UNEXPECTED_EOF, i, input);
//free(slices);
return NULL;
}
@ -120,25 +119,22 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
if (input[i] == '\n') {
lineNumber++;
}
l++;
length++;
}
}
i++;
} else {
while (!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '"' && input[i] != '\0') {
l++;
length++;
}
}
slices[slice].length = l;
slices[slice].length = length;
slice++;
}
if (parens != 0) {
err->context = malloc(sizeof(char) * ERR_LEN);
err->code = MISMATCHED_PARENS;
int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(err->context, &input[start], ERR_LEN);
buildErrFromInput(err, MISMATCHED_PARENS, i, input);
//free(slices);
return NULL;
}

View File

@ -150,8 +150,7 @@ int start(int port)
void addRouteO(Object path, Object textFunc, struct Environment* env, enum RouteType type)
{
char* p = malloc(sizeof(char) * strlen(path.string) + 1);
strcpy(p, path.string);
char* p = strdup(path.string);
struct Route r;
r.path = p;