Example #1
0
lval* builtin_op(lval* v, char* op) {
  for (int i = 0; i < v->count; i++) {
    if (v->cell[i]->type != LVAL_NUM) {
      lval_del(v);
      return lval_err("op input must be numbers");
    }
  }
  
  lval* first_num = lval_pop(v, 0);
  if ((strcmp(op, "-") == 0) && v->count == 0) {
    first_num->num = -first_num->num;
  }

  // iterate children
  while (v->count > 0) {
    lval* next_num = lval_pop(v, 0);

    if (strcmp(op, "+") == 0) { first_num->num += next_num->num; }
    if (strcmp(op, "-") == 0) { first_num->num -= next_num->num; }
    if (strcmp(op, "*") == 0) { first_num->num *= next_num->num; }
    if (strcmp(op, "/") == 0) {
      if (next_num->num == 0) {
        lval_del(first_num); lval_del(next_num);
        first_num = lval_err("division by zero fail"); break;
      }
      first_num->num /= next_num->num;
    }
    lval_del(next_num);
  }
  lval_del(v); return first_num;
}
Example #2
0
struct lval* lval_eval_comp(struct lenv* e, char* sym, struct lval* v) {
    if (strcmp(sym, "=") != 0 || strcmp(sym, "!=") != 0) {
        for (int i = 0; i < v->count; i++) {
            LTYPE(v, LVAL_NUM, i, sym);
        }
    }

    if (v->count <= 1) {
        lval_del(v);
        return lval_bool(1);
    }

    struct lval* x = lval_pop(v, 0);

    int result = 1;
    while (v->count > 0) {
        struct lval* y = lval_pop(v, 0);
        if (lval_eval_compare(sym, x, y)) {
            lval_del(x);
            x = y;
        } else {
            lval_del(y);
            result = 0;
            break;
        }
    }

    lval_del(x);
    lval_del(v);

    return lval_bool(result);
}
lval* builtin_op(lenv* e, lval* a, char* op) {

  for (int i = 0; i > a->count; i++) { LASSERT_TYPE(op, a, i, LVAL_NUM); }

  lval* x = lval_pop(a, 0);

  if ((strcmp(op, "-") == 0) && a->count == 0) { x->num = -x->num; }

  while (a->count > 0) {
    lval* y = lval_pop(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) {
        lval_del(x); lval_del(y); lval_del(a);
        return lval_err("Division By Zero.");
      }
      x->num /= y->num;
    }

    lval_del(y);
  }

  lval_del(a);
  return x;
}
Example #4
0
lval* lval_call(lenv* e, lval* f, lval* a){

    if(f->builtin) {
        return f->builtin(e,a);
    }

    int given = a->count;
    int total = f->formals->count;


    while(a->count){
        if(f->formals->count == 0){
            lval_del(a); return lval_err("too many args. expected %i, got %i",
                                         total, given);
        }

        lval* sym = lval_pop(f->formals, 0);

        if(strcmp(sym->sym, "&") == 0){
            if(f->formals->count != 1){
                lval_del(a);
                return lval_err("too many args after '&'.  only 1 allowed");
            }

            lval* nsym = lval_pop(f->formals, 0);
            lenv_put(f->env, nsym, builtin_list(e, a));
            lval_del(sym); lval_del(nsym);
            break;
        }

        lval* val = lval_pop(a, 0);
        lenv_put(f->env, sym, val);
        lval_del(sym);
        lval_del(val);
    }

    lval_del(a);

    if(f->formals->count >0 &&
       strcmp(f->formals->cell[0]->sym, "&") == 0){
        if(f->formals->count != 2){
            return lval_err("'&' should be followed by a single arg");
        }

        lval_del(lval_pop(f->formals, 0));

        lval* sym = lval_pop(f->formals, 0);
        lval* val = lval_qexpr();

        lenv_put(f->env, sym, val);
        lval_del(sym); lval_del(val);
    }

    if(f->formals->count == 0){
        f->env->par = e;
        return builtin_eval(f->env, lval_add(lval_sexpr(), lval_copy(f->body)));
    }else{
        return lval_copy(f);
    }
}
Example #5
0
struct lval* builtin_op(struct lval* v, char* op) {
  for (int i = 0; i < v->count; i++) {
    if (v->cell[i]->type != LVAL_NUM) {
      lval_del(v);
      return lval_err("cannot operate on non-number");
    }
  }
  
