Some optimization attempts in progress.
Toying with a more efficient native-function-use implementation. Replace getErrorCode with a macro. Store initial slice array on the stack, mallocing at the end.
This commit is contained in:
parent
0fd58832bf
commit
d9d2bca8c8
15
src/object.c
15
src/object.c
|
@ -1,5 +1,4 @@
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "pebblisp.h"
|
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -622,10 +621,6 @@ inline int isValidType(const Object test)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clones the given lambda with new allocations
|
|
||||||
* Will behave unexpectedly if given something other than a lambda object!
|
|
||||||
*/
|
|
||||||
inline Object cloneLambda(const Object old)
|
inline Object cloneLambda(const Object old)
|
||||||
{
|
{
|
||||||
old.lambda->refs += 1;
|
old.lambda->refs += 1;
|
||||||
|
@ -638,7 +633,6 @@ Object cloneString(Object obj)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an Object with a deep copy of the given Object
|
|
||||||
Object cloneOther(const Object src)
|
Object cloneOther(const Object src)
|
||||||
{
|
{
|
||||||
return src.other->clone ? src.other->clone(src.other) : src;
|
return src.other->clone ? src.other->clone(src.other) : src;
|
||||||
|
@ -815,15 +809,6 @@ inline Object errorObject(enum errorCode err)
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline enum errorCode getErrorCode(const Object obj)
|
|
||||||
{
|
|
||||||
#ifdef SIMPLE_ERRORS
|
|
||||||
return obj.error;
|
|
||||||
#else
|
|
||||||
return obj.error->code;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SIMPLE_ERRORS
|
#ifndef SIMPLE_ERRORS
|
||||||
|
|
||||||
inline void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName)
|
inline void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName)
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_TOK_CNT 1024
|
#define MAX_TOK_CNT 1024
|
||||||
#define MAX_ENV_ELM 100
|
|
||||||
#define RESULT_LENGTH 128
|
#define RESULT_LENGTH 128
|
||||||
|
|
||||||
#define FOR_POINTER_IN_LIST(_list) \
|
#define FOR_POINTER_IN_LIST(_list) \
|
||||||
|
@ -239,7 +238,11 @@ Object otherObject();
|
||||||
|
|
||||||
Object errorObject(enum errorCode err);
|
Object errorObject(enum errorCode err);
|
||||||
|
|
||||||
enum errorCode getErrorCode(Object obj);
|
#ifdef SIMPLE_ERRORS
|
||||||
|
#define getErrorCode(OBJ) ((OBJ).error)
|
||||||
|
#else
|
||||||
|
#define getErrorCode(OBJ) ((OBJ).error->code)
|
||||||
|
#endif
|
||||||
|
|
||||||
Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName);
|
Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName);
|
||||||
|
|
||||||
|
|
|
@ -419,6 +419,13 @@ Object parseBin(struct Slice* s)
|
||||||
return numberObject(num);
|
return numberObject(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct InlinedFunction {
|
||||||
|
Object (* func)(Object*, int, struct Environment*);
|
||||||
|
Object* arguments;
|
||||||
|
int argCount;
|
||||||
|
//struct Environment* env;
|
||||||
|
};
|
||||||
|
|
||||||
Result parseAtom(struct Slice* s)
|
Result parseAtom(struct Slice* s)
|
||||||
{
|
{
|
||||||
const char c = s->text[0];
|
const char c = s->text[0];
|
||||||
|
@ -441,15 +448,27 @@ Result parseAtom(struct Slice* s)
|
||||||
} else if (c == '"'/* || c == '\''*/) {
|
} else if (c == '"'/* || c == '\''*/) {
|
||||||
return (Result) { objFromSlice(s->text, s->length), s };
|
return (Result) { objFromSlice(s->text, s->length), s };
|
||||||
} else if (s->text[s->length] == '.') {
|
} else if (s->text[s->length] == '.') {
|
||||||
|
struct InlinedFunction f ={
|
||||||
|
.func = structAccess,
|
||||||
|
.arguments = malloc(sizeof(Object) * 2),
|
||||||
|
.argCount = 2,
|
||||||
|
};
|
||||||
|
f.arguments[0] = symFromSlice(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);
|
Object structAccessFunc = newObject(TYPE_FUNC);
|
||||||
structAccessFunc.func = &structAccess;
|
structAccessFunc.func = &structAccess;
|
||||||
Object list = startList(structAccessFunc);
|
Object list = startList(structAccessFunc);
|
||||||
Object theStruct = symFromSlice(s->text, s->length);
|
Object theStruct = symFromSlice(s->text, s->length);
|
||||||
nf_addToList(&list, theStruct);
|
nf_addToList(&list, theStruct);
|
||||||
struct Slice* next = s + 2;
|
struct Slice* next = s + 2;
|
||||||
Object structField = objFromSlice(&next->text[-1], next->length + 1);
|
Object structField = stringFromSlice(next->text, next->length);
|
||||||
nf_addToList(&list, structField);
|
nf_addToList(&list, structField);
|
||||||
return (Result) { list, next };
|
return (Result) { list, next };
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return (Result) { symFromSlice(s->text, s->length), s };
|
return (Result) { symFromSlice(s->text, s->length), s };
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,15 +57,13 @@ void* doAsync(void* args)
|
||||||
Object cloned = promise->object;
|
Object cloned = promise->object;
|
||||||
Object first_eval = eval(&cloned, promise->env);
|
Object first_eval = eval(&cloned, promise->env);
|
||||||
Object e = funcyEval(&first_eval, NULL, 0, promise->env);
|
Object e = funcyEval(&first_eval, NULL, 0, promise->env);
|
||||||
cleanObject(&cloned);
|
|
||||||
|
|
||||||
promise->object = e;
|
promise->object = e;
|
||||||
promise->done = 1;
|
promise->done = 1;
|
||||||
cleanPromise(promise);
|
|
||||||
|
|
||||||
|
cleanObject(&cloned);
|
||||||
|
cleanPromise(promise);
|
||||||
deleteEnv(promise->env);
|
deleteEnv(promise->env);
|
||||||
//cleanObject(&first_eval);
|
|
||||||
//cleanObject(&cloned);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +72,7 @@ Object async(Object* params, int length, struct Environment* env)
|
||||||
Object promise = newObject(TYPE_PROMISE);
|
Object promise = newObject(TYPE_PROMISE);
|
||||||
promise.promise = malloc(sizeof(struct Promise));
|
promise.promise = malloc(sizeof(struct Promise));
|
||||||
*promise.promise = (struct Promise) {
|
*promise.promise = (struct Promise) {
|
||||||
.refs = 2,
|
.refs = 2, // Held by doAsync and the returned object
|
||||||
.done = 0,
|
.done = 0,
|
||||||
.env = env,
|
.env = env,
|
||||||
.object = cloneObject(params[0]),
|
.object = cloneObject(params[0]),
|
||||||
|
|
|
@ -22,7 +22,8 @@ fn(async, "async",
|
||||||
|
|
||||||
tfn(await, "await",
|
tfn(await, "await",
|
||||||
({ expect(isPromise), anyType }),
|
({ expect(isPromise), anyType }),
|
||||||
"Waits for a promise to resolve before proceeding.",
|
"Waits for a promise to resolve before proceeding.\n"
|
||||||
|
"Note: Calling (await) on the same object multiple times is undefined behavior.",
|
||||||
"(def sleepy (fn () ((sys \"sleep 0.02\") \"Hiya\"))) (def x (async sleepy)) (await x)", "Hiya",
|
"(def sleepy (fn () ((sys \"sleep 0.02\") \"Hiya\"))) (def x (async sleepy)) (await x)", "Hiya",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
24
src/tokens.c
24
src/tokens.c
|
@ -1,6 +1,5 @@
|
||||||
#include "tokens.h"
|
#include "tokens.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define ERR_LEN 256
|
#define ERR_LEN 256
|
||||||
|
@ -51,12 +50,12 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int token_count = MAX_TOK_CNT;
|
struct Slice slices[MAX_TOK_CNT];
|
||||||
struct Slice* slices = malloc(sizeof(struct Slice) * token_count);
|
//int token_count = MAX_TOK_CNT;
|
||||||
while (slices == NULL) {
|
// do {
|
||||||
token_count /= 2;
|
// slices = malloc(sizeof(struct Slice) * token_count);
|
||||||
slices = malloc(sizeof(struct Slice) * token_count);
|
// token_count /= 2;
|
||||||
}
|
// } while (slices == NULL);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int slice = 0;
|
int slice = 0;
|
||||||
|
@ -82,7 +81,7 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
|
||||||
err->code = MISMATCHED_PARENS;
|
err->code = MISMATCHED_PARENS;
|
||||||
int start = i > ERR_LEN ? i - ERR_LEN : 0;
|
int start = i > ERR_LEN ? i - ERR_LEN : 0;
|
||||||
strncpy(err->context, &input[start], ERR_LEN);
|
strncpy(err->context, &input[start], ERR_LEN);
|
||||||
free(slices);
|
//free(slices);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +110,7 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
|
||||||
err->code = UNEXPECTED_EOF;
|
err->code = UNEXPECTED_EOF;
|
||||||
int start = i > ERR_LEN ? i - ERR_LEN : 0;
|
int start = i > ERR_LEN ? i - ERR_LEN : 0;
|
||||||
strncpy(err->context, &input[start], ERR_LEN);
|
strncpy(err->context, &input[start], ERR_LEN);
|
||||||
free(slices);
|
//free(slices);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,12 +139,15 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
|
||||||
err->code = MISMATCHED_PARENS;
|
err->code = MISMATCHED_PARENS;
|
||||||
int start = i > ERR_LEN ? i - ERR_LEN : 0;
|
int start = i > ERR_LEN ? i - ERR_LEN : 0;
|
||||||
strncpy(err->context, &input[start], ERR_LEN);
|
strncpy(err->context, &input[start], ERR_LEN);
|
||||||
free(slices);
|
//free(slices);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
slices[slice].text = NULL;
|
slices[slice].text = NULL;
|
||||||
slices[slice].length = 0;
|
slices[slice].length = 0;
|
||||||
|
size_t size = sizeof(struct Slice) * (slice + 1);
|
||||||
|
struct Slice* allocated = malloc(size);
|
||||||
|
memcpy(allocated, slices, size);
|
||||||
|
|
||||||
return slices;
|
return allocated;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue