static co_obj_t *
_csm_services_commit_i(co_obj_t *list, co_obj_t *current, void *context)
{
  if (IS_LIST(current)) return NULL;
  
  co_obj_t *service_list = (co_obj_t*)context;
  assert(IS_LIST(service_list));
  
  co_cbptr_t *handler = (co_cbptr_t*)current;
  handler->cb(service_list, NULL, service_list);
  return NULL;
}
Example #2
0
File: io.c Project: jaz303/lispy
void pretty_print(env_t *env, VALUE v, int i) {
    if (VALUE_IS_ERROR(v)) {
        printf("<error>\n");
    } else if (IS_LIST(v)) {
        printf("(\n");
		int j;
		for (j = 0; j < list_len(v); j++) {
            indent(i + 1); pretty_print(env, list_get(v, j), i + 1);
		}
		indent(i); printf(")\n");
    } else {
        if (VALUE_IS_INT(v)) {
    		printf("%lld\n", INTVAL(v));
    	} else if (VALUE_IS_BOOL(v)) {
    		printf("#%c\n", BOOLVAL(v) ? 't' : 'f');
        } else if (VALUE_IS_NIL(v)) {
            printf("#nil\n");
        } else if (VALUE_IS_IDENT(v)) {
            printf("%s\n", intern_table_get_str(&env->intern, IDENT(v)));
        } else if (VALUE_IS_ATOM(v)) {
            printf(":%s\n", intern_table_get_str(&env->intern, ATOM(v)));
        } else if (IS_STRING(v)) {
    		printf("\"%s\"\n", string_chars(v));
		} else {
            printf("<unknown %p>\n", v);
    	}
    }
}
Example #3
0
int olsrd_mdp_init(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
  keyring_file *mdp_keyring = NULL;
  unsigned char *mdp_key = NULL;
  int mdp_key_len = 0;
  unsigned char packedSid[SID_SIZE] = {0};
  
  CHECK(IS_LIST(params) && co_list_length(params) == 2,"Invalid params");
  
  size_t sid_len = co_str_len(co_list_element(params,1));
  char *sid_str = _LIST_ELEMENT(params,1);
  
  CHECK(sid_len == 2*SID_SIZE + 1 && str_is_subscriber_id(sid_str) == 1,"Invalid SID");
  stowSid(packedSid,0,sid_str);
  
  CHECK(serval_init_keyring(packedSid,
		     SID_SIZE,
		     _LIST_ELEMENT(params,0),
		     co_str_len(co_list_element(params,0)),
		     &mdp_keyring,
		     &mdp_key,
		     &mdp_key_len), "Failed to initialize Serval keyring");
  
  CMD_OUTPUT("key",co_bin8_create((char*)mdp_key,mdp_key_len,0));
  
  return 1;
error:
  return 0;
}
Example #4
0
int
olsrd_mdp_init(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  svl_crypto_ctx *ctx = NULL;
  CHECK(IS_LIST(params) && co_list_length(params) == 2, "Invalid params");
  
  size_t sid_len = co_str_len(co_list_element(params, 1));
  char *sid_str = _LIST_ELEMENT(params, 1);
  
  CHECK(sid_len == (2 * SID_SIZE) + 1 && str_is_subscriber_id(sid_str) == 1, "Invalid SID");
  
  ctx = svl_crypto_ctx_new();
  
  stowSid(ctx->sid, 0, sid_str);
  
  ctx->keyring_path = _LIST_ELEMENT(params, 0);
  ctx->keyring_len = co_str_len(co_list_element(params, 0)) - 1;
  CHECK_ERR(ctx->keyring_len < PATH_MAX,"Keyring path too long");
  
  CHECK(serval_init_keyring(ctx), "Failed to initialize Serval keyring");
  
  CMD_OUTPUT("key", co_bin8_create((char*)ctx->sas_private, crypto_sign_SECRETKEYBYTES, 0));
  
  return 1;
error:
  if (ctx)
    svl_crypto_ctx_free(ctx);
  return 0;
}
Example #5
0
File: apply.c Project: tcort/edgar
obj_t * apply(obj_t *args, obj_t *env) {

	assert(IS_LIST(args));

	if (IS_LIST(CAR(args)) && IS_FUNC(CAR(CAR(args)))) {

		return (FUNC(CAR(CAR(args))))(CDR(args), env);
	} else if (IS_LIST(CAR(args)) && IS_DEFUNC(CAR(CAR(args)))) {

		obj_t * func_args;
		obj_t * call_args;

		obj_t * body;
		obj_t * result;

		body = clone_obj(BODY(CAR(CAR(args))));
		func_args = ARGS(CAR(CAR(args)));
		call_args = CDR(args);

		/* ((<DEFUNC:[args=(X)][body=(TIMES X X)]>) 3) */

		while (IS_LIST(func_args) && IS_LIST(call_args)) {
			obj_t * func_arg = CAR(func_args);
			obj_t * call_arg = CAR(call_args);

			replace_obj(func_arg, call_arg, body);

			func_args = CDR(func_args);
			call_args = CDR(call_args);
		}

		if ((IS_LIST(func_args) && !IS_LIST(call_args)) ||
				(!IS_LIST(func_args) && IS_LIST(call_args))) {

			free_obj(body); /* clean up */

			fprintf(stdout, "Unexpected number of arguments\n");
			return alloc_fail();
		}

		result = eval(body, env);

		free_obj(body);

		return result;

	} else {

		return clone_obj(args);
	}
}
Example #6
0
//nilを空リストと解釈している。
int listp(int x){	
    if(IS_LIST(x) && (!(improperp(x))))
    	return(1);
    else
    if(IS_NIL(x))
    	return(1);
    else
    	return(0);
}
static co_obj_t *
_csm_service_list_find_service(co_obj_t *list, co_obj_t *current, void *context)
{
  if (IS_LIST(current)) return NULL;
  assert(IS_SERVICE(current));
  csm_service *srv_ptr = (csm_service*)context;
  if (((co_service_t*)current)->service == srv_ptr)
    return current;
  return NULL;
}
Example #8
0
int
co_request_append(co_obj_t *request, co_obj_t *object)
{
  CHECK_MEM(request);
  CHECK_MEM(object);
  CHECK(IS_LIST(request), "Not a valid request.");
  return co_list_append(request, object);
error:
  return 0;
}
Example #9
0
int
co_shutdown(void)
{
  CHECK_MEM(_sockets);
  CHECK(IS_LIST(_sockets), "API not properly initialized.");
  co_list_parse(_sockets, _co_shutdown_sockets_i, NULL);
  co_obj_free(_pool);
  return 1;
error:
  return 0;
}
Example #10
0
void _bam_check_template_list(SEXP template_list)
{
    if (!IS_LIST(template_list) || LENGTH(template_list) != N_TMPL_ELTS)
        Rf_error("'template' must be list(%d)", N_TMPL_ELTS);
    SEXP names = GET_ATTR(template_list, R_NamesSymbol);
    if (!IS_CHARACTER(names) || LENGTH(names) != N_TMPL_ELTS)
        Rf_error("'names(template)' must be character(%d)", N_TMPL_ELTS);
    for (int i = 0; i < LENGTH(names); ++i)
        if (strcmp(TMPL_ELT_NMS[i], CHAR(STRING_ELT(names, i))) != 0)
            Rf_error("'template' names do not match scan_bam_template\n'");
}
Example #11
0
int
co_call(co_obj_t *connection, co_obj_t **response, const char *method, const size_t mlen, co_obj_t *request)
{
  CHECK(method != NULL && mlen > 0 && mlen < UINT8_MAX, "Invalid method name.");
  CHECK(connection != NULL && IS_SOCK(connection), "Invalid connection.");
  co_obj_t *params = NULL, *rlist = NULL, *rtree = NULL;
  int retval = 0;
  size_t reqlen = 0, resplen = 0;
  char req[REQUEST_MAX];
  char resp[RESPONSE_MAX];
  if(request != NULL)
  {
    CHECK(IS_LIST(request), "Not a valid request.");
    params = request;
  }
  else
  {
    params = co_list16_create();
  }
  co_obj_t *m = co_str8_create(method, mlen, 0);
  reqlen = co_request_alloc(req, sizeof(req), m, params);
  CHECK(((co_socket_t*)connection)->send((co_obj_t*)((co_socket_t*)connection)->fd, req, reqlen) != -1, "Send error!");
  if((resplen = ((co_socket_t*)connection)->receive(connection, (co_obj_t*)((co_socket_t*)connection)->fd, resp, sizeof(resp))) > 0) 
  {
    CHECK(co_list_import(&rlist, resp, resplen) > 0, "Failed to parse response.");
    rtree = co_list_element(rlist, 3);
    if(!IS_NIL(rtree))
    {
      retval = 1;
    }
    else
    {
      rtree = co_list_element(rlist, 2);
      retval = 0;
    }
    if(rtree != NULL && IS_TREE(rtree)) 
    {
      *response = rtree;
      hattach(*response, _pool);
    }
    else SENTINEL("Invalid response.");
  }
  else SENTINEL("Failed to receive data.");

  co_obj_free(m);
  if(params != request) co_obj_free(params);
  return retval;
  
error:
  co_obj_free(m);
  if(params != request) co_obj_free(params);
  return retval;
}
Example #12
0
int
co_request_append_uint(co_obj_t *request, const unsigned int i)
{
  CHECK_MEM(request);
  CHECK(IS_LIST(request), "Not a valid request.");
  CHECK(i < UINT64_MAX, "Integer out of bounds.");
  if(i > UINT32_MAX) return co_list_append(request, co_uint64_create(i, 0));
  if(i > UINT16_MAX) return co_list_append(request, co_uint32_create(i, 0));
  if(i > UINT8_MAX) return co_list_append(request, co_uint16_create(i, 0));
  return co_list_append(request, co_uint8_create(i, 0));
error:
  return 0;
}
Example #13
0
int
co_request_append_int(co_obj_t *request, const int i)
{
  CHECK_MEM(request);
  CHECK(IS_LIST(request), "Not a valid request.");
  CHECK(i < INT64_MAX && i > INT64_MIN, "Integer out of bounds.");
  if(i > INT32_MAX || i < INT32_MIN) return co_list_append(request, co_int64_create(i, 0));
  if(i > INT16_MAX || i < INT16_MIN) return co_list_append(request, co_int32_create(i, 0));
  if(i > INT8_MAX || i < INT8_MIN) return co_list_append(request, co_int16_create(i, 0));
  return co_list_append(request, co_int8_create(i, 0));
error:
  return 0;
}
Example #14
0
int
co_request_append_bin(co_obj_t *request, const char *s, const size_t slen)
{
  CHECK_MEM(request);
  CHECK_MEM(s);
  CHECK(IS_LIST(request), "Not a valid request.");
  CHECK(slen < UINT32_MAX, "Binary is too large.");
  if(slen > UINT16_MAX) return co_list_append(request, co_bin32_create(s, slen, 0));
  if(slen > UINT8_MAX) return co_list_append(request, co_bin16_create(s, slen, 0));
  return co_list_append(request, co_bin8_create(s, slen, 0));
  error:
  return 0;
}
static co_obj_t *
_csm_find_service_i(co_obj_t *list, co_obj_t *current, void *context)
{
  if (IS_LIST(current)) return NULL;
  
  assert(IS_SERVICE(current));
  
  co_service_t *service = (co_service_t*)current;
  char *uuid = (char*)context;
  if (strcmp(uuid, service->service.uuid) == 0)
    return current;
  return NULL;
}
Example #16
0
File: eval.c Project: oswjk/lispish
struct atom *builtin_atom(struct atom *expr, struct env *env)
{
    struct list *list = expr->list;
    struct atom *op = LIST_FIRST(list);
    struct atom *a = LIST_NEXT(op, entries);

