feat: get working version!
The main bug I was having was infinite recursion!
This commit is contained in:
parent
e7b46b0ff9
commit
289de06edf
58
src/mumble.c
58
src/mumble.c
|
@ -169,7 +169,7 @@ void print_lispval_parenthesis(lispval* v)
|
||||||
printf("%li ", v->num);
|
printf("%li ", v->num);
|
||||||
break;
|
break;
|
||||||
case LISPVAL_ERR:
|
case LISPVAL_ERR:
|
||||||
printf("[Error: %s] ", v->err);
|
printf("%s ", v->err);
|
||||||
break;
|
break;
|
||||||
case LISPVAL_SYM:
|
case LISPVAL_SYM:
|
||||||
printf("%s ", v->sym);
|
printf("%s ", v->sym);
|
||||||
|
@ -228,7 +228,6 @@ lispval* take_lispval(lispval* v, int i){
|
||||||
delete_lispval(v);
|
delete_lispval(v);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
lispval* builtin_op(char* op, lispval* v){
|
lispval* builtin_op(char* op, lispval* v){
|
||||||
// For now, ensure all args are numbers
|
// For now, ensure all args are numbers
|
||||||
for(int i=0; i<v->count; i++){
|
for(int i=0; i<v->count; i++){
|
||||||
|
@ -240,7 +239,7 @@ lispval* builtin_op(char* op, lispval* v){
|
||||||
if(v->count == 0){
|
if(v->count == 0){
|
||||||
return lispval_err("Error: No numbers on which to operate!");
|
return lispval_err("Error: No numbers on which to operate!");
|
||||||
} else if(v->count == 1) {
|
} else if(v->count == 1) {
|
||||||
if(strcmp(op, "-")){
|
if(strcmp(op, "-") == 0){
|
||||||
return lispval_num(-v->cell[0]->num);
|
return lispval_num(-v->cell[0]->num);
|
||||||
}else {
|
}else {
|
||||||
return lispval_err("Error: Non minus unary operation");
|
return lispval_err("Error: Non minus unary operation");
|
||||||
|
@ -271,56 +270,15 @@ lispval* builtin_op(char* op, lispval* v){
|
||||||
return lispval_err("Error: Incorrect number of args. Perhaps a lispval->count was wrongly initialized?");
|
return lispval_err("Error: Incorrect number of args. Perhaps a lispval->count was wrongly initialized?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
lispval* builtin_op(lispval* a, char* op) {
|
|
||||||
return lispval_num(1);
|
|
||||||
/* Ensure all arguments are numbers */
|
|
||||||
for (int i = 0; i < a->count; i++) {
|
|
||||||
if (a->cell[i]->type != LISPVAL_NUM) {
|
|
||||||
// delete_lispval(a);
|
|
||||||
return lispval_err("Cannot operate on non-number!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pop the first element */
|
|
||||||
lispval* x = pop_lispval(a, 0);
|
|
||||||
|
|
||||||
/* If no arguments and sub then perform unary negation */
|
|
||||||
if ((strcmp(op, "-") == 0) && a->count == 0) {
|
|
||||||
x->num = -x->num;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* While there are still elements remaining */
|
|
||||||
while (a->count > 0) {
|
|
||||||
|
|
||||||
/* Pop the next element */
|
|
||||||
lispval* y = pop_lispval(a, 0);
|
|
||||||
|
|
||||||
if (strcmp(op, "+") == 0) { x->num += y->num; }
|
|
||||||
if (strcmp(op, "-") == 0) { x->num -= y->num; }
|
|
||||||
if (strcmp(op, "*") == 0) { x->num *= y->num; }
|
|
||||||
if (strcmp(op, "/") == 0) {
|
|
||||||
if (y->num == 0) {
|
|
||||||
delete_lispval(x); delete_lispval(y);
|
|
||||||
return lispval_err("Division By Zero!");
|
|
||||||
}
|
|
||||||
x->num /= y->num;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_lispval(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_lispval(a); return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
lispval* evaluate_lispval(lispval* l)
|
lispval* evaluate_lispval(lispval* l)
|
||||||
{
|
{
|
||||||
// Evaluate the children
|
// Evaluate the children if needed
|
||||||
for(int i=0; i<l->count; i++){
|
for(int i=0; i<l->count; i++){
|
||||||
l->cell[i] = evaluate_lispval(l->cell[i]);
|
if(l->cell[i]->type == LISPVAL_SEXPR){
|
||||||
|
l->cell[i] = evaluate_lispval(l->cell[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check if any are errors.
|
// Check if any are errors.
|
||||||
for(int i=0; i<l->count; i++){
|
for(int i=0; i<l->count; i++){
|
||||||
|
@ -332,7 +290,7 @@ lispval* evaluate_lispval(lispval* l)
|
||||||
// Check if the first element is an operation.
|
// Check if the first element is an operation.
|
||||||
if(l->count >=2 && ( (l->cell[0])->type == LISPVAL_SYM)){
|
if(l->count >=2 && ( (l->cell[0])->type == LISPVAL_SYM)){
|
||||||
lispval* op = pop_lispval(l, 0);
|
lispval* op = pop_lispval(l, 0);
|
||||||
lispval* result = builtin_op(l, op->sym);
|
lispval* result = builtin_op(op->sym, l);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
|
@ -394,7 +352,7 @@ int main(int argc, char** argv)
|
||||||
print_lispval_parenthesis(l);
|
print_lispval_parenthesis(l);
|
||||||
}
|
}
|
||||||
lispval* result = evaluate_lispval(l);
|
lispval* result = evaluate_lispval(l);
|
||||||
print_lispval_parenthesis(result);
|
printf("\n"); print_lispval_parenthesis(result);
|
||||||
delete_lispval(l);
|
delete_lispval(l);
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise Print the Error */
|
/* Otherwise Print the Error */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user