ns_value operator_node::eval(ns_rt_context *rtctx) { ns_value l = left->eval(rtctx); ns_value r = right->eval(rtctx); ns_value n; switch (opt) { case '+': n = l + r; break; case '-': n = l - r; break; case '*': n = l * r; break; case '/': n = l / r; break; case '%': n = l % r; break; default: n = eval_illegal; ns_panic(lineno) << "undefined operator:" << opt << std::endl; break; } if (n.is_exceptional_val()) { ns_panic(lineno) << "value operation failed." << "opt:[" << opt <<"]" << std::endl; } return n; }
ns_value dot_call_method_node::eval(ns_rt_context *rtctx) { ns_value arr = postfix->eval(rtctx); // eval paramter list ns_value arglist = args->eval(rtctx); std::vector<ns_value> *plist = arglist.list_val; if (arr.is_array() && arglist.is_array()) { if (name == "append") { if (arglist.len() == 1) { arr.append((*plist)[0]); return arr; } } else if (name == "len") { return ns_value(arr.len()); } else if (name == "del") { if (arglist.len() == 1) { ns_value arg = (*plist)[0]; if (arg.is_int()) { arr.del(arg.int_val); } else { ns_panic(lineno) << "paramter isn't type int!" << std::endl; } } else { ns_panic(lineno) << "Bad paramter number!" << std::endl; } return arr; } else if (name == "find") { if (arglist.len() == 1) { int idx = arr.find((*plist)[0]); if (idx == -1) { ns_panic(lineno) << "out of index. " << std::endl; return eval_illegal; } return ns_value(idx); } } else { ns_panic(lineno) << "func: " << name << "doesn't support." << std::endl; return eval_illegal; } } else if (arr.is_raw_string()) { if (name == "len") { return ns_value(arr.len()); } } return eval_illegal; }
ns_value array_ref_node::eval(ns_rt_context *rtctx) { ns_value pv = postfix->eval(rtctx); if (pv.is_iteratale()) { ns_value idx = index->eval(rtctx); if (idx.is_int()) { return pv.get_elem(idx.int_val); } ns_panic(lineno) << "index is not integer type." << std::endl; } else { ns_panic(lineno) << "the object is not iteratable" << std::endl; } return eval_illegal; }
void unblock_signals(void) { INSIST(blocked); if (sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) ns_panic(ns_log_os, 1, "sigblock failed: %s", strerror(errno)); blocked = 0; }
void init_signals(void) { size_t sh; /* The mask of all our handlers will block all our other handlers. */ (void)sigemptyset(&mask); for (sh = 0; sh < sizeof sighandlers / sizeof sighandlers[0]; sh++) sigaddset(&mask, sighandlers[sh].sig); /* Install our signal handlers with that shared mask. */ for (sh = 0; sh < sizeof sighandlers / sizeof sighandlers[0]; sh++) { struct sigaction sa; memset(&sa, 0, sizeof sa); sa.sa_mask = mask; sa.sa_handler = sighandlers[sh].hand; if (sigaction(sighandlers[sh].sig, &sa, NULL) < 0) ns_error(ns_log_os, "sigaction failed in set_signal_handler(%d): %s", sighandlers[sh].sig, strerror(errno)); } /* Unblock all signals that we expect to handle. */ if (sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) ns_panic(ns_log_os, 1, "sigblock failed: %s", strerror(errno)); }
ns_value variable_node::eval(ns_rt_context *rtctx) { symbol *sym = check_symbol(id, rtctx); if (!sym) { ns_panic(lineno) << "can't find symbol `" << id << "` in symbol table"; } return sym->value; }
ns_value array_def_node::eval(ns_rt_context *rtctx) { ns_value v = elements->eval(rtctx); if (v.is_array()) { return v; } ns_panic(lineno) << "array define eval failed" << std::endl; return eval_illegal; }
ns_value compare_node::eval(ns_rt_context *rtctx) { ns_value l = left->eval(rtctx); if (cmp_opt == AND) { /* fast death */ if (!l) { return ns_value(false); } } ns_value r = right->eval(rtctx); bool v = false; switch (cmp_opt) { case CMP_GT: v = l > r; break; case CMP_LS: v = l < r; break; case CMP_EQ: v = l == r; break; case CMP_NE: v = l != r; break; case CMP_GE: v = l >= r; break; case CMP_LE: v = l <= r; break; case OR: v = l || r; break; case AND: v = l && r; break; default: v = false; break; } if (l.is_exceptional_val() || r.is_exceptional_val()) { ns_panic(lineno) << "comparition operation failed." << "left: " << l << " right: " << r; } return ns_value(v); }
ns_value assign_array_elem_node::eval(ns_rt_context *rtctx) { ns_value pv = postfix->eval(rtctx); if (pv.is_iteratale()) { ns_value idx = index->eval(rtctx); if (idx.is_int()) { if (!pv.set_elem(idx.int_val, rvalue->eval(rtctx))) { ns_panic(lineno) << "set element failed." << std::endl; } } return pv; } else { ns_trace(lineno) << "eval failed in assign stmt" << std::endl; } return eval_illegal; }
ns_value builtin_func_node::eval(ns_rt_context *rtctx) { // eval paramter list std::vector<ns_value> func_param_value_list; exp_list_node::nl_iter it = plist->begin(); for(; it != plist->end(); ++it) { func_param_value_list.push_back((*it)->eval(rtctx)); } if (func_name == "print") { std::copy(func_param_value_list.begin(), func_param_value_list.end(), std::ostream_iterator<ns_value> (std::cout)); std::cout << std::endl; } else{ symbol *s = find_symbol(func_name, rtctx); if (s) { ns_value ns = s->value; if (ns.type == NSVAL_EXPERESS_AST) { node *func = ns.node_val; if (func) { // create a func run time environment. ns_rt_context func_rt_ctx; // pass the paramter list func_rt_ctx.func_param_list = &func_param_value_list; // eval the func node under local env; ns_value func_status = func->eval(&func_rt_ctx); if (func_status.is_status_return()) { return func_rt_ctx.func_return_val; } return func_status; } } } else { ns_panic(lineno) << "can't find the symbol: " << func_name << std::endl; return eval_illegal; } } return eval_status_ok; }
void ns_udp() { #if defined(CHECK_UDP_SUM) || defined(FIX_UDP_SUM) struct nlist nl[2]; int fd; int sum; u_long res, offset; nl[0].n_name = UDPSUM; nl[1].n_name = 0; if (nlist(KSYMS, nl)) { ns_debug(ns_log_default, 1, "ns_udp: nlist (%s,%s) failed", KSYMS, UDPSUM); return; } ns_debug(ns_log_default, 1, "ns_udp: %s %d %lu (%ld)", nl[0].n_name, nl[0].n_type, nl[0].n_value, nl[0].n_value); if (!nl[0].n_type) return; if ((fd = open(KMEM, O_RDWR, 0)) < 0) { ns_debug(ns_log_default, 1, "ns_udp: open %s failed: %s", KMEM, strerror(errno)); return; } offset = nl[0].n_value; #ifdef KMAP offset &= ((~0UL)>>1); #endif res = lseek(fd, offset, SEEK_SET); if (res != offset) { ns_debug(ns_log_default, 1, "ns_udp: lseek %lu failed %lu: %s", offset, res, strerror(errno)); goto cleanup; } if (read(fd, &sum, sizeof(sum)) != sizeof(sum)) { ns_debug(ns_log_default, 1, "ns_udp: read failed: %s", strerror(errno)); goto cleanup; } ns_debug(ns_log_default, 1, "ns_udp: %d", sum); if (sum == 0) { #ifdef FIX_UDP_SUM sum = 1; lseek(fd, offset, SEEK_SET); if (res != offset) { ns_debug(ns_log_default, 1, "ns_udp: lseek %lu failed %lu: %s", offset, res, strerror(errno)); goto cleanup; } if (write(fd, &sum, sizeof(sum)) != sizeof(sum)) { ns_debug(ns_log_default, 1, "ns_udp: write failed: %s", strerror(errno)); goto cleanup; } ns_warning(ns_log_default, "ns_udp: check sums turned on"); #else ns_panic(ns_log_default, 0, "ns_udp: checksums NOT turned on, exiting"); #endif } cleanup: close(fd); #endif }