Add simple sigint handler for repl.
inline evalLambdaArgs() and evalBuiltIns()
This commit is contained in:
parent
abaf3a1ddc
commit
4d215b1b79
34
src/main.c
34
src/main.c
|
@ -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, ¶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 <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();
|
||||
|
|
|
@ -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 <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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue