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);
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;
}

View File

@ -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*);

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)
{
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 };
}