Add simple sigint handler for repl.

inline evalLambdaArgs() and evalBuiltIns()
This commit is contained in:
Sage Vaillancourt 2022-04-06 16:55:49 -04:00 committed by Sage Vaillancourt
parent abaf3a1ddc
commit 4d215b1b79
3 changed files with 66 additions and 62 deletions

View File

@ -2,25 +2,31 @@
#include "pebblisp.h" #include "pebblisp.h"
#include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
#include <unistd.h>
char* getPrompt(struct Environment* env) Object getPrompt(struct Environment* env)
{ {
Object prompt = fetchFromEnvironment("prompt", env); Object prompt = fetchFromEnvironment("prompt", env);
prompt = cloneObject(prompt); prompt = cloneObject(prompt);
if (prompt.type == TYPE_STRING) { if (prompt.type == TYPE_STRING) {
char* ret = readline(prompt.string); return prompt;
cleanObject(&prompt);
return ret;
} }
Object param = stringFromSlice("", 1); Object param = stringFromSlice("", 1);
Object e = listEvalLambda(&prompt, &param, 2, env); Object e = listEvalLambda(&prompt, &param, 2, env);
cleanObject(&prompt); cleanObject(&prompt);
cleanObject(&param); cleanObject(&param);
char* ret = readline(e.string); return e;
cleanObject(&e); }
char* prompt(struct Environment* env)
{
Object p = getPrompt(env);
char* ret = readline(p.string);
cleanObject(&p);
return ret; return ret;
} }
@ -33,12 +39,21 @@ char* preprocess(char* buf, struct Environment* env)
return stringObj(&s, &length); 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) void repl(struct Environment* env)
{ {
signal(SIGINT, sigintHandler);
char* buf; char* buf;
using_history(); using_history();
while ((buf = getPrompt(env)) != NULL) { while ((buf = prompt(env)) != NULL) {
if (strcmp("q", buf) == 0) { if (strcmp("q", buf) == 0) {
free(buf); free(buf);
break; break;
@ -90,12 +105,11 @@ void loadArgsIntoEnv(int argc, const char* argv[], struct Environment* env)
#ifdef __x86_64__ #ifdef __x86_64__
#include <signal.h>
#include <ucontext.h> #include <ucontext.h>
int nestedSegfault = 0; 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) { if (nestedSegfault) {
printf("Nested segfault!!!\n"); printf("Nested segfault!!!\n");
@ -122,7 +136,6 @@ void setupSegfaultHandler()
action.sa_flags = SA_SIGINFO; action.sa_flags = SA_SIGINFO;
action.sa_sigaction = handler; action.sa_sigaction = handler;
sigaction(SIGSEGV, &action, NULL); sigaction(SIGSEGV, &action, NULL);
} }
#else #else
@ -176,6 +189,7 @@ void getSettings(int argc, const char* argv[])
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
setupSegfaultHandler(); setupSegfaultHandler();
getSettings(argc, argv); getSettings(argc, argv);
struct Environment env = defaultEnv(); struct Environment env = defaultEnv();

View File

@ -79,14 +79,6 @@ Object evalIfArgs(const Object* argForms, struct Environment* env)
return result; 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) Object mapO(Object* params, int length, struct Environment* env)
{ {
if (length < 2) { if (length < 2) {
@ -101,43 +93,25 @@ Object mapO(Object* params, int length, struct Environment* env)
} }
Object outputList = listObject(); Object outputList = listObject();
if (inputList) { FOR_POINTER_IN_LIST(inputList) {
FOR_POINTER_IN_LIST(inputList) { // Create a new list for each element,
// Create a new list for each element, // since lambda evaluation looks for a list
// since lambda evaluation looks for a list Object tempInput = cloneObject(*POINTER);
Object tempInput = cloneObject(*POINTER);
Object* lambdaParams = &lambda.lambda->params; Object* lambdaParams = &lambda.lambda->params;
struct Environment newEnv = envForLambda(lambdaParams, &tempInput, listLength(lambdaParams), env); struct Environment newEnv = envForLambda(lambdaParams, &tempInput, listLength(lambdaParams), env);
// Add the lambda evaluation to the list // Add the lambda evaluation to the list
Object lambda_output = eval(&lambda.lambda->body, &newEnv); Object lambda_output = eval(&lambda.lambda->body, &newEnv);
nf_addToList(&outputList, lambda_output); nf_addToList(&outputList, lambda_output);
deleteEnv(&newEnv); deleteEnv(&newEnv);
cleanObject(&tempInput); cleanObject(&tempInput);
}
} }
cleanObject(&lambda); cleanObject(&lambda);
return outputList; 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 * 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; Object* first_form = obj->list;
if (first_form->type == TYPE_SYMBOL) { if (first_form->type == TYPE_SYMBOL) {
int found; if (strcmp(first_form->string, "if") == 0) {
Object builtIn = evalBuiltIns(first_form, first_form->forward, env, &found); return evalIfArgs(first_form->forward, env);
if (found) { } else if (strcmp(first_form->string, "fn") == 0) {
return builtIn; 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); int i = getStructIndex(first_form->string);
@ -275,6 +253,19 @@ Object evalList(const Object* obj, struct Environment* env)
} }
} }
#include <stdarg.h>
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) Object eval(const Object* obj, struct Environment* env)
{ {
switch (obj->type) { switch (obj->type) {
@ -342,10 +333,10 @@ Result parse(struct Slice* slices)
} }
} }
#ifdef SUGAR #ifndef NO_SUGAR
#define sugar(_desc, _code) ;
#else
#define sugar(_desc, _code) _code #define sugar(_desc, _code) _code
#else
#define sugar(_desc, _code) ;
#endif #endif
Result readSeq(struct Slice* tokens) Result readSeq(struct Slice* tokens)

View File

@ -77,8 +77,6 @@ Object parseEval(const char* input, struct Environment* env);
Object evalList(const Object* obj, 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, Object listEvalLambda(Object* lambda, const Object* remaining, int evalLength,
struct Environment* env); struct Environment* env);
@ -110,9 +108,10 @@ struct Slice* getLastOpen();
#endif /* STANDALONE */ #endif /* STANDALONE */
fn(mapO, "map", tfn(mapO, "map",
"Map over a list with a function.", ({ expect(isFuncy), expect(isListy), returns(isListy) }),
"(map (fn (a) (* a a)) (1 2 3))", "( 1 4 9 )", "Map over a list with a function.",
"(map (fn (a) (* a a)) (1 2 3))", "( 1 4 9 )",
); );
fn(def, "def", fn(def, "def",
@ -123,9 +122,9 @@ fn(def, "def",
tfn(structAccess, "poss", tfn(structAccess, "poss",
({ expect(isStruct), expect(isStringy), anyType }), ({ expect(isStruct), expect(isStringy), anyType }),
"Get the value of a struct's field", "Get the value of a struct's field",
"(struct Post (title body))\n " "(struct Post (title body))\n "
"(def p (Post \"TI\" \"BO\"))\n " "(def p (Post \"This is a title\" \"This is the body\"))\n "
"p.title", "TI" "p.title", "This is a title"
); );
#endif #endif