Added head, tail, list, eval, and join for Q-expressions
This commit is contained in:
parent
dd5de0cafa
commit
a485e65838
3 changed files with 91 additions and 3 deletions
|
@ -6,7 +6,8 @@
|
|||
#include "operations.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* lval_sexpr(void) {
|
||||
|
@ -77,10 +78,68 @@ lval* lval_eval_sexpr(lval* v) {
|
|||
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);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -22,5 +22,20 @@ lval* lval_take(lval* v, int i);
|
|||
// Adds the ability to evalutate each expression in the group
|
||||
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
|
||||
|
|
16
prompt.c
16
prompt.c
|
@ -55,7 +55,7 @@ int main (int argc, char** argv) {
|
|||
"double : <long> '.' <number>; "
|
||||
"symbol : '+' | '-' | '*' | '/' | '%' \
|
||||
| '^' | \"min\" | \"max\" \
|
||||
| \"list\" | \"head\" | \"tail\" | \"join\" | \"eval\" "
|
||||
| \"list\" | \"head\" | \"tail\" | \"join\" | \"eval\";"
|
||||
|
||||
"sexpr : '(' <expr>* ')'; "
|
||||
"qexpr : '{' <expr>* '}'; "
|
||||
|
@ -159,3 +159,17 @@ lval* builtin_op(lval* a, char* op) {
|
|||
lval_del(a);
|
||||
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!");
|
||||
}
|
Reference in a new issue