static sexp sexp_add_import_binding (sexp ctx, sexp env) { sexp_gc_var2(sym, tmp); sexp_gc_preserve2(ctx, sym, tmp); sym = sexp_intern(ctx, "repl-import", -1); tmp = sexp_env_ref(ctx, sexp_meta_env(ctx), sym, SEXP_VOID); sym = sexp_intern(ctx, "import", -1); sexp_env_define(ctx, env, sym, tmp); sexp_gc_release3(ctx); return env; }
sexp sexp_mutex_state (sexp ctx sexp_api_params(self, n), sexp mutex) { sexp_assert_type(ctx, sexp_mutexp, sexp_mutex_id, mutex); if (sexp_truep(sexp_mutex_lockp(mutex))) { if (sexp_contextp(sexp_mutex_thread(mutex))) return sexp_mutex_thread(mutex); else return sexp_intern(ctx, "not-owned", -1); } else { return sexp_intern(ctx, (sexp_mutex_thread(mutex) ? "not-abandoned" : "abandoned"), -1); } }
sexp sexp_mutex_state (sexp ctx, sexp self, sexp_sint_t n, sexp mutex) { if (!sexp_mutexp(ctx, mutex)) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_global(ctx, SEXP_G_THREADS_POLLFDS_ID)), mutex); if (sexp_truep(sexp_mutex_lockp(mutex))) { if (sexp_contextp(sexp_mutex_thread(mutex))) return sexp_mutex_thread(mutex); else return sexp_intern(ctx, "not-owned", -1); } else { return sexp_intern(ctx, (sexp_mutex_thread(mutex) ? "not-abandoned" : "abandoned"), -1); } }
static sexp check_exception (sexp ctx, sexp res) { sexp_gc_var4(err, advise, sym, tmp); if (res && sexp_exceptionp(res)) { sexp_gc_preserve4(ctx, err, advise, sym, tmp); tmp = res; err = sexp_current_error_port(ctx); if (! sexp_oportp(err)) err = sexp_make_output_port(ctx, stderr, SEXP_FALSE); sexp_print_exception(ctx, res, err); sexp_stack_trace(ctx, err); #if SEXP_USE_MAIN_ERROR_ADVISE if (sexp_envp(sexp_global(ctx, SEXP_G_META_ENV))) { advise = sexp_eval_string(ctx, sexp_advice_environment, -1, sexp_global(ctx, SEXP_G_META_ENV)); if (sexp_vectorp(advise)) { advise = sexp_vector_ref(advise, SEXP_ONE); if (sexp_envp(advise)) { sym = sexp_intern(ctx, "repl-advise-exception", -1); advise = sexp_env_ref(ctx, advise, sym, SEXP_FALSE); if (sexp_procedurep(advise)) sexp_apply(ctx, advise, tmp=sexp_list2(ctx, res, err)); } } } #endif sexp_gc_release4(ctx); exit_failure(); } return res; }
static void sexp_define_type_predicate_by_tag (sexp ctx, sexp env, char *cname, sexp_uint_t type) { sexp_gc_var2(name, op); sexp_gc_preserve2(ctx, name, op); name = sexp_c_string(ctx, cname, -1); op = sexp_make_type_predicate(ctx, name, sexp_make_fixnum(type)); sexp_env_define(ctx, env, name=sexp_intern(ctx, cname, -1), op); sexp_gc_release2(ctx); }
static void sexp_define_accessors (sexp ctx, sexp env, sexp_uint_t ctype, sexp_uint_t cindex, char* get, char *set) { sexp type, index; sexp_gc_var2(name, op); sexp_gc_preserve2(ctx, name, op); type = sexp_make_fixnum(ctype); index = sexp_make_fixnum(cindex); if (get) { op = sexp_make_getter(ctx, name=sexp_c_string(ctx, get, -1), type, index); sexp_env_define(ctx, env, name=sexp_intern(ctx, get, -1), op); } if (set) { op = sexp_make_setter(ctx, name=sexp_c_string(ctx, set, -1), type, index); sexp_env_define(ctx, env, name=sexp_intern(ctx, set, -1), op); } sexp_gc_release2(ctx); }
sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { sexp_gc_var2(name, op); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) return SEXP_ABI_ERROR; sexp_gc_preserve2(ctx, name, op); name = sexp_c_string(ctx, "random-source", -1); op = sexp_register_type(ctx, name, SEXP_FALSE, SEXP_FALSE, sexp_make_fixnum(sexp_offsetof_slot0), ONE, ONE, ZERO, ZERO, sexp_make_fixnum(sexp_sizeof_random), ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, NULL, NULL); if (sexp_exceptionp(op)) return op; rs_type_id = sexp_type_tag(op); name = sexp_c_string(ctx, "random-source?", -1); op = sexp_make_type_predicate(ctx, name, sexp_make_fixnum(rs_type_id)); name = sexp_intern(ctx, "random-source?", -1); sexp_env_define(ctx, env, name, op); sexp_define_foreign(ctx, env, "make-random-source", 0, sexp_make_random_source); sexp_define_foreign(ctx, env, "%random-integer", 2, sexp_rs_random_integer); sexp_define_foreign(ctx, env, "random-integer", 1, sexp_random_integer); sexp_define_foreign(ctx, env, "%random-real", 1, sexp_rs_random_real); sexp_define_foreign(ctx, env, "random-real", 0, sexp_random_real); sexp_define_foreign(ctx, env, "random-source-state-ref", 1, sexp_random_source_state_ref); sexp_define_foreign(ctx, env, "random-source-state-set!", 2, sexp_random_source_state_set); sexp_define_foreign(ctx, env, "random-source-randomize!", 1, sexp_random_source_randomize); sexp_define_foreign(ctx, env, "random-source-pseudo-randomize!", 2, sexp_random_source_pseudo_randomize); default_random_source = op = sexp_make_random_source(ctx, NULL, 0); name = sexp_intern(ctx, "default-random-source", -1); sexp_env_define(ctx, env, name, default_random_source); sexp_random_source_randomize(ctx, NULL, 0, default_random_source); sexp_gc_release2(ctx); return SEXP_VOID; }
static sexp sexp_get_opcode_ret_type (sexp ctx, sexp self, sexp_sint_t n, sexp op) { sexp res; if (!op) return sexp_type_by_index(ctx, SEXP_OBJECT); if (! sexp_opcodep(op)) return sexp_type_exception(ctx, self, SEXP_OPCODE, op); if (sexp_opcode_code(op) == SEXP_OP_RAISE) return sexp_list1(ctx, sexp_intern(ctx, "error", -1)); res = sexp_opcode_return_type(op); if (sexp_fixnump(res)) res = sexp_type_by_index(ctx, sexp_unbox_fixnum(res)); return sexp_translate_opcode_type(ctx, res); }
sexp sexp_init_library (sexp ctx sexp_api_params(self, n), sexp env) { sexp_gc_var2(name, op); sexp_gc_preserve2(ctx, name, op); name = sexp_c_string(ctx, "random-source", -1); op = sexp_register_type(ctx, name, SEXP_FALSE, SEXP_FALSE, sexp_make_fixnum(sexp_offsetof_slot0), ONE, ONE, ZERO, ZERO, sexp_make_fixnum(sexp_sizeof_random), ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, NULL); if (sexp_exceptionp(op)) return op; rs_type_id = sexp_type_tag(op); name = sexp_c_string(ctx, "random-source?", -1); op = sexp_make_type_predicate(ctx, name, sexp_make_fixnum(rs_type_id)); name = sexp_intern(ctx, "random-source?", -1); sexp_env_define(ctx, env, name, op); sexp_define_foreign(ctx, env, "make-random-source", 0, sexp_make_random_source); sexp_define_foreign(ctx, env, "%random-integer", 2, sexp_rs_random_integer); sexp_define_foreign(ctx, env, "random-integer", 1, sexp_random_integer); sexp_define_foreign(ctx, env, "%random-real", 1, sexp_rs_random_real); sexp_define_foreign(ctx, env, "random-real", 0, sexp_random_real); sexp_define_foreign(ctx, env, "random-source-state-ref", 1, sexp_random_source_state_ref); sexp_define_foreign(ctx, env, "random-source-state-set!", 2, sexp_random_source_state_set); sexp_define_foreign(ctx, env, "random-source-randomize!", 1, sexp_random_source_randomize); sexp_define_foreign(ctx, env, "random-source-pseudo-randomize!", 2, sexp_random_source_pseudo_randomize); default_random_source = op = sexp_make_random_source(ctx sexp_api_pass(NULL, 0)); name = sexp_intern(ctx, "default-random-source", -1); sexp_env_define(ctx, env, name, default_random_source); sexp_random_source_randomize(ctx sexp_api_pass(NULL, 0), default_random_source); sexp_gc_release2(ctx); return SEXP_VOID; }
static sexp sexp_translate_opcode_type (sexp ctx, sexp type) { sexp_gc_var2(res, tmp); res = type; if (! res) { res = sexp_type_by_index(ctx, SEXP_OBJECT); } if (sexp_fixnump(res)) { res = sexp_type_by_index(ctx, sexp_unbox_fixnum(res)); } else if (sexp_nullp(res)) { /* opcode list types */ sexp_gc_preserve2(ctx, res, tmp); tmp = sexp_intern(ctx, "or", -1); res = sexp_cons(ctx, SEXP_NULL, SEXP_NULL); res = sexp_cons(ctx, sexp_type_by_index(ctx, SEXP_PAIR), res); res = sexp_cons(ctx, tmp, res); sexp_gc_release2(ctx); } return res; }
sexp run_main (int argc, char **argv) { #if SEXP_USE_MODULES char *impmod; #endif char *arg; const char *prefix=NULL, *suffix=NULL, *main_symbol=NULL, *main_module=NULL; sexp_sint_t i, j, c, quit=0, print=0, init_loaded=0, mods_loaded=0, fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS, nonblocking=0; sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE; sexp out=SEXP_FALSE, ctx=NULL, ls; sexp_gc_var4(tmp, sym, args, env); args = SEXP_NULL; env = NULL; /* SRFI 22: invoke `main` procedure by default if the interpreter is */ /* invoked as `scheme-r7rs`. */ arg = strrchr(argv[0], '/'); if (strncmp((arg == NULL ? argv[0] : arg + 1), "scheme-r7rs", strlen("scheme-r7rs")) == 0) { main_symbol = "main"; /* skip option parsing since we can't pass `--` before the name of script */ /* to avoid misinterpret the name as options when the interpreter is */ /* executed via `#!/usr/env/bin scheme-r7rs` shebang. */ i = 1; goto done_options; } /* parse options */ for (i=1; i < argc && argv[i][0] == '-'; i++) { switch ((c=argv[i][1])) { case 'D': init_context(); arg = (argv[i][2] == '\0') ? argv[++i] : argv[i]+2; sym = sexp_intern(ctx, arg, -1); ls = sexp_global(ctx, SEXP_G_FEATURES); if (sexp_pairp(ls)) { for (; sexp_pairp(sexp_cdr(ls)); ls=sexp_cdr(ls)) ; sexp_cdr(ls) = sexp_cons(ctx, sym, SEXP_NULL); } break; case 'e': case 'p': mods_loaded = 1; load_init(0); print = (argv[i][1] == 'p'); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('e', arg); tmp = check_exception(ctx, sexp_eval_string(ctx, arg, -1, env)); if (print) { if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write(ctx, tmp, out); sexp_write_char(ctx, '\n', out); } quit = 1; break; case 'l': mods_loaded = 1; load_init(0); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('l', arg); check_exception(ctx, sexp_load_module_file(ctx, arg, env)); break; case 'x': prefix = sexp_environment_prefix; suffix = sexp_environment_suffix; case 'm': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); if (c == 'x') { if (strcmp(arg, "chibi.primitive") == 0) { goto load_primitive; } else if (strcmp(arg, "scheme.small") == 0) { load_init(0); break; } } else { prefix = sexp_import_prefix; suffix = sexp_import_suffix; } mods_loaded = 1; load_init(c == 'x'); #if SEXP_USE_MODULES check_nonull_arg(c, arg); impmod = make_import(prefix, arg, suffix); tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, (c=='x' ? sexp_global(ctx, SEXP_G_META_ENV) : env))); free(impmod); if (c == 'x') { sexp_set_parameter(ctx, sexp_global(ctx, SEXP_G_META_ENV), sexp_global(ctx, SEXP_G_INTERACTION_ENV_SYMBOL), tmp); sexp_context_env(ctx) = env = tmp; sexp_add_import_binding(ctx, env); tmp = sexp_param_ref(ctx, env, sexp_global(ctx, SEXP_G_CUR_OUT_SYMBOL)); if (tmp != NULL && !sexp_oportp(tmp)) { sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0); } } #endif break; load_primitive: case 'Q': init_context(); mods_loaded = 1; if (! init_loaded++) sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0); handle_noarg(); break; case 'q': argv[i--] = (char*)"-xchibi"; break; case 'A': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('A', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_TRUE); break; case 'I': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('I', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_FALSE); break; #if SEXP_USE_GREEN_THREADS case 'b': nonblocking = 1; break; #endif case '-': if (argv[i][2] == '\0') { i++; goto done_options; } sexp_usage(1); case 'h': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('h', arg); #if ! SEXP_USE_BOEHM heap_size = strtoul(arg, &arg, 0); if (sexp_isalpha((unsigned char)*arg)) heap_size *= multiplier(*arg++); if (*arg == '/') { heap_max_size = strtoul(arg+1, &arg, 0); if (sexp_isalpha((unsigned char)*arg)) heap_max_size *= multiplier(*arg++); } #endif break; #if SEXP_USE_IMAGE_LOADING case 'i': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); if (ctx) { fprintf(stderr, "-:i <file>: image files must be loaded first\n"); exit_failure(); } ctx = sexp_load_image(arg, 0, heap_size, heap_max_size); if (!ctx || !sexp_contextp(ctx)) { fprintf(stderr, "-:i <file>: couldn't open image file for reading: %s\n", arg); fprintf(stderr, " %s\n", sexp_load_image_err()); ctx = NULL; } else { env = sexp_load_standard_params(ctx, sexp_context_env(ctx), nonblocking); init_loaded++; } break; case 'd': if (! init_loaded++) { init_context(); env = sexp_load_standard_env(ctx, env, SEXP_SEVEN); } arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); if (sexp_save_image(ctx, arg) != SEXP_TRUE) { fprintf(stderr, "-d <file>: couldn't save image to file: %s\n", arg); fprintf(stderr, " %s\n", sexp_load_image_err()); exit_failure(); } quit = 1; break; #endif case 'V': load_init(1); if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write_string(ctx, sexp_version_string, out); tmp = sexp_env_ref(ctx, env, sym=sexp_intern(ctx, "*features*", -1), SEXP_NULL); sexp_write(ctx, tmp, out); sexp_newline(ctx, out); return SEXP_TRUE; #if SEXP_USE_FOLD_CASE_SYMS case 'f': fold_case = 1; init_context(); sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE; handle_noarg(); break; #endif case 'R': main_module = argv[i][2] != '\0' ? argv[i]+2 : (i+1 < argc && argv[i+1][0] != '-') ? argv[++i] : "chibi.repl"; if (main_symbol == NULL) main_symbol = "main"; break; case 'r': main_symbol = argv[i][2] == '\0' ? "main" : argv[i]+2; break; case 's': init_context(); sexp_global(ctx, SEXP_G_STRICT_P) = SEXP_TRUE; handle_noarg(); break; case 'T': init_context(); sexp_global(ctx, SEXP_G_NO_TAIL_CALLS_P) = SEXP_TRUE; handle_noarg(); break; case 't': mods_loaded = 1; load_init(1); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); #if SEXP_USE_MODULES check_nonull_arg('t', arg); suffix = strrchr(arg, '.'); sym = sexp_intern(ctx, suffix + 1, -1); *(char*)suffix = '\0'; impmod = make_import(sexp_trace_prefix, arg, sexp_trace_suffix); tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, sexp_meta_env(ctx))); if (!(tmp && sexp_envp(tmp))) { fprintf(stderr, "couldn't find library to trace: %s\n", impmod); } else if (!((sym = sexp_env_cell(ctx, tmp, sym, 0)))) { fprintf(stderr, "couldn't find binding to trace: %s in %s\n", suffix + 1, impmod); } else { sym = sexp_list1(ctx, sym); tmp = check_exception(ctx, sexp_eval_string(ctx, "(environment '(chibi trace))", -1, sexp_meta_env(ctx))); tmp = sexp_env_ref(ctx, tmp, sexp_intern(ctx, "trace-cell", -1), 0); if (tmp && sexp_procedurep(tmp)) check_exception(ctx, sexp_apply(ctx, tmp, sym)); } free(impmod); #endif break; default: fprintf(stderr, "unknown option: %s\n", argv[i]); /* ... FALLTHROUGH ... */ case '?': sexp_usage(1); } } done_options: if (!quit || main_symbol != NULL) { init_context(); /* build argument list */ if (i < argc) for (j=argc-1; j>=i; j--) args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[j],-1), args); if (i >= argc || main_symbol != NULL) args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[0],-1), args); load_init(i < argc || main_symbol != NULL); sexp_set_parameter(ctx, sexp_meta_env(ctx), sym=sexp_intern(ctx, sexp_argv_symbol, -1), args); if (i >= argc && main_symbol == NULL) { /* no script or main, run interactively */ repl(ctx, env); } else { #if SEXP_USE_MODULES /* load the module or script */ if (main_module != NULL) { impmod = make_import("(load-module '(", main_module, "))"); env = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, sexp_meta_env(ctx))); if (sexp_vectorp(env)) env = sexp_vector_ref(env, SEXP_ONE); free(impmod); check_exception(ctx, env); if (!sexp_envp(env)) { fprintf(stderr, "couldn't find module: %s\n", main_module); exit_failure(); } } else #endif if (i < argc) { /* script usage */ #if SEXP_USE_MODULES /* reset the environment to have only the `import' and */ /* `cond-expand' bindings */ if (!mods_loaded) { env = sexp_make_env(ctx); sexp_set_parameter(ctx, sexp_meta_env(ctx), sexp_global(ctx, SEXP_G_INTERACTION_ENV_SYMBOL), env); sexp_context_env(ctx) = env; sym = sexp_intern(ctx, "repl-import", -1); tmp = sexp_env_ref(ctx, sexp_meta_env(ctx), sym, SEXP_VOID); sym = sexp_intern(ctx, "import", -1); check_exception(ctx, sexp_env_define(ctx, env, sym, tmp)); sym = sexp_intern(ctx, "cond-expand", -1); tmp = sexp_env_cell(ctx, sexp_meta_env(ctx), sym, 0); #if SEXP_USE_RENAME_BINDINGS sexp_env_rename(ctx, env, sym, tmp); #endif sexp_env_define(ctx, env, sym, sexp_cdr(tmp)); } #endif sexp_context_tracep(ctx) = 1; tmp = sexp_env_bindings(env); #if SEXP_USE_MODULES /* use scheme load if possible for better stack traces */ sym = sexp_intern(ctx, "load", -1); tmp = sexp_env_ref(ctx, sexp_meta_env(ctx), sym, SEXP_FALSE); if (sexp_procedurep(tmp)) { sym = sexp_c_string(ctx, argv[i], -1); sym = sexp_list2(ctx, sym, env); tmp = check_exception(ctx, sexp_apply(ctx, tmp, sym)); } else #endif tmp = check_exception(ctx, sexp_load(ctx, sym=sexp_c_string(ctx, argv[i], -1), env)); #if SEXP_USE_WARN_UNDEFS sexp_warn_undefs(ctx, env, tmp, SEXP_VOID); #endif #ifdef EMSCRIPTEN if (sexp_applicablep(tmp)) { sexp_resume_ctx = ctx; sexp_resume_proc = tmp; sexp_preserve_object(ctx, sexp_resume_proc); emscripten_exit_with_live_runtime(); } #endif } /* SRFI-22: run main if specified */ if (main_symbol) { sym = sexp_intern(ctx, main_symbol, -1); tmp = sexp_env_ref(ctx, env, sym, SEXP_FALSE); if (sexp_procedurep(tmp)) { args = sexp_list1(ctx, sexp_cdr(args)); check_exception(ctx, sexp_apply(ctx, tmp, args)); } else { fprintf(stderr, "couldn't find main binding: %s in %s\n", main_symbol, main_module ? main_module : argv[i]); } } } } sexp_gc_release4(ctx); if (sexp_destroy_context(ctx) == SEXP_FALSE) { fprintf(stderr, "destroy_context error\n"); return SEXP_FALSE; } return SEXP_TRUE; }
int sexp_lookup_type (sexp ctx, sexp env, const char *name) { sexp t = sexp_env_ref(env, sexp_intern(ctx, name, -1), SEXP_FALSE); return (sexp_typep(t)) ? sexp_type_tag(t) : -1; }
sexp sexp_scheduler (sexp ctx, sexp self, sexp_sint_t n, sexp root_thread) { int i, k; struct timeval tval; struct pollfd *pfds; useconds_t usecs = 0; sexp res, ls1, ls2, runner, paused, front, pollfds; sexp_gc_var1(tmp); sexp_gc_preserve1(ctx, tmp); front = sexp_global(ctx, SEXP_G_THREADS_FRONT); paused = sexp_global(ctx, SEXP_G_THREADS_PAUSED); /* check signals */ if (sexp_global(ctx, SEXP_G_THREADS_SIGNALS) != SEXP_ZERO) { runner = sexp_global(ctx, SEXP_G_THREADS_SIGNAL_RUNNER); if (! sexp_contextp(runner)) { /* ensure the runner exists */ if (sexp_envp(runner)) { tmp = sexp_env_cell(runner, (tmp=sexp_intern(ctx, "signal-runner", -1)), 0); if (sexp_pairp(tmp) && sexp_procedurep(sexp_cdr(tmp))) { runner = sexp_make_thread(ctx, self, 2, sexp_cdr(tmp), SEXP_FALSE); sexp_global(ctx, SEXP_G_THREADS_SIGNAL_RUNNER) = runner; sexp_thread_start(ctx, self, 1, runner); } } } else if (sexp_context_waitp(runner)) { /* wake it if it's sleeping */ sexp_context_waitp(runner) = 0; sexp_thread_start(ctx, self, 1, runner); } } /* check blocked fds */ pollfds = sexp_global(ctx, SEXP_G_THREADS_POLL_FDS); if (sexp_pollfdsp(ctx, pollfds) && sexp_pollfds_num_fds(pollfds) > 0) { pfds = sexp_pollfds_fds(pollfds); k = poll(sexp_pollfds_fds(pollfds), sexp_pollfds_num_fds(pollfds), 0); unblock_io_threads: for (i=sexp_pollfds_num_fds(pollfds)-1; i>=0 && k>0; --i) { if (pfds[i].revents > 0) { /* free all threads blocked on this fd */ k--; pfds[i].events = 0; /* FIXME: delete from queue completely */ for (ls1=SEXP_NULL, ls2=paused; sexp_pairp(ls2); ) { /* FIXME distinguish input and output on the same fd */ if (sexp_portp(sexp_context_event(sexp_car(ls2))) && sexp_port_fileno(sexp_context_event(sexp_car(ls2))) == pfds[i].fd) { sexp_context_waitp(sexp_car(ls2)) = 0; sexp_context_timeoutp(sexp_car(ls2)) = 0; if (ls1==SEXP_NULL) sexp_global(ctx, SEXP_G_THREADS_PAUSED) = paused = sexp_cdr(ls2); else sexp_cdr(ls1) = sexp_cdr(ls2); tmp = sexp_cdr(ls2); sexp_cdr(ls2) = SEXP_NULL; if (! sexp_pairp(sexp_global(ctx, SEXP_G_THREADS_BACK))) { sexp_global(ctx, SEXP_G_THREADS_FRONT) = front = ls2; } else { sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = ls2; } sexp_global(ctx, SEXP_G_THREADS_BACK) = ls2; ls2 = tmp; } else { ls1 = ls2; ls2 = sexp_cdr(ls2); } } } } } /* if we've terminated, check threads joining us */ if (sexp_context_refuel(ctx) <= 0) { for (ls1=SEXP_NULL, ls2=paused; sexp_pairp(ls2); ) { if (sexp_context_event(sexp_car(ls2)) == ctx) { sexp_context_waitp(sexp_car(ls2)) = 0; sexp_context_timeoutp(sexp_car(ls2)) = 0; if (ls1==SEXP_NULL) sexp_global(ctx, SEXP_G_THREADS_PAUSED) = paused = sexp_cdr(ls2); else sexp_cdr(ls1) = sexp_cdr(ls2); tmp = sexp_cdr(ls2); sexp_cdr(ls2) = SEXP_NULL; if (! sexp_pairp(sexp_global(ctx, SEXP_G_THREADS_BACK))) { sexp_global(ctx, SEXP_G_THREADS_FRONT) = front = ls2; } else { sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = ls2; } sexp_global(ctx, SEXP_G_THREADS_BACK) = ls2; ls2 = tmp; } else { ls1 = ls2; ls2 = sexp_cdr(ls2); } } } /* check timeouts */ if (sexp_pairp(paused)) { if (gettimeofday(&tval, NULL) == 0) { ls1 = SEXP_NULL; ls2 = paused; while (sexp_pairp(ls2) && sexp_context_before(sexp_car(ls2), tval)) { sexp_context_timeoutp(sexp_car(ls2)) = 1; sexp_context_waitp(ctx) = 0; ls1 = ls2; ls2 = sexp_cdr(ls2); } if (sexp_pairp(ls1)) { sexp_cdr(ls1) = SEXP_NULL; if (! sexp_pairp(sexp_global(ctx, SEXP_G_THREADS_BACK))) { sexp_global(ctx, SEXP_G_THREADS_FRONT) = front = paused; } else { sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = paused; } sexp_global(ctx, SEXP_G_THREADS_BACK) = ls1; sexp_global(ctx, SEXP_G_THREADS_PAUSED) = paused = ls2; } } } /* dequeue next thread */ if (sexp_pairp(front)) { res = sexp_car(front); if ((sexp_context_refuel(ctx) <= 0) || sexp_context_waitp(ctx)) { /* either terminated or paused */ sexp_global(ctx, SEXP_G_THREADS_FRONT) = sexp_cdr(front); if (! sexp_pairp(sexp_cdr(front))) sexp_global(ctx, SEXP_G_THREADS_BACK) = SEXP_NULL; } else { /* swap with front of queue */ sexp_car(sexp_global(ctx, SEXP_G_THREADS_FRONT)) = ctx; /* rotate front of queue to back */ sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = sexp_global(ctx, SEXP_G_THREADS_FRONT); sexp_global(ctx, SEXP_G_THREADS_FRONT) = sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_FRONT)); sexp_global(ctx, SEXP_G_THREADS_BACK) = sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)); sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = SEXP_NULL; } } else { res = ctx; } if (sexp_context_waitp(res)) { /* the only thread available was waiting */ if (sexp_pairp(paused) && sexp_context_before(sexp_car(paused), sexp_context_timeval(res))) { tmp = res; res = sexp_car(paused); sexp_global(ctx, SEXP_G_THREADS_PAUSED) = sexp_cdr(paused); if (sexp_not(sexp_memq(ctx, tmp, paused))) sexp_insert_timed(ctx, tmp, tmp); } usecs = 0; if ((sexp_context_timeval(res).tv_sec == 0) && (sexp_context_timeval(res).tv_usec == 0)) { /* no timeout, wait for default 10ms */ usecs = 10*1000; } else { /* wait until the next timeout */ gettimeofday(&tval, NULL); if (tval.tv_sec <= sexp_context_timeval(res).tv_sec) { usecs = (sexp_context_timeval(res).tv_sec - tval.tv_sec) * 1000000; if (tval.tv_usec < sexp_context_timeval(res).tv_usec || usecs > 0) usecs += sexp_context_timeval(res).tv_usec - tval.tv_usec; } } /* either wait on an fd, or just sleep */ pollfds = sexp_global(res, SEXP_G_THREADS_POLL_FDS); if (sexp_portp(sexp_context_event(res)) && sexp_pollfdsp(ctx, pollfds)) { if ((k = poll(sexp_pollfds_fds(pollfds), sexp_pollfds_num_fds(pollfds), usecs/1000)) > 0) { pfds = sexp_pollfds_fds(pollfds); goto unblock_io_threads; } } else { usleep(usecs); sexp_context_waitp(res) = 0; sexp_context_timeoutp(res) = 1; } } sexp_gc_release1(ctx); return res; }
sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, const sexp_abi_identifier_t abi) { sexp sexp_timezone_type_obj; sexp sexp_timeval_type_obj; sexp sexp_tm_type_obj; sexp_gc_var3(name, tmp, op); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) return SEXP_ABI_ERROR; sexp_gc_preserve3(ctx, name, tmp, op); name = sexp_c_string(ctx, "timezone", -1); sexp_timezone_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type); tmp = sexp_string_to_symbol(ctx, name); sexp_env_define(ctx, env, tmp, sexp_timezone_type_obj); sexp_type_slots(sexp_timezone_type_obj) = SEXP_NULL; sexp_push(ctx, sexp_type_slots(sexp_timezone_type_obj), sexp_intern(ctx, "tz_dsttime", -1)); sexp_push(ctx, sexp_type_slots(sexp_timezone_type_obj), sexp_intern(ctx, "tz_minuteswest", -1)); sexp_type_getters(sexp_timezone_type_obj) = sexp_make_vector(ctx, SEXP_TWO, SEXP_FALSE); sexp_type_setters(sexp_timezone_type_obj) = sexp_make_vector(ctx, SEXP_TWO, SEXP_FALSE); tmp = sexp_make_type_predicate(ctx, name, sexp_timezone_type_obj); name = sexp_intern(ctx, "timezone?", 9); sexp_env_define(ctx, env, name, tmp); name = sexp_c_string(ctx, "timeval", -1); sexp_timeval_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type); tmp = sexp_string_to_symbol(ctx, name); sexp_env_define(ctx, env, tmp, sexp_timeval_type_obj); sexp_type_slots(sexp_timeval_type_obj) = SEXP_NULL; sexp_push(ctx, sexp_type_slots(sexp_timeval_type_obj), sexp_intern(ctx, "tv_usec", -1)); sexp_push(ctx, sexp_type_slots(sexp_timeval_type_obj), sexp_intern(ctx, "tv_sec", -1)); sexp_type_getters(sexp_timeval_type_obj) = sexp_make_vector(ctx, SEXP_TWO, SEXP_FALSE); sexp_type_setters(sexp_timeval_type_obj) = sexp_make_vector(ctx, SEXP_TWO, SEXP_FALSE); tmp = sexp_make_type_predicate(ctx, name, sexp_timeval_type_obj); name = sexp_intern(ctx, "timeval?", 8); sexp_env_define(ctx, env, name, tmp); name = sexp_c_string(ctx, "tm", -1); sexp_tm_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type); tmp = sexp_string_to_symbol(ctx, name); sexp_env_define(ctx, env, tmp, sexp_tm_type_obj); sexp_type_slots(sexp_tm_type_obj) = SEXP_NULL; sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_gmtoff", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_zone", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_isdst", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_yday", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_wday", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_year", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_mon", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_mday", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_hour", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_min", -1)); sexp_push(ctx, sexp_type_slots(sexp_tm_type_obj), sexp_intern(ctx, "tm_sec", -1)); sexp_type_getters(sexp_tm_type_obj) = sexp_make_vector(ctx, sexp_make_fixnum(11), SEXP_FALSE); sexp_type_setters(sexp_tm_type_obj) = sexp_make_vector(ctx, sexp_make_fixnum(11), SEXP_FALSE); tmp = sexp_make_type_predicate(ctx, name, sexp_tm_type_obj); name = sexp_intern(ctx, "tm?", 3); sexp_env_define(ctx, env, name, tmp); op = sexp_define_foreign(ctx, env, "time-offset", 1, (sexp_proc1)sexp_tm_get_tm_gmtoff); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_TEN, op); op = sexp_define_foreign(ctx, env, "time-timezone-name", 1, (sexp_proc1)sexp_tm_get_tm_zone); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_NINE, op); op = sexp_define_foreign(ctx, env, "time-dst?", 1, (sexp_proc1)sexp_tm_get_tm_isdst); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_EIGHT, op); op = sexp_define_foreign(ctx, env, "time-day-of-year", 1, (sexp_proc1)sexp_tm_get_tm_yday); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_SEVEN, op); op = sexp_define_foreign(ctx, env, "time-day-of-week", 1, (sexp_proc1)sexp_tm_get_tm_wday); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_SIX, op); op = sexp_define_foreign(ctx, env, "time-year", 1, (sexp_proc1)sexp_tm_get_tm_year); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_FIVE, op); op = sexp_define_foreign(ctx, env, "time-month", 1, (sexp_proc1)sexp_tm_get_tm_mon); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_FOUR, op); op = sexp_define_foreign(ctx, env, "time-day", 1, (sexp_proc1)sexp_tm_get_tm_mday); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_THREE, op); op = sexp_define_foreign(ctx, env, "time-hour", 1, (sexp_proc1)sexp_tm_get_tm_hour); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_TWO, op); op = sexp_define_foreign(ctx, env, "time-minute", 1, (sexp_proc1)sexp_tm_get_tm_min); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_ONE, op); op = sexp_define_foreign(ctx, env, "time-second", 1, (sexp_proc1)sexp_tm_get_tm_sec); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_tm_type_obj))) sexp_vector_set(sexp_type_getters(sexp_tm_type_obj), SEXP_ZERO, op); op = sexp_define_foreign(ctx, env, "make-tm", 7, (sexp_proc1)sexp_make_tm_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg3_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_argn_type(op) = sexp_make_vector(ctx, SEXP_FOUR, sexp_make_fixnum(SEXP_OBJECT)); sexp_vector_set(sexp_opcode_argn_type(op), SEXP_ZERO, sexp_make_fixnum(SEXP_FIXNUM)); sexp_vector_set(sexp_opcode_argn_type(op), SEXP_ONE, sexp_make_fixnum(SEXP_FIXNUM)); sexp_vector_set(sexp_opcode_argn_type(op), SEXP_TWO, sexp_make_fixnum(SEXP_FIXNUM)); sexp_vector_set(sexp_opcode_argn_type(op), SEXP_THREE, sexp_make_fixnum(SEXP_FIXNUM)); } op = sexp_define_foreign(ctx, env, "timeval-microseconds", 1, (sexp_proc1)sexp_timeval_get_tv_usec); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timeval_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_timeval_type_obj))) sexp_vector_set(sexp_type_getters(sexp_timeval_type_obj), SEXP_ONE, op); op = sexp_define_foreign(ctx, env, "timeval-seconds", 1, (sexp_proc1)sexp_timeval_get_tv_sec); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timeval_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_timeval_type_obj))) sexp_vector_set(sexp_type_getters(sexp_timeval_type_obj), SEXP_ZERO, op); op = sexp_define_foreign(ctx, env, "make-timeval", 2, (sexp_proc1)sexp_make_timeval_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timeval_type_obj)); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "timezone-dst-time", 1, (sexp_proc1)sexp_timezone_get_tz_dsttime); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timezone_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_timezone_type_obj))) sexp_vector_set(sexp_type_getters(sexp_timezone_type_obj), SEXP_ONE, op); op = sexp_define_foreign(ctx, env, "timezone-offset", 1, (sexp_proc1)sexp_timezone_get_tz_minuteswest); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timezone_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_timezone_type_obj))) sexp_vector_set(sexp_type_getters(sexp_timezone_type_obj), SEXP_ZERO, op); op = sexp_define_foreign(ctx, env, "time->string", 1, (sexp_proc1)sexp_time_3e_string_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_CHAR); } op = sexp_define_foreign(ctx, env, "seconds->string", 1, (sexp_proc1)sexp_seconds_3e_string_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_CHAR); } op = sexp_define_foreign(ctx, env, "time->seconds", 1, (sexp_proc1)sexp_time_3e_seconds_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } op = sexp_define_foreign(ctx, env, "seconds->time", 1, (sexp_proc1)sexp_seconds_3e_time_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_tm_type_obj)); } op = sexp_define_foreign_opt(ctx, env, "set-time-of-day!", 2, (sexp_proc1)sexp_set_time_of_day_x_stub, SEXP_FALSE); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timeval_type_obj)); sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timezone_type_obj)); } op = sexp_define_foreign(ctx, env, "get-time-of-day", 0, (sexp_proc1)sexp_get_time_of_day_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timeval_type_obj)); sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_timezone_type_obj)); } op = sexp_define_foreign(ctx, env, "current-seconds", 0, (sexp_proc1)sexp_current_seconds_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); } sexp_gc_release3(ctx); return SEXP_VOID; }
sexp sexp_lookup_named_type (sexp ctx, sexp env, const char *name) { sexp t = sexp_env_ref(env, sexp_intern(ctx, name, -1), SEXP_FALSE); return sexp_make_fixnum((sexp_typep(t)) ? sexp_type_tag(t) : -1); }
void sexp_build_srv (sexp ctx, sexp_plan9_srv s, sexp ls) { s->context = ctx; s->auth = s->attach = s->walk = s->walk1 = s->clone = s->open = s->create = s->remove = s->read = s->write = s->stat = s->wstat = s->flush = s->destroyfid = s->destroyreq = s->end = SEXP_FALSE; for ( ; sexp_pairp(ls) && sexp_pairp(sexp_cdr(ls)); ls=sexp_cddr(ls)) { if (sexp_car(ls) == sexp_intern(ctx, "auth:", -1)) { s->auth = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "attach:", -1)) { s->attach = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "walk:", -1)) { s->walk = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "walk1:", -1)) { s->walk1 = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "clone:", -1)) { s->clone = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "open:", -1)) { s->open = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "create:", -1)) { s->create = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "remove:", -1)) { s->remove = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "read:", -1)) { s->read = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "write:", -1)) { s->write = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "stat:", -1)) { s->stat = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "wstat:", -1)) { s->wstat = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "flush:", -1)) { s->flush = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "destroyfid:", -1)) { s->destroyfid = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "destroyreq:", -1)) { s->destroyreq = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "end:", -1)) { s->end = sexp_cadr(ls); } } }
sexp sexp_scheduler (sexp ctx, sexp self, sexp_sint_t n, sexp root_thread) { int i, k; struct timeval tval; struct pollfd *pfds; useconds_t usecs = 0; sexp res, ls1, ls2, evt, runner, paused, front, pollfds; sexp_gc_var1(tmp); sexp_gc_preserve1(ctx, tmp); front = sexp_global(ctx, SEXP_G_THREADS_FRONT); paused = sexp_global(ctx, SEXP_G_THREADS_PAUSED); /* check signals */ if (sexp_global(ctx, SEXP_G_THREADS_SIGNALS) != SEXP_ZERO) { runner = sexp_global(ctx, SEXP_G_THREADS_SIGNAL_RUNNER); if (! sexp_contextp(runner)) { /* ensure the runner exists */ if (sexp_envp(runner)) { tmp = sexp_env_cell(runner, (tmp=sexp_intern(ctx, "signal-runner", -1)), 0); if (sexp_pairp(tmp) && sexp_procedurep(sexp_cdr(tmp))) { runner = sexp_make_thread(ctx, self, 2, sexp_cdr(tmp), SEXP_FALSE); sexp_global(ctx, SEXP_G_THREADS_SIGNAL_RUNNER) = runner; sexp_thread_start(ctx, self, 1, runner); if (!sexp_pairp(front)) front = sexp_global(ctx, SEXP_G_THREADS_FRONT); } } } else if (sexp_context_waitp(runner)) { /* wake it if it's sleeping */ sexp_context_waitp(runner) = 0; sexp_thread_start(ctx, self, 1, runner); } } /* check blocked fds */ pollfds = sexp_global(ctx, SEXP_G_THREADS_POLL_FDS); if (sexp_pollfdsp(ctx, pollfds) && sexp_pollfds_num_fds(pollfds) > 0) { pfds = sexp_pollfds_fds(pollfds); k = poll(sexp_pollfds_fds(pollfds), sexp_pollfds_num_fds(pollfds), 0); for (i=sexp_pollfds_num_fds(pollfds)-1; i>=0 && k>0; --i) { if (pfds[i].revents > 0) { /* free all threads blocked on this fd */ k--; /* maybe unblock the current thread */ evt = sexp_context_event(ctx); if ((sexp_portp(evt) && (sexp_port_fileno(evt) == pfds[i].fd)) || (sexp_fixnump(evt) && (sexp_unbox_fixnum(evt) == pfds[i].fd))) { sexp_context_waitp(ctx) = 0; sexp_context_timeoutp(ctx) = 0; sexp_context_event(ctx) = SEXP_FALSE; } /* maybe unblock paused threads */ for (ls1=SEXP_NULL, ls2=paused; sexp_pairp(ls2); ) { /* TODO: distinguish input and output on the same fd? */ evt = sexp_context_event(sexp_car(ls2)); if ((sexp_portp(evt) && sexp_port_fileno(evt) == pfds[i].fd) || (sexp_fixnump(evt) && sexp_unbox_fixnum(evt) == pfds[i].fd)) { sexp_context_waitp(sexp_car(ls2)) = 0; sexp_context_timeoutp(sexp_car(ls2)) = 0; sexp_context_event(sexp_car(ls2)) = SEXP_FALSE; if (ls1==SEXP_NULL) sexp_global(ctx, SEXP_G_THREADS_PAUSED) = paused = sexp_cdr(ls2); else sexp_cdr(ls1) = sexp_cdr(ls2); tmp = sexp_cdr(ls2); sexp_cdr(ls2) = SEXP_NULL; if (sexp_car(ls2) != ctx) { if (! sexp_pairp(sexp_global(ctx, SEXP_G_THREADS_BACK))) { sexp_global(ctx, SEXP_G_THREADS_FRONT) = front = ls2; } else { sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = ls2; } sexp_global(ctx, SEXP_G_THREADS_BACK) = ls2; } ls2 = tmp; } else { ls1 = ls2; ls2 = sexp_cdr(ls2); } } if (i < (sexp_pollfds_num_fds(pollfds) - 1)) { pfds[i] = pfds[sexp_pollfds_num_fds(pollfds) - 1]; } sexp_pollfds_num_fds(pollfds) -= 1; } } } /* if we've terminated, check threads joining us */ if (sexp_context_refuel(ctx) <= 0) { for (ls1=SEXP_NULL, ls2=paused; sexp_pairp(ls2); ) { if (sexp_context_event(sexp_car(ls2)) == ctx) { sexp_context_waitp(sexp_car(ls2)) = 0; sexp_context_timeoutp(sexp_car(ls2)) = 0; if (ls1==SEXP_NULL) sexp_global(ctx, SEXP_G_THREADS_PAUSED) = paused = sexp_cdr(ls2); else sexp_cdr(ls1) = sexp_cdr(ls2); tmp = sexp_cdr(ls2); sexp_cdr(ls2) = SEXP_NULL; if (! sexp_pairp(sexp_global(ctx, SEXP_G_THREADS_BACK))) { sexp_global(ctx, SEXP_G_THREADS_FRONT) = front = ls2; } else { sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = ls2; } sexp_global(ctx, SEXP_G_THREADS_BACK) = ls2; ls2 = tmp; } else { ls1 = ls2; ls2 = sexp_cdr(ls2); } } } /* check timeouts */ if (sexp_pairp(paused)) { if (gettimeofday(&tval, NULL) == 0) { ls1 = SEXP_NULL; ls2 = paused; while (sexp_pairp(ls2) && sexp_context_before(sexp_car(ls2), tval)) { sexp_context_timeoutp(sexp_car(ls2)) = 1; sexp_context_waitp(sexp_car(ls2)) = 0; ls1 = ls2; ls2 = sexp_cdr(ls2); } if (sexp_pairp(ls1)) { sexp_cdr(ls1) = SEXP_NULL; if (! sexp_pairp(sexp_global(ctx, SEXP_G_THREADS_BACK))) { sexp_global(ctx, SEXP_G_THREADS_FRONT) = front = paused; } else { sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = paused; } sexp_global(ctx, SEXP_G_THREADS_BACK) = ls1; sexp_global(ctx, SEXP_G_THREADS_PAUSED) = paused = ls2; } } } /* dequeue next thread */ if (sexp_pairp(front)) { res = sexp_car(front); if ((sexp_context_refuel(ctx) <= 0) || sexp_context_waitp(ctx)) { /* orig ctx is either terminated or paused */ sexp_global(ctx, SEXP_G_THREADS_FRONT) = sexp_cdr(front); if (! sexp_pairp(sexp_cdr(front))) sexp_global(ctx, SEXP_G_THREADS_BACK) = SEXP_NULL; if (sexp_context_refuel(ctx) > 0 && sexp_not(sexp_memq(ctx, ctx, paused))) sexp_insert_timed(ctx, ctx, SEXP_FALSE); paused = sexp_global(ctx, SEXP_G_THREADS_PAUSED); } else { /* swap with front of queue */ sexp_car(sexp_global(ctx, SEXP_G_THREADS_FRONT)) = ctx; /* rotate front of queue to back */ sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = sexp_global(ctx, SEXP_G_THREADS_FRONT); sexp_global(ctx, SEXP_G_THREADS_FRONT) = sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_FRONT)); sexp_global(ctx, SEXP_G_THREADS_BACK) = sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)); sexp_cdr(sexp_global(ctx, SEXP_G_THREADS_BACK)) = SEXP_NULL; } } else { /* no threads to dequeue */ res = ctx; /* prefer a thread we can wait on instead of spinning */ if (sexp_context_refuel(ctx) <= 0) { for (ls1=paused; sexp_pairp(ls1); ls1=sexp_cdr(ls1)) { evt = sexp_context_event(sexp_car(ls1)); if (sexp_fixnump(evt) || sexp_portp(evt)) { res = sexp_car(ls1); break; } } } } if (sexp_context_waitp(res)) { /* the only thread available was waiting */ if (sexp_pairp(paused) && sexp_context_before(sexp_car(paused), sexp_context_timeval(res))) { tmp = res; res = sexp_car(paused); paused = sexp_global(ctx, SEXP_G_THREADS_PAUSED) = sexp_cdr(paused); if (sexp_not(sexp_memq(ctx, tmp, paused))) sexp_insert_timed(ctx, tmp, tmp); } else { sexp_delete_list(ctx, SEXP_G_THREADS_PAUSED, res); } paused = sexp_global(ctx, SEXP_G_THREADS_PAUSED); usecs = 0; if ((sexp_context_timeval(res).tv_sec == 0) && (sexp_context_timeval(res).tv_usec == 0)) { /* no timeout, wait for default 10ms */ usecs = 10*1000; } else { /* wait until the next timeout */ gettimeofday(&tval, NULL); if (tval.tv_sec <= sexp_context_timeval(res).tv_sec) { usecs = (sexp_context_timeval(res).tv_sec - tval.tv_sec) * 1000000; if (tval.tv_usec < sexp_context_timeval(res).tv_usec || usecs > 0) usecs += sexp_context_timeval(res).tv_usec - tval.tv_usec; } } /* take a nap to avoid busy looping */ usleep(usecs); sexp_context_waitp(res) = 0; sexp_context_timeoutp(res) = 1; } sexp_gc_release1(ctx); return res; }
sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, const sexp_abi_identifier_t abi) { sexp sexp_player_type_obj; sexp_gc_var3(name, tmp, op); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) return SEXP_ABI_ERROR; sexp_gc_preserve3(ctx, name, tmp, op); name = sexp_c_string(ctx, "player", -1); sexp_player_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type); tmp = sexp_string_to_symbol(ctx, name); sexp_env_define(ctx, env, tmp, sexp_player_type_obj); sexp_type_slots(sexp_player_type_obj) = SEXP_NULL; sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "y", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "x", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "hp_max", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "hp", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "exp", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "level", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "race", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "gender", -1)); sexp_push(ctx, sexp_type_slots(sexp_player_type_obj), sexp_intern(ctx, "name", -1)); sexp_type_getters(sexp_player_type_obj) = sexp_make_vector(ctx, SEXP_NINE, SEXP_FALSE); sexp_type_setters(sexp_player_type_obj) = sexp_make_vector(ctx, SEXP_NINE, SEXP_FALSE); tmp = sexp_make_type_predicate(ctx, name, sexp_player_type_obj); name = sexp_intern(ctx, "player?", 7); sexp_env_define(ctx, env, name, tmp); op = sexp_define_foreign(ctx, env, "player-y", 1, (sexp_proc1)sexp_player_get_y); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_EIGHT, op); op = sexp_define_foreign(ctx, env, "player-x", 1, (sexp_proc1)sexp_player_get_x); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_SEVEN, op); op = sexp_define_foreign(ctx, env, "player-hp-max", 1, (sexp_proc1)sexp_player_get_hp_max); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_SIX, op); op = sexp_define_foreign(ctx, env, "player-hp", 1, (sexp_proc1)sexp_player_get_hp); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_FIVE, op); op = sexp_define_foreign(ctx, env, "player-exp", 1, (sexp_proc1)sexp_player_get_exp); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_FOUR, op); op = sexp_define_foreign(ctx, env, "player-level", 1, (sexp_proc1)sexp_player_get_level); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_THREE, op); op = sexp_define_foreign(ctx, env, "player-race", 1, (sexp_proc1)sexp_player_get_race); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_TWO, op); op = sexp_define_foreign(ctx, env, "player-gender", 1, (sexp_proc1)sexp_player_get_gender); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_ONE, op); op = sexp_define_foreign(ctx, env, "player-name", 1, (sexp_proc1)sexp_player_get_name); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_player_type_obj))) sexp_vector_set(sexp_type_getters(sexp_player_type_obj), SEXP_ZERO, op); op = sexp_define_foreign(ctx, env, "random_uint_range", 2, (sexp_proc1)sexp_random_uint_range_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "random_uint", 1, (sexp_proc1)sexp_random_uint_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "random_reseed_time", 0, (sexp_proc1)sexp_random_reseed_time_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = SEXP_VOID; } op = sexp_define_foreign(ctx, env, "random_reseed", 1, (sexp_proc1)sexp_random_reseed_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = SEXP_VOID; sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "random_init", 1, (sexp_proc1)sexp_random_init_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = SEXP_VOID; sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "player_move", 3, (sexp_proc1)sexp_player_move_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = SEXP_VOID; sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg3_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "player_delete", 1, (sexp_proc1)sexp_player_delete_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = SEXP_VOID; sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } op = sexp_define_foreign(ctx, env, "player_new", 0, (sexp_proc1)sexp_player_new_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_player_type_obj)); } op = sexp_define_foreign(ctx, env, "sleep", 1, (sexp_proc1)sexp_sleep_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = SEXP_VOID; sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } sexp_gc_release3(ctx); return SEXP_VOID; }
sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, const sexp_abi_identifier_t abi) { sexp sexp_stat_type_obj; sexp sexp_dirent_type_obj; sexp sexp_DIR_type_obj; sexp_gc_var3(name, tmp, op); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) return SEXP_ABI_ERROR; sexp_gc_preserve3(ctx, name, tmp, op); name = sexp_intern(ctx, "lock/unlock", 11); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, LOCK_UN)); name = sexp_intern(ctx, "lock/non-blocking", 17); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, LOCK_NB)); name = sexp_intern(ctx, "lock/exclusive", 14); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, LOCK_EX)); name = sexp_intern(ctx, "lock/shared", 11); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, LOCK_SH)); name = sexp_intern(ctx, "access/execute", 14); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, X_OK)); name = sexp_intern(ctx, "access/write", 12); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, W_OK)); name = sexp_intern(ctx, "access/read", 11); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, R_OK)); name = sexp_intern(ctx, "open/non-block", 14); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_NONBLOCK)); name = sexp_intern(ctx, "open/append", 11); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_APPEND)); name = sexp_intern(ctx, "open/truncate", 13); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_TRUNC)); name = sexp_intern(ctx, "open/exclusive", 14); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_EXCL)); name = sexp_intern(ctx, "open/create", 11); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_CREAT)); name = sexp_intern(ctx, "open/read-write", 15); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_RDWR)); name = sexp_intern(ctx, "open/write", 10); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_WRONLY)); name = sexp_intern(ctx, "open/read", 9); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, O_RDONLY)); name = sexp_intern(ctx, "perm/others-execute", 19); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IXOTH)); name = sexp_intern(ctx, "perm/others-write", 17); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IWOTH)); name = sexp_intern(ctx, "perm/others-read", 16); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IROTH)); name = sexp_intern(ctx, "perm/group-execute", 18); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IXGRP)); name = sexp_intern(ctx, "perm/group-write", 16); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IWGRP)); name = sexp_intern(ctx, "perm/group-read", 15); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IRGRP)); name = sexp_intern(ctx, "perm/user-execute", 17); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IXUSR)); name = sexp_intern(ctx, "perm/user-write", 15); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IWUSR)); name = sexp_intern(ctx, "perm/user-read", 14); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IRUSR)); name = sexp_intern(ctx, "file/sticky", 11); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_ISVTX)); name = sexp_intern(ctx, "file/sgid", 9); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_ISGID)); name = sexp_intern(ctx, "file/suid", 9); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_ISUID)); name = sexp_intern(ctx, "file/fifo", 9); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IFIFO)); name = sexp_intern(ctx, "file/character", 14); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IFCHR)); name = sexp_intern(ctx, "file/directory", 14); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IFDIR)); name = sexp_intern(ctx, "file/block", 10); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IFBLK)); name = sexp_intern(ctx, "file/regular", 12); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IFREG)); name = sexp_intern(ctx, "file/link", 9); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IFLNK)); name = sexp_intern(ctx, "file/socket", 11); sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, S_IFSOCK)); name = sexp_c_string(ctx, "stat", -1); sexp_stat_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type); tmp = sexp_string_to_symbol(ctx, name); sexp_env_define(ctx, env, tmp, sexp_stat_type_obj); sexp_type_slots(sexp_stat_type_obj) = SEXP_NULL; sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_ctime", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_mtime", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_atime", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_blocks", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_blksize", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_size", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_rdev", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_gid", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_uid", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_nlink", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_mode", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_ino", -1)); sexp_push(ctx, sexp_type_slots(sexp_stat_type_obj), sexp_intern(ctx, "st_dev", -1)); sexp_type_getters(sexp_stat_type_obj) = sexp_make_vector(ctx, sexp_make_fixnum(13), SEXP_FALSE); sexp_type_setters(sexp_stat_type_obj) = sexp_make_vector(ctx, sexp_make_fixnum(13), SEXP_FALSE); tmp = sexp_make_type_predicate(ctx, name, sexp_stat_type_obj); name = sexp_intern(ctx, "stat?", 5); sexp_env_define(ctx, env, name, tmp); name = sexp_c_string(ctx, "dirent", -1); sexp_dirent_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type); tmp = sexp_string_to_symbol(ctx, name); sexp_env_define(ctx, env, tmp, sexp_dirent_type_obj); sexp_type_slots(sexp_dirent_type_obj) = SEXP_NULL; sexp_push(ctx, sexp_type_slots(sexp_dirent_type_obj), sexp_intern(ctx, "d_name", -1)); sexp_type_getters(sexp_dirent_type_obj) = sexp_make_vector(ctx, SEXP_ONE, SEXP_FALSE); sexp_type_setters(sexp_dirent_type_obj) = sexp_make_vector(ctx, SEXP_ONE, SEXP_FALSE); name = sexp_c_string(ctx, "DIR", -1); sexp_DIR_type_obj = sexp_register_c_type(ctx, name, sexp_closedir_stub); tmp = sexp_string_to_symbol(ctx, name); sexp_env_define(ctx, env, tmp, sexp_DIR_type_obj); op = sexp_define_foreign(ctx, env, "closedir", 1, (sexp_proc1)sexp_closedir_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = SEXP_VOID; sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_DIR_type_obj)); } op = sexp_define_foreign(ctx, env, "dirent-name", 1, (sexp_proc1)sexp_dirent_get_d_name); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_dirent_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_dirent_type_obj))) sexp_vector_set(sexp_type_getters(sexp_dirent_type_obj), SEXP_ZERO, op); op = sexp_define_foreign(ctx, env, "stat-ctime", 1, (sexp_proc1)sexp_stat_get_st_ctime); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), sexp_make_fixnum(12), op); op = sexp_define_foreign(ctx, env, "stat-mtime", 1, (sexp_proc1)sexp_stat_get_st_mtime); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), sexp_make_fixnum(11), op); op = sexp_define_foreign(ctx, env, "stat-atime", 1, (sexp_proc1)sexp_stat_get_st_atime); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_TEN, op); op = sexp_define_foreign(ctx, env, "stat-blocks", 1, (sexp_proc1)sexp_stat_get_st_blocks); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_NINE, op); op = sexp_define_foreign(ctx, env, "stat-blksize", 1, (sexp_proc1)sexp_stat_get_st_blksize); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_EIGHT, op); op = sexp_define_foreign(ctx, env, "stat-size", 1, (sexp_proc1)sexp_stat_get_st_size); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_SEVEN, op); op = sexp_define_foreign(ctx, env, "stat-rdev", 1, (sexp_proc1)sexp_stat_get_st_rdev); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_SIX, op); op = sexp_define_foreign(ctx, env, "stat-gid", 1, (sexp_proc1)sexp_stat_get_st_gid); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_FIVE, op); op = sexp_define_foreign(ctx, env, "stat-uid", 1, (sexp_proc1)sexp_stat_get_st_uid); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_FOUR, op); op = sexp_define_foreign(ctx, env, "stat-nlinks", 1, (sexp_proc1)sexp_stat_get_st_nlink); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_THREE, op); op = sexp_define_foreign(ctx, env, "stat-mode", 1, (sexp_proc1)sexp_stat_get_st_mode); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_TWO, op); op = sexp_define_foreign(ctx, env, "stat-ino", 1, (sexp_proc1)sexp_stat_get_st_ino); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_ONE, op); op = sexp_define_foreign(ctx, env, "stat-dev", 1, (sexp_proc1)sexp_stat_get_st_dev); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } if (sexp_vectorp(sexp_type_getters(sexp_stat_type_obj))) sexp_vector_set(sexp_type_getters(sexp_stat_type_obj), SEXP_ZERO, op); op = sexp_define_foreign(ctx, env, "is-a-tty?", 1, (sexp_proc1)sexp_is_a_tty_p_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); } op = sexp_define_foreign(ctx, env, "chmod", 2, (sexp_proc1)sexp_chmod_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "file-lock", 2, (sexp_proc1)sexp_file_lock_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "file-access", 2, (sexp_proc1)sexp_file_access_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "file-truncate", 2, (sexp_proc1)sexp_file_truncate_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "set-file-descriptor-status!", 2, (sexp_proc1)sexp_set_file_descriptor_status_x_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg3_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "get-file-descriptor-status", 1, (sexp_proc1)sexp_get_file_descriptor_status_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "set-file-descriptor-flags!", 2, (sexp_proc1)sexp_set_file_descriptor_flags_x_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg3_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "get-file-descriptor-flags", 1, (sexp_proc1)sexp_get_file_descriptor_flags_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign_opt(ctx, env, "make-fifo", 2, (sexp_proc1)sexp_make_fifo_stub, sexp_make_integer(ctx, 436)); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "open-pipe", 0, (sexp_proc1)sexp_open_pipe_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FILENO); } op = sexp_define_foreign_opt(ctx, env, "open", 3, (sexp_proc1)sexp_open_stub, sexp_make_integer(ctx, 420)); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FILENO); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg3_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "close-file-descriptor", 1, (sexp_proc1)sexp_close_file_descriptor_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FILENO); } op = sexp_define_foreign(ctx, env, "duplicate-file-descriptor-to", 2, (sexp_proc1)sexp_duplicate_file_descriptor_to_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FILENO); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FILENO); } op = sexp_define_foreign(ctx, env, "duplicate-file-descriptor", 1, (sexp_proc1)sexp_duplicate_file_descriptor_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FILENO); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FILENO); } op = sexp_define_foreign(ctx, env, "readdir", 1, (sexp_proc1)sexp_readdir_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_dirent_type_obj)); sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_DIR_type_obj)); } op = sexp_define_foreign(ctx, env, "opendir", 1, (sexp_proc1)sexp_opendir_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_DIR_type_obj)); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); } op = sexp_define_foreign(ctx, env, "delete-directory", 1, (sexp_proc1)sexp_delete_directory_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); } op = sexp_define_foreign_opt(ctx, env, "create-directory", 2, (sexp_proc1)sexp_create_directory_stub, sexp_make_integer(ctx, 509)); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "change-directory", 1, (sexp_proc1)sexp_change_directory_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); } op = sexp_define_foreign(ctx, env, "current-directory", 0, (sexp_proc1)sexp_current_directory_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_CHAR); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "rename-file", 2, (sexp_proc1)sexp_rename_file_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_STRING); } op = sexp_define_foreign(ctx, env, "symbolic-link-file", 2, (sexp_proc1)sexp_symbolic_link_file_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_STRING); } op = sexp_define_foreign(ctx, env, "link-file", 2, (sexp_proc1)sexp_link_file_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_STRING); } op = sexp_define_foreign(ctx, env, "%delete-file", 1, (sexp_proc1)sexp_25_delete_file_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); } op = sexp_define_foreign(ctx, env, "readlink", 3, (sexp_proc1)sexp_readlink_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg3_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "file-link-status", 1, (sexp_proc1)sexp_file_link_status_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } op = sexp_define_foreign(ctx, env, "fstat", 1, (sexp_proc1)sexp_fstat_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } op = sexp_define_foreign(ctx, env, "stat", 1, (sexp_proc1)sexp_stat_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING); sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_stat_type_obj)); } op = sexp_define_foreign(ctx, env, "S_ISSOCK", 1, (sexp_proc1)sexp_S_ISSOCK_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "S_ISLNK", 1, (sexp_proc1)sexp_S_ISLNK_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "S_ISFIFO", 1, (sexp_proc1)sexp_S_ISFIFO_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "S_ISBLK", 1, (sexp_proc1)sexp_S_ISBLK_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "S_ISCHR", 1, (sexp_proc1)sexp_S_ISCHR_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "S_ISDIR", 1, (sexp_proc1)sexp_S_ISDIR_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } op = sexp_define_foreign(ctx, env, "S_ISREG", 1, (sexp_proc1)sexp_S_ISREG_stub); if (sexp_opcodep(op)) { sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN); sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM); } sexp_gc_release3(ctx); return SEXP_VOID; }
void run_main (int argc, char **argv) { char *arg, *impmod, *p; sexp out=SEXP_FALSE, env=NULL, ctx=NULL; sexp_sint_t i, j, len, quit=0, print=0, init_loaded=0, fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS; sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE; sexp_gc_var2(tmp, args); args = SEXP_NULL; /* parse options */ for (i=1; i < argc && argv[i][0] == '-'; i++) { switch (argv[i][1]) { case 'e': case 'p': load_init(); print = (argv[i][1] == 'p'); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('e', arg); tmp = check_exception(ctx, sexp_eval_string(ctx, arg, -1, env)); if (print) { if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write(ctx, tmp, out); sexp_write_char(ctx, '\n', out); } quit = 1; break; case 'l': load_init(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('l', arg); check_exception(ctx, sexp_load_module_file(ctx, arg, env)); break; case 'm': load_init(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('m', arg); len = strlen(arg)+strlen(sexp_import_prefix)+strlen(sexp_import_suffix); impmod = (char*) malloc(len+1); strcpy(impmod, sexp_import_prefix); strcpy(impmod+strlen(sexp_import_prefix), arg); strcpy(impmod+len-+strlen(sexp_import_suffix), sexp_import_suffix); impmod[len] = '\0'; for (p=impmod; *p; p++) if (*p == '.') *p=' '; check_exception(ctx, sexp_eval_string(ctx, impmod, -1, env)); free(impmod); break; case 'q': init_context(); if (! init_loaded++) sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0); break; case 'A': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('A', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_TRUE); break; case 'I': init_context(); arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('I', arg); sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_FALSE); break; case '-': i++; goto done_options; case 'h': arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2); check_nonull_arg('h', arg); heap_size = strtoul(arg, &arg, 0); if (sexp_isalpha(*arg)) heap_size *= multiplier(*arg++); if (*arg == '/') { heap_max_size = strtoul(arg+1, &arg, 0); if (sexp_isalpha(*arg)) heap_max_size *= multiplier(*arg++); } break; case 'V': load_init(); if (! sexp_oportp(out)) out = sexp_eval_string(ctx, "(current-output-port)", -1, env); sexp_write_string(ctx, sexp_version_string, out); tmp = sexp_env_ref(env, sexp_intern(ctx, "*features*", -1), SEXP_NULL); sexp_write(ctx, tmp, out); sexp_newline(ctx, out); return; #if SEXP_USE_FOLD_CASE_SYMS case 'f': fold_case = 1; if (ctx) sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE; break; #endif default: fprintf(stderr, "unknown option: %s\n", argv[i]); exit_failure(); } } done_options: if (! quit) { load_init(); if (i < argc) for (j=argc-1; j>i; j--) args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[j],-1), args); else args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[0],-1), args); sexp_env_define(ctx, env, sexp_intern(ctx, sexp_argv_symbol, -1), args); sexp_eval_string(ctx, sexp_argv_proc, -1, env); if (i < argc) { /* script usage */ sexp_context_tracep(ctx) = 1; check_exception(ctx, sexp_load(ctx, tmp=sexp_c_string(ctx, argv[i], -1), env)); tmp = sexp_intern(ctx, "main", -1); tmp = sexp_env_ref(env, tmp, SEXP_FALSE); if (sexp_procedurep(tmp)) { args = sexp_list1(ctx, args); check_exception(ctx, sexp_apply(ctx, tmp, args)); } } else { repl(ctx, env); } } sexp_gc_release2(ctx); sexp_destroy_context(ctx); }