Toying with a more optimized function representation.

Starting with just struct accesses.
This commit is contained in:
Sage Vaillancourt 2022-04-14 16:05:41 -04:00 committed by Sage Vaillancourt
parent 83b1b9212e
commit b0e89cafd4
3 changed files with 52 additions and 30 deletions

View File

@ -257,6 +257,9 @@ int stringNObj(struct string* s, const Object* obj)
s->cursor += sprintf(s->cursor, format, obj->string); s->cursor += sprintf(s->cursor, format, obj->string);
break; break;
} }
case TYPE_STATIC_FUNC:
s->cursor += sprintf(s->cursor, "STATIC FUNC");
break;
case TYPE_STRUCT: case TYPE_STRUCT:
stringStruct(s, obj); stringStruct(s, obj);
break; break;
@ -350,6 +353,7 @@ const char* getTypeName(const Object* obj)
SIMPLE_TYPE(TYPE_LIST); SIMPLE_TYPE(TYPE_LIST);
SIMPLE_TYPE(TYPE_SLIST); SIMPLE_TYPE(TYPE_SLIST);
SIMPLE_TYPE(TYPE_FUNC); SIMPLE_TYPE(TYPE_FUNC);
SIMPLE_TYPE(TYPE_STATIC_FUNC);
SIMPLE_TYPE(TYPE_SYMBOL); SIMPLE_TYPE(TYPE_SYMBOL);
SIMPLE_TYPE(TYPE_STRING); SIMPLE_TYPE(TYPE_STRING);
SIMPLE_TYPE(TYPE_PROMISE); SIMPLE_TYPE(TYPE_PROMISE);
@ -447,6 +451,9 @@ void cleanObject(Object* target)
target->other->cleanup(target); target->other->cleanup(target);
} }
break; break;
case TYPE_STATIC_FUNC:
// free(target->staticF);
break;
case TYPE_BOOL: case TYPE_BOOL:
case TYPE_NUMBER: case TYPE_NUMBER:
case TYPE_FUNC: case TYPE_FUNC:
@ -609,6 +616,7 @@ inline int isValidType(const Object test)
case TYPE_STRUCT: case TYPE_STRUCT:
case TYPE_SLIST: case TYPE_SLIST:
case TYPE_FUNC: case TYPE_FUNC:
case TYPE_STATIC_FUNC:
case TYPE_SYMBOL: case TYPE_SYMBOL:
case TYPE_LAMBDA: case TYPE_LAMBDA:
case TYPE_STRING: case TYPE_STRING:
@ -662,6 +670,7 @@ inline Object cloneObject(const Object src)
case TYPE_BOOL: case TYPE_BOOL:
case TYPE_NUMBER: case TYPE_NUMBER:
case TYPE_FUNC: case TYPE_FUNC:
case TYPE_STATIC_FUNC:
return src; return src;
} }

View File

@ -69,6 +69,7 @@ typedef enum Type {
TYPE_SLIST, TYPE_SLIST,
TYPE_STRUCT, TYPE_STRUCT,
TYPE_FUNC, TYPE_FUNC,
TYPE_STATIC_FUNC,
TYPE_SYMBOL, TYPE_SYMBOL,
TYPE_LAMBDA, TYPE_LAMBDA,
TYPE_STRING, TYPE_STRING,
@ -83,6 +84,7 @@ struct Lambda;
struct Environment; struct Environment;
struct Promise; struct Promise;
struct Other; struct Other;
struct StaticFunction;
struct Error { struct Error {
enum errorCode code; enum errorCode code;
char* context; char* context;
@ -101,6 +103,7 @@ struct Object {
struct StructObject* structObject; struct StructObject* structObject;
struct Lambda* lambda; struct Lambda* lambda;
struct StaticFunction* staticF;
struct Other* other; struct Other* other;
struct Promise* promise; struct Promise* promise;
#ifdef SIMPLE_ERRORS #ifdef SIMPLE_ERRORS
@ -135,6 +138,13 @@ struct Lambda {
Object body; Object body;
}; };
struct StaticFunction {
Object (* func)(Object*, int, struct Environment*);
Object* arguments;
int argCount;
};
struct Other { struct Other {
void (* cleanup)(Object*); void (* cleanup)(Object*);

View File

@ -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) Object eval(const Object* obj, struct Environment* env)
{ {
switch (obj->type) { switch (obj->type) {
@ -287,6 +297,9 @@ Object eval(const Object* obj, struct Environment* env)
case TYPE_PROMISE: case TYPE_PROMISE:
return cloneObject(*obj); return cloneObject(*obj);
case TYPE_STATIC_FUNC:
return runStatic(obj, env);
case TYPE_SYMBOL: case TYPE_SYMBOL:
return fetchFromEnvironment(obj->string, env); 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); throw(NULL_PARSE, "Could not find struct field named `%s`", field.string);
} }
if (isNumber(field)) { if (isNumber(field)) {
if (structDef->fieldCount < field.number || field.number < 0) { 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, 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); return numberObject(num);
} }
Object parseBin(struct Slice* s) Object optimize(Object (* func)(Object*, int, struct Environment*), int argCount, Object args[])
{ {
int num = 0; struct StaticFunction *f = malloc(sizeof(struct StaticFunction) + (sizeof(Object) * argCount));
for (int i = 2; i < s->length; i++) { f->func = func;
const char c = s->text[i]; f->arguments = (void*) f + sizeof(struct StaticFunction);
if (c != '0' && c != '1') { f->argCount = argCount;
return errorObject(BAD_NUMBER); for (int i = 0; i < argCount; i++) {
} f->arguments[i] = args[i];
num *= 2;
num += c - '0';
} }
return numberObject(num); Object staticF = newObject(TYPE_STATIC_FUNC);
staticF.staticF = f;
return staticF;
} }
struct InlinedFunction { #define ELEVENTH_ARGUMENT(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11
Object (* func)(Object*, int, struct Environment*); #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__ } )
Object* arguments;
int argCount;
//struct Environment* env;
};
Result parseAtom(struct Slice* s) Result parseAtom(struct Slice* s)
{ {
@ -477,19 +487,12 @@ Result parseAtom(struct Slice* s)
} }
if (s->text[s->length] == '.') { if (s->text[s->length] == '.') {
struct Slice* next = s + 2; struct Slice* next = s + 2;
f.arguments[1] = stringFromSlice(next->text, next->length); Object staticFunc = OPTIMIZE(
structAccess,
return (Result) { list, next }; symFromSlice(s->text, s->length), // struct name
*/ stringFromSlice(next->text, next->length) // field name
Object structAccessFunc = newObject(TYPE_FUNC); );
structAccessFunc.func = &structAccess; return (Result) { staticFunc, next };
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 };
} }
return (Result) { symFromSlice(s->text, s->length), s }; return (Result) { symFromSlice(s->text, s->length), s };
} }