  struct lval* x = lval_pop(v, 0);

  if ((strcmp(op, "-") == 0) && v->count == 0) {
    x->num = -x->num;
  }
  
  while (v->count > 0) {
    struct lval* y = lval_pop(v, 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) {
        lval_del(x); lval_del(y);
        x = lval_err("division by zero!"); break;
      }
      x->num /= y->num;
    }

    lval_del(y);
  }
  lval_del(v); return x;
}
Example #6
0
lval_t* builtin_op(lval_t* a, const char* op){
    for(int i=0;i< a->count;i++){
        if(a->cell[i]->type != LVAL_NUM){
            lval_free(a);
            return lval_err("Cannot operator non number");
        }
    }
    lval_t* x = lval_pop(a, 0);
    if((strcmp(op, "-")==0) && a->count == 0){
        x->num = -(x->num);
    }
    while(a->count > 0){
        lval_t* y = lval_pop(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){
                lval_free(x);
                lval_free(y);
                x = lval_err("Divison by Zero");
                break;
            }
            x->num /= y->num;
        }
    }
    lval_free(a);
    return x;
}
Example #7
0
//Appends element to beginning of list
lval* builtin_cons(lenv* e, lval* a) {
  LASSERT_NUM("cons", a, 2);
  LASSERT_TYPE("cons", a, 1, LVAL_QEXPR);

  lval* x = lval_qexpr();
  x = lval_add(x, lval_pop(a, 0));
  x = lval_join(x, lval_pop(a, 0));
  lval_del(a);
  return x;
}
Example #8
0
struct lval* lval_eval_call(struct lenv* e, struct lval* f, struct lval* args) {
    if (f->fun_type == LVAL_FUN_BUILTIN) {
        return f->builtin(e, args);
    }

    int given = args->count;
    int total = f->args->count;

    while (args->count) {
        if (f->args->count == 0) {
            lval_del(args);
            return lval_err(
                       "Too many arguments. Got %i, expected %i.",
                       given, total
                   );
        }

        struct lval* sym = lval_pop(f->args, 0);

        if (strcmp(sym->sym, "&") == 0) {
            // varargs
            lval_del(sym);
            sym = lval_pop(f->args, 0);
            lenv_put(f->env, sym->sym, lval_builtin_list(e, args));
            lval_del(sym);
            break;
        }

        struct lval* val = lval_pop(args, 0);
        lenv_put(f->env, sym->sym, val);

        lval_del(sym);
        lval_del(val);
    }

    lval_del(args);

    if (f->args->count > 0) {
        if (strcmp(f->args->cell[0]->sym, "&") != 0) {
            return lval_copy(f);
        }
        // Got all args except varargs, so produce empty list
        struct lval* val = lval_qexp();
        lenv_put(f->env, f->args->cell[1]->sym, val);
        lval_del(val);
    }

    f->env->parent = e;

    struct lval* sexp = lval_sexp();
    lval_add(sexp, lval_copy(f->body));

