diff --git a/src/main.c b/src/main.c index 96684d7..c0a8ff1 100644 --- a/src/main.c +++ b/src/main.c @@ -2,25 +2,31 @@ #include "pebblisp.h" +#include #include #include #include +#include -char* getPrompt(struct Environment* env) +Object getPrompt(struct Environment* env) { Object prompt = fetchFromEnvironment("prompt", env); prompt = cloneObject(prompt); if (prompt.type == TYPE_STRING) { - char* ret = readline(prompt.string); - cleanObject(&prompt); - return ret; + return prompt; } Object param = stringFromSlice("", 1); Object e = listEvalLambda(&prompt, ¶m, 2, env); cleanObject(&prompt); cleanObject(¶m); - char* ret = readline(e.string); - cleanObject(&e); + return e; +} + +char* prompt(struct Environment* env) +{ + Object p = getPrompt(env); + char* ret = readline(p.string); + cleanObject(&p); return ret; } @@ -33,12 +39,21 @@ char* preprocess(char* buf, struct Environment* env) return stringObj(&s, &length); } +void sigintHandler(unused int signalNumber) +{ + Object p = getPrompt(global()); + write(1, "\n", 1); + write(1, p.string, strlen(p.string)); + cleanObject(&p); +} + void repl(struct Environment* env) { + signal(SIGINT, sigintHandler); char* buf; using_history(); - while ((buf = getPrompt(env)) != NULL) { + while ((buf = prompt(env)) != NULL) { if (strcmp("q", buf) == 0) { free(buf); break; @@ -90,12 +105,11 @@ void loadArgsIntoEnv(int argc, const char* argv[], struct Environment* env) #ifdef __x86_64__ -#include #include int nestedSegfault = 0; -void handler(int nSignum, siginfo_t* si, void* vcontext) +void handler(unused int nSignum, unused siginfo_t* si, void* vcontext) { if (nestedSegfault) { printf("Nested segfault!!!\n"); @@ -122,7 +136,6 @@ void setupSegfaultHandler() action.sa_flags = SA_SIGINFO; action.sa_sigaction = handler; sigaction(SIGSEGV, &action, NULL); - } #else @@ -176,6 +189,7 @@ void getSettings(int argc, const char* argv[]) int main(int argc, const char* argv[]) { setupSegfaultHandler(); + getSettings(argc, argv); struct Environment env = defaultEnv(); diff --git a/src/pebblisp.c b/src/pebblisp.c index 092a2d7..4bf5f1d 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -79,14 +79,6 @@ Object evalIfArgs(const Object* argForms, struct Environment* env) return result; } -/** - * Not a typical pl function because it relies almost exclusively on symbols - */ -Object evalLambdaArgs(const Object* argForms, struct Environment* env) -{ - return constructLambda(argForms, argForms ? argForms->forward : NULL, env); -} - Object mapO(Object* params, int length, struct Environment* env) { if (length < 2) { @@ -101,43 +93,25 @@ Object mapO(Object* params, int length, struct Environment* env) } Object outputList = listObject(); - if (inputList) { - FOR_POINTER_IN_LIST(inputList) { - // Create a new list for each element, - // since lambda evaluation looks for a list - Object tempInput = cloneObject(*POINTER); + FOR_POINTER_IN_LIST(inputList) { + // Create a new list for each element, + // since lambda evaluation looks for a list + Object tempInput = cloneObject(*POINTER); - Object* lambdaParams = &lambda.lambda->params; - struct Environment newEnv = envForLambda(lambdaParams, &tempInput, listLength(lambdaParams), env); + Object* lambdaParams = &lambda.lambda->params; + struct Environment newEnv = envForLambda(lambdaParams, &tempInput, listLength(lambdaParams), env); - // Add the lambda evaluation to the list - Object lambda_output = eval(&lambda.lambda->body, &newEnv); - nf_addToList(&outputList, lambda_output); - deleteEnv(&newEnv); - cleanObject(&tempInput); - } + // Add the lambda evaluation to the list + Object lambda_output = eval(&lambda.lambda->body, &newEnv); + nf_addToList(&outputList, lambda_output); + deleteEnv(&newEnv); + cleanObject(&tempInput); } cleanObject(&lambda); return outputList; } -Object evalBuiltIns(const Object* first, const Object* rest, - struct Environment* env, int* found) -{ - *found = 1; - if (strcmp(first->string, "if") == 0) { - return evalIfArgs(rest, env); - } else if (strcmp(first->string, "fn") == 0) { - return evalLambdaArgs(rest, env); - } else if (strcmp(first->string, "struct") == 0) { - return evalStructArgs(rest, rest->forward, env); - } - - *found = 0; - return *first; -} - /** * Evaluates a paramList whose first element is a function, applying that function * @@ -229,10 +203,14 @@ Object evalList(const Object* obj, struct Environment* env) Object* first_form = obj->list; if (first_form->type == TYPE_SYMBOL) { - int found; - Object builtIn = evalBuiltIns(first_form, first_form->forward, env, &found); - if (found) { - return builtIn; + if (strcmp(first_form->string, "if") == 0) { + return evalIfArgs(first_form->forward, env); + } else if (strcmp(first_form->string, "fn") == 0) { + Object* params = first_form->forward; + Object* body = params ? params->forward : NULL; + return constructLambda(params, body, env); + } else if (strcmp(first_form->string, "struct") == 0) { + return evalStructArgs(first_form->forward, first_form->forward->forward, env); } int i = getStructIndex(first_form->string); @@ -275,6 +253,19 @@ Object evalList(const Object* obj, struct Environment* env) } } +#include +Object funcyWithArgs(Object funcy, int count, ...) +{ + va_list ptr; + va_start(ptr, count); + Object args[count]; + for (int i = 0; i < count; i++) { + args[i] = va_arg(ptr, Object); + } + va_end(ptr); + +} + Object eval(const Object* obj, struct Environment* env) { switch (obj->type) { @@ -342,10 +333,10 @@ Result parse(struct Slice* slices) } } -#ifdef SUGAR -#define sugar(_desc, _code) ; -#else +#ifndef NO_SUGAR #define sugar(_desc, _code) _code +#else +#define sugar(_desc, _code) ; #endif Result readSeq(struct Slice* tokens) diff --git a/src/pebblisp.h b/src/pebblisp.h index e3ebc8c..a771788 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -77,8 +77,6 @@ Object parseEval(const char* input, struct Environment* env); Object evalList(const Object* obj, struct Environment* env); -Object evalLambdaArgs(const Object* arg_forms, struct Environment* env); - Object listEvalLambda(Object* lambda, const Object* remaining, int evalLength, struct Environment* env); @@ -110,9 +108,10 @@ struct Slice* getLastOpen(); #endif /* STANDALONE */ -fn(mapO, "map", - "Map over a list with a function.", - "(map (fn (a) (* a a)) (1 2 3))", "( 1 4 9 )", +tfn(mapO, "map", + ({ expect(isFuncy), expect(isListy), returns(isListy) }), + "Map over a list with a function.", + "(map (fn (a) (* a a)) (1 2 3))", "( 1 4 9 )", ); fn(def, "def", @@ -123,9 +122,9 @@ fn(def, "def", tfn(structAccess, "poss", ({ expect(isStruct), expect(isStringy), anyType }), "Get the value of a struct's field", - "(struct Post (title body))\n " - "(def p (Post \"TI\" \"BO\"))\n " - "p.title", "TI" + "(struct Post (title body))\n " + "(def p (Post \"This is a title\" \"This is the body\"))\n " + "p.title", "This is a title" ); #endif