mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +03:00
Added a simple preprocessor to the netlist parsing pipeline.
This preprpcessor understands defines and nested if/else/endif #define MYMACRO 0 #if (MYMACRO) .... #else #endif One can now run ./nltool -c run -f src/mame/drivers/nl_pong.c -t 10 without removing preprocessor elements first. This does not work with netlist originating from DICE currently. These have to be converted first. In addition, cleaned up __attribute__ madness in the code. Specifically removed ATTR_COLD from virtual definitions to avoid the vtable being declared as cold.
This commit is contained in:
parent
784410e9c9
commit
d68fe923a1
@ -18,11 +18,13 @@ files {
|
||||
MAME_DIR .. "src/emu/netlist/pconfig.h",
|
||||
MAME_DIR .. "src/emu/netlist/palloc.c",
|
||||
MAME_DIR .. "src/emu/netlist/palloc.h",
|
||||
MAME_DIR .. "src/emu/netlist/pstring.c",
|
||||
MAME_DIR .. "src/emu/netlist/pstring.h",
|
||||
MAME_DIR .. "src/emu/netlist/plists.h",
|
||||
MAME_DIR .. "src/emu/netlist/pparser.c",
|
||||
MAME_DIR .. "src/emu/netlist/pparser.h",
|
||||
MAME_DIR .. "src/emu/netlist/pstate.c",
|
||||
MAME_DIR .. "src/emu/netlist/pstate.h",
|
||||
MAME_DIR .. "src/emu/netlist/pstring.c",
|
||||
MAME_DIR .. "src/emu/netlist/pstring.h",
|
||||
MAME_DIR .. "src/emu/netlist/analog/nld_bjt.c",
|
||||
MAME_DIR .. "src/emu/netlist/analog/nld_bjt.h",
|
||||
MAME_DIR .. "src/emu/netlist/analog/nld_fourterm.c",
|
||||
|
@ -46,8 +46,8 @@ public:
|
||||
inline bool is_qtype(q_type atype) const { return m_qtype == atype; }
|
||||
inline void set_qtype(q_type atype) { m_qtype = atype; }
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
ATTR_HOT void update();
|
||||
|
||||
netlist_param_model_t m_model;
|
||||
@ -110,9 +110,9 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD virtual void start();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
ATTR_HOT virtual void update_param();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
nl_double m_gB; // base conductance / switch on
|
||||
@ -142,8 +142,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
ATTR_HOT void update_param();
|
||||
ATTR_HOT void virtual update();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
@ -56,9 +56,9 @@ public:
|
||||
: netlist_device_t(afamily), m_gfac(1.0) { }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
ATTR_COLD virtual void update_param();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
/* ATTR_COLD */ virtual void update_param();
|
||||
ATTR_HOT void update();
|
||||
|
||||
ATTR_COLD void start_internal(const nl_double def_RI);
|
||||
@ -112,9 +112,9 @@ public:
|
||||
//: netlist_device_t(afamily), m_gfac(1.0) { }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
ATTR_COLD virtual void update_param();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
/* ATTR_COLD */ virtual void update_param();
|
||||
ATTR_HOT void update();
|
||||
|
||||
nl_double m_gfac;
|
||||
@ -156,9 +156,9 @@ public:
|
||||
: NETLIB_NAME(VCCS)(VCVS) { }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
ATTR_COLD virtual void update_param();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
/* ATTR_COLD */ virtual void update_param();
|
||||
//ATTR_HOT void update();
|
||||
|
||||
netlist_terminal_t m_OP2;
|
||||
|
@ -20,15 +20,15 @@ public:
|
||||
|
||||
virtual ~netlist_matrix_solver_direct_t();
|
||||
|
||||
ATTR_COLD virtual void vsetup(netlist_analog_net_t::list_t &nets);
|
||||
ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); }
|
||||
/* ATTR_COLD */ virtual void vsetup(netlist_analog_net_t::list_t &nets);
|
||||
/* ATTR_COLD */ virtual void reset() { netlist_matrix_solver_t::reset(); }
|
||||
|
||||
ATTR_HOT inline int N() const { return (m_N == 0 ? m_dim : m_N); }
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term);
|
||||
/* ATTR_COLD */ virtual void add_term(int net_idx, netlist_terminal_t *term);
|
||||
|
||||
ATTR_HOT virtual nl_double vsolve();
|
||||
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
|
||||
virtual ~netlist_matrix_solver_SOR_t() {}
|
||||
|
||||
ATTR_COLD virtual void log_stats();
|
||||
/* ATTR_COLD */ virtual void log_stats();
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic();
|
||||
protected:
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
virtual ~netlist_matrix_solver_SOR_t() {}
|
||||
|
||||
ATTR_COLD virtual void log_stats();
|
||||
/* ATTR_COLD */ virtual void log_stats();
|
||||
|
||||
ATTR_HOT virtual int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
virtual ~netlist_matrix_solver_SOR_mat_t() {}
|
||||
|
||||
ATTR_COLD virtual void log_stats();
|
||||
/* ATTR_COLD */ virtual void log_stats();
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
|
@ -97,9 +97,9 @@ public:
|
||||
};
|
||||
|
||||
ATTR_COLD netlist_matrix_solver_t(const eSolverType type, const netlist_solver_parameters_t ¶ms);
|
||||
ATTR_COLD virtual ~netlist_matrix_solver_t();
|
||||
/* ATTR_COLD */ virtual ~netlist_matrix_solver_t();
|
||||
|
||||
ATTR_COLD virtual void vsetup(netlist_analog_net_t::list_t &nets) = 0;
|
||||
/* ATTR_COLD */ virtual void vsetup(netlist_analog_net_t::list_t &nets) = 0;
|
||||
|
||||
template<class C>
|
||||
void solve_base(C *p);
|
||||
@ -117,11 +117,11 @@ public:
|
||||
|
||||
/* netdevice functions */
|
||||
ATTR_HOT virtual void update();
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
|
||||
ATTR_COLD int get_net_idx(netlist_net_t *net);
|
||||
ATTR_COLD virtual void log_stats() {};
|
||||
/* ATTR_COLD */ virtual void log_stats() {};
|
||||
|
||||
inline eSolverType type() const { return m_type; }
|
||||
|
||||
@ -133,7 +133,7 @@ protected:
|
||||
// should return next time step
|
||||
ATTR_HOT virtual nl_double vsolve() = 0;
|
||||
|
||||
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term) = 0;
|
||||
/* ATTR_COLD */ virtual void add_term(int net_idx, netlist_terminal_t *term) = 0;
|
||||
|
||||
plist_t<netlist_analog_net_t *> m_nets;
|
||||
plist_t<netlist_analog_output_t *> m_inps;
|
||||
@ -170,7 +170,7 @@ public:
|
||||
NETLIB_NAME(solver)()
|
||||
: netlist_device_t() { }
|
||||
|
||||
ATTR_COLD virtual ~NETLIB_NAME(solver)();
|
||||
/* ATTR_COLD */ virtual ~NETLIB_NAME(solver)();
|
||||
|
||||
ATTR_COLD void post_start();
|
||||
ATTR_COLD void stop();
|
||||
|
@ -122,8 +122,8 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
ATTR_HOT void update();
|
||||
|
||||
private:
|
||||
@ -144,8 +144,8 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
ATTR_HOT void update();
|
||||
};
|
||||
|
||||
@ -193,9 +193,9 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void reset();
|
||||
ATTR_COLD virtual void update_param();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
/* ATTR_COLD */ virtual void update_param();
|
||||
ATTR_HOT void update();
|
||||
|
||||
netlist_param_double_t m_C;
|
||||
@ -282,8 +282,8 @@ public:
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void update_param();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
/* ATTR_COLD */ virtual void update_param();
|
||||
ATTR_HOT void update();
|
||||
|
||||
netlist_param_model_t m_model;
|
||||
|
@ -138,7 +138,7 @@ public:
|
||||
ATTR_COLD NETLIB_NAME(gnd)()
|
||||
: netlist_device_t(GND) { }
|
||||
|
||||
ATTR_COLD virtual ~NETLIB_NAME(gnd)() {}
|
||||
/* ATTR_COLD */ virtual ~NETLIB_NAME(gnd)() {}
|
||||
|
||||
protected:
|
||||
|
||||
@ -171,7 +171,7 @@ public:
|
||||
ATTR_COLD NETLIB_NAME(dummy_input)()
|
||||
: netlist_device_t(DUMMY) { }
|
||||
|
||||
ATTR_COLD virtual ~NETLIB_NAME(dummy_input)() {}
|
||||
/* ATTR_COLD */ virtual ~NETLIB_NAME(dummy_input)() {}
|
||||
|
||||
protected:
|
||||
|
||||
@ -203,7 +203,7 @@ public:
|
||||
ATTR_COLD NETLIB_NAME(frontier)()
|
||||
: netlist_device_t(DUMMY) { }
|
||||
|
||||
ATTR_COLD virtual ~NETLIB_NAME(frontier)() {}
|
||||
/* ATTR_COLD */ virtual ~NETLIB_NAME(frontier)() {}
|
||||
|
||||
protected:
|
||||
|
||||
@ -238,7 +238,7 @@ public:
|
||||
ATTR_COLD NETLIB_NAME(res_sw)()
|
||||
: netlist_device_t() { }
|
||||
|
||||
ATTR_COLD virtual ~NETLIB_NAME(res_sw)() {}
|
||||
/* ATTR_COLD */ virtual ~NETLIB_NAME(res_sw)() {}
|
||||
|
||||
netlist_param_double_t m_RON;
|
||||
netlist_param_double_t m_ROFF;
|
||||
@ -271,14 +271,14 @@ public:
|
||||
m_proxy_term = &proxy_inout;
|
||||
}
|
||||
|
||||
ATTR_COLD virtual ~nld_base_proxy() {}
|
||||
/* ATTR_COLD */ virtual ~nld_base_proxy() {}
|
||||
|
||||
ATTR_COLD netlist_logic_t &term_proxied() const { return *m_term_proxied; }
|
||||
ATTR_COLD netlist_core_terminal_t &proxy_term() const { return *m_proxy_term; }
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD virtual const netlist_logic_family_desc_t &logic_family() const
|
||||
/* ATTR_COLD */ virtual const netlist_logic_family_desc_t &logic_family() const
|
||||
{
|
||||
return *m_logic_family;
|
||||
}
|
||||
@ -301,7 +301,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ATTR_COLD virtual ~nld_a_to_d_proxy() {}
|
||||
/* ATTR_COLD */ virtual ~nld_a_to_d_proxy() {}
|
||||
|
||||
netlist_analog_input_t m_I;
|
||||
netlist_logic_output_t m_Q;
|
||||
@ -343,12 +343,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ATTR_COLD virtual ~nld_base_d_to_a_proxy() {}
|
||||
/* ATTR_COLD */ virtual ~nld_base_d_to_a_proxy() {}
|
||||
|
||||
ATTR_COLD virtual netlist_logic_input_t &in() { return m_I; }
|
||||
/* ATTR_COLD */ virtual netlist_logic_input_t &in() { return m_I; }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start()
|
||||
/* ATTR_COLD */ virtual void start()
|
||||
{
|
||||
register_input("I", m_I);
|
||||
}
|
||||
@ -369,12 +369,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ATTR_COLD virtual ~nld_d_to_a_proxy() {}
|
||||
/* ATTR_COLD */ virtual ~nld_d_to_a_proxy() {}
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
/* ATTR_COLD */ virtual void start();
|
||||
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
|
||||
ATTR_HOT void update();
|
||||
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ATTR_COLD virtual void start()
|
||||
/* ATTR_COLD */ virtual void start()
|
||||
{
|
||||
pstring ttline = pstring(m_desc[0]);
|
||||
|
||||
|
@ -251,7 +251,7 @@ typedef void (*net_update_delegate)(netlist_core_device_t *);
|
||||
, _priv)
|
||||
|
||||
#define NETLIB_LOGIC_FAMILY(_fam) \
|
||||
ATTR_COLD virtual const netlist_logic_family_desc_t *default_logic_family() \
|
||||
/* ATTR_COLD */ virtual const netlist_logic_family_desc_t *default_logic_family() \
|
||||
{ \
|
||||
return &netlist_family_ ## _fam; \
|
||||
}
|
||||
@ -412,9 +412,9 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD virtual void reset() = 0;
|
||||
/* ATTR_COLD */ virtual void reset() = 0;
|
||||
// must call parent save_register !
|
||||
ATTR_COLD virtual void save_register() { };
|
||||
/* ATTR_COLD */ virtual void save_register() { };
|
||||
|
||||
private:
|
||||
pstring m_name;
|
||||
@ -486,7 +486,7 @@ public:
|
||||
ATTR_HOT inline void update_dev(const UINT32 mask);
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void save_register()
|
||||
/* ATTR_COLD */ virtual void save_register()
|
||||
{
|
||||
save(NLNAME(m_state));
|
||||
netlist_owned_object_t::save_register();
|
||||
@ -540,9 +540,9 @@ public:
|
||||
netlist_terminal_t *m_otherterm;
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void save_register();
|
||||
/* ATTR_COLD */ virtual void save_register();
|
||||
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
private:
|
||||
ATTR_HOT inline void set_ptr(nl_double *ptr, const nl_double val)
|
||||
{
|
||||
@ -616,7 +616,7 @@ public:
|
||||
ATTR_HOT inline void activate_lh();
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void reset()
|
||||
/* ATTR_COLD */ virtual void reset()
|
||||
{
|
||||
//netlist_core_terminal_t::reset();
|
||||
set_state(STATE_INP_ACTIVE);
|
||||
@ -640,7 +640,7 @@ public:
|
||||
ATTR_HOT inline nl_double Q_Analog() const;
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void reset()
|
||||
/* ATTR_COLD */ virtual void reset()
|
||||
{
|
||||
//netlist_core_terminal_t::reset();
|
||||
set_state(STATE_INP_ACTIVE);
|
||||
@ -659,7 +659,7 @@ public:
|
||||
typedef plist_t<netlist_net_t *> list_t;
|
||||
|
||||
ATTR_COLD netlist_net_t(const family_t afamily);
|
||||
ATTR_COLD virtual ~netlist_net_t();
|
||||
/* ATTR_COLD */ virtual ~netlist_net_t();
|
||||
|
||||
ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname);
|
||||
|
||||
@ -708,8 +708,8 @@ public:
|
||||
|
||||
protected: //FIXME: needed by current solver code
|
||||
|
||||
ATTR_COLD virtual void save_register();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void save_register();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
|
||||
netlist_sig_t m_new_Q;
|
||||
netlist_sig_t m_cur_Q;
|
||||
@ -739,7 +739,7 @@ public:
|
||||
typedef plist_t<netlist_logic_net_t *> list_t;
|
||||
|
||||
ATTR_COLD netlist_logic_net_t();
|
||||
ATTR_COLD virtual ~netlist_logic_net_t() { };
|
||||
/* ATTR_COLD */ virtual ~netlist_logic_net_t() { };
|
||||
|
||||
ATTR_HOT inline netlist_sig_t Q() const
|
||||
{
|
||||
@ -781,8 +781,8 @@ public:
|
||||
|
||||
protected: //FIXME: needed by current solver code
|
||||
|
||||
ATTR_COLD virtual void save_register();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void save_register();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
|
||||
|
||||
private:
|
||||
@ -799,7 +799,7 @@ public:
|
||||
typedef plist_t<netlist_analog_net_t *> list_t;
|
||||
|
||||
ATTR_COLD netlist_analog_net_t();
|
||||
ATTR_COLD virtual ~netlist_analog_net_t() { };
|
||||
/* ATTR_COLD */ virtual ~netlist_analog_net_t() { };
|
||||
|
||||
ATTR_HOT inline nl_double Q_Analog() const
|
||||
{
|
||||
@ -818,8 +818,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD virtual void save_register();
|
||||
ATTR_COLD virtual void reset();
|
||||
/* ATTR_COLD */ virtual void save_register();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
|
||||
|
||||
private:
|
||||
@ -844,7 +844,7 @@ public:
|
||||
ATTR_COLD netlist_logic_output_t();
|
||||
|
||||
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname);
|
||||
ATTR_COLD virtual void reset()
|
||||
/* ATTR_COLD */ virtual void reset()
|
||||
{
|
||||
set_state(STATE_OUT);
|
||||
}
|
||||
@ -868,7 +868,7 @@ public:
|
||||
ATTR_COLD netlist_analog_output_t();
|
||||
|
||||
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname);
|
||||
ATTR_COLD virtual void reset()
|
||||
/* ATTR_COLD */ virtual void reset()
|
||||
{
|
||||
set_state(STATE_OUT);
|
||||
}
|
||||
@ -906,7 +906,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD virtual void reset() { }
|
||||
/* ATTR_COLD */ virtual void reset() { }
|
||||
|
||||
private:
|
||||
const param_type_t m_param_type;
|
||||
@ -923,7 +923,7 @@ public:
|
||||
ATTR_HOT inline nl_double Value() const { return m_param; }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void save_register()
|
||||
/* ATTR_COLD */ virtual void save_register()
|
||||
{
|
||||
save(NLNAME(m_param));
|
||||
netlist_param_t::save_register();
|
||||
@ -945,7 +945,7 @@ public:
|
||||
ATTR_HOT inline int Value() const { return m_param; }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void save_register()
|
||||
/* ATTR_COLD */ virtual void save_register()
|
||||
{
|
||||
save(NLNAME(m_param));
|
||||
netlist_param_t::save_register();
|
||||
@ -1008,9 +1008,9 @@ public:
|
||||
|
||||
ATTR_COLD netlist_core_device_t(const family_t afamily);
|
||||
|
||||
ATTR_COLD virtual ~netlist_core_device_t();
|
||||
/* ATTR_COLD */ virtual ~netlist_core_device_t();
|
||||
|
||||
ATTR_COLD virtual void init(netlist_base_t &anetlist, const pstring &name);
|
||||
/* ATTR_COLD */ virtual void init(netlist_base_t &anetlist, const pstring &name);
|
||||
ATTR_HOT virtual void update_param() {}
|
||||
|
||||
ATTR_HOT inline void update_dev()
|
||||
@ -1076,9 +1076,9 @@ public:
|
||||
protected:
|
||||
|
||||
ATTR_HOT virtual void update() { }
|
||||
ATTR_COLD virtual void start() { }
|
||||
ATTR_COLD virtual void stop() { } \
|
||||
ATTR_COLD virtual const netlist_logic_family_desc_t *default_logic_family()
|
||||
/* ATTR_COLD */ virtual void start() { }
|
||||
/* ATTR_COLD */ virtual void stop() { } \
|
||||
/* ATTR_COLD */ virtual const netlist_logic_family_desc_t *default_logic_family()
|
||||
{
|
||||
return &netlist_family_TTL;
|
||||
}
|
||||
@ -1095,9 +1095,9 @@ public:
|
||||
ATTR_COLD netlist_device_t();
|
||||
ATTR_COLD netlist_device_t(const family_t afamily);
|
||||
|
||||
ATTR_COLD virtual ~netlist_device_t();
|
||||
/* ATTR_COLD */ virtual ~netlist_device_t();
|
||||
|
||||
ATTR_COLD virtual void init(netlist_base_t &anetlist, const pstring &name);
|
||||
/* ATTR_COLD */ virtual void init(netlist_base_t &anetlist, const pstring &name);
|
||||
|
||||
ATTR_COLD netlist_setup_t &setup();
|
||||
|
||||
@ -1252,12 +1252,12 @@ protected:
|
||||
};
|
||||
|
||||
// any derived netlist must override this ...
|
||||
ATTR_COLD virtual void verror(const loglevel_e level,
|
||||
/* ATTR_COLD */ virtual void verror(const loglevel_e level,
|
||||
const char *format, va_list ap) const = 0;
|
||||
|
||||
/* from netlist_object */
|
||||
ATTR_COLD virtual void reset();
|
||||
ATTR_COLD virtual void save_register();
|
||||
/* ATTR_COLD */ virtual void reset();
|
||||
/* ATTR_COLD */ virtual void save_register();
|
||||
|
||||
#if (NL_KEEP_STATISTICS)
|
||||
// performance
|
||||
|
@ -28,9 +28,9 @@ public:
|
||||
: m_name(name), m_classname(classname), m_def_param(def_param)
|
||||
{}
|
||||
|
||||
ATTR_COLD virtual ~net_device_t_base_factory() {}
|
||||
/* ATTR_COLD */ virtual ~net_device_t_base_factory() {}
|
||||
|
||||
ATTR_COLD virtual netlist_device_t *Create() const = 0;
|
||||
/* ATTR_COLD */ virtual netlist_device_t *Create() const = 0;
|
||||
|
||||
ATTR_COLD const pstring &name() const { return m_name; }
|
||||
ATTR_COLD const pstring &classname() const { return m_classname; }
|
||||
@ -66,8 +66,8 @@ class netlist_factory_t
|
||||
public:
|
||||
typedef plist_t<net_device_t_base_factory *> list_t;
|
||||
|
||||
ATTR_COLD netlist_factory_t();
|
||||
ATTR_COLD ~netlist_factory_t();
|
||||
netlist_factory_t();
|
||||
~netlist_factory_t();
|
||||
|
||||
template<class _C>
|
||||
ATTR_COLD void register_device(const pstring &name, const pstring &classname,
|
||||
|
@ -11,197 +11,6 @@
|
||||
//#undef NL_VERBOSE_OUT
|
||||
//#define NL_VERBOSE_OUT(x) printf x
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A simple tokenizer
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
pstring ptokenizer::currentline_str()
|
||||
{
|
||||
char buf[300];
|
||||
int bufp = 0;
|
||||
const char *p = m_line_ptr;
|
||||
while (*p && *p != 10)
|
||||
buf[bufp++] = *p++;
|
||||
buf[bufp] = 0;
|
||||
return pstring(buf);
|
||||
}
|
||||
|
||||
|
||||
void ptokenizer::skipeol()
|
||||
{
|
||||
char c = getc();
|
||||
while (c)
|
||||
{
|
||||
if (c == 10)
|
||||
{
|
||||
c = getc();
|
||||
if (c != 13)
|
||||
ungetc();
|
||||
return;
|
||||
}
|
||||
c = getc();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned char ptokenizer::getc()
|
||||
{
|
||||
if (*m_px == 10)
|
||||
{
|
||||
m_line++;
|
||||
m_line_ptr = m_px + 1;
|
||||
}
|
||||
if (*m_px)
|
||||
return *(m_px++);
|
||||
else
|
||||
return *m_px;
|
||||
}
|
||||
|
||||
void ptokenizer::ungetc()
|
||||
{
|
||||
m_px--;
|
||||
}
|
||||
|
||||
void ptokenizer::require_token(const token_id_t &token_num)
|
||||
{
|
||||
require_token(get_token(), token_num);
|
||||
}
|
||||
|
||||
void ptokenizer::require_token(const token_t tok, const token_id_t &token_num)
|
||||
{
|
||||
if (!tok.is(token_num))
|
||||
{
|
||||
error("Error: expected token <%s> got <%s>\n", m_tokens[token_num.id()].cstr(), tok.str().cstr());
|
||||
}
|
||||
}
|
||||
|
||||
pstring ptokenizer::get_string()
|
||||
{
|
||||
token_t tok = get_token();
|
||||
if (!tok.is_type(STRING))
|
||||
{
|
||||
error("Error: expected a string, got <%s>\n", tok.str().cstr());
|
||||
}
|
||||
return tok.str();
|
||||
}
|
||||
|
||||
pstring ptokenizer::get_identifier()
|
||||
{
|
||||
token_t tok = get_token();
|
||||
if (!tok.is_type(IDENTIFIER))
|
||||
{
|
||||
error("Error: expected an identifier, got <%s>\n", tok.str().cstr());
|
||||
}
|
||||
return tok.str();
|
||||
}
|
||||
|
||||
ptokenizer::token_t ptokenizer::get_token()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
token_t ret = get_token_internal();
|
||||
if (ret.is_type(ENDOFFILE))
|
||||
return ret;
|
||||
|
||||
if (ret.is(m_tok_comment_start))
|
||||
{
|
||||
do {
|
||||
ret = get_token_internal();
|
||||
} while (ret.is_not(m_tok_comment_end));
|
||||
}
|
||||
else if (ret.is(m_tok_line_comment))
|
||||
{
|
||||
skipeol();
|
||||
}
|
||||
else if (ret.str() == "#")
|
||||
{
|
||||
skipeol();
|
||||
}
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ptokenizer::token_t ptokenizer::get_token_internal()
|
||||
{
|
||||
/* skip ws */
|
||||
char c = getc();
|
||||
while (m_whitespace.find(c)>=0)
|
||||
{
|
||||
c = getc();
|
||||
if (eof())
|
||||
{
|
||||
return token_t(ENDOFFILE);
|
||||
}
|
||||
}
|
||||
if (m_identifier_chars.find(c)>=0)
|
||||
{
|
||||
/* read identifier till non identifier char */
|
||||
pstring tokstr = "";
|
||||
while (m_identifier_chars.find(c)>=0) {
|
||||
tokstr += c;
|
||||
c = getc();
|
||||
}
|
||||
ungetc();
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
else
|
||||
{
|
||||
return token_t(IDENTIFIER, tokstr);
|
||||
}
|
||||
}
|
||||
else if (c == m_string)
|
||||
{
|
||||
pstring tokstr = "";
|
||||
c = getc();
|
||||
while (c != m_string)
|
||||
{
|
||||
tokstr += c;
|
||||
c = getc();
|
||||
}
|
||||
return token_t(STRING, tokstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read identifier till first identifier char or ws */
|
||||
pstring tokstr = "";
|
||||
while ((m_identifier_chars.find(c)) < 0 && (m_whitespace.find(c) < 0)) {
|
||||
tokstr += c;
|
||||
/* expensive, check for single char tokens */
|
||||
if (tokstr.len() == 1)
|
||||
{
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
}
|
||||
c = getc();
|
||||
}
|
||||
ungetc();
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
else
|
||||
{
|
||||
return token_t(UNKNOWN, tokstr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ATTR_COLD void ptokenizer::error(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
pstring errmsg1 = pstring(format).vprintf(ap);
|
||||
va_end(ap);
|
||||
|
||||
verror(errmsg1, currentline_no(), currentline_str());
|
||||
|
||||
//throw error;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A netlist parser
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -217,9 +26,12 @@ ATTR_COLD void netlist_parser::verror(pstring msg, int line_num, pstring line)
|
||||
|
||||
bool netlist_parser::parse(const char *buf, const pstring nlname)
|
||||
{
|
||||
m_buf = buf;
|
||||
ppreprocessor prepro;
|
||||
|
||||
reset(buf);
|
||||
pstring processed = prepro.process(buf);
|
||||
m_buf = processed.cstr();
|
||||
|
||||
reset(m_buf);
|
||||
set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-");
|
||||
set_number_chars("01234567890eE-."); //FIXME: processing of numbers
|
||||
char ws[5];
|
||||
|
@ -9,132 +9,8 @@
|
||||
#define NL_PARSER_H_
|
||||
|
||||
#include "nl_setup.h"
|
||||
|
||||
class ptokenizer
|
||||
{
|
||||
NETLIST_PREVENT_COPYING(ptokenizer)
|
||||
public:
|
||||
virtual ~ptokenizer() {}
|
||||
|
||||
ptokenizer()
|
||||
: m_line(1), m_line_ptr(NULL), m_px(NULL), m_string('"')
|
||||
{}
|
||||
|
||||
enum token_type
|
||||
{
|
||||
IDENTIFIER,
|
||||
NUMBER,
|
||||
TOKEN,
|
||||
STRING,
|
||||
COMMENT,
|
||||
UNKNOWN,
|
||||
ENDOFFILE
|
||||
};
|
||||
|
||||
struct token_id_t
|
||||
{
|
||||
public:
|
||||
token_id_t() : m_id(-2) {}
|
||||
token_id_t(const int id) : m_id(id) {}
|
||||
int id() const { return m_id; }
|
||||
private:
|
||||
int m_id;
|
||||
};
|
||||
|
||||
struct token_t
|
||||
{
|
||||
token_t(token_type type)
|
||||
{
|
||||
m_type = type;
|
||||
m_id = token_id_t(-1);
|
||||
m_token ="";
|
||||
}
|
||||
token_t(token_type type, const pstring str)
|
||||
{
|
||||
m_type = type;
|
||||
m_id = token_id_t(-1);
|
||||
m_token = str;
|
||||
}
|
||||
token_t(const token_id_t id, const pstring str)
|
||||
{
|
||||
m_type = TOKEN;
|
||||
m_id = id;
|
||||
m_token = str;
|
||||
}
|
||||
|
||||
bool is(const token_id_t &tok_id) const { return m_id.id() == tok_id.id(); }
|
||||
bool is_not(const token_id_t &tok_id) const { return !is(tok_id); }
|
||||
|
||||
bool is_type(const token_type type) const { return m_type == type; }
|
||||
|
||||
pstring str() const { return m_token; }
|
||||
|
||||
private:
|
||||
token_type m_type;
|
||||
token_id_t m_id;
|
||||
pstring m_token;
|
||||
};
|
||||
|
||||
|
||||
int currentline_no() { return m_line; }
|
||||
pstring currentline_str();
|
||||
|
||||
/* tokenizer stuff follows ... */
|
||||
|
||||
token_t get_token();
|
||||
pstring get_string();
|
||||
pstring get_identifier();
|
||||
|
||||
void require_token(const token_id_t &token_num);
|
||||
void require_token(const token_t tok, const token_id_t &token_num);
|
||||
|
||||
token_id_t register_token(pstring token)
|
||||
{
|
||||
m_tokens.add(token);
|
||||
return token_id_t(m_tokens.count() - 1);
|
||||
}
|
||||
|
||||
void set_identifier_chars(pstring s) { m_identifier_chars = s; }
|
||||
void set_number_chars(pstring s) { m_number_chars = s; }
|
||||
void set_whitespace(pstring s) { m_whitespace = s; }
|
||||
void set_comment(pstring start, pstring end, pstring line)
|
||||
{
|
||||
m_tok_comment_start = register_token(start);
|
||||
m_tok_comment_end = register_token(end);
|
||||
m_tok_line_comment = register_token(line);
|
||||
m_string = '"';
|
||||
}
|
||||
|
||||
token_t get_token_internal();
|
||||
void error(const char *format, ...) ATTR_PRINTF(2,3);
|
||||
|
||||
protected:
|
||||
void reset(const char *p) { m_px = p; m_line = 1; m_line_ptr = p; }
|
||||
virtual void verror(pstring msg, int line_num, pstring line) = 0;
|
||||
|
||||
private:
|
||||
void skipeol();
|
||||
|
||||
unsigned char getc();
|
||||
void ungetc();
|
||||
bool eof() { return *m_px == 0; }
|
||||
|
||||
int m_line;
|
||||
const char * m_line_ptr;
|
||||
const char * m_px;
|
||||
|
||||
/* tokenizer stuff follows ... */
|
||||
|
||||
pstring m_identifier_chars;
|
||||
pstring m_number_chars;
|
||||
plist_t<pstring> m_tokens;
|
||||
pstring m_whitespace;
|
||||
char m_string;
|
||||
|
||||
token_id_t m_tok_comment_start;
|
||||
token_id_t m_tok_comment_end;
|
||||
token_id_t m_tok_line_comment;
|
||||
};
|
||||
#include "nl_util.h"
|
||||
#include "pparser.h"
|
||||
|
||||
class netlist_parser : public ptokenizer
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "pstring.h"
|
||||
#include "plists.h"
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
class nl_util
|
||||
{
|
||||
@ -45,6 +46,43 @@ public:
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
static pstring_list splitexpr(const pstring &str, const pstring_list &onstrl)
|
||||
{
|
||||
pstring_list temp;
|
||||
pstring col = "";
|
||||
|
||||
int i = 0;
|
||||
while (i<str.len())
|
||||
{
|
||||
int p = -1;
|
||||
for (int j=0; j < onstrl.count(); j++)
|
||||
{
|
||||
if (std::strncmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].len())==0)
|
||||
{
|
||||
p = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p>=0)
|
||||
{
|
||||
if (col != "")
|
||||
temp.add(col);
|
||||
col = "";
|
||||
temp.add(onstrl[p]);
|
||||
i += onstrl[p].len();
|
||||
}
|
||||
else
|
||||
{
|
||||
col += str.cstr()[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (col != "")
|
||||
temp.add(col);
|
||||
return temp;
|
||||
}
|
||||
|
||||
static const pstring environment(const pstring &var, const pstring &default_val = "")
|
||||
{
|
||||
if (getenv(var.cstr()) == NULL)
|
||||
|
@ -33,9 +33,9 @@
|
||||
/* not supported in GCC prior to 4.4.x */
|
||||
/* ATTR_HOT and ATTR_COLD cause performance degration in 5.1 */
|
||||
//#define ATTR_HOT
|
||||
#define ATTR_COLD
|
||||
//#define ATTR_COLD
|
||||
#define ATTR_HOT __attribute__((hot))
|
||||
//#define ATTR_COLD __attribute__((cold))
|
||||
#define ATTR_COLD __attribute__((cold))
|
||||
|
||||
#define RESTRICT
|
||||
#define EXPECTED(x) (x)
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
ATTR_COLD ~parray_t()
|
||||
~parray_t()
|
||||
{
|
||||
if (m_list != NULL)
|
||||
pfree_array(m_list);
|
||||
@ -127,7 +127,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
ATTR_COLD ~plist_t()
|
||||
~plist_t()
|
||||
{
|
||||
if (m_list != NULL)
|
||||
pfree_array(m_list);
|
||||
@ -333,7 +333,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
ATTR_COLD ~pstack_t()
|
||||
~pstack_t()
|
||||
{
|
||||
}
|
||||
|
||||
|
354
src/emu/netlist/pparser.c
Normal file
354
src/emu/netlist/pparser.c
Normal file
@ -0,0 +1,354 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* pparser.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pparser.h"
|
||||
|
||||
//#undef NL_VERBOSE_OUT
|
||||
//#define NL_VERBOSE_OUT(x) printf x
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A simple tokenizer
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
pstring ptokenizer::currentline_str()
|
||||
{
|
||||
char buf[300];
|
||||
int bufp = 0;
|
||||
const char *p = m_line_ptr;
|
||||
while (*p && *p != 10)
|
||||
buf[bufp++] = *p++;
|
||||
buf[bufp] = 0;
|
||||
return pstring(buf);
|
||||
}
|
||||
|
||||
|
||||
void ptokenizer::skipeol()
|
||||
{
|
||||
char c = getc();
|
||||
while (c)
|
||||
{
|
||||
if (c == 10)
|
||||
{
|
||||
c = getc();
|
||||
if (c != 13)
|
||||
ungetc();
|
||||
return;
|
||||
}
|
||||
c = getc();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned char ptokenizer::getc()
|
||||
{
|
||||
if (*m_px == 10)
|
||||
{
|
||||
m_line++;
|
||||
m_line_ptr = m_px + 1;
|
||||
}
|
||||
if (*m_px)
|
||||
return *(m_px++);
|
||||
else
|
||||
return *m_px;
|
||||
}
|
||||
|
||||
void ptokenizer::ungetc()
|
||||
{
|
||||
m_px--;
|
||||
}
|
||||
|
||||
void ptokenizer::require_token(const token_id_t &token_num)
|
||||
{
|
||||
require_token(get_token(), token_num);
|
||||
}
|
||||
|
||||
void ptokenizer::require_token(const token_t tok, const token_id_t &token_num)
|
||||
{
|
||||
if (!tok.is(token_num))
|
||||
{
|
||||
error("Error: expected token <%s> got <%s>\n", m_tokens[token_num.id()].cstr(), tok.str().cstr());
|
||||
}
|
||||
}
|
||||
|
||||
pstring ptokenizer::get_string()
|
||||
{
|
||||
token_t tok = get_token();
|
||||
if (!tok.is_type(STRING))
|
||||
{
|
||||
error("Error: expected a string, got <%s>\n", tok.str().cstr());
|
||||
}
|
||||
return tok.str();
|
||||
}
|
||||
|
||||
pstring ptokenizer::get_identifier()
|
||||
{
|
||||
token_t tok = get_token();
|
||||
if (!tok.is_type(IDENTIFIER))
|
||||
{
|
||||
error("Error: expected an identifier, got <%s>\n", tok.str().cstr());
|
||||
}
|
||||
return tok.str();
|
||||
}
|
||||
|
||||
ptokenizer::token_t ptokenizer::get_token()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
token_t ret = get_token_internal();
|
||||
if (ret.is_type(ENDOFFILE))
|
||||
return ret;
|
||||
|
||||
if (ret.is(m_tok_comment_start))
|
||||
{
|
||||
do {
|
||||
ret = get_token_internal();
|
||||
} while (ret.is_not(m_tok_comment_end));
|
||||
}
|
||||
else if (ret.is(m_tok_line_comment))
|
||||
{
|
||||
skipeol();
|
||||
}
|
||||
else if (ret.str() == "#")
|
||||
{
|
||||
skipeol();
|
||||
}
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ptokenizer::token_t ptokenizer::get_token_internal()
|
||||
{
|
||||
/* skip ws */
|
||||
char c = getc();
|
||||
while (m_whitespace.find(c)>=0)
|
||||
{
|
||||
c = getc();
|
||||
if (eof())
|
||||
{
|
||||
return token_t(ENDOFFILE);
|
||||
}
|
||||
}
|
||||
if (m_identifier_chars.find(c)>=0)
|
||||
{
|
||||
/* read identifier till non identifier char */
|
||||
pstring tokstr = "";
|
||||
while (m_identifier_chars.find(c)>=0) {
|
||||
tokstr += c;
|
||||
c = getc();
|
||||
}
|
||||
ungetc();
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
else
|
||||
{
|
||||
return token_t(IDENTIFIER, tokstr);
|
||||
}
|
||||
}
|
||||
else if (c == m_string)
|
||||
{
|
||||
pstring tokstr = "";
|
||||
c = getc();
|
||||
while (c != m_string)
|
||||
{
|
||||
tokstr += c;
|
||||
c = getc();
|
||||
}
|
||||
return token_t(STRING, tokstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* read identifier till first identifier char or ws */
|
||||
pstring tokstr = "";
|
||||
while ((m_identifier_chars.find(c)) < 0 && (m_whitespace.find(c) < 0)) {
|
||||
tokstr += c;
|
||||
/* expensive, check for single char tokens */
|
||||
if (tokstr.len() == 1)
|
||||
{
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
}
|
||||
c = getc();
|
||||
}
|
||||
ungetc();
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
else
|
||||
{
|
||||
return token_t(UNKNOWN, tokstr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ATTR_COLD void ptokenizer::error(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
pstring errmsg1 = pstring(format).vprintf(ap);
|
||||
va_end(ap);
|
||||
|
||||
verror(errmsg1, currentline_no(), currentline_str());
|
||||
|
||||
//throw error;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A simple preprocessor
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ppreprocessor::ppreprocessor()
|
||||
{
|
||||
m_expr_sep.add("(");
|
||||
m_expr_sep.add(")");
|
||||
m_expr_sep.add("+");
|
||||
m_expr_sep.add("-");
|
||||
m_expr_sep.add("*");
|
||||
m_expr_sep.add("/");
|
||||
m_expr_sep.add("==");
|
||||
m_expr_sep.add(" ");
|
||||
m_expr_sep.add("\t");
|
||||
}
|
||||
|
||||
|
||||
double ppreprocessor::expr(const nl_util::pstring_list &sexpr, int &start, int prio)
|
||||
{
|
||||
double val;
|
||||
pstring tok=sexpr[start];
|
||||
if (tok == "(")
|
||||
{
|
||||
start++;
|
||||
val = expr(sexpr, start, prio);
|
||||
if (sexpr[start] != ")")
|
||||
error("parsing error!");
|
||||
start++;
|
||||
}
|
||||
else
|
||||
{
|
||||
tok=sexpr[start];
|
||||
val = tok.as_double();
|
||||
start++;
|
||||
}
|
||||
while (start < sexpr.count())
|
||||
{
|
||||
tok=sexpr[start];
|
||||
if (tok == ")")
|
||||
{
|
||||
// FIXME: catch error
|
||||
return val;
|
||||
}
|
||||
else if (tok == "+")
|
||||
{
|
||||
if (prio >= 20)
|
||||
return val;
|
||||
start++;
|
||||
val = val + expr(sexpr, start, 10);
|
||||
}
|
||||
else if (tok == "-")
|
||||
{
|
||||
if (prio >= 20)
|
||||
return val;
|
||||
start++;
|
||||
val = val - expr(sexpr, start, 10);
|
||||
}
|
||||
else if (tok == "*")
|
||||
{
|
||||
start++;
|
||||
val = val * expr(sexpr, start, 20);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name)
|
||||
{
|
||||
for (int i = 0; i<m_defines.count(); i++)
|
||||
{
|
||||
if (m_defines[i].m_name == name)
|
||||
return &m_defines[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstring ppreprocessor::replace_macros(const pstring &line)
|
||||
{
|
||||
nl_util::pstring_list elems = nl_util::splitexpr(line, m_expr_sep);
|
||||
pstring ret = "";
|
||||
for (int i=0; i<elems.count(); i++)
|
||||
{
|
||||
define_t *def = get_define(elems[i]);
|
||||
if (def != NULL)
|
||||
ret = ret + def->m_replace;
|
||||
else
|
||||
ret = ret + elems[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
pstring ppreprocessor::process(const pstring &contents)
|
||||
{
|
||||
pstring ret = "";
|
||||
nl_util::pstring_list lines = nl_util::split(contents,"\n", false);
|
||||
UINT32 ifflag = 0; // 31 if levels
|
||||
int level = 0;
|
||||
|
||||
int i=0;
|
||||
while (i<lines.count())
|
||||
{
|
||||
pstring line = lines[i];
|
||||
pstring lt = line.replace("\t"," ").trim();
|
||||
lt = replace_macros(lt);
|
||||
if (lt.startsWith("#"))
|
||||
{
|
||||
nl_util::pstring_list lti = nl_util::split(lt, " ", true);
|
||||
if (lti[0].equals("#if"))
|
||||
{
|
||||
level++;
|
||||
int start = 0;
|
||||
nl_util::pstring_list t = nl_util::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep);
|
||||
int val = expr(t, start, 0);
|
||||
if (val == 0)
|
||||
ifflag |= (1 << level);
|
||||
}
|
||||
else if (lti[0].equals("#else"))
|
||||
{
|
||||
ifflag ^= (1 << level);
|
||||
}
|
||||
else if (lti[0].equals("#endif"))
|
||||
{
|
||||
ifflag &= ~(1 << level);
|
||||
level--;
|
||||
}
|
||||
else if (lti[0].equals("#include"))
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
else if (lti[0].equals("#define"))
|
||||
{
|
||||
if (lti.count() != 3)
|
||||
error(pstring::sprintf("PREPRO: only simple defines allowed: %s", line.cstr()));
|
||||
m_defines.add(define_t(lti[1], lti[2]));
|
||||
}
|
||||
else
|
||||
error(pstring::sprintf("unknown directive on line %d: %s\n", i, line.cstr()));
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (ifflag == 0 && level > 0)
|
||||
// fprintf(stderr, "conditional: %s\n", line.cstr());
|
||||
if (ifflag == 0)
|
||||
ret = ret + line + "\n";
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
}
|
181
src/emu/netlist/pparser.h
Normal file
181
src/emu/netlist/pparser.h
Normal file
@ -0,0 +1,181 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* pparser.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PPARSER_H_
|
||||
#define PPARSER_H_
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "nl_config.h" // FIXME
|
||||
#include "nl_util.h"
|
||||
|
||||
class ptokenizer
|
||||
{
|
||||
NETLIST_PREVENT_COPYING(ptokenizer)
|
||||
public:
|
||||
virtual ~ptokenizer() {}
|
||||
|
||||
ptokenizer()
|
||||
: m_line(1), m_line_ptr(NULL), m_px(NULL), m_string('"')
|
||||
{}
|
||||
|
||||
enum token_type
|
||||
{
|
||||
IDENTIFIER,
|
||||
NUMBER,
|
||||
TOKEN,
|
||||
STRING,
|
||||
COMMENT,
|
||||
UNKNOWN,
|
||||
ENDOFFILE
|
||||
};
|
||||
|
||||
struct token_id_t
|
||||
{
|
||||
public:
|
||||
token_id_t() : m_id(-2) {}
|
||||
token_id_t(const int id) : m_id(id) {}
|
||||
int id() const { return m_id; }
|
||||
private:
|
||||
int m_id;
|
||||
};
|
||||
|
||||
struct token_t
|
||||
{
|
||||
token_t(token_type type)
|
||||
{
|
||||
m_type = type;
|
||||
m_id = token_id_t(-1);
|
||||
m_token ="";
|
||||
}
|
||||
token_t(token_type type, const pstring str)
|
||||
{
|
||||
m_type = type;
|
||||
m_id = token_id_t(-1);
|
||||
m_token = str;
|
||||
}
|
||||
token_t(const token_id_t id, const pstring str)
|
||||
{
|
||||
m_type = TOKEN;
|
||||
m_id = id;
|
||||
m_token = str;
|
||||
}
|
||||
|
||||
bool is(const token_id_t &tok_id) const { return m_id.id() == tok_id.id(); }
|
||||
bool is_not(const token_id_t &tok_id) const { return !is(tok_id); }
|
||||
|
||||
bool is_type(const token_type type) const { return m_type == type; }
|
||||
|
||||
pstring str() const { return m_token; }
|
||||
|
||||
private:
|
||||
token_type m_type;
|
||||
token_id_t m_id;
|
||||
pstring m_token;
|
||||
};
|
||||
|
||||
|
||||
int currentline_no() { return m_line; }
|
||||
pstring currentline_str();
|
||||
|
||||
/* tokenizer stuff follows ... */
|
||||
|
||||
token_t get_token();
|
||||
pstring get_string();
|
||||
pstring get_identifier();
|
||||
|
||||
void require_token(const token_id_t &token_num);
|
||||
void require_token(const token_t tok, const token_id_t &token_num);
|
||||
|
||||
token_id_t register_token(pstring token)
|
||||
{
|
||||
m_tokens.add(token);
|
||||
return token_id_t(m_tokens.count() - 1);
|
||||
}
|
||||
|
||||
void set_identifier_chars(pstring s) { m_identifier_chars = s; }
|
||||
void set_number_chars(pstring s) { m_number_chars = s; }
|
||||
void set_whitespace(pstring s) { m_whitespace = s; }
|
||||
void set_comment(pstring start, pstring end, pstring line)
|
||||
{
|
||||
m_tok_comment_start = register_token(start);
|
||||
m_tok_comment_end = register_token(end);
|
||||
m_tok_line_comment = register_token(line);
|
||||
m_string = '"';
|
||||
}
|
||||
|
||||
token_t get_token_internal();
|
||||
void error(const char *format, ...) ATTR_PRINTF(2,3);
|
||||
|
||||
protected:
|
||||
void reset(const char *p) { m_px = p; m_line = 1; m_line_ptr = p; }
|
||||
virtual void verror(pstring msg, int line_num, pstring line) = 0;
|
||||
|
||||
private:
|
||||
void skipeol();
|
||||
|
||||
unsigned char getc();
|
||||
void ungetc();
|
||||
bool eof() { return *m_px == 0; }
|
||||
|
||||
int m_line;
|
||||
const char * m_line_ptr;
|
||||
const char * m_px;
|
||||
|
||||
/* tokenizer stuff follows ... */
|
||||
|
||||
pstring m_identifier_chars;
|
||||
pstring m_number_chars;
|
||||
plist_t<pstring> m_tokens;
|
||||
pstring m_whitespace;
|
||||
char m_string;
|
||||
|
||||
token_id_t m_tok_comment_start;
|
||||
token_id_t m_tok_comment_end;
|
||||
token_id_t m_tok_line_comment;
|
||||
};
|
||||
|
||||
|
||||
class ppreprocessor
|
||||
{
|
||||
NETLIST_PREVENT_COPYING(ppreprocessor)
|
||||
public:
|
||||
|
||||
struct define_t
|
||||
{
|
||||
define_t() { };
|
||||
define_t(const pstring &name, const pstring &replace)
|
||||
: m_name(name), m_replace(replace)
|
||||
{}
|
||||
pstring m_name;
|
||||
pstring m_replace;
|
||||
};
|
||||
|
||||
ppreprocessor();
|
||||
virtual ~ppreprocessor() {}
|
||||
|
||||
pstring process(const pstring &contents);
|
||||
|
||||
protected:
|
||||
|
||||
double expr(const nl_util::pstring_list &sexpr, int &start, int prio);
|
||||
|
||||
define_t *get_define(const pstring &name);
|
||||
|
||||
pstring replace_macros(const pstring &line);
|
||||
|
||||
virtual void error(const pstring &err)
|
||||
{
|
||||
fprintf(stderr, "PREPRO ERROR: %s\n", err.cstr());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
plist_t<define_t> m_defines;
|
||||
nl_util::pstring_list m_expr_sep;
|
||||
};
|
||||
|
||||
#endif /* PPARSER_H_ */
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "netlist/devices/net_lib.h"
|
||||
|
||||
#define FAST_CLOCK (1)
|
||||
|
||||
NETLIST_START(pong_fast)
|
||||
SOLVER(Solver, 48000)
|
||||
PARAM(Solver.PARALLEL, 0) // Don't do parallel solvers
|
||||
@ -22,15 +24,15 @@ NETLIST_START(pong_fast)
|
||||
TTL_INPUT(low, 0)
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
/* this is the clock circuit in schematics. */
|
||||
MAINCLOCK(xclk, 7159000.0*2)
|
||||
TTL_74107(ic_f6a, xclk, high, high, high)
|
||||
ALIAS(clk, ic_f6a.Q)
|
||||
#else
|
||||
#if (FAST_CLOCK)
|
||||
/* abstracting this, performance increases by 60%
|
||||
* No surprise, the clock is extremely expensive */
|
||||
MAINCLOCK(clk, 7159000.0)
|
||||
#else
|
||||
/* this is the clock circuit in schematics. */
|
||||
MAINCLOCK(xclk, 14318000.0) //7159000.0*2
|
||||
TTL_74107(ic_f6a, xclk, high, high, high)
|
||||
ALIAS(clk, ic_f6a.Q)
|
||||
#endif
|
||||
#else
|
||||
// benchmarking ...
|
||||
|
Loading…
Reference in New Issue
Block a user