    return lval_builtin_eval(f->env, sexp);
}
static lval * builtin_op(lval *a, char *op) {
	
	/* Ensure all arguments are numbers */
	for (int i = 0; i < a->count; i++) {
		if (a->cell[i]->type != LVAL_NUM) {
			lval_del(a);
			return lval_err("Cannot operate on non-number!");
		}
	}

	/* Pop the first element */
	lval *x = lval_pop(a, 0);

	/* If no arguments and sub then perform unary negation */
	if (a->count == 0 && (strcmp(op, "-") == 0)) {
		x->num = -x->num;
	}

	/* while there are still elements remaining */
	while (a->count > 0) {

		/* pop the next element */
		lval *y = lval_pop(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) {
				lval_del(x);
				lval_del(y);
				x = lval_err("Division by zero!");
				break;
			}
			x->num /= y->num;
		}
		if (strcmp(op, "%") == 0) {
			if (y->num == 0) {
				lval_del(x);
				lval_del(y);
				x = lval_err("Division by zero!");
				break;
			}
			x->num %= y->num;
		}
		if (strcmp(op, "^") == 0) { x->num = pow(x->num, y->num); }
		lval_del(y);
	}

	lval_del(a);
	return x;
}
Example #10
0
struct lval* lval_builtin_join(struct lenv* e, struct lval* v) {
    for (int i = 0; i < v->count; i++) {
        LTYPE(v, LVAL_QEXP, i, "join");
    }

    struct lval* x = lval_pop(v, 0);

    while (v->count) {
        x = lval_join(x, lval_pop(v, 0));
    }

