Lambdas begin to work!
This commit is contained in:
parent
a3bf8ab864
commit
359d8ed439
Binary file not shown.
|
@ -0,0 +1,215 @@
|
||||||
|
#include "object.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef STANDALONE
|
||||||
|
#define printf(...) stringObj(NULL, NULL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int listLength(const Object *listObj)
|
||||||
|
{
|
||||||
|
if(!listObj || listObj->type != TYPE_LIST)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
Object *t = listObj->list;
|
||||||
|
if(t == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int len = 1;
|
||||||
|
while(t->forward != NULL) {
|
||||||
|
t = t->forward;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *itemAt(const Object *listObj, int n)
|
||||||
|
{
|
||||||
|
if(!listObj || listObj->type != TYPE_LIST)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Object *march = listObj->list;
|
||||||
|
for(int i = 0; i < n; i++) {
|
||||||
|
march = march->forward;
|
||||||
|
|
||||||
|
if(march == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return march;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns last object in list (->forward == NULL)
|
||||||
|
Object *tail(const Object *listObj)
|
||||||
|
{
|
||||||
|
if(!listObj || listObj->type != TYPE_LIST)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Object *t = listObj->list;
|
||||||
|
while(t->forward != NULL) {
|
||||||
|
t = t->forward;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds an object to the end of a list object
|
||||||
|
void addToList(Object *dest, const Object src)
|
||||||
|
{
|
||||||
|
if(!dest || dest->type != TYPE_LIST)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(dest->list == NULL) {
|
||||||
|
dest->list = malloc(sizeof(struct Object));
|
||||||
|
*dest->list = src;
|
||||||
|
dest->list->forward = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *end = tail(dest);
|
||||||
|
end->forward = malloc(sizeof(struct Object));
|
||||||
|
*end->forward = src;
|
||||||
|
end->forward->forward = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Puts a string version of the given object into a given string
|
||||||
|
char* stringObj(char *dest, const Object *obj)
|
||||||
|
{
|
||||||
|
if(!dest || !obj)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(obj->type == TYPE_NUMBER) {
|
||||||
|
snprintf(dest, MAX_TOK_LEN, "%d", obj->number);
|
||||||
|
} else if(obj->type == TYPE_SYMBOL) {
|
||||||
|
snprintf(dest, MAX_TOK_LEN, "%s", obj->name);
|
||||||
|
} else if(obj->type == TYPE_BOOL) {
|
||||||
|
snprintf(dest, MAX_TOK_LEN, "%s", obj->number ? "T" : "F");
|
||||||
|
} else if(obj->type == TYPE_ERROR) {
|
||||||
|
snprintf(dest, MAX_TOK_LEN, "E%d", obj->err);
|
||||||
|
} else {
|
||||||
|
snprintf(dest, MAX_TOK_LEN, "%d", obj->number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int depth = 0;
|
||||||
|
|
||||||
|
// Prints the given object
|
||||||
|
void printObj(const Object *obj)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < depth; i++)
|
||||||
|
printf(" ");
|
||||||
|
depth++;
|
||||||
|
|
||||||
|
if(obj->type == TYPE_NUMBER) {
|
||||||
|
printf("TYPE_NUMBER");
|
||||||
|
} else if(obj->type == TYPE_BOOL) {
|
||||||
|
printf("TYPE_BOOL");
|
||||||
|
} else if(obj->type == TYPE_LIST) {
|
||||||
|
printf("TYPE_LIST\n");
|
||||||
|
printList(obj);
|
||||||
|
depth--;
|
||||||
|
return;
|
||||||
|
} else if(obj->type == TYPE_FUNC) {
|
||||||
|
printf("TYPE_FUNC");
|
||||||
|
} else if(obj->type == TYPE_SYMBOL) {
|
||||||
|
printf("TYPE_SYMBOL");
|
||||||
|
} else if(obj->type == TYPE_LAMBDA) {
|
||||||
|
printf("TYPE_LAMBDA Params:\n");
|
||||||
|
depth++;
|
||||||
|
printObj(&obj->lambda->params);
|
||||||
|
for(int i = 1; i < depth; i++)
|
||||||
|
printf(" ");
|
||||||
|
printf("Lambda Body: \n");
|
||||||
|
printObj(&obj->lambda->body);
|
||||||
|
} else if(obj->type == TYPE_ERROR) {
|
||||||
|
printf("TYPE_ERROR: ");
|
||||||
|
} else {
|
||||||
|
printf("TYPE_OTHER (as int)");
|
||||||
|
}
|
||||||
|
depth--;
|
||||||
|
char temp[20] = "";
|
||||||
|
stringObj(temp, obj);
|
||||||
|
printf(": %s\n", temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printList(const Object *list)
|
||||||
|
{
|
||||||
|
const Object *tail = list->list;
|
||||||
|
if(tail == NULL) {
|
||||||
|
for(int i = 0; i < depth; i++)
|
||||||
|
printf(" ");
|
||||||
|
printf("EMPTY LIST\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(tail != NULL) {
|
||||||
|
depth++;
|
||||||
|
printObj(tail);
|
||||||
|
depth--;
|
||||||
|
tail = tail->forward;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frees all objects in a list
|
||||||
|
void deleteList(const Object *dest)
|
||||||
|
{
|
||||||
|
if(dest->type != TYPE_LIST) {
|
||||||
|
printf("Tried to delete something other than a list\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *tail = dest->list;
|
||||||
|
while(tail != NULL) {
|
||||||
|
Object *prevTail = tail;
|
||||||
|
tail = tail->forward;
|
||||||
|
free(prevTail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Object listObject()
|
||||||
|
{
|
||||||
|
Object list;
|
||||||
|
list.forward = NULL;
|
||||||
|
list.type = TYPE_LIST;
|
||||||
|
list.list = NULL;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyList(Object *dest, const Object *src)
|
||||||
|
{
|
||||||
|
if(!dest || !src || dest->type != TYPE_LIST || src->type != TYPE_LIST)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// deleteList(dest);
|
||||||
|
const Object *march = src->list;
|
||||||
|
while(march != NULL) {
|
||||||
|
addToList(dest, *march);
|
||||||
|
march = march->forward;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Object numberObject(int num)
|
||||||
|
{
|
||||||
|
Object o;
|
||||||
|
o.forward = NULL;
|
||||||
|
o.type = TYPE_NUMBER;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Object lambdaObject()
|
||||||
|
{
|
||||||
|
Object o;
|
||||||
|
o.forward = NULL;
|
||||||
|
o.type = TYPE_LAMBDA;
|
||||||
|
o.lambda = malloc(sizeof(struct Lambda));
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Object errorObject(enum errorCode err)
|
||||||
|
{
|
||||||
|
Object o;
|
||||||
|
o.forward = NULL;
|
||||||
|
o.type = TYPE_ERROR;
|
||||||
|
o.err = err;
|
||||||
|
return o;
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef OBJECT_H
|
||||||
|
#define OBJECT_H
|
||||||
|
|
||||||
|
#define MAX_TOK_LEN 4 // 11
|
||||||
|
#define MAX_TOK_CNT 128 // 128
|
||||||
|
#define MAX_ENV_ELM 15 // 50
|
||||||
|
|
||||||
|
enum errorCode {
|
||||||
|
BAD_LIST_OF_SYMBOL_STRINGS,
|
||||||
|
TYPE_LIST_NOT_CAUGHT,
|
||||||
|
NULL_ENV,
|
||||||
|
BUILT_IN_NOT_FOUND,
|
||||||
|
NULL_PARSE
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum Type {
|
||||||
|
TYPE_NUMBER,
|
||||||
|
TYPE_BOOL,
|
||||||
|
TYPE_LIST,
|
||||||
|
TYPE_FUNC,
|
||||||
|
TYPE_SYMBOL,
|
||||||
|
TYPE_LAMBDA,
|
||||||
|
TYPE_ERROR // Currently unused
|
||||||
|
} Type;
|
||||||
|
|
||||||
|
typedef struct Object Object;
|
||||||
|
struct Lambda;
|
||||||
|
|
||||||
|
struct Object {
|
||||||
|
Type type;
|
||||||
|
Object *forward;
|
||||||
|
union {
|
||||||
|
int number;
|
||||||
|
Object *list;
|
||||||
|
char name[MAX_TOK_LEN];
|
||||||
|
Object (*func)(Object, Object);
|
||||||
|
struct Lambda *lambda; // Maybe better as not a pointer
|
||||||
|
enum errorCode err;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Maybe better as pointers
|
||||||
|
struct Lambda {
|
||||||
|
Object params;
|
||||||
|
Object body;
|
||||||
|
};
|
||||||
|
|
||||||
|
char* stringObj(char *dest, const Object *obj);
|
||||||
|
void printList(const Object *list);
|
||||||
|
void printObj(const Object *obj);
|
||||||
|
|
||||||
|
Object *tail(const Object *listObj);
|
||||||
|
void addToList(Object *dest, Object src);
|
||||||
|
void deleteList(const Object *dest);
|
||||||
|
int listLength(const Object *listObj);
|
||||||
|
Object *itemAt(const Object *listObj, int n);
|
||||||
|
void copyList(Object *dest, const Object *src);
|
||||||
|
|
||||||
|
Object listObject();
|
||||||
|
Object numberObject(int num);
|
||||||
|
Object lambdaObject();
|
||||||
|
Object errorObject();
|
||||||
|
|
||||||
|
#endif
|
171
src/pebblisp.c
171
src/pebblisp.c
|
@ -28,7 +28,11 @@ void debugSlice(struct Slice *s)
|
||||||
|
|
||||||
Object fetchFromEnvironment(const char *name, struct Environment *env)
|
Object fetchFromEnvironment(const char *name, struct Environment *env)
|
||||||
{
|
{
|
||||||
|
if(!env)
|
||||||
|
return errorObject(NULL_ENV);
|
||||||
|
|
||||||
printf("Fetching '%s' from env\n", name);
|
printf("Fetching '%s' from env\n", name);
|
||||||
|
printEnv(env);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const char *next = env->strings[i];
|
const char *next = env->strings[i];
|
||||||
while(next != NULL) {
|
while(next != NULL) {
|
||||||
|
@ -37,6 +41,10 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
|
||||||
}
|
}
|
||||||
next = env->strings[++i];
|
next = env->strings[++i];
|
||||||
}
|
}
|
||||||
|
printf("Trying outer\n");
|
||||||
|
if(env->outer) {
|
||||||
|
return fetchFromEnvironment(name, env->outer);
|
||||||
|
}
|
||||||
printf("DID NOT FIND SYMBOL\n");
|
printf("DID NOT FIND SYMBOL\n");
|
||||||
Object o;
|
Object o;
|
||||||
o.type = TYPE_ERROR;
|
o.type = TYPE_ERROR;
|
||||||
|
@ -51,7 +59,7 @@ Result parse(struct Slice *slices)
|
||||||
rest = &slices[1];
|
rest = &slices[1];
|
||||||
} else {
|
} else {
|
||||||
printf("Assigning null...\n");
|
printf("Assigning null...\n");
|
||||||
rest = NULL;
|
return R(errorObject(NULL_PARSE), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(token->text[0] == '(') {
|
if(token->text[0] == '(') {
|
||||||
|
@ -103,8 +111,6 @@ Object parseAtom(struct Slice *s)
|
||||||
|
|
||||||
Object evalDefArgs(const Object *arg_forms, struct Environment *env)
|
Object evalDefArgs(const Object *arg_forms, struct Environment *env)
|
||||||
{
|
{
|
||||||
printf("evalDefArgs()\n");
|
|
||||||
|
|
||||||
const Object *first_form = &arg_forms[0];
|
const Object *first_form = &arg_forms[0];
|
||||||
const char *name = first_form->name;
|
const char *name = first_form->name;
|
||||||
|
|
||||||
|
@ -122,69 +128,151 @@ Object evalIfArgs(const Object *arg_forms, struct Environment *env)
|
||||||
eval(arg_forms->forward->forward, env);
|
eval(arg_forms->forward->forward, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object evalBuiltIns(const Object *first, const Object *rest, int *found,
|
Object evalLambdaArgs(const Object *arg_forms)
|
||||||
|
{
|
||||||
|
const Object *params_expr = &arg_forms[0];
|
||||||
|
const Object *body_expr = &arg_forms[1];
|
||||||
|
|
||||||
|
Object o = lambdaObject();
|
||||||
|
o.lambda->params = listObject();
|
||||||
|
copyList(&o.lambda->params, params_expr);
|
||||||
|
|
||||||
|
o.lambda->body = listObject();
|
||||||
|
copyList(&o.lambda->body, arg_forms->forward);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseListOfSymbolStrings(const Object *form, const char **symbolStrings,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
if(!form || form->type != TYPE_LIST)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(int i = 0; i < len; i++)
|
||||||
|
symbolStrings[i] = itemAt(form, i)->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Environment envForLambda(const Object *params, const Object *arg_forms,
|
||||||
|
struct Environment *outer)
|
||||||
|
{
|
||||||
|
printf("\n#####################\nenvForLambda()\n");
|
||||||
|
printObj(arg_forms);
|
||||||
|
struct Environment env;
|
||||||
|
env.outer = outer;
|
||||||
|
env.strings = NULL;
|
||||||
|
env.objects = NULL;
|
||||||
|
|
||||||
|
int length = listLength(params);
|
||||||
|
|
||||||
|
if(length == 0)
|
||||||
|
return env;
|
||||||
|
|
||||||
|
env.strings = calloc(sizeof(char*), length);
|
||||||
|
env.objects = malloc(sizeof(Object) * length);
|
||||||
|
|
||||||
|
Object vs[length];
|
||||||
|
eval_forms(vs, arg_forms, outer);
|
||||||
|
|
||||||
|
for(int i = 0; i < length; i++) {
|
||||||
|
const char *n = itemAt(params, i)->name;
|
||||||
|
addToEnv(&env, n, eval(&arg_forms[i], outer)); // May not need eval?
|
||||||
|
} // Something is segfaulting, anyway
|
||||||
|
env.strings[length] = NULL;
|
||||||
|
|
||||||
|
printf("envForLambda env IT BROKE HERE()\n");
|
||||||
|
printf("envForLambda length=%d\n", length);
|
||||||
|
printEnv(&env);
|
||||||
|
printf("END envForLambda()\n\n");
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object evalBuiltIns(const Object *first, const Object *rest,
|
||||||
struct Environment *env)
|
struct Environment *env)
|
||||||
{
|
{
|
||||||
if(strcmp(first->name, "def") == 0) {
|
if(strcmp(first->name, "def") == 0) {
|
||||||
*found = 0;
|
|
||||||
return evalDefArgs(rest, env);
|
return evalDefArgs(rest, env);
|
||||||
}else if(strcmp(first->name, "if") == 0) {
|
}else if(strcmp(first->name, "if") == 0) {
|
||||||
*found = 0;
|
|
||||||
return evalIfArgs(rest, env);
|
return evalIfArgs(rest, env);
|
||||||
|
}else if(strcmp(first->name, "fn") == 0) {
|
||||||
|
// printf("EVALBUILTINS first:\n");
|
||||||
|
// printObj(first);
|
||||||
|
// printf("\nEVALBUILTINS rest:\n");
|
||||||
|
// printObj(rest);
|
||||||
|
return evalLambdaArgs(rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object o;
|
return errorObject(BUILT_IN_NOT_FOUND);
|
||||||
*found = -1;
|
}
|
||||||
return o;
|
|
||||||
|
void eval_forms(Object *destList, const Object *src, struct Environment *env)
|
||||||
|
{
|
||||||
|
int length = listLength(src) - 1; // Not counting first_form
|
||||||
|
for(int i = 0; i < length; i++) { // Evaluates all in list
|
||||||
|
destList[i] = eval(itemAt(src, i + 1), env); // Skip the first
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object eval(const Object *obj, struct Environment *env)
|
Object eval(const Object *obj, struct Environment *env)
|
||||||
{
|
{
|
||||||
// printf("eval(): ");
|
printf("eval():\n");
|
||||||
// printObj(obj);
|
printObj(obj);
|
||||||
Object o = *obj;
|
|
||||||
switch(obj->type) {
|
switch(obj->type) {
|
||||||
case TYPE_NUMBER:
|
case TYPE_NUMBER:
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
return o;
|
return *obj;
|
||||||
|
|
||||||
case TYPE_SYMBOL:
|
case TYPE_SYMBOL:
|
||||||
o = fetchFromEnvironment(obj->name, env);
|
return fetchFromEnvironment(obj->name, env);
|
||||||
printf("fetched object '%s':\n", obj->name);
|
|
||||||
printObj(&o);
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
{
|
{
|
||||||
if(listLength(obj) == 1) {
|
if(listLength(obj) == 0) {
|
||||||
o = *obj->list;
|
printf("empty list\n"); return *obj;
|
||||||
return o;
|
|
||||||
}
|
}
|
||||||
Object first_form = *obj->list;
|
|
||||||
|
if(listLength(obj) == 1)
|
||||||
|
return eval(obj->list, env);
|
||||||
|
|
||||||
|
Object *first_form = obj->list;
|
||||||
|
|
||||||
{ // Try to eval built-ins
|
{ // Try to eval built-ins
|
||||||
int i = -1;
|
|
||||||
Object built_in =
|
Object built_in =
|
||||||
evalBuiltIns(&first_form, first_form.forward, &i, env);
|
evalBuiltIns(first_form, first_form->forward, env);
|
||||||
|
|
||||||
if(i == 0)
|
if(built_in.type != TYPE_ERROR)
|
||||||
return built_in;
|
return built_in;
|
||||||
}
|
}
|
||||||
printf("\nNo built-ins found\n");
|
|
||||||
|
|
||||||
Object first_eval = eval(&first_form, env);
|
Object first_eval = eval(first_form, env);
|
||||||
Object arg1 = eval(first_form.forward, env);
|
if(first_eval.type == TYPE_FUNC) {
|
||||||
Object arg2 = eval(first_form.forward->forward, env);
|
int length = listLength(obj) - 1; // Not counting first_form
|
||||||
|
Object rest[length];
|
||||||
|
eval_forms(rest, obj, env);
|
||||||
|
|
||||||
printf("Evaluating func\n");
|
printf("Evaluating func\n");
|
||||||
Object func_eval = first_eval.func(arg1, arg2);
|
Object func_eval = first_eval.func(rest[0], rest[1]);
|
||||||
deleteList(obj);
|
// deleteList(obj);
|
||||||
return func_eval;
|
return func_eval;
|
||||||
|
} else if (first_eval.type == TYPE_LAMBDA) {
|
||||||
|
printf("lammy\n");
|
||||||
|
struct Environment newEnv =
|
||||||
|
envForLambda(&first_eval.lambda->params, first_form->forward, env);
|
||||||
|
return eval(&first_eval.lambda->body, &newEnv);
|
||||||
|
} else {
|
||||||
|
return errorObject(TYPE_LIST_NOT_CAUGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case TYPE_LAMBDA:
|
||||||
|
{
|
||||||
|
Object o;
|
||||||
|
o.type = TYPE_ERROR;
|
||||||
|
printf("UNEXPECTED FORM\n");
|
||||||
|
return o;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
return o;
|
return *obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result resultFromObjAndSlices(Object obj, struct Slice *slices)
|
Result resultFromObjAndSlices(Object obj, struct Slice *slices)
|
||||||
|
@ -206,6 +294,20 @@ void addToEnv(struct Environment *env, const char *name, const Object obj)
|
||||||
env->objects[i] = obj;
|
env->objects[i] = obj;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(strcmp(env->strings[i], name) == 0) {
|
||||||
|
env->objects[i] = obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printEnv(struct Environment *env)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < MAX_ENV_ELM; i++) {
|
||||||
|
if(env->strings[i] == NULL)
|
||||||
|
return;
|
||||||
|
printf("env[%d]: '%s'\n ", i, env->strings[i]);
|
||||||
|
printObj(&env->objects[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +392,7 @@ void deleteEnv(struct Environment *e)
|
||||||
|
|
||||||
struct Environment defaultEnv() {
|
struct Environment defaultEnv() {
|
||||||
struct Environment e;
|
struct Environment e;
|
||||||
|
e.outer = NULL;
|
||||||
e.strings = malloc(sizeof(char*) * MAX_ENV_ELM);
|
e.strings = malloc(sizeof(char*) * MAX_ENV_ELM);
|
||||||
for(int i = 0; i < MAX_ENV_ELM; i++) {
|
for(int i = 0; i < MAX_ENV_ELM; i++) {
|
||||||
e.strings[i] = NULL;
|
e.strings[i] = NULL;
|
||||||
|
@ -317,11 +420,15 @@ Object parseEval(const char *input, struct Environment *env)
|
||||||
while(debug->text) {
|
while(debug->text) {
|
||||||
char tok[MAX_TOK_LEN];
|
char tok[MAX_TOK_LEN];
|
||||||
copySlice(tok, debug);
|
copySlice(tok, debug);
|
||||||
|
//printf("slice: '%s'\n", tok);
|
||||||
debug++;
|
debug++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Object parsed = parse(tokens).obj;
|
Object parsed = parse(tokens).obj;
|
||||||
|
// printf("PARSEEVAL() PRINTLIST():\n");
|
||||||
|
// printObj(&parsed);
|
||||||
|
// printf("end PARSEEVAL() PRINTLIST():\n\n");
|
||||||
free(tokens);
|
free(tokens);
|
||||||
return eval(&parsed, env);
|
return eval(&parsed, env);
|
||||||
}
|
}
|
||||||
|
@ -335,7 +442,7 @@ int repl(struct Environment *env)
|
||||||
fgets(input, 100, stdin);
|
fgets(input, 100, stdin);
|
||||||
Object obj = parseEval(input, env);
|
Object obj = parseEval(input, env);
|
||||||
printObj(&obj);
|
printObj(&obj);
|
||||||
//break;
|
// printEnv(env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ typedef struct Result {
|
||||||
struct Environment {
|
struct Environment {
|
||||||
char **strings;
|
char **strings;
|
||||||
Object *objects;
|
Object *objects;
|
||||||
|
struct Environment *outer;
|
||||||
};
|
};
|
||||||
|
|
||||||
Object eval(const Object *obj, struct Environment *env);
|
Object eval(const Object *obj, struct Environment *env);
|
||||||
|
@ -27,9 +28,13 @@ Result readSeq(struct Slice *slices);
|
||||||
Object parseAtom(struct Slice *slice);
|
Object parseAtom(struct Slice *slice);
|
||||||
void copySlice(char * dest, struct Slice *src);
|
void copySlice(char * dest, struct Slice *src);
|
||||||
Object parseEval(const char *input, struct Environment *env);
|
Object parseEval(const char *input, struct Environment *env);
|
||||||
|
void eval_forms(Object *destList, const Object *src, struct Environment *env);
|
||||||
|
|
||||||
struct Environment defaultEnv();
|
struct Environment defaultEnv();
|
||||||
void deleteEnv(struct Environment *e);
|
void deleteEnv(struct Environment *e);
|
||||||
void addToEnv(struct Environment *env, const char *name, const Object obj);
|
void addToEnv(struct Environment *env, const char *name, const Object obj);
|
||||||
|
Object fetchFromEnvironment(const char *name, struct Environment *env);
|
||||||
|
void printEnv(struct Environment *env);
|
||||||
|
|
||||||
Result resultFromObjAndSlices(Object obj, struct Slice *slices);
|
Result resultFromObjAndSlices(Object obj, struct Slice *slices);
|
||||||
Object add(Object obj1, Object obj2);
|
Object add(Object obj1, Object obj2);
|
||||||
|
|
29
src/tags
29
src/tags
|
@ -4,19 +4,23 @@
|
||||||
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
||||||
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
||||||
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
|
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
|
||||||
|
BAD_LIST_OF_SYMBOL_STRINGS object.h /^ BAD_LIST_OF_SYMBOL_STRINGS,$/;" e enum:errorCode
|
||||||
|
BUILT_IN_NOT_FOUND object.h /^ BUILT_IN_NOT_FOUND$/;" e enum:errorCode
|
||||||
CALC_H calc.h 2;" d
|
CALC_H calc.h 2;" d
|
||||||
CODE_PKEY calc.h 11;" d
|
CODE_PKEY calc.h 11;" d
|
||||||
END_PHRASE calc.h 9;" d
|
END_PHRASE calc.h 9;" d
|
||||||
Environment pebblisp.h /^struct Environment {$/;" s
|
Environment pebblisp.h /^struct Environment {$/;" s
|
||||||
|
Lambda object.h /^struct Lambda {$/;" s
|
||||||
MAX_ENV_ELM object.h 6;" d
|
MAX_ENV_ELM object.h 6;" d
|
||||||
MAX_LENGTH calc.h 8;" d
|
MAX_LENGTH calc.h 8;" d
|
||||||
MAX_TOK_CNT object.h 5;" d
|
MAX_TOK_CNT object.h 5;" d
|
||||||
MAX_TOK_LEN object.h 4;" d
|
MAX_TOK_LEN object.h 4;" d
|
||||||
|
NULL_ENV object.h /^ NULL_ENV,$/;" e enum:errorCode
|
||||||
OBJECT_H object.h 2;" d
|
OBJECT_H object.h 2;" d
|
||||||
Object object.h /^struct Object {$/;" s
|
Object object.h /^struct Object {$/;" s
|
||||||
Object object.h /^typedef struct Object Object;$/;" t typeref:struct:Object
|
Object object.h /^typedef struct Object Object;$/;" t typeref:struct:Object
|
||||||
PEBBLISP_H pebblisp.h 2;" d
|
PEBBLISP_H pebblisp.h 2;" d
|
||||||
R pebblisp.h 41;" d
|
R pebblisp.h 45;" d
|
||||||
Result pebblisp.h /^typedef struct Result {$/;" s
|
Result pebblisp.h /^typedef struct Result {$/;" s
|
||||||
Result pebblisp.h /^} Result;$/;" t typeref:struct:Result
|
Result pebblisp.h /^} Result;$/;" t typeref:struct:Result
|
||||||
SMAX_LENGTH calc.h 7;" d
|
SMAX_LENGTH calc.h 7;" d
|
||||||
|
@ -24,9 +28,11 @@ Slice pebblisp.h /^struct Slice {$/;" s
|
||||||
TOKENS_H tokens.h 2;" d
|
TOKENS_H tokens.h 2;" d
|
||||||
TOKEN_END calc.h 42;" d
|
TOKEN_END calc.h 42;" d
|
||||||
TYPE_BOOL object.h /^ TYPE_BOOL,$/;" e enum:Type
|
TYPE_BOOL object.h /^ TYPE_BOOL,$/;" e enum:Type
|
||||||
TYPE_ERROR object.h /^ TYPE_ERROR$/;" e enum:Type
|
TYPE_ERROR object.h /^ TYPE_ERROR \/\/ Currently unused$/;" e enum:Type
|
||||||
TYPE_FUNC object.h /^ TYPE_FUNC,$/;" e enum:Type
|
TYPE_FUNC object.h /^ TYPE_FUNC,$/;" e enum:Type
|
||||||
|
TYPE_LAMBDA object.h /^ TYPE_LAMBDA,$/;" e enum:Type
|
||||||
TYPE_LIST object.h /^ TYPE_LIST,$/;" e enum:Type
|
TYPE_LIST object.h /^ TYPE_LIST,$/;" e enum:Type
|
||||||
|
TYPE_LIST_NOT_CAUGHT object.h /^ TYPE_LIST_NOT_CAUGHT,$/;" e enum:errorCode
|
||||||
TYPE_NUMBER object.h /^ TYPE_NUMBER,$/;" e enum:Type
|
TYPE_NUMBER object.h /^ TYPE_NUMBER,$/;" e enum:Type
|
||||||
TYPE_SYMBOL object.h /^ TYPE_SYMBOL,$/;" e enum:Type
|
TYPE_SYMBOL object.h /^ TYPE_SYMBOL,$/;" e enum:Type
|
||||||
Type object.h /^typedef enum Type {$/;" g
|
Type object.h /^typedef enum Type {$/;" g
|
||||||
|
@ -36,9 +42,11 @@ addToEnv pebblisp.c /^void addToEnv(struct Environment *env, const char *name, c
|
||||||
addToList object.c /^void addToList(Object *dest, const Object src)$/;" f
|
addToList object.c /^void addToList(Object *dest, const Object src)$/;" f
|
||||||
back_handler calc.c /^static void back_handler(ClickRecognizerRef recognizer, void *context) {$/;" f file:
|
back_handler calc.c /^static void back_handler(ClickRecognizerRef recognizer, void *context) {$/;" f file:
|
||||||
basicOp pebblisp.c /^Object basicOp(Object *obj1, Object *obj2, const char op)$/;" f
|
basicOp pebblisp.c /^Object basicOp(Object *obj1, Object *obj2, const char op)$/;" f
|
||||||
bopf pebblisp.c 264;" d file:
|
body object.h /^ Object body;$/;" m struct:Lambda
|
||||||
|
bopf pebblisp.c 365;" d file:
|
||||||
calculate calc.c /^static void calculate(){$/;" f file:
|
calculate calc.c /^static void calculate(){$/;" f file:
|
||||||
click_config_provider calc.c /^static void click_config_provider(void *context) {$/;" f file:
|
click_config_provider calc.c /^static void click_config_provider(void *context) {$/;" f file:
|
||||||
|
copyList object.c /^void copyList(Object *dest, const Object *src)$/;" f
|
||||||
copySlice pebblisp.c /^void copySlice(char * dest, struct Slice *src)$/;" f
|
copySlice pebblisp.c /^void copySlice(char * dest, struct Slice *src)$/;" f
|
||||||
debugSlice pebblisp.c /^void debugSlice(struct Slice *s)$/;" f
|
debugSlice pebblisp.c /^void debugSlice(struct Slice *s)$/;" f
|
||||||
defaultEnv pebblisp.c /^struct Environment defaultEnv() {$/;" f
|
defaultEnv pebblisp.c /^struct Environment defaultEnv() {$/;" f
|
||||||
|
@ -47,10 +55,16 @@ deleteEnv pebblisp.c /^void deleteEnv(struct Environment *e)$/;" f
|
||||||
deleteList object.c /^void deleteList(const Object *dest)$/;" f
|
deleteList object.c /^void deleteList(const Object *dest)$/;" f
|
||||||
enter calc.c /^static void enter(){$/;" f file:
|
enter calc.c /^static void enter(){$/;" f file:
|
||||||
env calc.h /^static struct Environment env;$/;" v typeref:struct:Environment
|
env calc.h /^static struct Environment env;$/;" v typeref:struct:Environment
|
||||||
|
envForLambda pebblisp.c /^struct Environment envForLambda(const Object *params, const Object *arg_forms,$/;" f
|
||||||
|
err object.h /^ enum errorCode err;$/;" m union:Object::__anon1 typeref:enum:Object::__anon1::errorCode
|
||||||
|
errorCode object.h /^enum errorCode {$/;" g
|
||||||
|
errorObject object.c /^inline Object errorObject(enum errorCode err)$/;" f
|
||||||
eval pebblisp.c /^Object eval(const Object *obj, struct Environment *env)$/;" f
|
eval pebblisp.c /^Object eval(const Object *obj, struct Environment *env)$/;" f
|
||||||
evalBuiltIns pebblisp.c /^Object evalBuiltIns(const Object *first, const Object *rest, int *found,$/;" f
|
evalBuiltIns pebblisp.c /^Object evalBuiltIns(const Object *first, const Object *rest,$/;" f
|
||||||
evalDefArgs pebblisp.c /^Object evalDefArgs(const Object *arg_forms, struct Environment *env)$/;" f
|
evalDefArgs pebblisp.c /^Object evalDefArgs(const Object *arg_forms, struct Environment *env)$/;" f
|
||||||
evalIfArgs pebblisp.c /^Object evalIfArgs(const Object *arg_forms, struct Environment *env)$/;" f
|
evalIfArgs pebblisp.c /^Object evalIfArgs(const Object *arg_forms, struct Environment *env)$/;" f
|
||||||
|
evalLambdaArgs pebblisp.c /^Object evalLambdaArgs(const Object *arg_forms, struct Environment *env)$/;" f
|
||||||
|
eval_forms pebblisp.c /^void eval_forms(Object *destList, const Object *src, struct Environment *env)$/;" f
|
||||||
fetchFromEnvironment pebblisp.c /^Object fetchFromEnvironment(const char *name, struct Environment *env)$/;" f
|
fetchFromEnvironment pebblisp.c /^Object fetchFromEnvironment(const char *name, struct Environment *env)$/;" f
|
||||||
forward object.h /^ Object *forward;$/;" m struct:Object
|
forward object.h /^ Object *forward;$/;" m struct:Object
|
||||||
func object.h /^ Object (*func)(Object, Object);$/;" m union:Object::__anon1
|
func object.h /^ Object (*func)(Object, Object);$/;" m union:Object::__anon1
|
||||||
|
@ -59,6 +73,9 @@ init calc.c /^static void init(void) {$/;" f file:
|
||||||
isDigit tokens.c /^int isDigit(const char c) {$/;" f
|
isDigit tokens.c /^int isDigit(const char c) {$/;" f
|
||||||
isSingle tokens.c /^int isSingle(const char c) {$/;" f
|
isSingle tokens.c /^int isSingle(const char c) {$/;" f
|
||||||
isWhitespace tokens.c /^int isWhitespace(const char c) {$/;" f
|
isWhitespace tokens.c /^int isWhitespace(const char c) {$/;" f
|
||||||
|
itemAt object.c /^Object *itemAt(const Object *listObj, int n)$/;" f
|
||||||
|
lambda object.h /^ struct Lambda *lambda; \/\/ Maybe better as not a pointer$/;" m union:Object::__anon1 typeref:struct:Object::__anon1::Lambda
|
||||||
|
lambdaObject object.c /^inline Object lambdaObject()$/;" f
|
||||||
length pebblisp.h /^ char length;$/;" m struct:Slice
|
length pebblisp.h /^ char length;$/;" m struct:Slice
|
||||||
list object.h /^ Object *list;$/;" m union:Object::__anon1
|
list object.h /^ Object *list;$/;" m union:Object::__anon1
|
||||||
listLength object.c /^int listLength(const Object *listObj)$/;" f
|
listLength object.c /^int listLength(const Object *listObj)$/;" f
|
||||||
|
@ -73,9 +90,13 @@ number object.h /^ int number;$/;" m union:Object::__anon1
|
||||||
numberObject object.c /^inline Object numberObject(int num)$/;" f
|
numberObject object.c /^inline Object numberObject(int num)$/;" f
|
||||||
obj pebblisp.h /^ Object obj;$/;" m struct:Result
|
obj pebblisp.h /^ Object obj;$/;" m struct:Result
|
||||||
objects pebblisp.h /^ Object *objects;$/;" m struct:Environment
|
objects pebblisp.h /^ Object *objects;$/;" m struct:Environment
|
||||||
|
outer pebblisp.h /^ struct Environment *outer;$/;" m struct:Environment typeref:struct:Environment::Environment
|
||||||
|
params object.h /^ Object params;$/;" m struct:Lambda
|
||||||
parse pebblisp.c /^Result parse(struct Slice *slices)$/;" f
|
parse pebblisp.c /^Result parse(struct Slice *slices)$/;" f
|
||||||
parseAtom pebblisp.c /^Object parseAtom(struct Slice *s)$/;" f
|
parseAtom pebblisp.c /^Object parseAtom(struct Slice *s)$/;" f
|
||||||
parseEval pebblisp.c /^Object parseEval(const char *input, struct Environment *env)$/;" f
|
parseEval pebblisp.c /^Object parseEval(const char *input, struct Environment *env)$/;" f
|
||||||
|
parseListOfSymbolStrings pebblisp.c /^void parseListOfSymbolStrings(const Object *form, const char **symbolStrings,$/;" f
|
||||||
|
printEnv pebblisp.c /^void printEnv(struct Environment *env)$/;" f
|
||||||
printList object.c /^void printList(const Object *list)$/;" f
|
printList object.c /^void printList(const Object *list)$/;" f
|
||||||
printObj object.c /^void printObj(const Object *obj)$/;" f
|
printObj object.c /^void printObj(const Object *obj)$/;" f
|
||||||
printf object.c 7;" d file:
|
printf object.c 7;" d file:
|
||||||
|
|
Loading…
Reference in New Issue