    (void) env;

    if (!a)
        return &nil_atom;

    if (IS_LIST(a))
        return &false_atom;
    else
        return &true_atom;
}
Example #17
0
static inline void
_co_tree_raw_r(char **output, const size_t *olen, size_t *written, _treenode_t *current)
{
  if(current == NULL) return;
  size_t klen = 0, vlen = 0; 
  char *kbuf = NULL, *vbuf = NULL;
  if(current->value != NULL)
  {
    CHECK((klen = co_obj_raw(&kbuf, current->key)) > 0, "Failed to read key.");
    memmove(*output, kbuf, klen);
    *output += klen;
    *written += klen;
    if(IS_TREE(current->value))
    {
      vlen = co_tree_raw(*output, *olen - *written, current->value);
      CHECK(vlen > 0, "Failed to dump tree value.");
    }
    else if(IS_LIST(current->value))
    {
      vlen = co_list_raw(*output, *olen, current->value);
      CHECK(vlen > 0, "Failed to dump tree value.");
    }
    else
    {
      CHECK((vlen = co_obj_raw(&vbuf, current->value)) > 0, "Failed to read value.");
      CHECK((klen + vlen) < ((*olen) - (*written)), "Data too large for buffer.");
      DEBUG("Dumping value %s of size %d with key %s of size %d.", vbuf, (int)vlen, kbuf, (int)klen);
      memmove(*output, vbuf, vlen);
    }
    *written += vlen;
    *output += vlen;
  }
  _co_tree_raw_r(output, olen, written, current->low); 
  _co_tree_raw_r(output, olen, written, current->equal); 
  _co_tree_raw_r(output, olen, written, current->high); 
  return; 
error:
  return;
}
Example #18
0
File: eval.c Project: oswjk/lispish
struct atom *builtin_lambda(struct atom *expr, struct env *env)
{
    struct list *list = expr->list;
    struct atom *op = LIST_FIRST(list);

