//------------------------------------------------- // split //------------------------------------------------- static std.vector <string> split(string text, char sep) { std.vector <string> tokens = new std.vector <string>(); size_t start = 0; size_t end = 0; while ((end = text.find(sep, start)) != npos) { string temp = text.substr(start, end - start); if (temp != "") { tokens.push_back(temp); } start = end + 1; } { string temp = text.substr(start); if (temp != "") { tokens.push_back(temp); } } return(tokens); }
void device(string dev_type) { std.vector <string> params_ = new std.vector <string>(); require_token(m_tok_paren_left); string devname = get_identifier(); m_setup.log().debug.op("Parser: IC: {0}\n", devname); var tok = get_token(); while (tok.is_(m_tok_comma)) { tok = get_token(); if (/*tok.is_type(token_type::IDENTIFIER) ||*/ tok.is_type(parser_t_token_type.STRING)) { params_.push_back(tok.str()); tok = get_token(); } else { var value = stringify_expression(ref tok); params_.push_back(value); } } require_token(tok, m_tok_paren_right); std.vector <string> params_temp = new std.vector <string>(); params_temp.Add(devname); params_temp.AddRange(params_); m_setup.register_dev(dev_type, params_temp.ToArray()); //m_setup.register_dev(dev_type, devname, params); }
public void run(netlist_state_t nlstate) { foreach (var net in nlstate.nets()) { nlstate.log().verbose.op("processing {0}", net.name()); if (!net.is_rail_net() && !nlstate.core_terms(net).empty()) { nlstate.log().verbose.op(" ==> not a rail net"); // Must be an analog net var n = (analog_net_t)net; //auto &n = dynamic_cast<analog_net_t &>(*net); if (!already_processed(n)) { groupspre.emplace_back(new nld_solver_net_list_t()); process_net(nlstate, n); } } } foreach (var g in groupspre) { if (!g.empty()) { groups.push_back(g); } } }
public void add(terminal_t term, int net_other, bool sorted) { if (sorted) { for (int i = 0; i < m_connected_net_idx.size(); i++) { if (m_connected_net_idx[i] > net_other) { m_terms.Insert(i, term); //plib::container::insert_at(m_terms, i, term); m_connected_net_idx.Insert(i, net_other); //plib::container::insert_at(m_connected_net_idx, i, net_other); m_gt.Insert(i, 0.0); //plib::container::insert_at(m_gt, i, 0.0); m_go.Insert(i, 0.0); //plib::container::insert_at(m_go, i, 0.0); m_Idr.Insert(i, 0.0); //plib::container::insert_at(m_Idr, i, 0.0); m_connected_net_V.Insert(i, null); //plib::container::insert_at(m_connected_net_V, i, null); return; } } } m_terms.push_back(term); m_connected_net_idx.push_back(net_other); m_gt.push_back(0.0); m_go.push_back(0.0); m_Idr.push_back(0.0); m_connected_net_V.push_back(null); }
//bool hit_test(float x, float y, size_t &start, size_t &span) const; //void restyle(size_t start, size_t span, rgb_t *fgcolor, rgb_t *bgcolor); //------------------------------------------------- // get_wrap_info //------------------------------------------------- public int get_wrap_info(out std.vector <int> xstart, out std.vector <int> xend) { xstart = new std.vector <int>(); xend = new std.vector <int>(); // this is a hacky method (tailored to the need to implement // mame_ui_manager::wrap_text) but so be it int line_count = 0; foreach (var line in m_lines) { int start_pos = 0; int end_pos = 0; var line_character_count = line.character_count(); if (line_character_count > 0) { start_pos = (int)line.character(0).source.start; end_pos = (int)(line.character(line_character_count - 1).source.start + line.character(line_character_count - 1).source.span); } line_count++; xstart.push_back(start_pos); xend.push_back(end_pos); } return(line_count); }
// stream creation //------------------------------------------------- // stream_alloc - allocate a new stream //------------------------------------------------- public sound_stream stream_alloc(device_t device, int inputs, int outputs, int sample_rate, stream_update_delegate callback = null) { var stream = new sound_stream(device, inputs, outputs, sample_rate, callback); m_stream_list.push_back(stream); return(stream); }
// toolbar protected override void inkey_export() { std.vector <game_driver> list = new std.vector <game_driver>(); if (m_populated_favorites) { // iterate over favorites mame_machine_manager.instance().favorite().apply((info) => { assert(info.driver != null); if (info.startempty != 0) { list.push_back(info.driver); } }); } else { list.reserve(m_displaylist.size()); foreach (ui_system_info info in m_displaylist) { list.emplace_back(info.driver); } } throw new emu_unimplemented(); #if false #endif }
//template <typename T> public static std.vector <string> psplit(string str, std.vector <string> onstrl) //std::vector<T> psplit(const T &str, const std::vector<T> &onstrl) { string col = ""; //T col = ""; std.vector <string> ret = new std.vector <string>(); //std::vector<T> ret; size_t i = 0; //auto i = str.begin(); while (i != (size_t)str.Length) //while (i != str.end()) { size_t p = npos; //auto p = T::npos; for (size_t j = 0; j < onstrl.size(); j++) //for (std::size_t j=0; j < onstrl.size(); j++) { if (onstrl[j] == str.Substring((int)i, Math.Min(str.Length - (int)i, onstrl[j].Length))) //if (std::equal(onstrl[j].begin(), onstrl[j].end(), i)) { p = j; break; } } if (p != npos) //if (p != T::npos) { if (col != "") //if (!col.empty()) { ret.push_back(col); } col = ""; //col.clear(); ret.push_back(onstrl[p]); i += onstrl[p].length(); //i = std::next(i, narrow_cast<typename T::difference_type>(onstrl[p].length())); } else { char c = str[(int)i]; //typename T::value_type c = *i; col += c; i++; } } if (col != "") //if (!col.empty()) { ret.push_back(col); } return(ret); }
/// \brief Get vector of devices /// /// \tparam C Device class for which devices will be returned /// /// \return vector with pointers to devices //template<class C> public std.vector <C> get_device_list <C>() where C : core_device_t { std.vector <C> tmp = new std.vector <C>(); foreach (var d in m_devices) { var dev = d.second is C ? (C)d.second : null; //auto dev = dynamic_cast<C *>(d.second.get()); if (dev != null) { tmp.push_back(dev); } } return(tmp); }
//------------------------------------------------- // start_new_line //------------------------------------------------- void start_new_line(text_layout.text_justify justify, float height) { // create a new line line new_line = new line(this, justify, actual_height(), height * yscale()); // update the current line m_current_line = new_line; m_last_break = 0; m_truncating = false; // append it m_lines.push_back(new_line); }
public device_state_entry state_add(device_state_entry entry) //device_state_entry &state_add(std::unique_ptr<device_state_entry> &&entry); { // append to the end of the list m_state_list.push_back(entry); //m_state_list.push_back(std::move(entry)); device_state_entry new_entry = m_state_list.back(); // set the fast entry if applicable if (new_entry.index() >= FAST_STATE_MIN && new_entry.index() <= FAST_STATE_MAX && !new_entry.divider()) { m_fast_state[new_entry.index() - FAST_STATE_MIN] = new_entry; } return(new_entry); }
public void run(netlist_base_t netlist) { foreach (var net in netlist.nets()) { netlist.log().debug.op("processing {0}\n", net.name()); if (!net.isRailNet() && net.num_cons() > 0) { netlist.log().debug.op(" ==> not a rail net\n"); /* Must be an analog net */ analog_net_t n = (analog_net_t)net; if (!already_processed(n)) { groups.push_back(new analog_net_t_list_t()); process_net(n); } } } }
// methods //------------------------------------------------- // line::add_character //------------------------------------------------- public void add_character(char32_t ch, char_style style, source_info source) { // get the width of this character float chwidth = m_layout.get_char_width(ch, style.size); // create the positioned character positioned_char positioned_char; positioned_char.character = ch; positioned_char.xoffset = m_width; positioned_char.xwidth = chwidth; positioned_char.style = style; positioned_char.source = source; // append the character m_characters.push_back(positioned_char); m_width += chwidth; // we might be bigger m_height = Math.Max(m_height, style.size * m_layout.yscale()); }
//------------------------------------------------- // missing_mandatory_images - search for devices // which need an image to be loaded //------------------------------------------------- public std.vector <string> missing_mandatory_images() //std::vector<std::reference_wrapper<const std::string>> mame_machine_manager::missing_mandatory_images() { std.vector <string> results = new std.vector <string>(); assert(machine() != null); // make sure that any required image has a mounted file foreach (device_image_interface image in new image_interface_enumerator(machine().root_device())) { if (image.must_be_loaded()) { if (machine().options().image_option(image.instance_name()).value().empty()) { // this is a missing image; give LUA plugins a chance to handle it if (!lua().on_missing_mandatory_image(image.instance_name())) { results.push_back(image.instance_name()); } } } } return(results); }
public void post_start() { log().verbose.op("Scanning net groups ..."); // determine net groups net_splitter splitter = new net_splitter(); splitter.run(state()); log().verbose.op("Found {1} net groups in {2} nets\n", splitter.groups.size(), state().nets().size()); int num_errors = 0; log().verbose.op("checking net consistency ..."); foreach (var grp in splitter.groups) { int railterms = 0; string nets_in_grp = ""; foreach (var n in grp) { nets_in_grp += (n.name() + " "); if (!n.is_analog()) { state().log().error.op(ME_SOLVER_CONSISTENCY_NOT_ANALOG_NET(n.name())); num_errors++; } if (n.is_rail_net()) { state().log().error.op(ME_SOLVER_CONSISTENCY_RAIL_NET(n.name())); num_errors++; } foreach (var t in state().core_terms(n)) { if (!t.has_net()) { state().log().error.op(ME_SOLVER_TERMINAL_NO_NET(t.name())); num_errors++; } else { var otherterm = t is terminal_t ? (terminal_t)t : null; //auto *otherterm = dynamic_cast<terminal_t *>(t); if (otherterm != null) { if (state().setup().get_connected_terminal(otherterm).net().is_rail_net()) { railterms++; } } } } } if (railterms == 0) { state().log().error.op(ME_SOLVER_NO_RAIL_TERMINAL(nets_in_grp)); num_errors++; } } if (num_errors > 0) { throw new nl_exception(MF_SOLVER_CONSISTENCY_ERRORS(num_errors)); } // setup the solvers foreach (var grp in splitter.groups) { nld_solver_solver_ptr ms = null; string sname = new plib.pfmt("Solver_{0}").op(m_mat_solvers.size()); nld_solver_params_uptr params_ = new solver.solver_parameters_t(this, sname + ".", m_params); //params_uptr params = plib::make_unique<solver::solver_parameters_t, solver_arena>(*this, sname + ".", m_params); switch (params_.m_fp_type.op()) { case solver.matrix_fp_type_e.FLOAT: if (!config.use_float_matrix) { log().info.op("FPTYPE {0} not supported. Using DOUBLE", params_.m_fp_type.op().ToString()); } //ms = create_solvers<std::conditional_t<config::use_float_matrix::value, float, double>>(sname, params.get(), grp); if (config.use_float_matrix) { ms = create_solvers <float, plib.constants_operators_float>(sname, params_, grp); } else { ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); } break; case solver.matrix_fp_type_e.DOUBLE: ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); //ms = create_solvers<double>(sname, params.get(), grp); break; case solver.matrix_fp_type_e.LONGDOUBLE: if (!config.use_long_double_matrix) { log().info.op("FPTYPE {0} not supported. Using DOUBLE", params_.m_fp_type.op().ToString()); } //ms = create_solvers<std::conditional_t<config::use_long_double_matrix::value, long double, double>>(sname, params.get(), grp); if (config.use_long_double_matrix) { throw new emu_unimplemented(); //ms = create_solvers<long double>(sname, params_, grp); } else { ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); } break; case solver.matrix_fp_type_e.FLOATQ128: #if (NL_USE_FLOAT128) ms = create_solvers <FLOAT128>(sname, params.get(), grp); #else log().info.op("FPTYPE {0} not supported. Using DOUBLE", params_.m_fp_type.op().ToString()); ms = create_solvers <double, plib.constants_operators_double>(sname, params_, grp); //ms = create_solvers<double>(sname, params.get(), grp); #endif break; } log().verbose.op("Solver {0}", ms.name()); log().verbose.op(" ==> {0} nets", grp.size()); log().verbose.op(" has {0} dynamic elements", ms.dynamic_device_count()); log().verbose.op(" has {0} timestep elements", ms.timestep_device_count()); foreach (var n in grp) { log().verbose.op("Net {0}", n.name()); foreach (var t in state().core_terms(n)) { log().verbose.op(" {0}", t.name()); } } m_mat_params.push_back(params_); m_mat_solvers.push_back(ms); } }
} //void gaussian_back_substitution(V1 &V, const V2 &RHS) //template <typename V1> //void gaussian_back_substitution(V1 &V) //template <typename M> void build_parallel_gaussian_execution_scheme(std.vector <std.vector <unsigned> > fill) //void build_parallel_gaussian_execution_scheme(const M &fill) { // calculate parallel scheme for gaussian elimination std.vector <std.vector <size_t> > rt = new std.vector <std.vector <size_t> >(base.size()); for (size_t k = 0; k < base.size(); k++) { rt[k] = new std.vector <size_t>(); for (size_t j = k + 1; j < base.size(); j++) { if (fill[j][k] < (size_t)pmatrix_cr <B, B_OPS, int_N> .constants_e.FILL_INFINITY) { rt[k].push_back(j); } } } std.vector <size_t> levGE = new std.vector <size_t>(base.size(), 0); size_t cl = 0; for (size_t k = 0; k < base.size(); k++) { if (levGE[k] >= cl) { std.vector <size_t> t = rt[k]; for (size_t j = k + 1; j < base.size(); j++) { bool overlap = false; // is there overlap if (plib.container.contains(t, j)) { overlap = true; } foreach (var x in rt[j]) { if (plib.container.contains(t, x)) { overlap = true; break; } } if (overlap) { levGE[j] = cl + 1; } else { t.push_back(j); foreach (var x in rt[j]) { t.push_back(x); } } } cl++; } } m_ge_par.clear(); m_ge_par.resize(cl + 1); m_ge_par.Fill(() => { return(new std.vector <size_t>()); }); for (size_t k = 0; k < base.size(); k++) { m_ge_par[levGE[k]].push_back(k); } //for (std::size_t k = 0; k < m_ge_par.size(); k++) // printf("%d %d\n", (int) k, (int) m_ge_par[k].size()); }
// parsing/input //------------------------------------------------- // parse_command_line - parse a series of // command line arguments //------------------------------------------------- public void parse_command_line(std.vector <string> args, int priority, bool ignore_unknown_options = false) { string error_stream = ""; //std::ostringstream error_stream; condition_type condition = condition_type.NONE; // reset the errors and the command m_command = ""; // we want to identify commands first for (int arg = 1; arg < args.Count; arg++) { if (!args[(int)arg].empty() && args[(int)arg][0] == '-') { var curentry = get_entry(args[arg].Substring(1)); if (curentry != null && curentry.type() == OPTION_COMMAND) { // can only have one command if (!m_command.empty()) { throw new options_error_exception("Error: multiple commands specified -{0} and {1}\n", m_command, args[arg]); } m_command = curentry.name(); } } } // iterate through arguments int unadorned_index = 0; for (int arg = 1; arg < args.Count; arg++) { // determine the entry name to search for string curarg = args[(int)arg]; bool is_unadorned = curarg[0] != '-'; string optionname = is_unadorned ? core_options.unadorned(unadorned_index++) : curarg.Remove(0, 1); // curarg[1]; // special case - collect unadorned arguments after commands into a special place if (is_unadorned && !m_command.empty()) { m_command_arguments.push_back(args[(int)arg]); command_argument_processed(); continue; } // find our entry; if not found, continue var curentry = get_entry(optionname); if (curentry == null) { if (!ignore_unknown_options) { throw new options_error_exception("Error: unknown option: -{0}\n", optionname); } continue; } // at this point, we've already processed commands if (curentry.type() == OPTION_COMMAND) { continue; } // get the data for this argument, special casing booleans string newdata; if (curentry.type() == OPTION_BOOLEAN) { newdata = string.Compare(curarg.Remove(0, 1), 0, "no", 0, 2) == 0 ? "0" : "1"; //(strncmp(&curarg[1], "no", 2) == 0) ? "0" : "1"; } else if (is_unadorned) { newdata = curarg; } else if (arg + 1 < args.Count) { newdata = args[++arg]; } else { throw new options_error_exception("Error: option {0} expected a parameter\n", curarg); } // set the new data do_set_value(curentry, newdata, priority, ref error_stream, condition); } // did we have any errors that may need to be aggregated? throw_options_exception_if_appropriate(condition, error_stream); }
//------------------------------------------------- // add_entry - adds an entry based on an // options_entry //------------------------------------------------- void add_entry(options_entry opt, bool override_existing = false) { std.vector <string> names = new std.vector <string>(); string minimum = ""; string maximum = ""; // copy in the name(s) as appropriate if (opt.name != null) { // first extract any range string namestr = opt.name; size_t lparen = namestr.find_first_of('(', 0); if (lparen != npos) { size_t dash = namestr.find_first_of('-', lparen + 1); if (dash != npos) { size_t rparen = namestr.find_first_of(')', dash + 1); if (rparen != npos) { minimum = namestr.Substring((int)lparen + 1, (int)(dash - (lparen + 1))).Trim(); //minimum.assign(strtrimspace(std::string_view(&namestr[lparen + 1], dash - (lparen + 1)))); maximum = namestr.Substring((int)dash + 1, (int)(rparen - (dash + 1))).Trim(); //maximum.assign(strtrimspace(std::string_view(&namestr[dash + 1], rparen - (dash + 1)))); namestr = namestr.Remove((int)lparen, (int)(rparen + 1 - lparen)); //namestr.erase(lparen, rparen + 1 - lparen); } } } // then chop up any semicolon-separated names size_t semi; while ((semi = namestr.find_first_of(';')) != npos) { names.push_back(namestr.substr(0, semi)); // for booleans, add the "-noXYZ" option as well if (opt.type == option_type.BOOLEAN) { names.push_back("no" + names.back()); } namestr = namestr.Remove(0, (int)semi + 1); //namestr.erase(0, semi + 1); } // finally add the last item names.push_back(namestr); if (opt.type == option_type.BOOLEAN) { names.push_back("no" + names.back()); } } // we might be called with an existing entry entry existing_entry = null; do { foreach (string name in names) { existing_entry = get_entry(name); if (existing_entry != null) { break; } } if (existing_entry != null) { if (override_existing) { remove_entry(existing_entry); } else { return; } } } while (existing_entry != null); // set the default value string defdata = opt.defvalue != null ? opt.defvalue : ""; // create and add the entry add_entry( names, opt.description, opt.type, defdata, minimum, maximum); }
//struct stats_info //{ // const detail::queue_t &m_queue;// performance // const plib::pperftime_t<true> &m_stat_mainloop; // const plib::pperfcount_t<true> &m_perf_out_processed; //}; /// \brief print statistics gathered during run /// //void print_stats(stats_info &si) const; /// \brief call reset on all netlist components /// public void reset() { // Reset all nets once ! log().verbose.op("Call reset on all nets:"); foreach (var n in nets()) { n.reset(); } // Reset all devices once ! log().verbose.op("Call reset on all devices:"); foreach (var dev in m_devices) { dev.second.reset(); } // Make sure everything depending on parameters is set // Currently analog input and logic input also // push their outputs to queue. std.vector <core_device_t> devices_called = new std.vector <core_device_t>(); log().verbose.op("Call update_param on all devices:"); foreach (var dev in m_devices) { dev.second.update_param(); if (!plib.container.contains(devices_called, dev.second)) { devices_called.push_back(dev.second); } } // Step all devices once ! // // INFO: The order here affects power up of e.g. breakout. However, such // variations are explicitly stated in the breakout manual. var netlist_params = get_single_device <devices.nld_netlistparams>("parameter"); switch (netlist_params.m_startup_strategy.op()) { case 0: { std.vector <nldelegate> t = new std.vector <nldelegate>(); log().verbose.op("Using default startup strategy"); foreach (var n in m_nets) { n.update_inputs(); // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1 foreach (var term in core_terms(n)) { if (!plib.container.contains(t, term.delegate_())) { t.push_back(term.delegate_()); term.run_delegate(); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) var dev = (core_device_t)term.delegate_device(); //auto *dev = reinterpret_cast<core_device_t *>(term->delegate().object()); if (!plib.container.contains(devices_called, dev)) { devices_called.push_back(dev); } } } log().verbose.op("Devices not yet updated:"); foreach (var dev in m_devices) { if (!plib.container.contains(devices_called, dev.second)) { // FIXME: doesn't seem to be needed, use cases include // analog output devices. Check and remove log().error.op("\t Device {0} not yet updated", dev.second.name()); //dev.second->update(); } } } break; } // the above may screw up m_active and the list rebuild_lists(); }
public void compile_infix(string expr, std.vector <string> inputs) //void compile_infix(const pstring &expr, const inputs_container &inputs = inputs_container()) noexcept(false); { // Shunting-yard infix parsing std.vector <string> sep = new std.vector <string> { "(", ")", ",", "*", "/", "+", "-", "^", "<=", ">=", "==", "!=", "<", ">" }; std.vector <string> sexpr2 = plib.pg.psplit(plib.pg.replace_all(expr, " ", ""), sep); std.stack <string> opstk = new std.stack <string>(); std.vector <string> postfix = new std.vector <string>(); std.vector <string> sexpr1 = new std.vector <string>(); std.vector <string> sexpr = new std.vector <string>(); // FIXME: We really need to switch to ptokenizer and fix negative number // handling in ptokenizer. // copy/paste to the int version below // Fix numbers exponential numbers for (size_t i = 0; i < sexpr2.size();) { if (i + 2 < sexpr2.size() && sexpr2[i].length() > 1) { var r = plib.pg.right(sexpr2[i], 1); var ne = sexpr2[i + 1]; if (is_number(sexpr2[i]) && (r == "e" || r == "E") && (ne == "-" || ne == "+")) { sexpr1.push_back(sexpr2[i] + ne + sexpr2[i + 2]); i += 3; } else { sexpr1.push_back(sexpr2[i++]); } } else { sexpr1.push_back(sexpr2[i++]); } } // Fix numbers with unary minus/plus for (size_t i = 0; i < sexpr1.size();) { if (sexpr1[i] == "-" && (i + 1 < sexpr1.size()) && is_number(sexpr1[i + 1])) { if (i == 0 || !(is_number(sexpr1[i - 1]) || sexpr1[i - 1] == ")" || is_id(sexpr1[i - 1]))) { sexpr.push_back("-" + sexpr1[i + 1]); i += 2; } else { sexpr.push_back(sexpr1[i++]); } } else if (sexpr1[i] == "-" && (i + 1 < sexpr1.size()) && (is_id(sexpr1[i + 1]) || sexpr1[i + 1] == "(")) { if (i == 0 || !(is_number(sexpr1[i - 1]) || sexpr1[i - 1] == ")" || is_id(sexpr1[i - 1]))) { sexpr.emplace_back("neg"); sexpr.push_back(sexpr1[i + 1]); i += 2; } else { sexpr.push_back(sexpr1[i++]); } } else { sexpr.push_back(sexpr1[i++]); } } for (size_t i = 0; i < sexpr.size(); i++) { string s = sexpr[i]; if (s == "(") { opstk.push(s); } else if (s == ")") { string x = pop_check(opstk, expr); while (x != "(") { postfix.push_back(x); x = pop_check(opstk, expr); } if (!opstk.empty() && get_prio(opstk.top()) == 0) { postfix.push_back(pop_check(opstk, expr)); } } else if (s == ",") { string x = pop_check(opstk, expr); while (x != "(") { postfix.push_back(x); x = pop_check(opstk, expr); } opstk.push(x); } else { int prio = get_prio(s); if (prio > 0) { if (opstk.empty()) { opstk.push(s); } else { if (get_prio(opstk.top()) >= prio) { postfix.push_back(pop_check(opstk, expr)); } opstk.push(s); } } else if (prio == 0) // Function or variable { if ((i + 1 < sexpr.size()) && sexpr[i + 1] == "(") { opstk.push(s); } else { postfix.push_back(s); } } else { postfix.push_back(s); } } } while (!opstk.empty()) { postfix.push_back(opstk.top()); opstk.pop(); } //for (auto &e : postfix) // printf("\t%s\n", e.c_str()); compile_postfix(inputs, postfix, expr); }
//template <typename NT> void compile_postfix(std.vector <string> inputs, std.vector <string> cmds, string expr) //void pfunction<NT>::compile_postfix(const inputs_container &inputs, const std::vector<pstring> &cmds, const pstring &expr) noexcept(false) { m_precompiled.clear(); int stk = 0; foreach (string cmd in cmds) { rpn_inst rc = new rpn_inst(); var p = pcmds().find(cmd); if (p != default) { rc = new rpn_inst(p.cmd); stk -= p.adj; } else { for (size_t i = 0; i < inputs.size(); i++) { if (inputs[i] == cmd) { rc = new rpn_inst(rpn_cmd.PUSH_INPUT, i); stk += 1; break; } } if (rc.cmd() != rpn_cmd.PUSH_INPUT) { bool err = false; var rs = plib.pg.right(cmd, 1); var r = units_si().find(rs); //auto r=units_si<NT>().find(rs); if (ops.equals(r, ops.default_)) //if (r == units_si<NT>().end()) { rc = new rpn_inst(ops.pstonum_ne(false, cmd, out err)); //rc = rpn_inst(plib::pstonum_ne<NT>(cmd, err)); } else { rc = new rpn_inst(ops.multiply(ops.pstonum_ne(false, plib.pg.left(cmd, cmd.length() - 1), out err), r)); //rc = rpn_inst(plib::pstonum_ne<NT>(plib::left(cmd, cmd.length()-1), err) * r->second); } if (err) { throw new pexception(new plib.pfmt("pfunction: unknown/misformatted token <{0}> in <{1}>").op(cmd, expr)); } stk += 1; } } if (stk < 1) { throw new pexception(new plib.pfmt("pfunction: stack underflow on token <{0}> in <{1}>").op(cmd, expr)); } if (stk >= (int)MAX_STACK) { throw new pexception(new plib.pfmt("pfunction: stack overflow on token <{0}> in <{1}>").op(cmd, expr)); } if (rc.cmd() == rpn_cmd.LP || rc.cmd() == rpn_cmd.RP) { throw new pexception(new plib.pfmt("pfunction: parenthesis inequality on token <{1}> in <{2}>").op(cmd, expr)); } m_precompiled.push_back(rc); } if (stk != 1) { throw new pexception(new plib.pfmt("pfunction: stack count {0} different to one on <{1}>").op(stk, expr)); } compress(); }
//------------------------------------------------- // add_entry - adds an entry based on an // options_entry //------------------------------------------------- void add_entry(options_entry opt, bool override_existing = false) { std.vector <string> names = new std.vector <string>(); string minimum = ""; string maximum = ""; // copy in the name(s) as appropriate if (opt.name != null) { // first extract any range string namestr = opt.name; int lparen = namestr.find_first_of('(', 0); int dash = namestr.find_first_of('-', lparen + 1); int rparen = namestr.find_first_of(')', dash + 1); if (lparen != -1 && dash != -1 && rparen != -1) { minimum = namestr.substr(lparen + 1, dash - (lparen + 1)).Trim(); //strtrimspace(minimum.assign(namestr.substr(lparen + 1, dash - (lparen + 1)))); maximum = namestr.substr(dash + 1, rparen - (dash + 1)).Trim(); //strtrimspace(maximum.assign(namestr.substr(dash + 1, rparen - (dash + 1)))); namestr = namestr.Remove(lparen, rparen + 1 - lparen); // .erase(lparen, rparen + 1 - lparen); } // then chop up any semicolon-separated names int semi; while ((semi = namestr.find_first_of(';')) != -1) { names.push_back(namestr.substr(0, semi)); namestr = namestr.Remove(0, semi + 1); //namestr.erase(0, semi + 1); } // finally add the last item names.push_back(namestr); } // we might be called with an existing entry entry existing_entry = null; do { foreach (string name in names) { existing_entry = get_entry(name.c_str()); if (existing_entry != null) { break; } } if (existing_entry != null) { if (override_existing) { remove_entry(existing_entry); } else { return; } } } while (existing_entry != null); // set the default value string defdata = opt.defvalue != null ? opt.defvalue : ""; // create and add the entry add_entry( names, opt.description, opt.type, defdata, minimum, maximum); }
//speaker_device &rear_center() { set_position( 0.0, 0.0, -0.5); return *this; } //speaker_device &rear_left() { set_position(-0.2, 0.0, -0.5); return *this; } //speaker_device &rear_right() { set_position( 0.2, 0.0, -0.5); return *this; } //speaker_device &headrest_center() { set_position( 0.0, 0.0, -0.1); return *this; } //speaker_device &headrest_left() { set_position(-0.1, 0.0, -0.1); return *this; } //speaker_device &headrest_right() { set_position( 0.1, 0.0, -0.1); return *this; } //speaker_device &seat() { set_position( 0.0, -0.5, 0.0); return *this; } //speaker_device &backrest() { set_position( 0.0, -0.2, 0.1); return *this; } // internally for use by the sound system //------------------------------------------------- // mix - mix in samples from the speaker's stream //------------------------------------------------- public void mix(Pointer <stream_buffer_sample_t> leftmix, Pointer <stream_buffer_sample_t> rightmix, attotime start, attotime end, int expected_samples, bool suppress) //void mix(stream_buffer::sample_t *leftmix, stream_buffer::sample_t *rightmix, attotime start, attotime end, int expected_samples, bool suppress) { // skip if no stream if (m_dimixer.m_mixer_stream == null) { return; } // skip if invalid range if (start > end) { return; } // get a view on the desired range read_stream_view view = m_dimixer.m_mixer_stream.update_view(start, end); sound_assert(view.samples() >= expected_samples); // track maximum sample value for each 0.1s bucket if (machine().options().speaker_report() != 0) { u32 samples_per_bucket = m_dimixer.m_mixer_stream.sample_rate() / BUCKETS_PER_SECOND; for (int sample = 0; sample < expected_samples; sample++) { m_current_max = std.max(m_current_max, std.fabsf(view.get(sample))); if (++m_samples_this_bucket >= samples_per_bucket) { m_max_sample.push_back(m_current_max); m_current_max = 0.0f; m_samples_this_bucket = 0; } } } // mix if sound is enabled if (!suppress) { // if the speaker is centered, send to both left and right if (m_x == 0) { for (int sample = 0; sample < expected_samples; sample++) { stream_buffer_sample_t cursample = view.get(sample); leftmix[sample] += cursample; rightmix[sample] += cursample; } } // if the speaker is to the left, send only to the left else if (m_x < 0) { for (int sample = 0; sample < expected_samples; sample++) { leftmix[sample] += view.get(sample); } } // if the speaker is to the right, send only to the right else { for (int sample = 0; sample < expected_samples; sample++) { rightmix[sample] += view.get(sample); } } } }
//~nld_solver() //{ // for (auto &s : m_mat_solvers) // { // plib::pfree(s); // } //} public void post_start() { const bool use_specific = true; m_params.m_pivot = m_pivot.op() ? 1 : 0; m_params.m_accuracy = m_accuracy.op(); /* FIXME: Throw when negative */ m_params.m_gs_loops = (UInt32)m_gs_loops.op(); m_params.m_nr_loops = (UInt32)m_nr_loops.op(); m_params.m_nr_recalc_delay = netlist_time.from_double(m_nr_recalc_delay.op()); m_params.m_dynamic_lte = m_dynamic_lte.op(); m_params.m_gs_sor = m_gs_sor.op(); m_params.m_min_timestep = m_dynamic_min_ts.op(); m_params.m_dynamic_ts = (m_dynamic_ts.op() == true ? true : false); m_params.m_max_timestep = netlist_time.from_double(1.0 / m_freq.op()).as_double(); if (m_params.m_dynamic_ts) { m_params.m_max_timestep *= 1;//NL_FCONST(1000.0); } else { m_params.m_min_timestep = m_params.m_max_timestep; } //m_params.m_max_timestep = std::max(m_params.m_max_timestep, m_params.m_max_timestep::) // Override log statistics string p = ""; //plib::util::environment("NL_STATS", ""); if (p != "") { m_params.m_log_stats = plib.pstring_global.pstonum_bool(p); //plib::pstonum<decltype(m_params.m_log_stats)>(p); } else { m_params.m_log_stats = m_log_stats.op(); } log().verbose.op("Scanning net groups ..."); // determine net groups net_splitter splitter = new net_splitter(); splitter.run(state()); // setup the solvers log().verbose.op("Found {0} net groups in {1} nets\n", splitter.groups.size(), state().nets().size()); foreach (var grp in splitter.groups) { matrix_solver_t ms; UInt32 net_count = (UInt32)grp.size(); string sname = new plib.pfmt("Solver_{0}").op(m_mat_solvers.size()); switch (net_count) { #if true case 1: if (use_specific) { ms = new matrix_solver_direct1_t(state(), sname, m_params); //ms = plib::palloc<matrix_solver_direct1_t<double>>(state(), sname, &m_params); } else { ms = create_solver/*<double, 1>*/ (1, 1, sname); } break; case 2: if (use_specific) { ms = new matrix_solver_direct2_t(state(), sname, m_params); //ms = plib::palloc<matrix_solver_direct2_t<double>>(state(), sname, &m_params); } else { ms = create_solver/*<double, 2>*/ (2, 2, sname); } break; #if false case 3: ms = create_solver <double, 3>(3, sname); break; case 4: ms = create_solver <double, 4>(4, sname); break; case 5: ms = create_solver <double, 5>(5, sname); break; case 6: ms = create_solver <double, 6>(6, sname); break; case 7: ms = create_solver <double, 7>(7, sname); break; case 8: ms = create_solver <double, 8>(8, sname); break; case 9: ms = create_solver <double, 9>(9, sname); break; case 10: ms = create_solver <double, 10>(10, sname); break; case 11: ms = create_solver <double, 11>(11, sname); break; case 12: ms = create_solver <double, 12>(12, sname); break; case 15: ms = create_solver <double, 15>(15, sname); break; case 31: ms = create_solver <double, 31>(31, sname); break; case 35: ms = create_solver <double, 35>(35, sname); break; case 43: ms = create_solver <double, 43>(43, sname); break; case 49: ms = create_solver <double, 49>(49, sname); break; #endif #if false case 87: ms = create_solver <87, 87>(87, sname); break; #endif #endif default: log().warning.op(nl_errstr_global.MW_1_NO_SPECIFIC_SOLVER, net_count); if (net_count <= 8) { ms = create_solver/*<double, -8>*/ (-8, net_count, sname); } else if (net_count <= 16) { ms = create_solver/*<double, -16>*/ (-16, net_count, sname); } else if (net_count <= 32) { ms = create_solver/*<double, -32>*/ (-32, net_count, sname); } else if (net_count <= 64) { ms = create_solver/*<double, -64>*/ (-64, net_count, sname); } else if (net_count <= 128) { ms = create_solver/*<double, -128>*/ (-128, net_count, sname); } else { log().fatal.op(nl_errstr_global.MF_1_NETGROUP_SIZE_EXCEEDED_1, 128); ms = null; /* tease compilers */ } break; } // FIXME ... ms.setup(grp); log().verbose.op("Solver {0}", ms.name()); log().verbose.op(" ==> {0} nets", grp.size()); log().verbose.op(" has {0} elements", ms.has_dynamic_devices() ? "dynamic" : "no dynamic"); log().verbose.op(" has {0} elements", ms.has_timestep_devices() ? "timestep" : "no timestep"); foreach (var n in grp) { log().verbose.op("Net {0}", n.name()); foreach (var pcore in n.core_terms) { log().verbose.op(" {0}", pcore.name()); } } m_mat_solvers.push_back(ms); if (ms.has_timestep_devices()) { m_mat_solvers_timestepping.push_back(ms); } } }
/* return number of floating point operations for solve */ //std::size_t ops() { return m_ops; } protected void setup_base(analog_net_t_list_t nets) { log().debug.op("New solver setup\n"); m_nets.clear(); m_terms.clear(); foreach (var net in nets) { m_nets.push_back(net); m_terms.push_back(new terms_for_net_t()); m_rails_temp.push_back(new terms_for_net_t()); } for (UInt32 k = 0; k < nets.size(); k++) { analog_net_t net = nets[k]; log().debug.op("setting up net\n"); net.set_solver(this); foreach (var p in net.core_terms) { log().debug.op("{0} {1} {2}\n", p.name(), net.name(), net.isRailNet()); switch (p.type()) { case detail.terminal_type.TERMINAL: if (p.device().is_timestep()) { if (!m_step_devices.Contains(p.device())) //(!plib::container::contains(m_step_devices, &p->device())) { m_step_devices.push_back(p.device()); } } if (p.device().is_dynamic()) { if (!m_dynamic_devices.Contains(p.device())) //if (!plib::container::contains(m_dynamic_devices, &p->device())) { m_dynamic_devices.push_back(p.device()); } } { terminal_t pterm = (terminal_t)p; add_term(k, pterm); } log().debug.op("Added terminal {0}\n", p.name()); break; case detail.terminal_type.INPUT: { proxied_analog_output_t net_proxy_output = null; foreach (var input in m_inps) { if (input.proxied_net == p.net()) { net_proxy_output = input; break; } } if (net_proxy_output == null) { string nname = this.name() + "." + new plib.pfmt("m{0}").op(m_inps.size()); var net_proxy_output_u = new proxied_analog_output_t(this, nname); net_proxy_output = net_proxy_output_u; m_inps.push_back(net_proxy_output_u); nl_base_global.nl_assert(p.net().is_analog()); net_proxy_output.proxied_net = (analog_net_t)p.net(); } net_proxy_output.net().add_terminal(p); // FIXME: repeated calling - kind of brute force net_proxy_output.net().rebuild_list(); log().debug.op("Added input\n"); } break; case detail.terminal_type.OUTPUT: log().fatal.op(nl_errstr_global.MF_1_UNHANDLED_ELEMENT_1_FOUND, p.name()); break; } } log().debug.op("added net with {0} populated connections\n", net.core_terms.size()); } /* now setup the matrix */ setup_matrix(); }
// debugging //void dump(std::ostream &str) const; //std::string dump(); // internal helpers //------------------------------------------------- // build_codes - given an input port table, create // an input code table useful for mapping unicode // chars //------------------------------------------------- void build_codes() { ioport_manager manager = machine().ioport(); // find all the devices with keyboard or keypad inputs foreach (var port in manager.ports()) { var devinfo = std.find_if( m_keyboards, (kbd_dev_info info) => { return(port.second().device() == info.device); }); foreach (ioport_field field in port.second().fields()) { bool is_keyboard = field.type() == ioport_type.IPT_KEYBOARD; if (is_keyboard || (field.type() == ioport_type.IPT_KEYPAD)) { if (default == devinfo) { //devinfo = m_keyboards.emplace(devinfo, port.second->device()); devinfo = new kbd_dev_info(port.second().device()); m_keyboards.push_back(devinfo); } devinfo.keyfields.emplace_back(field); if (is_keyboard) { devinfo.keyboard = true; } else { devinfo.keypad = true; } } } } std.sort( m_keyboards, (kbd_dev_info l, kbd_dev_info r) => { return(std.strcmp(l.device.tag(), r.device.tag())); }); // set up key mappings for each keyboard std.array <ioport_field, size_t_const_SHIFT_COUNT> shift = new std.array <ioport_field, size_t_const_SHIFT_COUNT>(); unsigned mask; bool have_keyboard = false; foreach (kbd_dev_info devinfo in m_keyboards) { if (LOG_NATURAL_KEYBOARD) { machine().logerror("natural_keyboard: building codes for {0}... ({1} fields)\n", devinfo.device.tag(), devinfo.keyfields.size()); } // enable all pure keypads and the first keyboard if (!devinfo.keyboard || !have_keyboard) { devinfo.enabled = true; } have_keyboard = have_keyboard || devinfo.keyboard; // find all shift keys std.fill(shift, (ioport_field)null); //std::fill(std::begin(shift), std::end(shift), nullptr); mask = 0; foreach (ioport_field field in devinfo.keyfields) { if (field.type() == ioport_type.IPT_KEYBOARD) { std.vector <char32_t> codes = field.keyboard_codes(0); foreach (char32_t code in codes) { if ((code >= UCHAR_SHIFT_BEGIN) && (code <= UCHAR_SHIFT_END)) { mask |= 1U << (int)(code - UCHAR_SHIFT_BEGIN); shift[code - UCHAR_SHIFT_BEGIN] = field; if (LOG_NATURAL_KEYBOARD) { machine().logerror("natural_keyboard: UCHAR_SHIFT_{0} found\n", code - UCHAR_SHIFT_BEGIN + 1); } } } } } // iterate over keyboard/keypad fields foreach (ioport_field field in devinfo.keyfields) { field.live().lockout = !devinfo.enabled; if (field.type() == ioport_type.IPT_KEYBOARD) { // iterate over all shift states for (unsigned curshift = 0; curshift < SHIFT_STATES; ++curshift) { if ((curshift & ~mask) == 0) { // fetch the code, ignoring 0 and shifters std.vector <char32_t> codes = field.keyboard_codes((int)curshift); foreach (char32_t code in codes) { if (((code < UCHAR_SHIFT_BEGIN) || (code > UCHAR_SHIFT_END)) && (code != 0)) { m_have_charkeys = true; var found = devinfo.codemap.find(code); //keycode_map::iterator const found(devinfo.codemap.find(code)); keycode_map_entry newcode = new keycode_map_entry(); std.fill(newcode.field, (ioport_field)null); //std::fill(std::begin(newcode.field), std::end(newcode.field), nullptr); newcode.shift = curshift; newcode.condition = field.condition(); unsigned fieldnum = 0; for (unsigned i = 0, bits = curshift; (i < SHIFT_COUNT) && (bits != 0); ++i, bits >>= 1) { if (BIT(bits, 0) != 0) { newcode.field[fieldnum++] = shift[i]; } } newcode.field[fieldnum] = field; if (default == found) { natural_keyboard_keycode_map_entries entries = new natural_keyboard_keycode_map_entries(); entries.emplace_back(newcode); devinfo.codemap.emplace(code, entries); } else { found.emplace_back(newcode); } if (LOG_NATURAL_KEYBOARD) { machine().logerror("natural_keyboard: code={0} ({1}) port={2} field.name='{3}'\n", code, unicode_to_string(code), field.port(), field.name()); } } } } } } } // sort mapping entries by shift state foreach (var mapping in devinfo.codemap) { std.sort( mapping.second(), (keycode_map_entry x, keycode_map_entry y) => { return(x.shift.CompareTo(y.shift)); }); //[] (keycode_map_entry const &x, keycode_map_entry const &y) { return x.shift < y.shift; }); } }