Archived
1
0
Fork 0

Added head, tail, list, eval, and join for Q-expressions

This commit is contained in:
Brandon Rozek 2018-06-07 20:06:57 -04:00
parent dd5de0cafa
commit a485e65838
3 changed files with 91 additions and 3 deletions

View file

@ -6,7 +6,8 @@
#include "operations.h" #include "operations.h"
#include "error.h" #include "error.h"
// Think about where to put this declaration later // Think about where to put these declarations later
lval* builtin(lval* a, char* func);
lval* builtin_op(lval* v, char* op); lval* builtin_op(lval* v, char* op);
lval* lval_sexpr(void) { lval* lval_sexpr(void) {
@ -77,10 +78,68 @@ lval* lval_eval_sexpr(lval* v) {
return lval_err("S-expression does not start with symbol"); return lval_err("S-expression does not start with symbol");
} }
lval* result = builtin_op(v, f->sym); lval* result = builtin(v, f->sym);
lval_del(f); lval_del(f);
return result; return result;
} }
lval* builtin_head(lval* a) {
LASSERT(a, a->count == 1, "Function 'head' passed too many arguments")
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Function 'head' passed incorrect type")
LASSERT(a, a->cell[0]->count != 0, "Function 'head' passed {}")
lval* v = lval_take(a, 0);
while (v->count > 1) { lval_del(lval_pop(v, 1)); }
return v;
}
lval* builtin_tail(lval* a) {
LASSERT(a, a->count == 1, "Function 'tail' passed too many arguments")
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Function 'tail' passed incorrect type")
LASSERT(a, a->cell[0]->count != 0, "Function 'tail' passed {}")
lval* v = lval_take(a, 0);
lval_del(lval_pop(v, 0));
return v;
}
lval* builtin_list(lval* a) {
a->type = LVAL_QEXPR;
return a;
}
lval* builtin_eval(lval* a) {
LASSERT(a, a->count == 1, "Function 'eval' passed too many arguments")
LASSERT(a, a->cell[0]->type == LVAL_QEXPR, "Function 'eval' passed incorrect type")
lval* x = lval_take(a, 0);
x->type = LVAL_SEXPR;
return lval_eval(x);
}
lval* lval_join(lval* x, lval* y) {
// For each cell in 'y' add it to 'x'
while (y->count) {
x = lval_add(x, lval_pop(y, 0));
}
// Delete the empty y and return x
lval_del(y);
return x;
}
lval* builtin_join(lval* a) {
for (int i = 0 ; i < a->count; i++) {
LASSERT(a, a->cell[i]->type == LVAL_QEXPR, "Function 'join' passed incorrect type")
}
lval* x = lval_pop(a, 0);
while (a->count) {
x = lval_join(x, lval_pop(a, 0));
}
lval_del(a);
return x;
}

View file

@ -22,5 +22,20 @@ lval* lval_take(lval* v, int i);
// Adds the ability to evalutate each expression in the group // Adds the ability to evalutate each expression in the group
lval* lval_eval_sexpr(lval* v); lval* lval_eval_sexpr(lval* v);
/*
QEXPR Operations
Head: Takes a Q-Expression and returns a Q-Expression with only of the first element
Tail: Takes a Q-Expression and returns a Q-Expression with the first element removed
List: Takes one or more arguments and returns a new Q-Expression containing the arguments
Eval: Takes a Q-Expression and evaluates it as if it were a S-Expression
Join: join Takes one or more Q-Expressions and returns a Q-Expression of them conjoined together
*/
lval* builtin_head(lval* a);
lval* builtin_tail(lval* a);
lval* builtin_list(lval* a);
lval* builtin_eval(lval* a);
lval* lval_join(lval* x, lval* y);
lval* builtin_join(lval* a);
#endif #endif

View file

@ -55,7 +55,7 @@ int main (int argc, char** argv) {
"double : <long> '.' <number>; " "double : <long> '.' <number>; "
"symbol : '+' | '-' | '*' | '/' | '%' \ "symbol : '+' | '-' | '*' | '/' | '%' \
| '^' | \"min\" | \"max\" \ | '^' | \"min\" | \"max\" \
| \"list\" | \"head\" | \"tail\" | \"join\" | \"eval\" " | \"list\" | \"head\" | \"tail\" | \"join\" | \"eval\";"
"sexpr : '(' <expr>* ')'; " "sexpr : '(' <expr>* ')'; "
"qexpr : '{' <expr>* '}'; " "qexpr : '{' <expr>* '}'; "
@ -159,3 +159,17 @@ lval* builtin_op(lval* a, char* op) {
lval_del(a); lval_del(a);
return x; return x;
} }
lval* builtin(lval* a, char* func) {
if (strcmp("list", func) == 0) { return builtin_list(a); }
if (strcmp("head", func) == 0) { return builtin_head(a); }
if (strcmp("tail", func) == 0) { return builtin_tail(a); }
if (strcmp("join", func) == 0) { return builtin_join(a); }
if (strcmp("eval", func) == 0) { return builtin_eval(a); }
if (strstr("+-/*^%", func)) { return builtin_op(a, func); }
if (strcmp("min", func) == 0) { return builtin_op(a, func); }
if (strcmp("max", func) == 0) { return builtin_op(a, func); }
lval_del(a);
return lval_err("Unknown Function!");
}