    struct atom *params = CDR(op);
    struct atom *body = CDR(params);

    if (!params || !body || CDR(body))
    {
        printf("error: lambda takes exactly 2 arguments\n");
        return &nil_atom;
    }

    if (!IS_LIST(params) && !IS_NIL(params))
    {
        printf("error: first arg to lambda must be a list\n");
        return &nil_atom;
    }

    return atom_new_closure(params, body, env);
}
Example #19
0
/**
 * slice string/list
 * string.slice(a,b) [a,b), b is not included
 * string.slice(0,-1) = string.slice(0,len(string))
 * @since 2016-11-19
 * <code>
 * 'test'.slice(0,1) = 't'
 * 'test'.slice(0,-1) = 'test'
 * </code>
 */
Object obj_slice(Object self, Object first, Object second) {
    int start = GET_NUM(first);
    int end = GET_NUM(second);
    Object ret = NONE_OBJECT;
    
    if (IS_STR(self)) {
        int length = GET_STR_LEN(self);
        start = start >= 0 ? start : start + length + 1;
        end   = end   >= 0 ? end   : end   + length + 1;
        if (start < 0 || start > length) {
            start = 0;
        } 
        if (end < 0 || end > length) {
            end = length; // do not overflow;
        } 
        if (end <= start) {
            return string_alloc("", 0);
        }
        return string_alloc(GET_STR(self) + start, end - start);
    } else if (IS_LIST(self)) {
        int length = LIST_LEN(self);
        start = start > 0 ? start : start + length + 1;
        end   = end   > 0 ? end   : end   + length + 1;
        if (start < 0 || start > length) {
            start = 0;
        } 
        if (end < 0 || end > length) {
            end = length;
        } 
        int i = 0;
        ret = list_new(end - start);
        for (i = start; i < end ; i++) {
            obj_append(ret, LIST_GET(self, i));
        }
    } else {
        tm_raise("slice not implemented for type %s", tm_type(self.type));
    }
    return ret;
}
Example #20
0
File: eval.c Project: bhuztez/lisp0
term_t
eval_term(struct lisp0_state*state,term_t term){
  X = term;
  CALL(L_eval);
  return X;

 L_eval:
  if(IS_ERROR(X)){
    RETURN(X);
  }

  if(IS_ATOM(X)){
    RETURN(subst(ENV,X));
  }

  if(!IS_LIST(X)){
    RETURN(ERR(E_BAD_EXPR));
  }

  PUSH(CDR(X));
  X = CAR(X);
  CALL(L_eval);
  Y = POP();

  switch(TAG(X)){
  case TAG_ERROR: RETURN(X);
  case TAG_PRIMITIVE:
    switch(VALUE(X)){
    case PRIM_QUOTE:  goto L_quote;
    case PRIM_ATOM:   goto L_atom;
    case PRIM_EQ:     goto L_eq;
    case PRIM_COND:   goto L_cond;
    case PRIM_CAR:    goto L_car;
    case PRIM_CDR:    goto L_cdr;
    case PRIM_CONS:   goto L_cons;
    case PRIM_LABEL:  goto L_label;
    case PRIM_LAMBDA: goto L_lambda;
    case PRIM_MACRO:  goto L_macro;
    default:          break;
    };
    break;
  case TAG_POINTER:
    if(!X) break;
    switch(PTAG(X)){
    case PTAG_LAMBDA: goto L_eval_lambda;
    case PTAG_MACRO:  goto L_eval_macro;
    default: break;
    };
  default: break;
  }

  RETURN(ERR(E_NOT_CALLABLE));

 L_quote:
  PARSE_ARG1();
  RETURN(X);

 L_atom:
  PARSE_AND_EVAL_ARG1();
  RETURN(((!X)||IS_ATOM(X))?TRUE:FALSE);

 L_eq:
  PARSE_AND_EVAL_ARG2();
  RETURN(eq(Y,X)?TRUE:FALSE);

 L_cond:
  PARSE_ARG();
  PUSH(CDR(Y));
  Y = CAR(Y);
  PARSE_ARG2();
  PUSH(Y);
  CLEAR(Y);
  CALL(L_eval);
  Y = POP();
  switch(X){
  case TRUE:
    X = Y;
    CLEAR(Y);
    goto L_eval;
  case FALSE:
    Y = POP();
    goto L_cond;
  default:
    RETURN(ERR(E_COND_END));
  };

 L_car:
  PARSE_AND_EVAL_ARG1();
  if(!IS_LIST(X)){
    RETURN(ERR(E_ARGUMENT));
  }
  RETURN(CAR(X));

 L_cdr:
  PARSE_AND_EVAL_ARG1();
  if(!IS_LIST(X)){
    RETURN(ERR(E_ARGUMENT));
  }
  RETURN(CDR(X));

 L_cons:
  PARSE_AND_EVAL_ARG2();
 L_cons_1:
  RETURN(cons(state,Y,X));

 L_label:
  PARSE_ARG2();
  PUSH(X);
  X = Y;
  CLEAR(Y);
  CALL(L_eval);
  RETURN_ERROR(X);
  Y = POP();
  CALL(L_cons_1);
  Y = X;
  X = ENV;
  CALL(L_cons_1);
  ENV = X;
  RETURN(CDR(CAR(ENV)));

 L_lambda:
  PARSE_ARG2();
  RETURN(mklist(state,X,Y,PTAG_LAMBDA));

 L_macro:
  PARSE_ARG2();
  RETURN(mklist(state,X,Y,PTAG_MACRO));

 L_eval_lambda:
  PUSH(X);
  push_list_builder(state);
  CALL(L_eval_list);
  Y = pop_list_builder(state,NIL);
  RETURN_ERROR(X);
  X = POP();
  PUSH(CDR(X));
  X = CAR(X);
  push_list_builder(state);
  CALL(L_zip);
  Y = POP();
  PUSH(ENV);
  ENV = pop_list_builder(state,ENV);
  RETURN_ERROR(X);
  X = Y;
  CLEAR(Y);
  CALL(L_eval);
  RETURN_ERROR(ENV);
  ENV = POP();
  RETURN(X);

 L_eval_list:
  if(!Y){
    RETURN(Y);
  }
  PARSE_ARG();
  X = CAR(Y);
  PUSH(CDR(Y));
  CLEAR(Y);
  CALL(L_eval);
  RETURN_ERROR(X);
  list_builder_add_term(state,X);
  Y = POP();
  goto L_eval_list;

 L_eval_macro:
  PUSH(CDR(X));
  X = CAR(X);
  push_list_builder(state);
  CALL(L_zip);
  Y = POP();
  PUSH(ENV);
  ENV = pop_list_builder(state,ENV);
  RETURN_ERROR(X);
  X = Y;
  CLEAR(Y);
  CALL(L_eval);
  ENV = POP();
  goto L_eval;

 L_zip:
  if((!X)||(!Y))
    goto L_zip_finish;

  RETURN_ERROR(X);
  RETURN_ERROR(Y);

  if(!IS_LIST(X)){
    RETURN(ERR(E_IMPROPER_LIST));
  }
  if(!IS_LIST(Y)){
    RETURN(ERR(E_IMPROPER_LIST));
  }
  list_builder_add_term(state,cons(state,CAR(X),CAR(Y)));
  X = CDR(X);
  Y = CDR(Y);
  goto L_zip;

 L_zip_finish:
  if(X||Y){
    RETURN(ERR(E_ARGUMENT));
  }

  RETURN(NIL);
}
Example #21
0
File: eval.c Project: Pilen/ubertex
Value eval_get_bindings(Value arguments, Value parameters) {
    /* Returns bindings in opposite direction (first is tightest bound) */
    w_assert(IS_LIST(arguments));
    w_assert(IS_LIST(parameters));
    /* Most of the error logging should be in defun, not here! */
    Bool optional = false;
    Bool rest = false;
    Value bindings = VALUE_NIL;
    while (parameters.type == CONS) {
        Value parameter = NEXT(parameters);
        if (parameter.val.symbol_val == symbols_ampersand_optional.val.symbol_val) {
            optional = true;
            break;
        }
        if (parameter.val.symbol_val == symbols_ampersand_rest.val.symbol_val) {
            rest = true;
            break;
        }
        ENSURE_NOT_EMPTY(arguments);
        Value argument = NEXT(arguments);
        bindings = CONS(CONS(parameter, argument), bindings);
    }

    if (optional) {
        while (parameters.type == CONS) {
            Value parameter = NEXT(parameters);
            if (parameter.val.symbol_val == symbols_ampersand_rest.val.symbol_val) {
                rest = true;
                break;
            }
            Value argument;
            if (arguments.type == CONS) {
                argument = NEXT(arguments);
            } else {
                argument = VALUE_NIL;
            }
            bindings = CONS(CONS(parameter, argument), bindings);
        }
    }

    if (rest) {
        if (parameters.type == CONS) {
            Value parameter = NEXT(parameters);
            bindings = CONS(CONS(parameter, arguments), bindings);
            arguments = VALUE_NIL;
            /* It would make sense to only allow one rest parameter
               But as Emacs allows more (or none) so do we.
               But defun could definitely give a warning */
            while (parameters.type == CONS) {
                parameter = NEXT(parameters);
                bindings = CONS(CONS(parameter, VALUE_NIL), bindings);
                arguments = VALUE_NIL;
            }
        } else {
            arguments = VALUE_NIL;
            parameters = VALUE_NIL;
        }
    }
    ENSURE_EMPTY(arguments);
    ENSURE_EMPTY(parameters);
    /* w_assert(parameters.type == NIL); */
    /* w_assert(arguments.type == NIL); */
    return bindings;
}
Example #22
0
/** 
** evaluate byte code.
** @param f: Frame
** @return evaluated value.
*/
Object tm_eval(TmFrame* f) {
    Object* locals    = f->locals;
    Object* top       = f->stack;
    Object cur_fnc    = f->fnc;
    Object globals    = get_globals(cur_fnc);
    // TODO use code cache to replace unsigned char*
    unsigned char* pc = f->pc;
    const char* func_name_sz = get_func_name_sz(cur_fnc);

    Object x, k, v;
    Object ret = NONE_OBJECT;
    int i;

    #if INTERP_DB
        printf("File \"%s\": enter function %s\n",get_func_file_sz(cur_fnc), get_func_name_sz(cur_fnc));
    #endif
    while (1) {
        i = (pc[1] << 8) | pc[2];
        
        #if INTERP_DB
            printf("%30s%2d: %d frame = %d, top = %d\n","", pc[0], i, tm->cur, (int) (top - f->stack));
        #endif    
        switch (pc[0]) {

        case OP_NUMBER: {
            double d = atof((char*)pc + 3);
            pc += i;
            v = tm_number(d);
            /* obj_append(tm->constants,v);*/
            dict_set(tm->constants, v, NONE_OBJECT);
            break;
        }

        case OP_STRING: {
            v = string_alloc((char*)pc + 3, i);
            pc += i;
            /* obj_append(tm->constants,v); */
            dict_set(tm->constants, v, NONE_OBJECT);
            break;
        }

        case OP_IMPORT: {
            // TODO
            // tm_import(globals)
            Object import_func = tm_get_global(globals, "_import");
            arg_start();
            arg_push(globals);
            Object modname, attr;
            
            if (i == 1) {
                modname = TM_POP();
                arg_push(modname); // arg1
            } else {
                attr = TM_POP();
                modname = TM_POP();
                arg_push(modname);
                arg_push(attr);
            }
            call_function(import_func);
            break;
        }
        case OP_CONSTANT: {
            TM_PUSH(GET_CONST(i));
            break;
        }
        
        case OP_NONE: {
            TM_PUSH(NONE_OBJECT);
            break;
        }

        case OP_LOAD_LOCAL: {
            TM_PUSH(locals[i]);
            break;
        }

        case OP_STORE_LOCAL:
            locals[i] = TM_POP();
            break;

        case OP_LOAD_GLOBAL: {
            /* tm_printf("load global %o\n", GET_CONST(i)); */
            int idx = dict_get_attr(GET_DICT(globals), i);
            if (idx == -1) {
                idx = dict_get_attr(GET_DICT(tm->builtins), i);
                if (idx == -1) {
                    tm_raise("NameError: name %o is not defined", GET_CONST(i));
                } else {
                    Object value = GET_DICT(tm->builtins)->nodes[idx].val;
                    // OPTIMIZE
                    // set the builtin to `globals()`
                    obj_set(globals, GET_CONST(i), value);
                    idx = dict_get_attr(GET_DICT(globals), i);
                    pc[0] = OP_FAST_LD_GLO;
                    code16(pc+1, idx);
                    // OPTIMIZE END
                    TM_PUSH(value);
                }
            } else {
                TM_PUSH(GET_DICT(globals)->nodes[idx].val);
                pc[0] = OP_FAST_LD_GLO;
                code16(pc+1, idx);
            }
            break;
        }
        case OP_STORE_GLOBAL: {
            x = TM_POP();
            int idx = dict_set_attr(GET_DICT(globals), i, x);
            pc[0] = OP_FAST_ST_GLO;
            code16(pc+1, idx);
            break;
        }
        case OP_FAST_LD_GLO: {
            TM_PUSH(GET_DICT(globals)->nodes[i].val);
            break;
        }
        case OP_FAST_ST_GLO: {
            GET_DICT(globals)->nodes[i].val = TM_POP();
            break;
        }
        case OP_LIST: {
            TM_PUSH(list_new(2));
            FRAME_CHECK_GC();
            break;
        }
        case OP_APPEND:
            v = TM_POP();
            x = TM_TOP();
            tm_assert(IS_LIST(x), "tm_eval: OP_APPEND require list");
            list_append(GET_LIST(x), v);
            break;
        case OP_DICT_SET:
            v = TM_POP();
            k = TM_POP();
            x = TM_TOP();
            tm_assert(IS_DICT(x), "tm_eval: OP_DICT_SET require dict");
            obj_set(x, k, v);
            break;
        case OP_DICT: {
            TM_PUSH(dict_new());
            FRAME_CHECK_GC();
            break;
        }
        TM_OP(OP_ADD, obj_add)
        TM_OP(OP_SUB, obj_sub)
        TM_OP(OP_MUL, obj_mul)
        TM_OP(OP_DIV, obj_div)
        TM_OP(OP_MOD, obj_mod)
        TM_OP(OP_GET, obj_get)
        case OP_SLICE: {
            Object second = TM_POP();
            Object first = TM_POP();
            *top = obj_slice(*top, first, second);
            break;
        }
        case OP_EQEQ: { *(top-1) = tm_number(obj_equals(*(top-1), *top)); top--; break; }
        case OP_NOTEQ: { *(top-1) = tm_number(!obj_equals(*(top-1), *top)); top--; break; }
        case OP_LT: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)<0);
            top--;
            break;
        }
        case OP_LTEQ: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)<=0);
            top--;
            break;
        }
        case OP_GT: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)>0);
            top--;
            break;
        }
        case OP_GTEQ: {
            *(top-1) = tm_number(obj_cmp(*(top-1), *top)>=0);
            top--;
            break;
        }
        case OP_IN: {
            *(top-1) = tm_number(obj_in(*(top-1), *top));
            top--;
            break;
        }
        case OP_AND: {
            *(top-1) = tm_number(is_true_obj(*(top-1)) && is_true_obj(*top));
            top--;
            break;
        }
        case OP_OR: {
            *(top-1) = tm_number(is_true_obj(*(top-1)) || is_true_obj(*top));
            top--;
            break;
        }
        case OP_NOT:{
            *top = tm_number(!is_true_obj(*top));
            break;
        }
        case OP_SET:
            k = TM_POP();
            x = TM_POP();
            v = TM_POP();
            #if INTERP_DB
                tm_printf("Self %o, Key %o, Val %o\n", x, k, v);
            #endif
            obj_set(x, k, v);
            break;
        case OP_POP: {
            top--;
            break;
        }
        case OP_NEG:
            TM_TOP() = obj_neg(TM_TOP());
            break;
        case OP_CALL: {
            f->top = top;
            top -= i;
            arg_set_arguments(top + 1, i);
            Object func = TM_POP();
            
            TM_PUSH(call_function(func));
            // TM_PUSH(call_function(func));
            tm->frame = f;
            FRAME_CHECK_GC();
            break;
        }
        
        case OP_APPLY: {
            f->top = top;
            Object args = TM_POP();
            tm_assert_type(args, TYPE_LIST, "tm_eval: OP_APPLY");
            arg_set_arguments(LIST_NODES(args), LIST_LEN(args));
            Object func = TM_POP();
            x = call_function(func);
            TM_PUSH(x);
            tm->frame = f;
            FRAME_CHECK_GC();
            break;
        }
        case OP_LOAD_PARAMS: {
            int parg = pc[1];
            int varg = pc[2];
            if (tm->arg_cnt < parg || tm->arg_cnt > parg + varg) {
                tm_raise("ArgError,parg=%d,varg=%d,given=%d", 
                    parg, varg, tm->arg_cnt);
            }
            for(i = 0; i < tm->arg_cnt; i++){
                locals[i] = tm->arguments[i];
            }
            break;
        }
        case OP_LOAD_PARG: {
            int parg = i;
            for (i = 0; i < parg; i++) {
                locals[i] = arg_take_obj(func_name_sz);
            }
            break;
        }
        case OP_LOAD_NARG: {
            int arg_index = i;
            Object list = list_new(tm->arg_cnt);
            while (arg_remains() > 0) {
                obj_append(list, arg_take_obj(func_name_sz));
            }
            locals[arg_index] = list;
            break;
        }
        case OP_ITER: {
            *top = iter_new(*top);
            break;
        }
        case OP_NEXT: {
            Object *next = next_ptr(*top);
            if (next != NULL) {
                TM_PUSH(*next);
                break;
            } else {
                pc += i * 3;
                continue;
            }
            break;
        }
        case OP_DEF: {
            Object mod = GET_FUNCTION(cur_fnc)->mod;
            Object fnc = func_new(mod, NONE_OBJECT, NULL);
            pc = func_resolve(GET_FUNCTION(fnc), pc);
            GET_FUNCTION_NAME(fnc) = GET_CONST(i);
            TM_PUSH(fnc);
            continue;
        }
        case OP_RETURN: {
            ret = TM_POP();
            goto end;
        }
        case OP_ROT: {
            int half = i / 2;
            int j;
            for (j = 0; j < half; j++) {
                Object temp = *(top - j);
                *(top-j) = *(top - i + j + 1);
                *(top-i+j+1) = temp;
            }
            break;
        }
        case OP_UNPACK: {
            x = TM_POP();
            tm_assert_type(x, TYPE_LIST, "tm_eval:UNPACK");
            int j;
            for(j = LIST_LEN(x)-1; j >= 0; j--) {
                TM_PUSH(LIST_GET(x, j));
            }
            break;
        }

        case OP_DEL: {
            k = TM_POP();
            x = TM_POP();
            obj_del(x, k);
            break;
        }

        case OP_POP_JUMP_ON_FALSE: {
            if (!is_true_obj(TM_POP())) {
                pc += i * 3;
                continue;
            }
            break;
        }

        case OP_JUMP_ON_TRUE: {
            if (is_true_obj(TM_TOP())) {
                pc += i * 3;
                continue;
            }
            break;
        }

        case OP_JUMP_ON_FALSE: {
            if (!is_true_obj(TM_TOP())) {
                pc += i * 3;
                continue;
            }
            break;
        }

        case OP_UP_JUMP:
            pc -= i * 3;
            continue;

        case OP_JUMP:
            pc += i * 3;
            continue;

        case OP_EOP:
        case OP_EOF: {
           ret = NONE_OBJECT;
           goto end;
        }

        case OP_LOAD_EX: { top = f->last_top; TM_PUSH(tm->ex); break; }
        case OP_SETJUMP: { f->last_top = top; f->jmp = pc + i * 3; break; }
        case OP_CLR_JUMP: { f->jmp = NULL; break;}
        case OP_LINE: { f->lineno = i; break;}

        case OP_DEBUG: {
            #if 0
            Object fdebug = tm_get_global(globals, "__debug__");
            f->top = top;
            tm_call(0, fdebug, 1, tm_number(tm->frame - tm->frames));        
            break;
            #endif
        }
        
        case OP_FILE: {
            // module name here.
            break;
        }

        default:
            tm_raise("BAD INSTRUCTION, %d\n  globals() = \n%o", pc[0],
                    GET_FUNCTION_GLOBALS(f->fnc));
            goto end;
        }

        pc += 3;
    }

    end:
    /*
    if (top != f->stack) {
        tm_raise("tm_eval: operand stack overflow");
    }*/
    pop_frame();
    return ret;
}
Example #23
0
Object obj_append(Object a, Object item) {
    if (IS_LIST(a)) {
        list_append(GET_LIST(a), item);
    }
    return a;
}
Example #24
0
static void out(register cell xval, stack wam)
{ register term xref;
  static char ibuf[MAX1];
  
  FDEREF(xval);
  if(g.stop-g.sbuf>(bp_long)max.SBUF-MAX1)
    { warnmes("string buffer (-i option) exceeded or infinite term"); return; }
  if(VAR(xval))
    { 
/* obsolete
      ASSERT2((void*)g.shared[BBoardStk].base<(void*)htable &&
              (void*)htable<(void*)wam[HeapStk].base, xval);
*/
      VOUT(HeapStk,COUT('x'))
        BOUT(COUT('b'))
           TVOUT(htable,max.DICT*3*sizeof(cell),COUT('h')) 
            MVOUT(COUT('m'));
    }
  else
    {
      if(INTEGER(xval))
        {IOUT(OUTPUT_INT(xval));}
      else
  { 
    if(!GETARITY(xval))
      {SOUT(NAME(xval));}
    /* operators can be handled here easily
    else if(g.DIF==xval)
      {
        out(xref+1,wam),
        SOUT(NAME(s));
        out(xref+2,wam);
      }
    */
    else if IS_LIST(xval)
      {
        COUT('[');
        out((cell)(++xref),wam); 
        ++xref;
        FDEREF(T2C(xref));
        while(IS_LIST(xval))
         {
           COUT(',');
           out((cell)(++xref),wam);
           ++xref;
           FDEREF(T2C(xref));
         }
        if(g.NIL!=xval)
          {
            COUT('|');
            out((cell)xref,wam);
          }
        COUT(']');
      }
        else if (BP_FLOAT(xval)) 
        {
           FLOAT_OUT(ints_to_double(
                (half)(xref[1]),
                (half)(xref[2]),
                (half)(xref[3])));
        }
    else
      { register no i;
        SOUT(NAME(xval));
        COUT('(');
        for (i=1; i<GETARITY(xval); i++)
          {
            out(xref[i],wam);
            COUT(',');
          }
        out((cell)(xref+i),wam);
        COUT(')');
      }
  }
    }
Example #25
0
File: mlis.c Project: kzfm1024/misc
int listp(int addr){    
    if(IS_LIST(addr) || IS_NIL(addr))
        return(1);
    else
        return(0);
}
Example #26
0
/**
 * position must be a list
 * If the list consists of two numbers (x y) the surface will be rendered at location x,y
 * the same is true for (plain x y)
 * (x y)
 * (plain x y) x,y = numbers, rendered with top left corner at x,y with scale=1
 * (full) fullscreen
 * (centered)
 * (scaled)
 * (sized)
 * (rotated)

 * (windowed)
 */
Bool graphics_render_at_position(Renderable *renderable, Value position, Environment *environment) {
    if (environment -> fast_run) {return false;}
    profiler_start(profile_render);

    Double width = renderable -> width;
    Double height = renderable -> height;
    Double screen_width = environment -> width;
    Double screen_height = environment -> height;

    cairo_save(environment -> cairo);

    if (position.type == NIL) {
        cairo_scale(environment -> cairo, screen_width/width, screen_height/height);
        goto RENDER;
    }
    if (!IS_LIST(position)) {
        log_error_in;
        goto ERROR;
    }
    if (position.type != CONS) {
        log_error_in;
        goto ERROR;
    }
    Value length_val = list_length(position);
    if (length_val.type != INTEGER) {
        log_error_in;
        goto ERROR;
    }
    Unt length = NUM_VAL(length_val);
    Value first = NEXT(position);


    if (first.type == SYMBOL) {
        if (equal(first, symbols_plain)) {
            /**** plain ****/
            /* Render at coords, unscaled */
            if (length == 3) {
                Value x = NEXT(position);
                Value y = NEXT(position);
                if (IS_NUMERIC(x) && IS_NUMERIC(y)) {
                    cairo_translate(environment -> cairo, NUM_VAL(x), NUM_VAL(y));
                    goto RENDER;
                } /* Return a specific error? */
            }
        } else if (equal(first, symbols_full)) {
            /**** full ****/
            /* Stretch image to fill entire screen */
            if (length == 1) {
                cairo_scale(environment -> cairo, screen_width/width, screen_height/height);
                goto RENDER;
            }
        } else if (equal(first, symbols_centered)) {
            /**** centered ****/
            if (length == 3) {
                Value x = NEXT(position);
                Value y = NEXT(position);
                if (x.type == INTEGER && y.type == INTEGER) {
                    /* Render offset from center */
                    Double dx = (screen_width - width) / 2 + NUM_VAL(x);
                    Double dy = (screen_height - height) / 2 + NUM_VAL(y);
                    cairo_translate(environment -> cairo, dx, dy);
                    goto RENDER;
                }
                if (x.type == FLOAT && y.type == FLOAT) {
                    /* As in sized */
                    Double dx = (screen_width - width) / 2 + ((screen_width - width)/2 * NUM_VAL(x));
                    Double dy = (screen_height - height) / 2 + ((screen_height - height)/2 * NUM_VAL(y));
                    cairo_translate(environment -> cairo, dx, dy);
                    goto RENDER;
                }
            } else if (length == 1) {
                Double dx = (screen_width - width) / 2;
                Double dy = (screen_height - height) / 2;
                cairo_translate(environment -> cairo, dx, dy);
            }
        } else if (equal(first, symbols_scaled)) {
            /**** scaled ****/
            /* ('scaled x y scale) */
            /* ('scaled x y scalex scaley) */
            /* TODO: make it work with relative float positions */
            if (length < 4 || length > 5) {
                log_error_in;
                goto ERROR;
            }

            Value x_val = NEXT(position);
            Value y_val = NEXT(position);
            Value scale_x = NEXT(position);
            Value scale_y = scale_x;
            if (length == 5) {
                scale_y = NEXT(position);
            }

            Double new_width;
            Double new_height;
            if (scale_x.type == INTEGER) {
                new_width = NUM_VAL(scale_x);
            } else if (scale_x.type == FLOAT) {
                new_width = width * NUM_VAL(scale_x);
            } else {
                log_error_in;
                goto ERROR;
            }
            if (scale_y.type == INTEGER) {
                new_height = NUM_VAL(scale_y);
            } else if (scale_y.type == FLOAT) {
                new_height = height * NUM_VAL(scale_y);
            } else {
                log_error_in;
                goto ERROR;
            }

            Double x = 0;
            Double y = 0;
            if (x_val.type == INTEGER) {
                x = NUM_VAL(x_val);
            } else if (x_val.type == FLOAT) {
                x = (screen_width - new_width) / 2 + ((screen_width - new_width)/2 * NUM_VAL(x_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            if (y_val.type == INTEGER) {
                y = NUM_VAL(y_val);
            } else if (y_val.type == FLOAT) {
                y = (screen_height - new_height) / 2 + ((screen_height - new_height)/2 * NUM_VAL(y_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            cairo_translate(environment -> cairo, x, y);
            cairo_scale(environment -> cairo, new_width/width, new_height/height);
            goto RENDER;

        } else if (equal(first, symbols_sized)) {
            /**** sized ****/
            /* ('sized x y sizex/boundx sizey/boundy) */
            /* Render scaled but keep aspect ratio */
            if (length < 4 || length > 5) {
                log_error_in;
                goto ERROR;
            }
            Value x_val = NEXT(position);
            Value y_val = NEXT(position);
            Value size_x = NEXT(position);
            Value size_y = size_x;
            if (length == 5) {
                size_y = NEXT(position);
            }

            Double desired_width;
            Double desired_height;
            if (size_x.type == INTEGER) {
                desired_width = NUM_VAL(size_x);
            } else if (size_x.type == FLOAT) {
                desired_width = screen_width * NUM_VAL(size_x);
            } else {
                log_error_in;
                goto ERROR;
            }
            if (size_y.type == INTEGER) {
                desired_height = NUM_VAL(size_y);
            } else if (size_y.type == FLOAT) {
                desired_height = screen_height * NUM_VAL(size_y);
            } else {
                log_error_in;
                goto ERROR;
            }

            Double new_width;
            Double new_height;
            Double ratio_w = desired_width / width;
            Double ratio_h = desired_height / height;
            if (ratio_w <= ratio_h) {
                new_height = desired_width * ((Double) height / (Double) width);
                new_width = desired_width;
            } else {
                new_width = desired_height * ((Double) width / (Double) height);
                new_height = desired_height;
            }

            Double x = 0;
            Double y = 0;
            if (x_val.type == INTEGER) {
                x = NUM_VAL(x_val);
            } else if (x_val.type == FLOAT) {
                x = (screen_width - new_width) / 2 + ((screen_width - new_width)/2 * NUM_VAL(x_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            if (y_val.type == INTEGER) {
                y = NUM_VAL(y_val);
            } else if (y_val.type == FLOAT) {
                y = (screen_height - new_height) / 2 + ((screen_height - new_height)/2 * NUM_VAL(y_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            cairo_translate(environment -> cairo, x, y);
            cairo_scale(environment -> cairo, new_width/width, new_height/height);
            goto RENDER;
        } else if (equal(first, symbols_rotated)) {
            /**** Rotated ****/
            if (length < 4) {
                log_error_in;
                goto ERROR;
            }

            Value angle_v = NEXT(position);
            if (!IS_NUMERIC(angle_v)) {
                log_error_in;
                goto ERROR;
            }
            Double angle = NUM_VAL(angle_v);

            Value x = NEXT(position);
            Value y = NEXT(position);
            if (!IS_NUMERIC(x) || !IS_NUMERIC(y)) {
                log_error_in;
                goto ERROR;
            }
            Double dx = NUM_VAL(x);
            Double dy = NUM_VAL(y);

            Value scale_x;
            Value scale_y;
            if (length == 5) {
                scale_x = NEXT(position);
                scale_y = scale_x;
            } else if (length == 6) {
                scale_x = NEXT(position);
                scale_y = NEXT(position);
            } else {
                log_error_in;
                goto ERROR;
            }

            Double sx;
            Double sy;
            if (scale_x.type == INTEGER && scale_y.type == INTEGER) {
                sx = NUM_VAL(scale_x)/width;
                sy = NUM_VAL(scale_y)/height;
            } else if (scale_x.type == FLOAT && scale_y.type == FLOAT) {
                sx = NUM_VAL(scale_x);
                sy = NUM_VAL(scale_y);
            } else {
                log_error_in;
                goto ERROR;
            }
            if (sx == 0.0 || sy == 0.0) {
                /* Scaled to 0, thus is not shown. Cairo freezes if given scales of 0 */
                return true;
            }
            cairo_translate(environment -> cairo, dx, dy);
            cairo_translate(environment -> cairo, sx*width/2, sx*height/2);
            cairo_rotate(environment -> cairo, angle);
            cairo_scale(environment -> cairo, sx, sy);
            cairo_translate(environment -> cairo, -width/2, -height/2);
            goto RENDER;
        }

    } else if (IS_NUMERIC(first) && length == 2) {/* (x y) */
        Value second = NEXT(position);
        if (IS_NUMERIC(second)) {
            Double x = NUM_VAL(first);
            Double y = NUM_VAL(second);
            cairo_translate(environment -> cairo, x, y);
            goto RENDER;
        }
    }
 ERROR:
    cairo_restore(environment -> cairo);
    profiler_end(profile_render);
    return false;
 RENDER:
    renderable -> render(renderable -> data, environment);
    /* cairo_set_source_surface(environment -> cairo, surface, 0, 0); */
    /* cairo_paint(environment -> cairo); */
    cairo_restore(environment -> cairo);
    profiler_end(profile_render);
    return true;
}
Example #27
0
int GAP_IsList(Obj obj)
{
    return obj && IS_LIST(obj);
}
Example #28
0
size_t
co_response_alloc(char *output, const size_t olen, const uint32_t id, const co_obj_t *error, co_obj_t *result)
{
    CHECK(((output != NULL) && (error != NULL) && (result != NULL)), "Invalid response components.");
    CHECK(olen > sizeof(_resp_header) + sizeof(uint32_t) + sizeof(co_str16_t) + sizeof(co_list16_t), "Output buffer too small.");
    size_t written = 0;
    char *cursor = NULL;
    size_t s = 0;

    /* Pack response header */
    memmove(output + written, &_resp_header.list_type, sizeof(_resp_header.list_type));
    written += sizeof(_resp_header.list_type);

    memmove(output + written, &_resp_header.list_len, sizeof(_resp_header.list_len));
    written += sizeof(_resp_header.list_len);

    memmove(output + written, &_resp_header.type_type, sizeof(_resp_header.type_type));
    written += sizeof(_resp_header.type_type);

    memmove(output + written, &_resp_header.type_value, sizeof(_resp_header.type_value));
    written += sizeof(_resp_header.type_value);

    memmove(output + written, &_resp_header.id_type, sizeof(_resp_header.id_type));
    written += sizeof(_resp_header.id_type);

    /* Pack response ID */
    memmove(output + written, &id, sizeof(uint32_t));
    written += sizeof(uint32_t);

    /* Pack error code */
    //CHECK(IS_STR(error) || IS_NIL(error), "Not a valid error name.");
    if(error != NULL)
    {
        if(IS_LIST(error))
            written += co_list_raw(output + written, olen - written, error);
        else if(IS_TREE(error))
        {
            written += co_tree_raw(output + written, olen - written, error);
        }
        else
        {
            s = co_obj_raw(&cursor, error);
            memmove(output + written, cursor, s);
            written += s;
        }
    }

    /* Pack method result */
    CHECK(written < olen, "Output buffer too small.");
    if(result != NULL)
    {
        if(IS_LIST(result))
            written += co_list_raw(output + written, olen - written, result);
        else if(IS_TREE(result))
        {
            written += co_tree_raw(output + written, olen - written, result);
        }
        else
        {
            s = co_obj_raw(&cursor, result);
            memmove(output + written, cursor, s);
            written += s;
        }
    }

    DEBUG("Response bytes written: %d", (int)written);
    CHECK(written < olen, "Output buffer too small.");

    return written;
error:
    return -1;
}
Example #29
0
size_t
co_request_alloc(char *output, const size_t olen, const co_obj_t *method, co_obj_t *param)
{

    CHECK(((output != NULL) && (method != NULL)), "Invalid request components.");
    CHECK(olen > sizeof(_req_header) + sizeof(uint32_t) + sizeof(co_str16_t) + sizeof(co_list16_t), "Output buffer too small.");
    size_t written = 0;
    char *cursor = NULL;
    size_t s = 0;

    /* Pack request header */
    memmove(output + written, &_req_header.list_type, sizeof(_req_header.list_type));
    written += sizeof(_req_header.list_type);

    memmove(output + written, &_req_header.list_len, sizeof(_req_header.list_len));
    written += sizeof(_req_header.list_len);

    memmove(output + written, &_req_header.type_type, sizeof(_req_header.type_type));
    written += sizeof(_req_header.type_type);

    memmove(output + written, &_req_header.type_value, sizeof(_req_header.type_value));
    written += sizeof(_req_header.type_value);

    memmove(output + written, &_req_header.id_type, sizeof(_req_header.id_type));
    written += sizeof(_req_header.id_type);

    /* Pack request ID */
    memmove(output + written, &_id, sizeof(uint32_t));
    written += sizeof(uint32_t);
    _id++;

    /* Pack method call */
    CHECK(IS_STR(method), "Not a valid method name.");
    char *buffer = NULL;
    size_t buffer_write = co_obj_raw(&buffer, method);
    CHECK(buffer_write >= 0, "Failed to pack object.");
    memmove(output + written, buffer, buffer_write);
    written += buffer_write;

    /* Pack parameters */
    CHECK(written < olen, "Output buffer too small.");
    if(param != NULL)
    {
        if(IS_LIST(param))
            written += co_list_raw(output + written, olen - written, param);
        else
        {
            s = co_obj_raw(&cursor, param);
            written += s;
            memmove(output + written, cursor, s);
        }
    }
    CHECK(written >= 0, "Failed to pack object.");
    DEBUG("Request bytes written: %d", (int)written);
    CHECK(written < olen, "Output buffer too small.");

    return written;
error:
    return -1;

}
Example #30
0
File: eval.c Project: oswjk/lispish
struct atom *eval(struct atom *expr, struct env *env)
{
    // symbols and not-a-lists are evaluated or returned directly

    if (IS_SYM(expr))
    {
        struct atom *atom = env_lookup(env, expr->str.str);

        if (atom)
        {
            return atom;
        }
        else
        {
            printf("error: undefined variable: %s\n",
                expr->str.str);
            return &nil_atom;
        }
    }

    if (!IS_LIST(expr))
        return expr;

    struct list *list = expr->list;
    struct atom *op = LIST_FIRST(list);

    // Check if the first elem is not a symbol or a closure. If it's
    // not, then we'll evaluate it (it could be a lambda form).

    if (!IS_SYM(op) && !IS_CLOSURE(op))
    {
        struct atom *evaluated_op = eval(op, env);
        // Replace the evaluated one to the list!
        LIST_REMOVE(op, entries);
        LIST_INSERT_HEAD(list, evaluated_op, entries);
        op = evaluated_op;
    }

    // If the first elem is a symbol, it should be a name for a builtin
    // function or a closure bound to that name by the user. If the
    // first argument is directly a closure, eval that with the args.

    if (IS_SYM(op))
    {
        struct builtin_function_def *def = builtin_function_defs;
        while (def->name && def->fn)
        {
            if (strcmp(op->str.str, def->name) == 0)
            {
                return def->fn(expr, env);
            }

            ++def;
        }

        struct atom *closure = env_lookup(env, op->str.str);

        if (closure)
        {
            return eval_closure(closure, CDR(op), env);
        }

        printf("error: unknown function %s\n", op->str.str);
    }
    else if (IS_CLOSURE(op))
    {
        return eval_closure(op, CDR(op), env);
    }

    printf("error: cannot evaluate\n");

    return &nil_atom;
}