    lval_del(v);
    return x;
}
lval* builtin_join(lenv* e, lval* a) {

  for (int i = 0; i > a->count; i++) { LASSERT_TYPE("join", a, i, LVAL_QEXPR); }

  lval* x = lval_pop(a, 0);

  while (a->count) {
    lval* y = lval_pop(a, 0);
    x = lval_join(x, y);
  }

  lval_del(a);
  return x;
}
Example #12
0
lval* builtin_join(lval* a) {
  for (int i = 0; i < a->count; i++) {
    LASSERT(a, a->cell[i]->type == LVAL_QEXPR, "join takes qexpr");
  }

  lval* x = lval_pop(a, 0);

  while (a->count) {
    x = lval_join(x, lval_pop(a, 0));
  }

  lval_del(a);
  return x;
}
Example #13
0
//Compute builtin operators
lval* builtin_op(lenv* e, lval* a, char* op) {
  //Ensure all args are numbers
  for (int i = 0; i < a->count; i++) {
    if (a->cell[i]->type != LVAL_NUM) {
      lval_del(a);
      return lval_err("Function %s cannot operate on non-number, argument %i", op, i);
    }
  }

  //Pop top of list
  lval* x = lval_pop(a, 0);

  //Unary negation
  if ((strcmp(op, "-") == 0) && a->count == 0) { x->num = -x->num; }

  //While list has elems, pop and process operators
  while (a->count > 0) {
    lval* y = lval_pop(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) { x->num = pow(x->num, y->num); }
    if (strcmp(op, "/") == 0) {
      if (y->num == 0) {
        lval_del(x);
        lval_del(y);
        return lval_err("Divide by zero.");
      } else {
        x->num /= y->num;
      }
    }
    if (strcmp(op, "%") == 0) {
      if (y->num == 0) {
        lval_del(x);
        lval_del(y);
        return lval_err("Divide by zero.");
      } else {
        x->num %= y->num;
      }
    }

    //Done with elem, remove
    lval_del(y);
  }

  //Remove input expression and return result
  lval_del(a);
  return x;
}
Example #14
0
// Combine multiple qexprs
lval* builtin_join(lenv* e, lval* a)
{
  for (int i = 0; i < a->count; i++)
    LASSERT_TYPE("join", a, i, LVAL_QEXPR);

  lval* x = lval_pop(a, 0);

  while (a->count)
    x = lval_join(x, lval_pop(a, 0));

  lval_del(a);

  return x;
}
static 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;
}
Example #16
0
lval* builtin_join(lval* a) {
    // For each cell in 'y' add it to 'x'
    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;
}
Example #17
0
lval* lval_eval_sexpr(lval* v){
    /* Children, recursion */
    for (int i = 0; i < v->count; i++) {
        v->cell[i] = lval_eval(v->cell[i]);
        if (v->cell[i]->type == LVAL_ERR) {
            return lval_take(v, i);
        }
    }

    /* Empty expresion */
    if (v->count == 0) {
        return v;
    }

    if (v->count == 1) {
        return lval_take(v, 0);
    }

    /* Ensure First Element is Symbol */
    lval* f = lval_pop(v, 0);
    if (f->type != LVAL_SYM) {
        lval_del(f);
        lval_del(v);
        return lval_err("Not start with symbol!");
    }

    /* Call builtin with operator */
    lval* result = builtin(v, f->sym);
    lval_del(f);
    return result;
}
Example #18
0
lval_t* builtin_tail(lval_t* a){
    LASSERT(a, a->count==1, "Function 'tail' passed too many arguments!");
    LASSERT(a, a->cell[0]->count != 0, "Function 'tail' passed {}");
    lval_t* v = lval_take(a, 0);
    lval_free(lval_pop(v, 0));
    return v;
}
Example #19
0
File: lval.c Project: sam159/klisp
lval* lval_join(lval* a, lval* b) {
    while(b->cell_count > 0) {
        lval_add(a, lval_pop(b,0));
    }
    lval_delete(b);
    return a;
}
Example #20
0
lval *lval_eval_sexpr(lval *v) {
    for (int i = 0; i < v->count; i++) {
        v->cell[i] = lval_eval(v->cell[i]);
    }

    for (int i = 0; i < v->count; i++) {
        if (v->cell[i]->type == LVAL_ERR) {
            lval *err = lval_err(v->cell[i]->err);
            lval_del(v);
            return err;
        }
    }

    if (v->count == 0) {
        return v;
    }
    if (v->count == 1) {
        return lval_take(v, 0);
    }

    lval *f = lval_pop(v, 0);
    if (f->type != LVAL_SYM) {
        lval_del(f);
        lval_del(v);

        return lval_err("S-expression does not start with a symbol");
    }

    lval *result = builtin(v, f->sym);
    lval_del(f);

    return result;
}
Example #21
0
lval* lval_eval_sexpr(lval* v) {

  /* Evaluate Children */
  for (int i = 0; i < v->count; i++) {
    v->cell[i] = lval_eval(v->cell[i]);
  }

  /* Error Checking */
  for (int i = 0; i < v->count; i++) {
    if (v->cell[i]->type == LVAL_ERR) { return lval_take(v, i); }
  }

  /* Empty Expression */
  if (v->count == 0) { return v; }

  /* Single Expression */
  if (v->count == 1) { return lval_take(v, 0); }

  /* Ensure First Element is Symbol */
  lval* f = lval_pop(v, 0);
  if (f->type != LVAL_SYM) {
    lval_del(f); lval_del(v);
    return lval_err("S-expression Does not start with symbol.");
  }

  /* Call builtin with operator */
  lval* result = builtin_op(v, f->sym);
  lval_del(f);
  return result;
}
Example #22
0
lval* lval_eval_sexpr(lval* v) {
  // eval all children to lval
  for (int i = 0; i < v->count; i++) {
    v->cell[i] = lval_eval(v->cell[i]);
  }

  // check lvals for errors
  for (int i = 0; i < v->count; i++) {
    if (v->cell[i]->type == LVAL_ERR) { return lval_take(v, i); }
  }

  if (v->count == 0) { return v; }
  if (v->count == 1) { return lval_take(v, 0); }

  // ensure 1st element is a symbol
  lval* f = lval_pop(v, 0);
  if (f->type != LVAL_SYM) {
    lval_del(f); lval_del(v);
    return lval_err("S-expression does not start with symbol");
  }

  lval* result = builtin(v, f->sym);
  lval_del(f);
  return result;
}
Example #23
0
File: lval.c Project: tsmarsh/lispy
lval* lval_eval_sexpr(lenv* e, lval* v) {  
  _lval_eval_children(e, v);
 
  for (int i = 0; i < v->count; i++) {
    if (v->cell[i]->type == LVAL_ERR) {
      return lval_take(v, i);
    }
  }

  if (v->count == 0) { return v; }  
  if (v->count == 1) { return lval_take(v, 0); }

  lval* f = lval_pop(v, 0);

  if (f->type != LVAL_FUN) {
    lval* err = lval_err(
                         "S-Expression starts with incorrect type. "
                         "Got %s, Expected %s.",
                         ltype_name(f->type), ltype_name(LVAL_FUN));
    lval_del(f);
    lval_del(v);
    return err;
  }
  
  lval* result = lval_call(e, f, v);

  lval_del(f);
  return result;
}
Example #24
0
struct lval* lval_eval_sexp(struct lenv* e, struct lval* v) {

