Exemplo n.º 1
0
/* Evaluate an S-expression */
long
l_eval(long s)
{
  long  v, f, a, av[2];
  int n;

  switch(D_GET_TAG(s)){

  case TAG_NIL:        /* self-evaluating objects */
  case TAG_T:
  case TAG_INT:
    v = s;
    break;

  case TAG_SYMB:       /* symbol ... refer to the symbol table */
    if ((v = t_symb_val[D_GET_DATA(s)]) == TAG_UNDEF)
      return err_msg(errmsg_sym_undef, 1, s);
    break;

  case TAG_CONS:       /* cons ... function call */
    f = l_car(s);   /* function name or lambda exp */
    a = l_cdr(s);   /* actual argument list */
#ifndef minimalistic
    if ((D_GET_TAG(f) == TAG_CONS) && (D_GET_TAG(l_car(f)) == TAG_SYMB) 
        && ((D_GET_DATA(l_car(f)) == KW_LAMBDA))){   /* lambda exp */
      if (eval_args(f, a, av, FTYPE_ANY_ARGS) < 0)
        return -1;
      v = apply(l_cdr(f), av[0], list_len(l_car(l_cdr(f))));
    } else
#endif
        if (D_GET_TAG(f) == TAG_SYMB){
      n = FTYPE_GET_NARGS(t_symb_ftype[D_GET_DATA(f)]);
      switch (FTYPE_GET_TYPE(t_symb_ftype[D_GET_DATA(f)])){
      case FTYPE_UNDEF:
        return err_msg(errmsg_func_undef, 1, f);
      case FTYPE_SPECIAL:
        v = special(f, a);
        break;
      case FTYPE_SYS:
        if (eval_args(f, a, av, n) < 0)
          return -1;
        v = fcall(f, av/*, n*/);
        break;
      case FTYPE_USER:
        if (eval_args(f, a, av, FTYPE_ANY_ARGS) < 0)
          return -1;
        v = apply(f, av[0], n);
      }
    } else {
      return err_msg(errmsg_ill_call, 1, s);
    }
    break;
  }
  return v;
}
Exemplo n.º 2
0
Arquivo: vm.c Projeto: adrusi/Ciapos
static ciapos_sexp ciapos_vm_eval_withstack(ciapos_vm *self, ciapos_sexp stack, ciapos_sexp expr) {
    expr = macroexpand(self, expr);
    switch (expr.tag) {
    case CIAPOS_TAGNIL: case CIAPOS_TAGINT: case CIAPOS_TAGREAL: case CIAPOS_TAGSTR: case CIAPOS_TAGOPAQUE:
    case CIAPOS_TAGFN: return expr;
    case CIAPOS_TAGSYM: return lookup(stack, expr.symbol);
    case CIAPOS_TAGTUP: default:
        assert(expr.tuple->length == 2);
        ciapos_sexp fexpr = ciapos_tuple_get(expr, 0);
        if (fexpr.tag == CIAPOS_TAGSYM) {
            if (fexpr.symbol == ciapos_symbolof(&self->registry, "std:quote")) {
                ciapos_sexp args = ciapos_tuple_get(expr, 1);
                assert(args.tag == CIAPOS_TAGTUP);
                assert(args.tuple->length == 2);
                assert(ciapos_tuple_get(args, 1).tag == CIAPOS_TAGNIL);
                return ciapos_tuple_get(args, 0);
            }
            if (fexpr.symbol == ciapos_symbolof(&self->registry, "std:lambda")) {
                ciapos_sexp args = ciapos_tuple_get(expr, 1);
                return parsefn(self, stack, args);
            }
            if (fexpr.symbol == ciapos_symbolof(&self->registry, "std:env")) {
                assert(ciapos_tuple_get(expr, 1).tag == CIAPOS_TAGNIL);
                return stack;
            }
        }
        ciapos_sexp function = ciapos_vm_eval_withstack(self, stack, fexpr);
        assert(function.tag == CIAPOS_TAGFN);
        ciapos_sexp args = eval_args(self, stack, ciapos_tuple_get(expr, 1));
        return ciapos_function_eval(function, self, args);
    }
}
Exemplo n.º 3
0
Arquivo: vm.c Projeto: adrusi/Ciapos
static ciapos_sexp eval_args(ciapos_vm *self, ciapos_sexp stack, ciapos_sexp args) {
    if (args.tag == CIAPOS_TAGNIL) return args;
    assert(args.tag == CIAPOS_TAGTUP);
    assert(args.tuple->length == 2);
    ciapos_sexp result = ciapos_mktuple(&self->top_of_heap, 2);
    ciapos_tuple_put(result, 0, ciapos_vm_eval_withstack(self, stack, ciapos_tuple_get(args, 0)));
    ciapos_tuple_put(result, 1, eval_args(self, stack, ciapos_tuple_get(args, 1)));
    return result;
}
Exemplo n.º 4
0
/* Eval the args given to -test and computes the function, unused */
ast_st* eval_args(int argc, const char ** argv, int par, int * index) {

  ast_st *tmp1, *tmp2;
  kind_en op = Nothing;
  int i;

  for (i = 0; i < argc; i++) {

    if (!strcmp(argv[i],"(")) {

      tmp2 = eval_args(argc-i, argv+i+1, 1, index);
      if (tmp2 == NULL) return NULL;
      i += *index;
    }
    else if (!strcmp(argv[i], ")"))
      if (par) {
        *index = i+1;
        return tmp1;
      }
      else {
        printf("Closing parenthesis unmatched\n");
        return NULL;
      }

    else if (is_op(argv[i])) { 
      op = get_op(argv[i]);
    }

    else {
      int val = !strcmp(argv[i], "") ? 0 : atoi(argv[i]);
      tmp2 = create_int(val);
      
      if (op != Nothing) {
        tmp1 = create_node(op, tmp1, tmp2);
        op = Nothing;
      } else tmp1 = tmp2;
    }
  }

  if (!par)
    return tmp1;
  else {
    printf("Opening parenthesis unmatched\n");
    return NULL;
  }
}
Exemplo n.º 5
0
/**
   Evaluate the argument list (as supplied by complete -a) and insert
   any return matching completions. Matching is done using \c
   copy_strings_with_prefix, meaning the completion may contain
   wildcards. Logically, this is not always the right thing to do, but
   I have yet to come up with a case where this matters.

   \param str The string to complete.
   \param args The list of option arguments to be evaluated.
   \param desc Description of the completion
   \param comp_out The list into which the results will be inserted
*/
static void complete_from_args( const wchar_t *str,
								const wchar_t *args,
								const wchar_t *desc,
								array_list_t *comp_out,
								int flags )
{

	array_list_t possible_comp;

	al_init( &possible_comp );

	proc_push_interactive(0);
	eval_args( args, &possible_comp );
	proc_pop_interactive();

	complete_strings( comp_out, str, desc, 0, &possible_comp, flags );

	al_foreach( &possible_comp, &free );
	al_destroy( &possible_comp );
}
Exemplo n.º 6
0
Variable* run_function(Interpretator *interpretator, Function *f, Array *args)
{
    //Variable *return_var=undefined;
    int       i;
    int      *prev_base;

    //if(f->return_var)
        //return_var=interpretator_add_var(interpretator, f->return_var);

    if(f->return_var)
        interpretator->stack_head++;

    if(args)
        eval_args(interpretator, args, f->args);

    prev_base=interpretator->stack_base;
    interpretator->stack_base=(int*)interpretator->stack_head;
    *interpretator->stack_base=prev_base;
    interpretator->stack_head=(int*)interpretator->stack_head+f->variables->length+1;

    execute(interpretator, f->body);

    interpretator->stack_base=*(int*)interpretator->stack_base;

    if(f->return_var)
    {
        printf("\n<function ");
        str_print(f->name);
        printf(" return ");
        str_print(f->return_var->name);
        printf(">\n");
    }

    return f->return_var;
    //return return_var;
}
Exemplo n.º 7
0
static double eval_item(const char *buf, int *pos) /* item = -item | +item | int | var | (expr) */
{
	double rv = 0.0;
	void *data;
	int tlen, nargs, xargs;
	DB(int i);
	FunctionPtr fn;
	DB(char *fname);
	Token tok;
	
	DB(printf("-- eval_item(\"%s\", &pos=%p pos=%d)\n", buf+*pos, pos, *pos));
	tok = pull_token(buf, pos);
	if(G_eval_error)
		return rv;
	DB(printf("-- item token type '%c' = ", tok.type));
	switch(tok.type)
	{
	case '+': /* positive */
		DB(printf("positive\n"));
		rv = eval_fact(buf, pos);
		break;
	case '-': /* negative */
		DB(printf("negative\n"));
		rv = -eval_fact(buf, pos);
		break;
	case 'v': /* variable */
		DB(printf("variable name '%s'=%f\n", tok.str, tok.value));
		rv = tok.value;
		break;
	case 'f': /* function */
		DB(printf("function name '%s'=%p(%d)\n", tok.str, tok.fn, tok.args));
		tlen = tok.args;
		nargs = tok.args;
		xargs = nargs;
		data = tok.data;
		fn = tok.fn;
		DB(fname = tok.str);
		tok = pull_token(buf, pos);
		if(G_eval_error == 0)
		{
			if(tok.type != '(')
				G_eval_error = EVAL_SYNTAX_ERROR;
			else
			{
				double *targ = NULL;
				
				if(tlen > 0)
				{
					targ = (double*)lalloc(sizeof(double)*tlen);
					if(targ == NULL)
					{
						G_eval_error = EVAL_MEM_ERROR;
						break;
					}
				}else
					tlen = 0;
				if(eval_args(buf, pos, &nargs, &targ, &tlen, 0))
					break;
				DB(printf("-- item %d arguments\n", nargs));
				if(xargs < 0)
				{
					if(nargs < 1)
					{
						DB(printf("-- item too few arguments\n"));
						G_eval_error = EVAL_ARGS_ERROR;
						break;
					}
				}else if(nargs != xargs)
				{
					DB(printf("-- item bad argument count (%d) need %d\n",
						nargs, xargs));
					G_eval_error = EVAL_ARGS_ERROR;
					break;
				}
				tok = pull_token(buf, pos);
				if(tok.type != ')')
					G_eval_error = EVAL_SYNTAX_ERROR;
				else if(G_eval_error == 0)
				{
					DB(printf("-- call function [%p] with %d args [%p]\n",
						fn, nargs, targ));
					DB(printf("-- %s(%f", fname, targ[0]));
					DB(for(i=1;i<nargs;i++)printf(",%f",targ[i]));
					DB(printf(")\n"));
					if(fn(nargs, targ, &rv, data) != 0)
						G_eval_error = EVAL_FUNCTION_ERROR;
					DB(printf("-- rv = %f\n", rv));
				}
			}
		}
		break;
	case 'n': /* number */
		DB(printf("number value '%s'=%f\n", tok.str, tok.value));
		rv = tok.value;
		break;
	case '(':
		DB(printf("start grouping\n"));
		rv = eval_expr(buf, pos);
		tok = pull_token(buf, pos);
		if(tok.type != ')')
			G_eval_error = EVAL_SYNTAX_ERROR;
		break;
	default:
		DB(printf("PUSHBACK\n"));
		push_token(tok);
	}
Exemplo n.º 8
0
int evaluate(int exp_id) {
  if (DEBUG) {
    print(exp_id);
    indent += 1;
  }

  if (ATOM(exp_id)) {
    int found = find_env(exp_id);
    if (!NILP(found)) {
      expression[exp_id] = REMOVE_BIT(found);
    }
  } else {
    switch (expression[CAR(exp_id)]) {
    // car
    case 1:
      evaluate(CADR(exp_id));
      if (ATOM(CADR(exp_id))) {
        error(LIST_EXPECTED);
      }
      expression[exp_id] = expression[CAADR(exp_id)];
      break;

    // cdr
    case 2:
      evaluate(CADR(exp_id));
      if (ATOM(CADR(exp_id))) {
        error(LIST_EXPECTED);
      }
      expression[exp_id] = expression[CDR(CADR(exp_id))];
      break;

    // cons
    case 3:
      evaluate(CADR(exp_id));
      evaluate(CADDR(exp_id));
      expression[exp_id] = CONS(CADR(exp_id), CADDR(exp_id));
      break;

    // quote
    case 4:
      expression[exp_id] = expression[CADR(exp_id)];
      break;

    // eq
    case 5:
      evaluate(CADR(exp_id));
      evaluate(CADDR(exp_id));
      if (expression[CADR(exp_id)] == expression[CADDR(exp_id)]) {
        expression[exp_id] = L_T;
      } else {
        expression[exp_id] = L_NIL;
      }
      break;

    // atom
    case 6:
      evaluate(CADR(exp_id));
      if (ATOM(CADR(exp_id))) {
        expression[exp_id] = L_T;
      } else {
        expression[exp_id] = L_NIL;
      }
      break;

    // cond
    case 7:
      evaluate_cond(CDR(exp_id));
      expression[exp_id] = expression[CDR(exp_id)];
      break;

    // print
    case 8:
      evaluate(CADR(exp_id));
      print(CADR(exp_id));
      expression[exp_id] = expression[CADR(exp_id)];
      break;

    // apply
    case 12:
      {
        int callee = CADR(exp_id);
        int args = CDDR(exp_id);

        eval_args(args);

        before_call();

        // if expression stack is not sufficient,
        // you can save and restore max id here
        if (expression[CAR(callee)] == L_LAMBDA) {
          int new_exp_id = move_exp(CADDR(callee));
          update_environment(CADR(callee), args);
          evaluate(new_exp_id);
          expression[exp_id] = expression[new_exp_id];

        } else if (expression[CAR(callee)] == L_LABEL) {
          int lambda_name = CADR(callee);
          int lambda = CADDR(callee);
          int new_exp_id = 0;

          if (ATOM(lambda_name)) {
            env[(call_depth << 8) + expression[lambda_name]] = SET_BIT(expression[lambda]);
          } else {
            error(INVALID_LABEL_NAME);
          }

          new_exp_id = move_exp(CADDR(lambda));
          update_environment(CADR(lambda), args);
          evaluate(new_exp_id);
          expression[exp_id] = expression[new_exp_id];

        } else {
          error(NOT_LAMBDA);
        }

        after_call();
      }
      break;

    default:
      {
        int found = find_env(CAR(exp_id));
        if (!NILP(found)) {
          int cdr = (REMOVE_BIT(found) << 16) >> 16;
          int new_exp_id = 0;
          int args = CDR(exp_id);

          eval_args(args);

          before_call();

          new_exp_id = move_exp(CADR(cdr));

          update_environment(CAR(cdr), args);
          evaluate(new_exp_id);
          expression[exp_id] = expression[new_exp_id];

          after_call();
        } else {
          print(exp_id);
          error(FUNCTION_NOT_FOUND);
        }
      }
      break;
    }