memptr func_true(memptr func_expr) { if (num_nodes(func_expr) != 2) { #ifdef DEBUG printf("15\n"); #endif ERROR(ERROR_TRUE, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); return NOT_FOUND; } #ifdef EXTENDED_SECURITY memptr local_security = safe_allocate_cons(); cons_pool[local_security].carKind = NIL; cons_pool[local_security].cdrKind = NIL; #endif memptr param = resolve_expr(cons_pool[cons_pool[func_expr].cdr].car); #ifdef EXTENDED_SECURITY cons_pool[local_security].car = param; cons_pool[local_security].carKind = CONS; #endif if (type(param) == TYPE_OBJECT) { memptr lu = object_lookup(param, cons_pool[func_expr].car); if (lu == NOT_FOUND) { param = object_lookup(param, core_symbol); } else { return resolve_func_expr(func_expr, param, lu, true); } } return ((param == t) ? t : nil); }
void attack(void) { object_t *objp = (object_t *)random(); object_t obj = (object_t)random(); char *name = (char *)random(); void *msg = (void *)random(); size_t size = (size_t)random(); task_t self = task_self(); void *addr = (void *)random(); int attr = random() & 7; thread_t t = (thread_t)random(); thread_t *tp = (thread_t *)random(); object_create(NULL, NULL); object_create(NULL, objp); object_create(name, NULL); object_create(name, objp); object_destroy(0); object_destroy(obj); object_lookup(NULL, objp); object_lookup(name, NULL); object_lookup(name, objp); msg_send(0, msg, size); msg_send(obj, NULL, size); msg_send(obj, msg, 0); msg_send(0, msg, 0); msg_send(0, NULL, size); msg_send(obj, msg, size); msg_receive(0, msg, size); msg_receive(obj, NULL, size); msg_receive(obj, msg, 0); msg_receive(0, msg, 0); msg_receive(0, NULL, size); msg_receive(obj, msg, size); msg_reply(0, msg, size); msg_reply(obj, NULL, size); msg_reply(obj, msg, 0); msg_reply(0, msg, 0); msg_reply(0, NULL, size); msg_reply(obj, msg, size); vm_allocate(self, addr, size, 1); vm_allocate(self, &addr, size, 1); vm_free(self, addr); vm_attribute(self, addr, attr); vm_map(self, addr, size, &addr); thread_create(self, tp); thread_suspend(t); thread_terminate(t); }
memptr func_cdr(memptr func_expr) { if (num_nodes(func_expr) != 2) { #ifdef DEBUG printf("12\n"); #endif ERROR(ERROR_CDR, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); return NOT_FOUND; } memptr local_security = safe_allocate_cons(); cons_pool[local_security].carKind = NIL; cons_pool[local_security].cdrKind = NIL; memptr param = resolve_expr(cons_pool[cons_pool[func_expr].cdr].car); cons_pool[local_security].car = param; cons_pool[local_security].carKind = CONS; while (true) { Type param_type = type(param); if (param_type == TYPE_CONS) { return cons_pool[param].cdr; } else if (param_type == TYPE_STRING) { memptr result; if ((cons_pool[param].cdr < 0) || (string_length(param) == 1)) { result = nil; } else { result = allocate_cons(); cons_pool[result].car = cons_pool[param].car; cons_pool[result].cdr = cons_pool[param].cdr + 1; cons_pool[result].carKind = STRING; cons_pool[result].cdrKind = INTEGER; } return result; } else if (param_type == TYPE_OBJECT) { memptr lu = object_lookup(param, cons_pool[func_expr].car); if (lu == NOT_FOUND) { param = object_lookup(param, core_symbol); continue; } else { return resolve_func_expr(func_expr, param, lu, true); } } break; } #ifdef DEBUG printf("13\n"); #endif ERROR(ERROR_CDR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); return NOT_FOUND; }
static bool supps(memptr value, memptr symbol) { bool s = false; Type value_type = type(value); switch (value_type) { case TYPE_CONS: s = (SUPPORTS(4) || SUPPORTS(5) || SUPPORTS(6) || SUPPORTS(7) || SUPPORTS(8) || SUPPORTS(9) || SUPPORTS(10) || SUPPORTS(11) || SUPPORTS(18) || SUPPORTS(19)); break; case TYPE_INTEGER: s = (SUPPORTS(0) || SUPPORTS(1) || SUPPORTS(2) || SUPPORTS(3) || SUPPORTS(4) || SUPPORTS(5) || SUPPORTS(6) || SUPPORTS(7) || SUPPORTS(10) || SUPPORTS(11) || SUPPORTS(18) || SUPPORTS(19)); break; case TYPE_NATIVE_FUNCTION: s = (SUPPORTS(4) || SUPPORTS(5) || SUPPORTS(6) || SUPPORTS(7) || SUPPORTS(10) || SUPPORTS(11) || SUPPORTS(18) || SUPPORTS(19)); break; case TYPE_NIL_TRUE: s = (SUPPORTS(4) || SUPPORTS(5) || SUPPORTS(6) || SUPPORTS(7) || SUPPORTS(10) || SUPPORTS(11) || SUPPORTS(15) || SUPPORTS(16) || SUPPORTS(17) || SUPPORTS(18) || SUPPORTS(19)); break; case TYPE_STRING: s = (SUPPORTS(4) || SUPPORTS(5) || SUPPORTS(6) || SUPPORTS(7) || SUPPORTS(8) || SUPPORTS(9) || SUPPORTS(10) || SUPPORTS(11) || SUPPORTS(18) || SUPPORTS(19)); break; case TYPE_USER_FUNCTION: s = (SUPPORTS(4) || SUPPORTS(5) || SUPPORTS(6) || SUPPORTS(7) || SUPPORTS(10) || SUPPORTS(11) || SUPPORTS(18) || SUPPORTS(19)); break; case TYPE_OBJECT: s = (object_lookup(value, symbol) != NOT_FOUND) || supps(object_lookup(value, core_symbol), symbol); break; default: s = false; break; } return s; }
int main(int argc, char *argv[]) { int i = 0; int found = 0; if (argc < 2) { pmctrl_help(1, NULL); exit(1); } if (object_lookup("!pow", &powobj) != 0) { fprintf(stderr, "No power server found\n"); exit(1); } while (cmdtab[i].cmd != NULL) { if (!strncmp(argv[1], cmdtab[i].cmd, LINE_MAX)) { (cmdtab[i].func)(argc, argv); found = 1; break; } i++; } if (!found) pmctrl_help(1, NULL); exit(1); }
memptr func_list(memptr func_expr) { if (num_nodes(func_expr) == 1) { return nil; } memptr current_node, current_param, current_dup_node = safe_allocate_cons(), base = current_dup_node; cons_pool[current_dup_node].carKind = NIL; cons_pool[current_dup_node].cdrKind = NIL; current_node = cons_pool[func_expr].cdr; current_param = resolve_expr(cons_pool[current_node].car); if (current_param == NOT_FOUND) { #ifdef DEBUG printf("29\n"); #endif ERROR(ERROR_LIST, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); return NOT_FOUND; } else if (type(current_param) == TYPE_OBJECT) { memptr lu = object_lookup(current_param, cons_pool[func_expr].car); if (lu != NOT_FOUND) { #ifdef EXTENDED_SECURITY memptr local_security = safe_allocate_cons(); cons_pool[local_security].car = current_param; cons_pool[local_security].carKind = CONS; cons_pool[local_security].cdrKind = NIL; #endif return resolve_func_expr(func_expr, current_param, lu, true); } } cons_pool[current_dup_node].car = current_param; cons_pool[current_dup_node].carKind = CONS; while (cons_pool[current_node].cdrKind == CONS) { current_node = cons_pool[current_node].cdr; cons_pool[current_dup_node].cdr = allocate_cons(); cons_pool[current_dup_node].cdrKind = CONS; current_dup_node = cons_pool[current_dup_node].cdr; cons_pool[current_dup_node].carKind = NIL; cons_pool[current_dup_node].cdrKind = NIL; current_param = resolve_expr(cons_pool[current_node].car); if (current_param == NOT_FOUND) { #ifdef DEBUG printf("30\n"); #endif ERROR(ERROR_LIST, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); return NOT_FOUND; } cons_pool[current_dup_node].car = current_param; cons_pool[current_dup_node].carKind = CONS; } cons_pool[current_dup_node].cdrKind = CONS; cons_pool[current_dup_node].cdr = nil; return base; }
/* * Send thread */ static void send_thread(void) { struct my_msg msg; object_t o1, o2; int error; char string[] = "A lazy dog laying on the road!!"; printf("Send thread is starting...\n"); /* * Find objects. */ error = object_lookup("test-A", &o1); error = object_lookup("test-B", &o2); /* * Wait a sec. */ timer_sleep(1000, 0); /* * Delete object A. */ printf("Delete object A\n"); object_destroy(o1); /* * Wait a sec. */ timer_sleep(1000, 0); /* * Send message to object B. */ printf("Send message to object B.\n"); strncpy(msg.data, string, sizeof(string)); msg.hdr.code = 42; msg_send(o2, &msg, sizeof(msg)); printf("Send completed.\n"); for (;;) ; }
void __process_init(void) { int error; /* Look up process server */ error = object_lookup("!proc", &__proc_obj); if (error) __proc_obj = 0; }
/* * Test invalid request */ static void test_invalid(void) { object_t fs_obj; struct msg m; object_lookup(OBJNAME_FS, &fs_obj); m.hdr.code = 0x300; msg_send(fs_obj, &m, sizeof(m), 0); }
/* * This is called first when task is started */ void __file_init(void) { int error; /* * Look up file system server */ error = object_lookup("!fs", &__fs_obj); if (error) __fs_obj = 0; }
/* * Send thread */ static void send_thread(void) { struct msg msg; object_t o1, o2; int error; printf("Send thread is starting...\n"); /* * Find objects. */ error = object_lookup("test-A", &o1); error = object_lookup("test-B", &o2); /* * Wait a sec. */ timer_sleep(1000, 0); /* * Delete object A. */ printf("Delete object A\n"); object_destroy(o1); /* * Wait a sec. */ timer_sleep(1000, 0); /* * Send message to object B. */ printf("Send message to object B.\n"); msg_send(o2, &msg, sizeof(msg)); printf("Send completed.\n"); for (;;) ; }
memptr func_cons(memptr func_expr) { if (num_nodes(func_expr) != 3) { #ifdef DEBUG printf("9\n"); #endif ERROR(ERROR_CONS, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); return NOT_FOUND; } memptr res = safe_allocate_cons(); cons_pool[res].carKind = NIL; cons_pool[res].cdrKind = NIL; memptr current_node, current_data; // first parameter current_node = cons_pool[func_expr].cdr; current_data = cons_pool[current_node].car; cons_pool[res].car = resolve_expr(current_data); cons_pool[res].carKind = CONS; if (type(cons_pool[res].car) == TYPE_OBJECT) { memptr lu = object_lookup(cons_pool[res].car, cons_pool[func_expr].car); if (lu == NOT_FOUND && OBJECT_OPERATE_CORE) { cons_pool[res].car = object_lookup(cons_pool[res].car, core_symbol); } else if (lu != NOT_FOUND) { return resolve_func_expr(func_expr, cons_pool[res].car, lu, true); } } // second parameter current_node = cons_pool[current_node].cdr; current_data = cons_pool[current_node].car; cons_pool[res].cdr = resolve_expr(current_data); cons_pool[res].cdrKind = CONS; if (type(cons_pool[res].cdr) == TYPE_OBJECT && OBJECT_OPERATE_CORE) { cons_pool[res].cdr = object_lookup(cons_pool[res].cdr, core_symbol); } return res; }
static void register_process(void) { struct msg m; object_t obj; int error; error = object_lookup("!proc", &obj); if (error) sys_panic("pow: no proc found"); m.hdr.code = PS_REGISTER; msg_send(obj, &m, sizeof(m)); }
static void shutdown_server(const char *name) { struct msg m; object_t obj; int error; DPRINTF(("pow: shutdown %s\n", name)); error = object_lookup((char *)name, &obj); if (error != 0) return; m.hdr.code = STD_SHUTDOWN; error = msg_send(obj, &m, sizeof(m)); if (error) sys_panic("pow: shutdown error"); }
int main(int argc, char *argv[]) { object_t obj; struct msg m; if (argc != 2) usage(); if (object_lookup(argv[1], &obj) != 0) { fprintf(stderr, "debug: can not find object %s\n", argv[1]); exit(1); } m.hdr.code = STD_DEBUG; msg_send(obj, &m, sizeof(m), 0); exit(0); }
/** * Find the object under this object that matches the given name. * * object: Object to search under. * name: Regex to check names against. **/ object_t * object_lookup(object_t *object, const char *name) { size_t i; object_t *ret; if (! strcmp(object->name, name)) return object; /* FIXME: use cursors, not recursion */ for (i = 0; i < object->child_count; i++) { ret = object_lookup(object->children[i], name); if (ret) return ret; } return NULL; }
memptr func_value(memptr func_expr) { if (num_nodes(func_expr) < 2) { #ifdef DEBUG printf("31\n"); #endif ERROR(ERROR_VALUE, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); return NOT_FOUND; } memptr next_node = cons_pool[func_expr].cdr, current_node, current_value; bool first_param = true; do { #ifdef EXTENDED_SECURITY memptr local_security = safe_allocate_cons(); cons_pool[local_security].carKind = NIL; cons_pool[local_security].cdrKind = NIL; #endif current_node = next_node; current_value = resolve_expr(cons_pool[current_node].car); #ifdef EXTENDED_SECURITY cons_pool[local_security].car = current_value; cons_pool[local_security].carKind = CONS; #endif if (current_value == NOT_FOUND) { #ifdef DEBUG printf("32\n"); #endif ERROR(ERROR_VALUE, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); return NOT_FOUND; } else if (first_param && (type(current_value) == TYPE_OBJECT)) { memptr lu = object_lookup(current_value, cons_pool[func_expr].car); if (lu != NOT_FOUND) { return resolve_func_expr(func_expr, current_value, lu, true); } } next_node = cons_pool[current_node].cdr; first_param = false; } while (cons_pool[current_node].cdrKind == CONS); return current_value; }
/* * Wait until specified server starts. */ static void wait_server(const char *name, object_t *pobj) { int i, error = 0; /* Give chance to run other servers. */ thread_yield(); /* * Wait for server loading. timeout is 1 sec. */ for (i = 0; i < 100; i++) { error = object_lookup((char *)name, pobj); if (error == 0) break; /* Wait 10msec */ timer_sleep(10, 0); thread_yield(); } if (error) sys_panic("pow: server not found"); }
int main(int argc, char *argv[]) { static const char stat[][2] = { "R", "Z", "S" }; static const char pol[][5] = { "FIFO", "RR " }; static struct threadinfo ti; static struct procinfo pi; int ch, rc, ps_flag = 0; pid_t last_pid = -2; while ((ch = getopt(argc, argv, "lx")) != -1) switch(ch) { case 'x': ps_flag |= PSFX; break; case 'l': ps_flag |= PSFL; break; case '?': default: fprintf(stderr, "usage: ps [-lx]\n"); exit(1); } argc -= optind; argv += optind; if (object_lookup("!proc", &procobj)) exit(1); if (ps_flag & PSFL) printf(" PID PPID PRI STAT POL TIME WCHAN CMD\n"); else printf(" PID TIME CMD\n"); rc = 0; ti.cookie = 0; do { /* * Get thread info from kernel. */ rc = sys_info(INFO_THREAD, &ti); if (!rc) { /* * Get process info from server. */ if (pstat(ti.task, &pi) && !(ps_flag & PSFX)) continue; if (ps_flag & PSFL) { if (pi.pid == -1) printf(" - -"); /* kernel */ else printf("%5d %5d", pi.pid, pi.ppid); printf(" %3d %s %s %8d " "%-11s %-11s\n", ti.priority, stat[pi.stat-1], pol[ti.policy], ti.time, ti.slpevt, ti.taskname); } else { if (!(ps_flag & PSFX) && (pi.pid == last_pid)) continue; if (pi.pid == -1) printf(" -"); /* kernel */ else printf("%5d", pi.pid); printf(" %8d %-11s\n", ti.time, ti.taskname); last_pid = pi.pid; } } } while (rc == 0); exit(0); }
/* * Note: * * The state after exec() are as follows: * - Opened file descriptors remain open except FD_CLOEXEC flag is set. * - Opened directory streams are closed * - Signals set to the default action. * - Any asynchronous I/O operations are cancelled. */ int execve(char *path, char *argv[], char *envp[]) { object_t exec_obj; struct exec_msg msg; int err, i, argc, envc; size_t bufsz; char *dest, *src; if ((err = object_lookup(OBJNAME_EXEC, &exec_obj)) != 0) { errno = ENOSYS; return -1; } if (path == NULL) { errno = EFAULT; return -1; } /* if (strlen(path) >= PATH_MAX) return ENAMETOOLONG; */ /* Get arg/env buffer size */ bufsz = 0; argc = 0; if (argv) { while (argv[argc]) { bufsz += (strlen(argv[argc]) + 1); argc++; } } envc = 0; if (envp) { while (envp[envc]) { bufsz += (strlen(envp[envc]) + 1); envc++; } } if (bufsz >= ARG_MAX) { errno = E2BIG; return -1; } dest = msg.buf; for (i = 0; i < argc; i++) { src = argv[i]; while ((*dest++ = *src++) != 0); } for (i = 0; i < envc; i++) { src = envp[i]; while ((*dest++ = *src++) != 0); } /* Request to exec server */ msg.hdr.code = EX_EXEC; msg.argc = argc; msg.envc = envc; msg.bufsz = bufsz; strlcpy(msg.path, path, PATH_MAX); do { err = msg_send(exec_obj, &msg, sizeof(msg), 0); } while (err == EINTR); /* * If exec() request is done successfully, control never comes here. */ errno = 0; if (err) errno = EIO; else if (msg.hdr.status) errno = msg.hdr.status; return -1; }
int main(int argc, char *argv[]) { int ret; time_t t; double jd; struct tm tm; const struct object *obj; /* Default options */ double horizon = LN_SOLAR_STANDART_HORIZON; /* 50 Bogenminuten; no twilight, normal sunset/rise */ int tz = INT_MAX; char *obj_str = basename(argv[0]); char *format = "%H:%M %d.%m.%Y"; //char *format = "time: %Y-%m-%d %H:%M:%S (%Z) az: §a (§s) alt: §h"; char tzid[32]; char *query = NULL; bool horizon_set = false; bool next = false; bool local_tz = false; time(&t); localtime_r(&t, &tm); enum { MOMENT_NOW, MOMENT_RISE, MOMENT_SET, MOMENT_TRANSIT } moment = MOMENT_NOW; struct ln_lnlat_posn obs = { DBL_MAX, DBL_MAX }; struct object_details result; /* set tzid as empty (without repointing the buffer) */ strcpy(tzid, ""); /* parse command line arguments */ while (1) { int c = getopt_long(argc, argv, "+hvnult:d:f:a:o:q:z:p:m:H:", long_options, NULL); /* detect the end of the options. */ if (c == -1) break; switch (c) { case 'H': if (strcmp(optarg, "civil") == 0) horizon = LN_SOLAR_CIVIL_HORIZON; else if (strcmp(optarg, "nautic") == 0) horizon = LN_SOLAR_NAUTIC_HORIZON; else if (strcmp(optarg, "astronomical") == 0) horizon = LN_SOLAR_ASTRONOMICAL_HORIZON; else { char *endptr; horizon = strtod(optarg, &endptr); if (endptr == optarg) usage_error("invalid horizon / twilight parameter"); } horizon_set = true; break; case 't': tm.tm_isdst = -1; /* update dst */ if (strchr(optarg, '_')) { if (!strptime(optarg, "%Y-%m-%d_%H:%M:%S", &tm)) usage_error("invalid time/date parameter"); } else { if (!strptime(optarg, "%Y-%m-%d", &tm)) usage_error("invalid time/date parameter"); } break; case 'm': if (strcmp(optarg, "rise") == 0) moment = MOMENT_RISE; else if (strcmp(optarg, "set") == 0) moment = MOMENT_SET; else if (strcmp(optarg, "transit") == 0) moment = MOMENT_TRANSIT; else usage_error("invalid moment"); break; case 'n': next = true; break; case 'f': format = strdup(optarg); break; case 'a': obs.lat = strtod(optarg, NULL); break; case 'o': obs.lng = strtod(optarg, NULL); break; #ifdef GEONAMES_SUPPORT case 'q': query = strdup(optarg); break; case 'l': local_tz = true; break; #endif case 'p': obj_str = optarg; break; case 'z': strncpy(tzid, optarg, sizeof(tzid)); break; case 'u': strncpy(tzid, "UTC", sizeof(tzid)); break; case 'v': print_version(); return 0; case 'h': print_usage(); return 0; case '?': default: usage_error("unrecognized option"); } } /* Parse planet/obj */ obj = object_lookup(obj_str); if (!obj) usage_error("invalid or missing object, use --object"); #ifdef GEONAMES_SUPPORT /* Lookup place at http://geonames.org */ if (query) { ret = geonames_lookup_latlng(query, &obs, NULL, 0); if (ret) usage_error("failed to lookup location"); } if (local_tz) { int gmt_offset; ret = geonames_lookup_tz(obs, &gmt_offset, tzid, sizeof(tzid)); if (ret) usage_error("failed to lookup location"); } #endif if(strlen(tzid) > 0) /* set TZ variable only when we have a value - otherwise rely on /etc/localtime or whatever other system fallbacks */ setenv("TZ", tzid, 1); tzset(); /* Validate observer coordinates */ if (fabs(obs.lat) > 90) usage_error("invalid latitude, use --lat"); if (fabs(obs.lng) > 180) usage_error("invalid longitude, use --lon"); if (horizon_set && strcmp(object_name(obj), "sun")) usage_error("the twilight parameter can only be used for the sun"); /* Calculate julian date */ t = mktime(&tm); jd = ln_get_julian_from_timet(&t); result.obs = obs; #ifdef DEBUG printf("Debug: calculate for jd: %f\n", jd); printf("Debug: calculate for ts: %ld\n", t); printf("Debug: for position: N %f, E %f\n", obs.lat, obs.lng); printf("Debug: for object: %s\n", object_name(obj)); printf("Debug: with horizon: %f\n", horizon); printf("Debug: with timezone: %s\n", tzid); #endif /* calc rst date */ rst: if (object_rst(obj, jd - .5, horizon, &result.obs, &result.rst) == 1) { if (moment != MOMENT_NOW) { fprintf(stderr, "object is circumpolar\n"); return 2; } } else { switch (moment) { case MOMENT_NOW: result.jd = jd; break; case MOMENT_RISE: result.jd = result.rst.rise; break; case MOMENT_SET: result.jd = result.rst.set; break; case MOMENT_TRANSIT: result.jd = result.rst.transit; break; } if (next && result.jd < jd) { jd++; next = false; goto rst; } } ln_get_timet_from_julian(result.jd, &t); localtime_r(&t, &result.tm); object_pos(obj, jd, &result); format_result(format, &result); return 0; }
memptr do_join_operation(memptr func_expr, JoinOperation operation_type) { if (num_nodes(func_expr) != 3) { #ifdef DEBUG printf("1\n"); #endif switch (operation_type) { case PLUS: ERROR(ERROR_PLUS, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case MINUS: ERROR(ERROR_MINUS, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case MULT: ERROR(ERROR_MULT, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case DIV: ERROR(ERROR_DIV, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case EQUAL: ERROR(ERROR_EQUALS, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case SMALLER: ERROR(ERROR_SMALLER, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case GREATER: ERROR(ERROR_GREATER, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case OR: ERROR(ERROR_OR, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case AND: ERROR(ERROR_AND, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; case XOR: ERROR(ERROR_XOR, ERROR_FAILURE, ERROR_INVALID, ERROR_COUNT); break; default: break; } return NOT_FOUND; } memptr current_node = cons_pool[func_expr].cdr; memptr local_security = safe_allocate_cons(); cons_pool[local_security].carKind = NIL; cons_pool[local_security].cdrKind = NIL; memptr first_param = resolve_expr(cons_pool[current_node].car); if (first_param == NOT_FOUND) { #ifdef DEBUG printf("2\n"); #endif switch (operation_type) { case PLUS: ERROR(ERROR_PLUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MINUS: ERROR(ERROR_MINUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MULT: ERROR(ERROR_MULT, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case DIV: ERROR(ERROR_DIV, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case EQUAL: ERROR(ERROR_EQUALS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case SMALLER: ERROR(ERROR_SMALLER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case GREATER: ERROR(ERROR_GREATER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case OR: ERROR(ERROR_OR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case AND: ERROR(ERROR_AND, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case XOR: ERROR(ERROR_XOR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; default: break; } return NOT_FOUND; } cons_pool[local_security].car = first_param; cons_pool[local_security].carKind = CONS; Type first_param_type = type(first_param); if (first_param_type == TYPE_OBJECT) { memptr lu = object_lookup(first_param, cons_pool[func_expr].car); if (lu == NOT_FOUND) { first_param = object_lookup(first_param, core_symbol); first_param_type = type(first_param); } else { return resolve_func_expr(func_expr, first_param, lu, true); } } current_node = cons_pool[current_node].cdr; memptr second_param = resolve_expr(cons_pool[current_node].car); if (second_param == NOT_FOUND) { #ifdef DEBUG printf("3\n"); #endif switch (operation_type) { case PLUS: ERROR(ERROR_PLUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MINUS: ERROR(ERROR_MINUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MULT: ERROR(ERROR_MULT, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case DIV: ERROR(ERROR_DIV, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case EQUAL: ERROR(ERROR_EQUALS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case SMALLER: ERROR(ERROR_SMALLER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case GREATER: ERROR(ERROR_GREATER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case OR: ERROR(ERROR_OR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case AND: ERROR(ERROR_AND, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case XOR: ERROR(ERROR_XOR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; default: break; } return NOT_FOUND; } cons_pool[local_security].cdr = second_param; cons_pool[local_security].cdrKind = CONS; Type second_param_type = type(second_param); if (second_param_type == TYPE_OBJECT) { second_param = object_lookup(second_param, core_symbol); second_param_type = type(second_param); } memptr result = NOT_FOUND; if (operation_type == PLUS || operation_type == MINUS || operation_type == MULT || operation_type == DIV) { if (first_param_type != TYPE_INTEGER || second_param_type != TYPE_INTEGER) { #ifdef DEBUG printf("4\n"); #endif switch (operation_type) { case PLUS: ERROR(ERROR_PLUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MINUS: ERROR(ERROR_MINUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MULT: ERROR(ERROR_MULT, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case DIV: ERROR(ERROR_DIV, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case EQUAL: ERROR(ERROR_EQUALS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case SMALLER: ERROR(ERROR_SMALLER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case GREATER: ERROR(ERROR_GREATER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case OR: ERROR(ERROR_OR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case AND: ERROR(ERROR_AND, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case XOR: ERROR(ERROR_XOR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; default: break; } return NOT_FOUND; } int first_value = fix_integer(cons_pool[first_param].car); int second_value = fix_integer(cons_pool[second_param].car); result = allocate_cons(); cons_pool[result].carKind = INTEGER; cons_pool[result].cdrKind = NIL; switch (operation_type) { case PLUS: cons_pool[result].car = first_value + second_value; break; case MINUS: cons_pool[result].car = first_value - second_value; break; case MULT: cons_pool[result].car = first_value * second_value; break; case DIV: if (second_value == 0) { #ifdef DEBUG printf("5\n"); #endif return NOT_FOUND; } cons_pool[result].car = first_value / second_value; break; default: break; } } else if (operation_type == EQUAL || operation_type == SMALLER || operation_type == GREATER) { if (first_param_type != second_param_type) { #ifdef DEBUG printf("6\n"); #endif switch (operation_type) { case PLUS: ERROR(ERROR_PLUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MINUS: ERROR(ERROR_MINUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MULT: ERROR(ERROR_MULT, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case DIV: ERROR(ERROR_DIV, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case EQUAL: ERROR(ERROR_EQUALS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case SMALLER: ERROR(ERROR_SMALLER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case GREATER: ERROR(ERROR_GREATER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case OR: ERROR(ERROR_OR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case AND: ERROR(ERROR_AND, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case XOR: ERROR(ERROR_XOR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; default: break; } } int first_value; int second_value; if (first_param_type == TYPE_NIL_TRUE) { first_value = ((first_param == nil) ? 0 : 1); second_value = ((second_param == nil) ? 0 : 1); } else if (first_param_type == TYPE_INTEGER) { first_value = fix_integer(cons_pool[first_param].car); second_value = fix_integer(cons_pool[second_param].car); } else { // addresses comparison first_value = first_param; second_value = second_param; } // strings logic if (first_param_type == TYPE_STRING) { bool full_equal = false; int len1 = string_length(first_param); int len2 = string_length(second_param); if ((len1 == 1) || (len2 == 1)) { first_value = strings_pool[get_string(cons_pool[first_param].car, cons_pool[first_param].cdr)]; second_value = strings_pool[get_string( cons_pool[second_param].car, cons_pool[second_param].cdr)]; if (len1 != 1) { if (first_value == second_value) { first_value++; } } if (len2 != 1) { if (first_value == second_value) { second_value++; } } } else { int iter1 = get_string(cons_pool[first_param].car, cons_pool[first_param].cdr), iter2 = get_string( cons_pool[second_param].car, cons_pool[second_param].cdr); first_value = second_value = 0; while (first_value == second_value && strings_pool[iter1] != '\0' && strings_pool[iter2] != '\0') { first_value = strings_pool[iter1++]; second_value = strings_pool[iter2++]; } if ((strings_pool[iter1] != '\0') && (strings_pool[iter2] == '\0') && (first_value == second_value)) { first_value++; } else if ((strings_pool[iter1] == '\0') && (strings_pool[iter2] != '\0') && (first_value == second_value)) { second_value++; } } } switch (operation_type) { case EQUAL: result = ((first_value == second_value) ? t : nil); break; case SMALLER: result = ((first_value < second_value) ? t : nil); break; case GREATER: result = ((first_value > second_value) ? t : nil); break; default: #ifdef DEBUG printf("7\n"); #endif return NOT_FOUND; break; } } else if (operation_type == XOR || operation_type == OR || operation_type == AND) { if (first_param_type != TYPE_NIL_TRUE || second_param_type != TYPE_NIL_TRUE) { #ifdef DEBUG printf("7.5\n"); #endif switch (operation_type) { case PLUS: ERROR(ERROR_PLUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MINUS: ERROR(ERROR_MINUS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case MULT: ERROR(ERROR_MULT, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case DIV: ERROR(ERROR_DIV, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case EQUAL: ERROR(ERROR_EQUALS, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case SMALLER: ERROR(ERROR_SMALLER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case GREATER: ERROR(ERROR_GREATER, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case OR: ERROR(ERROR_OR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case AND: ERROR(ERROR_AND, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; case XOR: ERROR(ERROR_XOR, ERROR_FAILURE, ERROR_INVALID, ERROR_EMPTY); break; default: break; } return NOT_FOUND; } switch (operation_type) { case XOR: result = ((first_param != second_param) ? t : nil); break; case OR: result = ((first_param == t || second_param == t) ? t : nil); break; case AND: result = ((first_param == t && second_param == t) ? t : nil); break; default: #ifdef DEBUG printf("8\n"); #endif return NOT_FOUND; break; } } return result; }