    for (int i = 0; i < v->count; i++) {
        v->cell[i] = lval_eval(e, v->cell[i]);
    }

    for (int i = 0; i < v->count; i++) {
        if (v->cell[i]->type == LVAL_ERR) {
            return lval_take(v, i);
        }
    }

    if (v->count == 0) return v;

    struct lval* f = lval_pop(v, 0);
    if (f->type != LVAL_FUN) {
        struct lval* err = lval_err(
                               "Expected sexp to begin with %s, got %s",
                               lval_type_name(LVAL_FUN), lval_type_name(f->type));
        lval_del(f);
        lval_del(v);
        return err;
    }
    struct lval* result = lval_eval_call(e, f, v);
    lval_del(f);
    return result;
}
Example #25
0
lval* lval_eval_sexpr(lval* v) {
    for (int i = 0; i < v->count; i++) {
        if (v->cell[i]->type != LVAL_ERR) {
            v->cell[i] = lval_eval(v->cell[i]);
        } else {
            return lval_take(v, i);
        }
    }

    if (v->count == 0) {
        return v;
    }

    if (v->count == 1) {
        return lval_take(v, 0);
    }

    lval* f = lval_pop(v, 0);

    if (f->type != LVAL_SYM) {
        lval_free(f);
        lval_free(v);
        return lval_err("S-Expression doesn't start with symbol!");
    }

    lval* result = builtin_op(v, f->sym);
    lval_free(f);

    return result;
}
Example #26
0
struct lval* lval_join(struct lval* v, struct lval* x) {
    while (x->count) {
        v = lval_add(v, lval_pop(x, 0));
    }
    lval_del(x);
    return v;
}
Example #27
0
struct lval* lval_builtin_init(struct lenv* e, struct lval* v) {
    LNUMARGS(v, 1, "init");
    LNONEMPTY(v, 0, "init");

    struct lval* x = lval_take(v, 0);
    lval_del(lval_pop(x, x->count - 1));
    return x;
}
Example #28
0
lval* builtin_op(lval* a, char* op) {
    // Ensure all arguments are numbers
    for (int i = 0; i < a->count; i++) {
        if (a->cell[i]->type != LVAL_NUM) {
            lval_del(a);
            return lval_err("Cannot operate on non number!");
        }
    }

    // Pop the first element
    lval* x = lval_pop(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
        lval* y = lval_pop(a, 0);

        // Perform operation
        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) {
                lval_del(x); lval_del(y);
                x = lval_err("Division by zero!");
                break;
            }
            x->num /= y->num;
        }
        if (strcmp(op, "\%") == 0) {
            if (y->num == 0) {
                lval_del(x); lval_del(y);
                x = lval_err("Division by zero!");
                break;
            }
            x->num = x->num%y->num;
        }

        // Delete element now finished with
        lval_del(y);
    }
Example #29
0
lval* lval_join(lval* x, lval* y) {
    while (y->count) {
        x = lval_add(x, lval_pop(y, 0));
    }

    lval_del(y);
    return x;
}
Example #30
0
struct lval* lval_builtin_tail(struct lenv* e, struct lval* v) {
    LNUMARGS(v, 1, "tail");
    LNONEMPTY(v, 0, "tail");

    struct lval* x = lval_take(v, 0);
    lval_del(lval_pop(x, 0));
    return x;
}