diff --git a/src/object.c b/src/object.c index de21cd2..48ea975 100644 --- a/src/object.c +++ b/src/object.c @@ -257,6 +257,9 @@ int stringNObj(struct string* s, const Object* obj) s->cursor += sprintf(s->cursor, format, obj->string); break; } + case TYPE_STATIC_FUNC: + s->cursor += sprintf(s->cursor, "STATIC FUNC"); + break; case TYPE_STRUCT: stringStruct(s, obj); break; @@ -350,6 +353,7 @@ const char* getTypeName(const Object* obj) SIMPLE_TYPE(TYPE_LIST); SIMPLE_TYPE(TYPE_SLIST); SIMPLE_TYPE(TYPE_FUNC); + SIMPLE_TYPE(TYPE_STATIC_FUNC); SIMPLE_TYPE(TYPE_SYMBOL); SIMPLE_TYPE(TYPE_STRING); SIMPLE_TYPE(TYPE_PROMISE); @@ -447,6 +451,9 @@ void cleanObject(Object* target) target->other->cleanup(target); } break; + case TYPE_STATIC_FUNC: + // free(target->staticF); + break; case TYPE_BOOL: case TYPE_NUMBER: case TYPE_FUNC: @@ -609,6 +616,7 @@ inline int isValidType(const Object test) case TYPE_STRUCT: case TYPE_SLIST: case TYPE_FUNC: + case TYPE_STATIC_FUNC: case TYPE_SYMBOL: case TYPE_LAMBDA: case TYPE_STRING: @@ -662,6 +670,7 @@ inline Object cloneObject(const Object src) case TYPE_BOOL: case TYPE_NUMBER: case TYPE_FUNC: + case TYPE_STATIC_FUNC: return src; } diff --git a/src/object.h b/src/object.h index ad52d47..fe820c1 100644 --- a/src/object.h +++ b/src/object.h @@ -69,6 +69,7 @@ typedef enum Type { TYPE_SLIST, TYPE_STRUCT, TYPE_FUNC, + TYPE_STATIC_FUNC, TYPE_SYMBOL, TYPE_LAMBDA, TYPE_STRING, @@ -83,6 +84,7 @@ struct Lambda; struct Environment; struct Promise; struct Other; +struct StaticFunction; struct Error { enum errorCode code; char* context; @@ -101,6 +103,7 @@ struct Object { struct StructObject* structObject; struct Lambda* lambda; + struct StaticFunction* staticF; struct Other* other; struct Promise* promise; #ifdef SIMPLE_ERRORS @@ -135,6 +138,13 @@ struct Lambda { Object body; }; +struct StaticFunction { + Object (* func)(Object*, int, struct Environment*); + + Object* arguments; + int argCount; +}; + struct Other { void (* cleanup)(Object*); diff --git a/src/pebblisp.c b/src/pebblisp.c index 8feeafe..2a89585 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -272,6 +272,16 @@ Object evalList(const Object* obj, struct Environment* env) } } +Object runStatic(const Object* staticF, struct Environment* env) +{ + struct StaticFunction* f = staticF->staticF; + Object evaluatedArgs[f->argCount]; + for (int i = 0; i < f->argCount; i++) { + evaluatedArgs[i] = eval(&f->arguments[i], env); + } + return f->func(evaluatedArgs, f->argCount, env); +} + Object eval(const Object* obj, struct Environment* env) { switch (obj->type) { @@ -287,6 +297,9 @@ Object eval(const Object* obj, struct Environment* env) case TYPE_PROMISE: return cloneObject(*obj); + case TYPE_STATIC_FUNC: + return runStatic(obj, env); + case TYPE_SYMBOL: return fetchFromEnvironment(obj->string, env); @@ -313,6 +326,7 @@ Object structAccess(Object* params, unused int length, unused struct Environment } throw(NULL_PARSE, "Could not find struct field named `%s`", field.string); } + 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, @@ -427,27 +441,23 @@ Object parseNum(int base, const char* text, int length, int (*func)(char)) return numberObject(num); } -Object parseBin(struct Slice* s) +Object optimize(Object (* func)(Object*, int, struct Environment*), int argCount, Object args[]) { - int num = 0; - for (int i = 2; i < s->length; i++) { - const char c = s->text[i]; - if (c != '0' && c != '1') { - return errorObject(BAD_NUMBER); - } - num *= 2; - num += c - '0'; + struct StaticFunction *f = malloc(sizeof(struct StaticFunction) + (sizeof(Object) * argCount)); + f->func = func; + f->arguments = (void*) f + sizeof(struct StaticFunction); + f->argCount = argCount; + for (int i = 0; i < argCount; i++) { + f->arguments[i] = args[i]; } - return numberObject(num); + Object staticF = newObject(TYPE_STATIC_FUNC); + staticF.staticF = f; + return staticF; } -struct InlinedFunction { - Object (* func)(Object*, int, struct Environment*); - - Object* arguments; - int argCount; - //struct Environment* env; -}; +#define ELEVENTH_ARGUMENT(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11 +#define COUNT_ARGUMENTS(...) ELEVENTH_ARGUMENT(dummy, ## __VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define OPTIMIZE(FUNC, ...) optimize(FUNC, COUNT_ARGUMENTS(__VA_ARGS__), (Object[]) { __VA_ARGS__ } ) Result parseAtom(struct Slice* s) { @@ -477,19 +487,12 @@ Result parseAtom(struct Slice* s) } if (s->text[s->length] == '.') { struct Slice* next = s + 2; - f.arguments[1] = stringFromSlice(next->text, next->length); - - return (Result) { list, next }; - */ - Object structAccessFunc = newObject(TYPE_FUNC); - structAccessFunc.func = &structAccess; - Object list = startList(structAccessFunc); - Object theStruct = symFromSlice(s->text, s->length); - nf_addToList(&list, theStruct); - struct Slice* next = s + 2; - Object structField = stringFromSlice(next->text, next->length); - nf_addToList(&list, structField); - return (Result) { list, next }; + Object staticFunc = OPTIMIZE( + structAccess, + symFromSlice(s->text, s->length), // struct name + stringFromSlice(next->text, next->length) // field name + ); + return (Result) { staticFunc, next }; } return (Result) { symFromSlice(s->text, s->length), s }; }