Toying with a more optimized function representation.
Starting with just struct accesses.
This commit is contained in:
parent
83b1b9212e
commit
b0e89cafd4
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
10
src/object.h
10
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*);
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue