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 <signal.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <unistd.h>
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, &param, 2, env);
cleanObject(&prompt);
cleanObject(&param);
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 <signal.h>
#include <ucontext.h>
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();

View File

@ -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,7 +93,6 @@ 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
@ -116,28 +107,11 @@ Object mapO(Object* params, int length, struct Environment* env)
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 <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)
{
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)

View File

@ -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,7 +108,8 @@ struct Slice* getLastOpen();
#endif /* STANDALONE */
fn(mapO, "map",
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 )",
);
@ -124,8 +123,8 @@ 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"
"(def p (Post \"This is a title\" \"This is the body\"))\n "
"p.title", "This is a title"
);
#endif