Example #1
0
int list__to_tuple(data_t **args, argc_t argc, data_t *ret, scope_t *scope)
{
    (void) argc;
    data_t ret1;
    checkf(list__length(args, 1, &ret1, scope) == 0, "Failed to find list length.");
    int len = ret1.value.integral;

    struct type **multiple = gc_add(scope->gc, malloc(sizeof(struct type *) * (len + 1)));
    multiple[len] = NULL;
    
    ret->value.tuple = gc_add(scope->gc, malloc(sizeof(data_t *) * (len + 1)));
    ret->value.tuple[len] = NULL;

    list_node_t *node;
    list_iterator_t *it = list_iterator_new(args[0]->value.list, LIST_HEAD);

    int i = 0;

    while ((node = list_iterator_next(it))) {
        ret->value.tuple[i] = copy_data((data_t *) node->val, scope);
        multiple[i] = ret->value.tuple[i]->type;
        check_mem(ret->value.tuple[i]);

        ++i;
    }

    ret->type = construct_type(tid_tuple, multiple, scope->gc);

    if (it) list_iterator_destroy(it);
    return 0;

error:
    if (it) list_iterator_destroy(it);
    return -1;
}
Example #2
0
int list__tail(data_t **args, argc_t argc, data_t *ret, scope_t *scope)
{
    (void) argc;

    list_node_t *node;
    list_iterator_t *it = list_iterator_new(args[0]->value.list, LIST_HEAD);
    check_mem(it);

    ret->type = typedup(args[0]->type, scope->gc);
    ret->value.list = gc_add_list(scope->gc, list_new());

    node = list_iterator_next(it);

    while ((node = list_iterator_next(it))) {
        list_rpush(ret->value.list, list_node_new(node->val));
    }

    if (it) list_iterator_destroy(it);

    return 0;

error:
    if (it) list_iterator_destroy(it);
    return -1;
}
Example #3
0
void timers_handleMessage(int type, int reason, int value){
	if (type == SDK_PRC_MESSAGE_CLK){
		int nearest_id = getNearestFinishedTimer();
		while (nearest_id >= 0){
			if (nearest_id >= 0){
				// process timer
				list_node_t * node;
				list_iterator_t * it = list_iterator_new(timers_list, LIST_HEAD);
				while(node = list_iterator_next(it)){
					STR_TIMER * timer = (STR_TIMER*)node->val;
					if (timer->timer_number == nearest_id){
						timer->last_tick = sdk_clk_timeSinceBoot();
						(*timer->cback)(timer->timer_number);
						break;
					}
				}
				list_iterator_destroy(it);
			}	
			nearest_id = getNearestFinishedTimer();
		}
	
		// set next timer
		int nearest = getNearestTimerDelta();
		if (nearest >= 0)
			sdk_clk_setCountdownTimer(APP_TIMER_RESERVED, nearest, false);
	}
}
Example #4
0
static inline int
install_packages(list_t *list, const char *dir, int verbose) {
  if (!list || !dir) return 0;

  list_node_t *node;
  list_iterator_t *it = list_iterator_new(list, LIST_HEAD);
  while ((node = list_iterator_next(it))) {
    clib_package_dependency_t *dep = node->val;
    char *slug = clib_package_slug(dep->author, dep->name, dep->version);
    clib_package_t *pkg = clib_package_new_from_slug(slug, verbose);

    free(slug);

    if (NULL == pkg) {
      return -1;
    }

    int rc = clib_package_install(pkg, dir, verbose);
    clib_package_free(pkg);
    if (-1 == rc) {
      list_iterator_destroy(it);
      return -1;
    }
  }

  list_iterator_destroy(it);
  return 0;
}
Example #5
0
int list__length(data_t **args, argc_t argc, data_t *ret, scope_t *scope)
{
    (void) argc;
    (void) scope;

    list_node_t *node;
    list_iterator_t *it = list_iterator_new(args[0]->value.list, LIST_HEAD);

    check_mem(it);

    int length = 0;

    while ((node = list_iterator_next(it))) {
        ++length;
    }
    
    ret->type = construct_type(tid_integral, NULL, scope->gc);
    ret->value.integral = length;

    if (it) list_iterator_destroy(it);

    return 0;

error:
    if (it) list_iterator_destroy(it);
    return -1;
}
Example #6
0
void app_chat_server(){
	canvas2 = (Canvas *)sdk_prc_getCanvas();
	
	sdk_scr_printfXY(canvas2, 0, 0, "Starting server.\n");
	while (1){
		int addr;
		char msg[1024];
		memset(msg, 0, 1024 * sizeof(char));
		int recv_size = sdk_nic_recv(msg, 1024, &addr);
		
		if ((strlen(msg) > 0) && (strcmp(msg, "> SEARCH CR CHAT SERVER") == 0)){
			sdk_scr_printf(canvas2, "New client addr: %d. Reply.\n", addr);
			sdk_nic_send(addr, "< SEARCH RESPONSE", strlen("< SEARCH RESPONSE"));
		}
		
		if ((strlen(msg) > 0) && (strncmp(msg, "> NICKNAME", 8) == 0)){
			sdk_scr_printf(canvas2, "name: %s\n", &msg[11]);
			
			ClientInfo * cl = malloc(sizeof(ClientInfo));
			memset(cl, 0, sizeof(ClientInfo));
			
			cl->addr = addr;
			strncpy(cl->name, &msg[10], strlen(&msg[10]));
			
			if (list_clients == 0){
				list_clients = list_new((void*)cl);
			}
			
			list_rpush(list_clients, list_node_new((void*)cl));			
			
			sendMsg(addr, "< NEWUSER %s", cl->name);
		}
		
		if ((strlen(msg) > 0) && (strncmp(msg, "> MESSAGE ", 8) == 0)){
			sdk_scr_printf(canvas2, "msg: %s\n", &msg[10]);
			
			//sender name
			ClientInfo * author = NULL;
			
			list_node_t *node;
			list_iterator_t *it = list_iterator_new(list_clients, LIST_HEAD);
			while ((node = list_iterator_next(it))) {
				author = (ClientInfo*)node->val;
				if (author->addr == addr){
					break;
				}
			}	
			list_iterator_destroy(it);
			
			sendMsg(addr, "< MESSAGE %s: %s", author->name, &msg[10]);
		}
	}
}
Example #7
0
static void
test_list_iterator_t() {
  // Setup
  list_t *list = list_new();
  list_node_t *tj = list_node_new("tj");
  list_node_t *taylor = list_node_new("taylor");
  list_node_t *simon = list_node_new("simon");
  
  // tj taylor simon
  list_rpush(list, tj);
  list_rpush(list, taylor);
  list_rpush(list, simon);
  
  // Assertions
  
  // From head
  list_iterator_t *it = list_iterator_new(list, LIST_HEAD);
  list_node_t *a = list_iterator_next(it);
  list_node_t *b = list_iterator_next(it);
  list_node_t *c = list_iterator_next(it);
  list_node_t *d = list_iterator_next(it);
  
  assert(a == tj);
  assert(b == taylor);
  assert(c == simon);
  assert(d == NULL);

  // From tail
  it = list_iterator_new(list, LIST_TAIL);
  list_node_t *a2 = list_iterator_next(it);
  list_node_t *b2 = list_iterator_next(it);
  list_node_t *c2 = list_iterator_next(it);
  list_node_t *d2 = list_iterator_next(it);
  
  assert(a2 == simon);
  assert(b2 == taylor);
  assert(c2 == tj);
  assert(d2 == NULL);
  list_iterator_destroy(it);
}
Example #8
0
void timers_del_timer(unsigned int timer_number){
	if (timers_list == NULL)
		return;
	
	list_node_t * node;
	list_iterator_t * it = list_iterator_new(timers_list, LIST_HEAD);
	while(node = list_iterator_next(it)){
		if (((STR_TIMER*)node->val)->timer_number == timer_number){
			break;
		}
	}
	list_remove(timers_list, node);
	list_iterator_destroy(it);
}
Example #9
0
int getNearestTimerDelta(){
	list_node_t * node;
	list_iterator_t * it = list_iterator_new(timers_list, LIST_HEAD);
	int nearest = -1;
	unsigned int current = sdk_clk_timeSinceBoot();
	while(node = list_iterator_next(it)){
		STR_TIMER * timer = (STR_TIMER *)node->val;
		unsigned int to_go = timer->ms - (current - timer->last_tick);
		if (nearest < 0 || to_go < nearest)
			nearest = to_go;		
	}
	list_iterator_destroy(it);
	
	return nearest;
}
Example #10
0
void sendMsg(int addr, char * fmt, ...){	
	va_list ap;
	char buf[256];
	char* out = &buf[0];
	va_start(ap, fmt);	
	vsprintf(buf, fmt, ap);
		
	list_node_t *node;	
	list_iterator_t *it = list_iterator_new(list_clients, LIST_HEAD);
	while ((node = list_iterator_next(it))) {
		ClientInfo * cl = (ClientInfo*)node->val;

		sdk_nic_sendf(cl->addr, buf);
	}
	list_iterator_destroy(it);
}
Example #11
0
void sendMessageToFocused(PRC_MESSAGE type, int reason, int value){
	krn_getIdleProcess()->sync_lock = TRUE;
	Process * prc;
	list_node_t * node;
	
	list_iterator_t * it = list_iterator_new(listPrcLoop, LIST_HEAD);
	while (node = list_iterator_next(it)){
		// send to currently focused process
		if (currFocusedProc == node->val){		
			unsigned int msg = type << 24 | reason << 16 | value;
			prc = node->val;
			list_rpush(prc->list_msgs, list_node_new((void*)msg));
		}
	}
	list_iterator_destroy(it);
	krn_getIdleProcess()->sync_lock = FALSE;
}
Example #12
0
static inline int
install_packages(list_t *list, const char *dir, int verbose) {
  list_node_t *node = NULL;
  list_iterator_t *iterator = NULL;
  int rc = -1;

  if (!list || !dir) goto cleanup;

  iterator = list_iterator_new(list, LIST_HEAD);
  if (NULL == iterator) goto cleanup;

  while ((node = list_iterator_next(iterator))) {
    clib_package_dependency_t *dep = NULL;
    char *slug = NULL;
    clib_package_t *pkg = NULL;
    int error = 1;

    dep = (clib_package_dependency_t *) node->val;
    slug = clib_package_slug(dep->author, dep->name, dep->version);
    if (NULL == slug) goto loop_cleanup;

    pkg = clib_package_new_from_slug(slug, verbose);
    if (NULL == pkg) goto loop_cleanup;

    if (-1 == clib_package_install(pkg, dir, verbose)) goto loop_cleanup;

    error = 0;

  loop_cleanup:
    if (slug) free(slug);
    if (pkg) clib_package_free(pkg);
    if (error) {
      list_iterator_destroy(iterator);
      iterator = NULL;
      rc = -1;
      goto cleanup;
    }
  }

  rc = 0;

cleanup:
  if (iterator) list_iterator_destroy(iterator);
  return rc;
}
Example #13
0
likedListNo* linkedList_posicao(likedList *self, int index) {
  likedListDirecao direction = LISTA_FINAL;

  if (index < 0) {
    direction = LISTA_FINAL;
    index = ~index;
  }

  if ((unsigned)index < self->len) {
    listIterator *it = list_iterator_new(self, direction);
    likedListNo*node = list_iterator_next(it);
    while (index--) node = list_iterator_next(it);
    list_iterator_destroy(it);
    return node;
  }

  return NULL;
}
Example #14
0
State state_new(Settings *settings) {

  // Allocate memory for tracking previous sets
  int **completed_games = (int **) malloc(settings->num_games * sizeof(int*));
  for (int i = 0; i < settings->num_games; i++) {
    completed_games[i] = (int *) malloc(4 * sizeof(int*));
    completed_games[i][0] = 0;
    completed_games[i][1] = 0;
  }

  return (State)
    { .player_points = 0
    , .opponent_points = 0
    , .player_games = 0
    , .opponent_games = 0

    , .num_games = settings->num_games
    , .num_points = settings->num_points
    , .scoring_mode = settings->scoring_mode
    , .server = settings->first_server

    // Collected stats
    , .match_start_time = -1
    , .match_end_time = -1
    , .player_total_points = 0
    , .completed_games = completed_games

    };

}

void state_destroy(State *s) {
  for (int i = 0; i < s->num_games; i++) free(s->completed_games[i]);
  free(s->completed_games);
}

State compute_state(list_t *serial, Settings *settings) {
  list_node_t *node;
  list_iterator_t *it = list_iterator_new(serial, LIST_HEAD);
  State state = state_new(settings);
  while ((node = list_iterator_next(it))) next_state(&state, (Point *) node->val);
  list_iterator_destroy(it);
  return state;
}
Example #15
0
File: list.c Project: brickbtv/CROS
list_node_t *
list_at(list_t *self, int index) {
  list_direction_t direction = LIST_HEAD;

  if (index < 0) {
    direction = LIST_TAIL;
    index = ~index;
  }

  if ((unsigned)index < self->len) {
    list_iterator_t *it = list_iterator_new(self, direction);
    list_node_t *node = list_iterator_next(it);
    while (index--) node = list_iterator_next(it);
    list_iterator_destroy(it);
    return node;
  }

  return NULL;
}
Example #16
0
int getNearestFinishedTimer(){
	list_node_t * node;
	list_iterator_t * it = list_iterator_new(timers_list, LIST_HEAD);
	int nearest = 1000000;
	int nearest_id = -1;
	unsigned int current = sdk_clk_timeSinceBoot();
	while(node = list_iterator_next(it)){
		STR_TIMER * timer = (STR_TIMER *)node->val;
		int to_go = timer->ms - (current - timer->last_tick);
		//sdk_debug_logf("TOGO: %d", to_go)
		if (to_go < nearest && to_go <= 0){
			nearest = to_go;
			nearest_id = timer->timer_number;
			break;
		}
	}
	list_iterator_destroy(it);
	
	return nearest_id;
}
Example #17
0
File: list.c Project: arschles/luna
list_node_t *
list_find(list_t *self, void *val) {
  list_iterator_t *it = list_iterator_new(self, LIST_HEAD);
  list_node_t *node;
  while ((node = list_iterator_next(it))) {
    if (self->match) {
      if (self->match(val, node->val)) {
        list_iterator_destroy(it);
        return node;
      }
    } else {
      if (val == node->val) {
        list_iterator_destroy(it);
        return node;
      }
    }
  }
  list_iterator_destroy(it);
  return NULL;
}
Example #18
0
likedListNo* linkedList_encontrar(likedList *self, void *val) {
  listIterator *it = list_iterator_new(self, LISTA_FINAL);
  likedListNo*node;

  while ((node = list_iterator_next(it))) {
    if (self->match) {
      if (self->match(val, node->val)) {
        list_iterator_destroy(it);
        return node;
      }
    } else {
      if (val == node->val) {
        list_iterator_destroy(it);
        return node;
      }
    }
  }

  list_iterator_destroy(it);
  return NULL;
}
Example #19
0
int
main(void) {
    list_t *pkgs = wiki_registry(DEFAULT_URL);
    list_node_t *node;
    list_iterator_t *it = list_iterator_new(pkgs, LIST_HEAD);
    while ((node = list_iterator_next(it))) {
        wiki_package_t *pkg = (wiki_package_t *) node->val;
        printf("[package]\n"
               "  repo: %s\n"
               "  description: %s\n"
               "  category: %s\n"
               "  href: %s\n"
               , pkg->repo
               , pkg->description
               , pkg->category
               , pkg->href);
        wiki_package_free(pkg);
    }
    list_iterator_destroy(it);
    list_destroy(pkgs);
}
Example #20
0
int
main(int argc, char *argv[]) {
    command_t program;
    command_init(&program, "clib-search", CLIB_VERSION);
    program.usage = "[options] [query ...]";
    command_parse(&program, argc, argv);

    for (int i = 0; i < program.argc; i++) case_lower(program.argv[i]);

    char *html = wiki_html_cache();
    if (NULL == html) {
        command_free(&program);
        fprintf(stderr, "Failed to fetch wiki HTML\n");
        return 1;
    }

    list_t *pkgs = wiki_registry_parse(html);
    free(html);

    list_node_t *node;
    list_iterator_t *it = list_iterator_new(pkgs, LIST_HEAD);
    printf("\n");
    while ((node = list_iterator_next(it))) {
        wiki_package_t *pkg = (wiki_package_t *) node->val;
        if (matches(program.argc, program.argv, pkg)) {
            cc_fprintf(CC_FG_DARK_CYAN, stdout, "  %s\n", pkg->repo);
            printf("  url: ");
            cc_fprintf(CC_FG_DARK_GRAY, stdout, "%s\n", pkg->href);
            printf("  desc: ");
            cc_fprintf(CC_FG_DARK_GRAY, stdout, "%s\n", pkg->description);
            printf("\n");
        }
        wiki_package_free(pkg);
    }
    list_iterator_destroy(it);
    list_destroy(pkgs);
    command_free(&program);
    return 0;
}
int
main(int argc, char **argv) {
  filter.executables = true;
  filter.utilities = true;

  command_t program;
  command_init(&program, "clib-search", CLIB_SEARCH_VERSION);
  program.usage = "[options] [query ...]";
  command_option(&program, "-a", "--author <author>", "filter by author", author);
  command_option(&program, "-e", "--executables", "filter by executables", executables);
  command_option(&program, "-u", "--utilities", "filter by utilities", utilities);
  command_parse(&program, argc, argv);

  char *html = wiki_html_cache();
  if (NULL == html) {
    fprintf(stderr, "Failed to fetch wiki HTML\n");
    return 1;
  }

  list_t *pkgs = wiki_registry_parse(html);

  list_node_t *node;
  list_iterator_t *it = list_iterator_new(pkgs, LIST_HEAD);
  while ((node = list_iterator_next(it))) {
    package_t *pkg = (package_t *) node->val;
    if (matches(program.argc, program.argv, pkg)) {
      printf("  \033[36m%s\033[m\n", pkg->repo);
      printf("  url: \033[90m%s\033[m\n", pkg->href);
      printf("  desc: \033[90m%s\033[m\n", pkg->description);
      printf("\n");
    }
  }
  list_iterator_destroy(it);
  list_destroy(pkgs);
  command_free(&program);

  return 0;
}
Example #22
0
int
json_array_indexof (json_array_t *self, json_value_t *value) {
  int idx = -1;
  list_iterator_t *it = list_iterator_new(self->list, LIST_HEAD);
  list_node_t *node;

  while ((node = list_iterator_next(it))) {
    idx++;
    if (self->list->match) {
      if (self->list->match(value, node->val)) {
        list_iterator_destroy(it);
        return idx;
      }
    } else {
      if (value == node->val) {
        list_iterator_destroy(it);
        return idx;
      }
    }
  }

  list_iterator_destroy(it);
  return idx;
}
Example #23
0
/*
*	Messages queue
*/
void sendMessageToAll(PRC_MESSAGE type, int reason, int value){
	krn_getIdleProcess()->sync_lock = TRUE;
	Process * prc;
	list_node_t * node;
	
	list_iterator_t * it = list_iterator_new(listPrcLoop, LIST_HEAD);
	while (node = list_iterator_next(it)){
		/*PrcMessage * msg = malloc(sizeof(PrcMessage));
		msg->type = type;
		msg->reason = reason;
		msg->value = value;*/
		unsigned int msg = type << 24 | reason << 16 | value;
	
		prc = node->val;
		
		list_rpush(prc->list_msgs, list_node_new((void*)msg));
			
		/*size_t us, fr, ma;
		_getmemstats(&us, &fr, &ma);
		krn_debugLogf("us: %d, fr: %d, ma: %d\n", us, fr, ma);*/
	}
	list_iterator_destroy(it);
	krn_getIdleProcess()->sync_lock = FALSE;
}
Example #24
0
int
clib_package_install(clib_package_t *pkg, const char *dir, int verbose) {
  char *pkg_dir = NULL;
  char *package_json = NULL;
  list_iterator_t *iterator = NULL;
  int rc = -1;

  if (!pkg || !dir) goto cleanup;
  if (!(pkg_dir = path_join(dir, pkg->name))) goto cleanup;

  // create directory for pkg
  if (-1 == mkdirp(pkg_dir, 0777)) goto cleanup;

  if (NULL == pkg->url) {
    pkg->url = clib_package_url(pkg->author
      , pkg->repo_name
      , pkg->version);
    if (NULL == pkg->url) goto cleanup;
  }

  // if no sources are listed, just install
  if (NULL == pkg->src) goto install;

  // write package.json
  if (!(package_json = path_join(pkg_dir, "package.json"))) goto cleanup;
  if (-1 == fs_write(package_json, pkg->json)) {
    logger_error("error", "Failed to write %s", package_json);
    goto cleanup;
  }

  iterator = list_iterator_new(pkg->src, LIST_HEAD);
  list_node_t *source;
  while ((source = list_iterator_next(iterator))) {
    char *filename = NULL;
    char *file_url = NULL;
    char *file_path = NULL;
    int error = 0;

    filename = source->val;

    // get file URL to fetch
    if (!(file_url = clib_package_file_url(pkg->url, filename))) {
      error = 1;
      goto loop_cleanup;
    }

    // get file path to save
    if (!(file_path = path_join(pkg_dir, basename(filename)))) {
      error = 1;
      goto loop_cleanup;
    }

    // TODO the whole URL is overkill and floods my terminal
    if (verbose) logger_info("fetch", file_url);

    // fetch source file and save to disk
    if (-1 == http_get_file(file_url, file_path)) {
      logger_error("error", "unable to fetch %s", file_url);
      error = 1;
      goto loop_cleanup;
    }

    if (verbose) logger_info("save", file_path);

  loop_cleanup:
    if (file_url) free(file_url);
    if (file_path) free(file_path);
    if (error) {
      list_iterator_destroy(iterator);
      rc = -1;
      goto cleanup;
    }
  }

install:
  rc = clib_package_install_dependencies(pkg, dir, verbose);

cleanup:
  if (pkg_dir) free(pkg_dir);
  if (package_json) free(package_json);
  if (iterator) list_iterator_destroy(iterator);
  return rc;
}
Example #25
0
int
clib_package_install(clib_package_t *pkg, const char *dir, int verbose) {
  if (!pkg || !dir) return -1;

  char *pkg_dir = path_join(dir, pkg->name);
  if (NULL == pkg_dir) {
    return -1;
  }

  if (-1 == mkdirp(pkg_dir, 0777)) {
    free(pkg_dir);
    return -1;
  }

  if (NULL == pkg->url) {
    pkg->url = clib_package_url(pkg->author, pkg->repo_name, pkg->version);
  }
  if (NULL == pkg->url) {
    free(pkg_dir);
    return -1;
  }

  if (NULL != pkg->src) {
    // write package.json

    char *package_json = path_join(pkg_dir, "package.json");
    if (NULL == package_json) {
      free(pkg_dir);
      return -1;
    }

    fs_write(package_json, pkg->json);
    free(package_json);

    // write each source

    list_node_t *node;
    list_iterator_t *it = list_iterator_new(pkg->src, LIST_HEAD);
    while ((node = list_iterator_next(it))) {
      char *filename = node->val;

      // download source file

      char *file_url = clib_package_file_url(pkg->url, filename);
      char *file_path = path_join(pkg_dir, basename(filename));

      if (NULL == file_url || NULL == file_path) {
        if (file_url) free(file_url);
        free(pkg_dir);
        return -1;
      }

      if (verbose) {
        clib_package_log("fetch", file_url);
        clib_package_log("save", file_path);
      }

      int rc = http_get_file(file_url, file_path);
      free(file_url);
      free(file_path);
      if (-1 == rc) {
        if (verbose) clib_package_error("error", "unable to fetch %s", file_url);
        free(pkg_dir);
        return -1;
      }
    }

    list_iterator_destroy(it);
  }

  return clib_package_install_dependencies(pkg, dir, verbose);
}
Example #26
0
int list__unzip(data_t **args, argc_t argc, data_t *ret, scope_t *scope)
{
    (void) argc;

    ret->type = construct_type(tid_tuple, itta(stt{
        construct_type(tid_list, itta(stt{
            typedup(((data_t *) args[0]->value.list->head->val)->value.tuple[0]->type, scope->gc)
        }, 1, scope->gc), scope->gc),
        construct_type(tid_list, itta(stt{
            typedup(((data_t *) args[0]->value.list->head->val)->value.tuple[1]->type, scope->gc)
        }, 1, scope->gc), scope->gc),
    }, 2, scope->gc), scope->gc);
    check_mem(ret->type);

    ret->value.tuple = gc_add(scope->gc, malloc(sizeof(data_t *) * 3));
    check_mem(ret->value.list);

    ret->value.tuple[0] = gc_add(scope->gc, malloc(sizeof(data_t)));
    check_mem(ret->value.tuple[0]);
    ret->value.tuple[1] = gc_add(scope->gc, malloc(sizeof(data_t)));
    check_mem(ret->value.tuple[0]);
    
    ret->value.tuple[0]->type = construct_type(tid_list, itta(stt{
        typedup(((data_t *) args[0]->value.list->head->val)->value.tuple[0]->type, scope->gc)
    }, 1, scope->gc), scope->gc);
    ret->value.tuple[0]->value.list = gc_add(scope->gc, list_new());
    check_mem(ret->value.tuple[0]->value.list);

    ret->value.tuple[1]->type = construct_type(tid_list, itta(stt{
        typedup(((data_t *) args[0]->value.list->head->val)->value.tuple[1]->type, scope->gc)
    }, 1, scope->gc), scope->gc);
    ret->value.tuple[1]->value.list = gc_add(scope->gc, list_new());
    check_mem(ret->value.tuple[1]->value.list);

    ret->value.tuple[2] = NULL;

    list_node_t *node;
    list_iterator_t *it = list_iterator_new(args[0]->value.list, LIST_HEAD);

    while ((node = list_iterator_next(it))) {
        list_rpush(ret->value.tuple[0]->value.list, gc_add(scope->gc, list_node_new(
            copy_data(((data_t *) node->val)->value.tuple[0], scope))));
        list_rpush(ret->value.tuple[1]->value.list, gc_add(scope->gc, list_node_new(
            copy_data(((data_t *) node->val)->value.tuple[1], scope))));
    }

    // ret->value.tuple = gc_add(scope->gc, malloc(sizeof(data_t *) * 3));
    // check_mem(ret->value.tuple);

    // ret->value.tuple[0] = gc_add(scope->gc, malloc(sizeof(data_t)));
    // check_mem(ret->value.tuple[0]);
    
    // ret->value.tuple[0]->type = tid_tuple;
    // ret->value.tuple[0]->value.tuple = gc_add(scope->gc, malloc(sizeof(data_t *) * (length + 1)));
    // check_mem(ret->value.tuple[0]->value.tuple);

    // ret->value.tuple[1] = gc_add(scope->gc, malloc(sizeof(data_t)));
    // check_mem(ret->value.tuple[1]);
    
    // ret->value.tuple[1]->type = tid_tuple;
    // ret->value.tuple[1]->value.tuple = gc_add(scope->gc, malloc(sizeof(data_t *) * (length + 1)));
    // check_mem(ret->value.tuple[1]->value.tuple);
    
    // ret->value.tuple[2] = NULL;

    // list_node_t *node;
    // list_iterator_t *it = list_iterator_new(args[0]->value.list, LIST_HEAD);

    // int i = 0;

    // while ((node = list_iterator_next(it))) {
    //     if (((data_t *) node->val)->type != tid_tuple) {
    //         scope->error = gc_add(scope->gc, malloc(sizeof(huserr_t)));
    //         scope->error->name = "typeErr";
    //         scope->error->msg = "must be a zipped list";
    //         scope->error->token = NULL;
    //         goto error;
    //     }

    //     ret->value.tuple[0]->value.tuple[i] = copy_data(((data_t *) node->val)->value.tuple[0], scope);
    //     check_mem(ret->value.tuple[0]->value.tuple[i]);

    //     ret->value.tuple[1]->value.tuple[i] = copy_data(((data_t *) node->val)->value.tuple[1], scope);
    //     check_mem(ret->value.tuple[1]->value.tuple[i]);

    //     ++i;
    // }

    // ret->value.tuple[0]->value.tuple[i] = NULL;
    // ret->value.tuple[1]->value.tuple[i] = NULL;

    if (it) list_iterator_destroy(it);

    return 0;

error:
    if (it) list_iterator_destroy(it);
    return -1;
}