mirror of
https://github.com/holub/mame
synced 2025-06-29 23:48:56 +03:00
Netlist: code maintenance and improvements. [Couriersud]
- Added support for line markers to the preprocessor and parser. - Added support for include processing to the preprocessor. - Moved sources base type to plib to be used for preprocessor includes. This enables to include e.g. from rom memory regions. - Renamed some defines
This commit is contained in:
parent
ad27643c07
commit
b09fa00cca
@ -286,13 +286,13 @@ public:
|
||||
: netlist::nl_exception(plib::pfmt(fmt)(std::forward<Args>(args)...)) { }
|
||||
};
|
||||
|
||||
class netlist_source_memregion_t : public netlist::source_t
|
||||
class netlist_source_memregion_t : public netlist::source_netlist_t
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
netlist_source_memregion_t(device_t &dev, pstring name)
|
||||
: netlist::source_t(), m_dev(dev), m_name(name)
|
||||
: netlist::source_netlist_t(), m_dev(dev), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
@ -302,7 +302,7 @@ private:
|
||||
pstring m_name;
|
||||
};
|
||||
|
||||
class netlist_data_memregions_t : public netlist::source_t
|
||||
class netlist_data_memregions_t : public netlist::source_data_t
|
||||
{
|
||||
public:
|
||||
netlist_data_memregions_t(const device_t &dev);
|
||||
@ -333,7 +333,7 @@ plib::unique_ptr<std::istream> netlist_source_memregion_t::stream(const pstring
|
||||
}
|
||||
|
||||
netlist_data_memregions_t::netlist_data_memregions_t(const device_t &dev)
|
||||
: netlist::source_t(netlist::source_t::DATA), m_dev(dev)
|
||||
: netlist::source_data_t(), m_dev(dev)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace devices
|
||||
LIB_ENTRY(2102A_dip)
|
||||
LIB_ENTRY(2716)
|
||||
LIB_ENTRY(2716_dip)
|
||||
#if !(USE_TRUTHTABLE_7448)
|
||||
#if !(NL_USE_TRUTHTABLE_7448)
|
||||
LIB_ENTRY(7448)
|
||||
LIB_ENTRY(7448_dip)
|
||||
#endif
|
||||
@ -92,7 +92,7 @@ namespace devices
|
||||
LIB_ENTRY(7493_dip)
|
||||
LIB_ENTRY(7497)
|
||||
LIB_ENTRY(7497_dip)
|
||||
#if (!USE_TRUTHTABLE_74107)
|
||||
#if (!NL_USE_TRUTHTABLE_74107)
|
||||
LIB_ENTRY(74107)
|
||||
LIB_ENTRY(74107_dip)
|
||||
#endif
|
||||
|
@ -145,7 +145,7 @@ namespace netlist
|
||||
m_clk.activate_hl();
|
||||
}
|
||||
|
||||
#if (!USE_TRUTHTABLE_74107)
|
||||
#if (!NL_USE_TRUTHTABLE_74107)
|
||||
NETLIB_DEVICE_IMPL(74107, "TTL_74107", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
|
||||
NETLIB_DEVICE_IMPL(74107_dip, "TTL_74107_DIP", "")
|
||||
#endif
|
||||
|
@ -75,7 +75,7 @@
|
||||
NET_CONNECT(name, K, cK) \
|
||||
NET_CONNECT(name, CLRQ, cCLRQ)
|
||||
|
||||
#if (!USE_TRUTHTABLE_74107)
|
||||
#if (!NL_USE_TRUTHTABLE_74107)
|
||||
#define TTL_74107(name, cCLK, cJ, cK, cCLRQ) \
|
||||
TTL_74107A(name, cCLK, cJ, cK, cCLRQ)
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace netlist
|
||||
{
|
||||
namespace devices
|
||||
{
|
||||
#if !(USE_TRUTHTABLE_7448)
|
||||
#if !(NL_USE_TRUTHTABLE_7448)
|
||||
NETLIB_OBJECT(7448)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(7448)
|
||||
@ -79,7 +79,7 @@ namespace netlist
|
||||
#endif
|
||||
|
||||
|
||||
#if !(USE_TRUTHTABLE_7448)
|
||||
#if !(NL_USE_TRUTHTABLE_7448)
|
||||
|
||||
#define BITS7(b6,b5,b4,b3,b2,b1,b0) ((b6)<<6) | ((b5)<<5) | ((b4)<<4) | ((b3)<<3) | ((b2)<<2) | ((b1)<<1) | ((b0)<<0)
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
#ifndef NL_AUTO_DEVICES
|
||||
#if !(USE_TRUTHTABLE_7448)
|
||||
#if !(NL_USE_TRUTHTABLE_7448)
|
||||
#define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \
|
||||
NET_REGISTER_DEV(TTL_7448, name) \
|
||||
NET_CONNECT(name, VCC, VCC) \
|
||||
|
@ -604,7 +604,7 @@ static NETLIST_START(TTL_7486_DIP)
|
||||
)
|
||||
NETLIST_END()
|
||||
|
||||
#if (USE_TRUTHTABLE_74107)
|
||||
#if (NL_USE_TRUTHTABLE_74107)
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
#define TTL_74107_TT(name) \
|
||||
NET_REGISTER_DEV(TTL_74107, name)
|
||||
@ -846,7 +846,7 @@ static NETLIST_START(DM9312_DIP)
|
||||
)
|
||||
NETLIST_END()
|
||||
|
||||
#if (USE_TRUTHTABLE_7448)
|
||||
#if (NL_USE_TRUTHTABLE_7448)
|
||||
|
||||
/*
|
||||
* DM7448: BCD to 7-Segment decoders/drivers
|
||||
@ -1115,7 +1115,7 @@ NETLIST_START(TTL74XX_lib)
|
||||
TT_FAMILY("74XX")
|
||||
TRUTHTABLE_END()
|
||||
|
||||
#if (USE_TRUTHTABLE_7448)
|
||||
#if (NL_USE_TRUTHTABLE_7448)
|
||||
TRUTHTABLE_START(TTL_7448, 7, 7, "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ,@VCC,@GND")
|
||||
TT_HEAD(" LTQ,BIQ,RBIQ, A , B , C , D | a, b, c, d, e, f, g")
|
||||
|
||||
@ -1207,7 +1207,7 @@ NETLIST_START(TTL74XX_lib)
|
||||
TT_FAMILY("74XX")
|
||||
TRUTHTABLE_END()
|
||||
|
||||
#if (USE_TRUTHTABLE_74107)
|
||||
#if (NL_USE_TRUTHTABLE_74107)
|
||||
/*
|
||||
* +-----+-----+-----+---++---+-----+
|
||||
* | CLRQ| CLK | J | K || Q | QQ |
|
||||
@ -1379,11 +1379,11 @@ NETLIST_START(TTL74XX_lib)
|
||||
LOCAL_LIB_ENTRY(TTL_7430_DIP)
|
||||
LOCAL_LIB_ENTRY(TTL_7432_DIP)
|
||||
LOCAL_LIB_ENTRY(TTL_7437_DIP)
|
||||
#if (USE_TRUTHTABLE_7448)
|
||||
#if (NL_USE_TRUTHTABLE_7448)
|
||||
LOCAL_LIB_ENTRY(TTL_7448_DIP)
|
||||
#endif
|
||||
LOCAL_LIB_ENTRY(TTL_7486_DIP)
|
||||
#if (USE_TRUTHTABLE_74107)
|
||||
#if (NL_USE_TRUTHTABLE_74107)
|
||||
LOCAL_LIB_ENTRY(TTL_74107_DIP)
|
||||
#endif
|
||||
LOCAL_LIB_ENTRY(TTL_74155_DIP)
|
||||
|
@ -209,7 +209,7 @@
|
||||
NET_REGISTER_DEV(TTL_7437_DIP, name)
|
||||
|
||||
|
||||
#if (USE_TRUTHTABLE_7448)
|
||||
#if (NL_USE_TRUTHTABLE_7448)
|
||||
#define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \
|
||||
NET_REGISTER_DEV(TTL_7448, name) \
|
||||
NET_CONNECT(name, VCC, VCC) \
|
||||
@ -240,7 +240,7 @@
|
||||
#define TTL_7486_DIP(name) \
|
||||
NET_REGISTER_DEV(TTL_7486_DIP, name)
|
||||
|
||||
#if (USE_TRUTHTABLE_74107)
|
||||
#if (NL_USE_TRUTHTABLE_74107)
|
||||
#define TTL_74107(name, cCLK, cJ, cK, cCLRQ) \
|
||||
NET_REGISTER_DEV(TTL_74107, name) \
|
||||
NET_CONNECT(name, GND, GND) \
|
||||
|
@ -254,23 +254,46 @@ namespace netlist
|
||||
|
||||
void netlist_state_t::compile_defines(std::vector<std::pair<pstring, pstring>> &defs)
|
||||
{
|
||||
//#define ENTRY(x) { #x, PSTRINGIFY(x) }
|
||||
#define ENTRY(x) std::pair<pstring, pstring>(#x, PSTRINGIFY(x))
|
||||
defs.emplace_back(ENTRY(PHAS_RDTSCP));
|
||||
defs.emplace_back(ENTRY(PUSE_ACCURATE_STATS));
|
||||
defs.emplace_back(ENTRY(PHAS_INT128));
|
||||
defs.emplace_back(ENTRY(USE_ALIGNED_OPTIMIZATIONS));
|
||||
defs.emplace_back(ENTRY(NVCCBUILD));
|
||||
defs.emplace_back(ENTRY(USE_MEMPOOL));
|
||||
defs.emplace_back(ENTRY(USE_QUEUE_STATS));
|
||||
defs.emplace_back(ENTRY(USE_COPY_INSTEAD_OF_REFERENCE));
|
||||
defs.emplace_back(ENTRY(USE_TRUTHTABLE_7448));
|
||||
defs.emplace_back(ENTRY(NL_DEBUG));
|
||||
defs.emplace_back(ENTRY(HAS_OPENMP));
|
||||
defs.emplace_back(ENTRY(USE_OPENMP));
|
||||
#define ENTRY(x) if (pstring(#x) != PSTRINGIFY(x)) defs.emplace_back(std::pair<pstring, pstring>(#x, PSTRINGIFY(x)));
|
||||
ENTRY(PHAS_RDTSCP)
|
||||
ENTRY(PUSE_ACCURATE_STATS)
|
||||
ENTRY(PHAS_INT128)
|
||||
ENTRY(PUSE_ALIGNED_OPTIMIZATIONS)
|
||||
ENTRY(PHAS_OPENMP)
|
||||
ENTRY(PUSE_OPENMP)
|
||||
ENTRY(PPMF_TYPE)
|
||||
ENTRY(PHAS_PMF_INTERNAL)
|
||||
ENTRY(NL_USE_MEMPOOL)
|
||||
ENTRY(NL_USE_QUEUE_STATS)
|
||||
ENTRY(NL_USE_COPY_INSTEAD_OF_REFERENCE)
|
||||
ENTRY(NL_USE_TRUTHTABLE_7448)
|
||||
ENTRY(NL_AUTO_DEVICES)
|
||||
ENTRY(NL_DEBUG)
|
||||
ENTRY(NVCCBUILD)
|
||||
|
||||
defs.emplace_back(ENTRY(PPMF_TYPE));
|
||||
defs.emplace_back(ENTRY(PHAS_PMF_INTERNAL));
|
||||
ENTRY(__cplusplus)
|
||||
ENTRY(__VERSION__)
|
||||
|
||||
ENTRY(__GNUC__)
|
||||
ENTRY(__GNUC_MINOR__)
|
||||
ENTRY(__GNUC_PATCHLEVEL__)
|
||||
|
||||
ENTRY(__clang__)
|
||||
ENTRY(__clang_major__)
|
||||
ENTRY(__clang_minor__)
|
||||
ENTRY(__clang_patchlevel__)
|
||||
ENTRY(__clang_version__)
|
||||
|
||||
ENTRY(OPENMP )
|
||||
ENTRY(_OPENMP )
|
||||
|
||||
ENTRY(__x86_64__ )
|
||||
ENTRY(__i386__)
|
||||
ENTRY(_WIN32)
|
||||
ENTRY(_MSC_VER)
|
||||
ENTRY(__APPLE__)
|
||||
ENTRY(__unix__)
|
||||
ENTRY(__linux__)
|
||||
|
||||
#undef ENTRY
|
||||
}
|
||||
@ -417,7 +440,7 @@ namespace netlist
|
||||
log().verbose("Total time {1:15}", total_time);
|
||||
|
||||
// FIXME: clang complains about unreachable code without
|
||||
const auto clang_workaround_unreachable_code = USE_QUEUE_STATS;
|
||||
const auto clang_workaround_unreachable_code = NL_USE_QUEUE_STATS;
|
||||
if (clang_workaround_unreachable_code)
|
||||
{
|
||||
/* Only one serialization should be counted in total time */
|
||||
@ -717,7 +740,7 @@ namespace netlist
|
||||
: device_object_t(dev, dev.name() + "." + aname)
|
||||
, plib::linkedlist_t<core_terminal_t>::element_t()
|
||||
, m_delegate(delegate)
|
||||
#if USE_COPY_INSTEAD_OF_REFERENCE
|
||||
#if NL_USE_COPY_INSTEAD_OF_REFERENCE
|
||||
, m_Q(*this, "m_Q", 0)
|
||||
#endif
|
||||
, m_net(nullptr)
|
||||
|
@ -589,7 +589,7 @@ namespace netlist
|
||||
void reset() noexcept { set_state(is_type(OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
|
||||
|
||||
nldelegate m_delegate;
|
||||
#if USE_COPY_INSTEAD_OF_REFERENCE
|
||||
#if NL_USE_COPY_INSTEAD_OF_REFERENCE
|
||||
void set_copied_input(netlist_sig_t val) noexcept
|
||||
{
|
||||
m_Q = val;
|
||||
@ -667,7 +667,7 @@ namespace netlist
|
||||
void move_connections(net_t &dest_net);
|
||||
|
||||
std::vector<core_terminal_t *> &core_terms() { return m_core_terms; }
|
||||
#if USE_COPY_INSTEAD_OF_REFERENCE
|
||||
#if NL_USE_COPY_INSTEAD_OF_REFERENCE
|
||||
void update_inputs() noexcept
|
||||
{
|
||||
for (auto & term : m_core_terms)
|
||||
@ -1553,7 +1553,7 @@ namespace netlist
|
||||
void process_queue(netlist_time delta) NL_NOEXCEPT;
|
||||
void abort_current_queue_slice() NL_NOEXCEPT
|
||||
{
|
||||
if (!USE_QUEUE_STATS || !m_use_stats)
|
||||
if (!NL_USE_QUEUE_STATS || !m_use_stats)
|
||||
m_queue.retime<false>(detail::queue_t::entry_t(m_time, nullptr));
|
||||
else
|
||||
m_queue.retime<true>(detail::queue_t::entry_t(m_time, nullptr));
|
||||
@ -1564,7 +1564,7 @@ namespace netlist
|
||||
template <typename E>
|
||||
void qpush(E && e) noexcept
|
||||
{
|
||||
if (!USE_QUEUE_STATS || !m_use_stats)
|
||||
if (!NL_USE_QUEUE_STATS || !m_use_stats)
|
||||
m_queue.push<false>(std::forward<E>(e)); // NOLINT(performance-move-const-arg)
|
||||
else
|
||||
m_queue.push<true>(std::forward<E>(e)); // NOLINT(performance-move-const-arg)
|
||||
@ -1573,7 +1573,7 @@ namespace netlist
|
||||
template <class R>
|
||||
void qremove(const R &elem) noexcept
|
||||
{
|
||||
if (!USE_QUEUE_STATS || !m_use_stats)
|
||||
if (!NL_USE_QUEUE_STATS || !m_use_stats)
|
||||
m_queue.remove<false>(elem);
|
||||
else
|
||||
m_queue.remove<true>(elem);
|
||||
@ -1860,7 +1860,7 @@ namespace netlist
|
||||
nl_assert(terminal_state() != STATE_INP_PASSIVE);
|
||||
//if (net().Q() != m_Q)
|
||||
// printf("term: %s, %d %d TS %d\n", this->name().c_str(), net().Q(), m_Q, terminal_state());
|
||||
#if USE_COPY_INSTEAD_OF_REFERENCE
|
||||
#if NL_USE_COPY_INSTEAD_OF_REFERENCE
|
||||
return m_Q;
|
||||
#else
|
||||
return net().Q();
|
||||
|
@ -28,8 +28,8 @@
|
||||
* Your mileage may vary.
|
||||
*
|
||||
*/
|
||||
#ifndef USE_MEMPOOL
|
||||
#define USE_MEMPOOL (1)
|
||||
#ifndef NL_USE_MEMPOOL
|
||||
#define NL_USE_MEMPOOL (1)
|
||||
#endif
|
||||
|
||||
/*! Enable queue statistics.
|
||||
@ -39,8 +39,8 @@
|
||||
* only needed during development.
|
||||
*
|
||||
*/
|
||||
#ifndef USE_QUEUE_STATS
|
||||
#define USE_QUEUE_STATS (0)
|
||||
#ifndef NL_USE_QUEUE_STATS
|
||||
#define NL_USE_QUEUE_STATS (0)
|
||||
#endif
|
||||
|
||||
/*! Store input values in logic_terminal_t.
|
||||
@ -53,8 +53,8 @@
|
||||
* the default approach. It is up to 10% slower.
|
||||
*
|
||||
*/
|
||||
#ifndef USE_COPY_INSTEAD_OF_REFERENCE
|
||||
#define USE_COPY_INSTEAD_OF_REFERENCE (0)
|
||||
#ifndef NL_USE_COPY_INSTEAD_OF_REFERENCE
|
||||
#define NL_USE_COPY_INSTEAD_OF_REFERENCE (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -63,7 +63,9 @@
|
||||
* setting param USE_DEACTIVATE for the device.
|
||||
*/
|
||||
|
||||
#define USE_TRUTHTABLE_7448 (0)
|
||||
#ifndef NL_USE_TRUTHTABLE_7448
|
||||
#define NL_USE_TRUTHTABLE_7448 (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FIXME: The truthtable implementation of 74107 (JK-Flipflop)
|
||||
@ -72,7 +74,9 @@
|
||||
* It will completely nuke performance for pong.
|
||||
*/
|
||||
|
||||
#define USE_TRUTHTABLE_74107 (0)
|
||||
#ifndef NL_USE_TRUTHTABLE_74107
|
||||
#define NL_USE_TRUTHTABLE_74107 (0)
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// DEBUGGING
|
||||
|
@ -87,12 +87,21 @@ namespace netlist
|
||||
|
||||
void nlparse_t::include(const pstring &netlist_name)
|
||||
{
|
||||
for (auto &source : m_sources)
|
||||
#if 0
|
||||
for (auto &base : m_sources)
|
||||
{
|
||||
if (source->parse(*this, netlist_name))
|
||||
auto source(dynamic_cast<source_netlist_t *>(base.get()));
|
||||
if (source && source->parse(*this, netlist_name))
|
||||
return;
|
||||
}
|
||||
log().fatal(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name));
|
||||
#endif
|
||||
if (m_sources.for_all<source_netlist_t>(netlist_name, [this, &netlist_name] (auto &src)
|
||||
{
|
||||
return src->parse(*this, netlist_name);
|
||||
}))
|
||||
return;
|
||||
log().fatal(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name));
|
||||
}
|
||||
|
||||
|
||||
@ -206,9 +215,9 @@ namespace netlist
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nlparse_t::parse_stream(plib::unique_ptr<std::istream> &&istrm, const pstring &name)
|
||||
bool nlparse_t::parse_stream(plib::psource_t::stream_ptr &&istrm, const pstring &name)
|
||||
{
|
||||
plib::ppreprocessor y(&m_defines);
|
||||
plib::ppreprocessor y(m_includes, &m_defines);
|
||||
plib::ppreprocessor &x(y.process(std::move(istrm)));
|
||||
return parser_t(std::move(x), *this).parse(name);
|
||||
//return parser_t(std::move(plib::ppreprocessor(&m_defines).process(std::move(istrm))), *this).parse(name);
|
||||
@ -239,12 +248,6 @@ setup_t::setup_t(netlist_state_t &nlstate)
|
||||
|
||||
setup_t::~setup_t() noexcept
|
||||
{
|
||||
// FIXME: can't see a need any longer
|
||||
m_links.clear();
|
||||
m_params.clear();
|
||||
m_terminals.clear();
|
||||
m_param_values.clear();
|
||||
m_sources.clear();
|
||||
}
|
||||
|
||||
pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const
|
||||
@ -1019,19 +1022,13 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
|
||||
// Sources
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
plib::unique_ptr<std::istream> setup_t::get_data_stream(const pstring &name)
|
||||
plib::psource_t::stream_ptr setup_t::get_data_stream(const pstring &name)
|
||||
{
|
||||
for (auto &source : m_sources)
|
||||
{
|
||||
if (source->type() == source_t::DATA)
|
||||
{
|
||||
auto strm = source->stream(name);
|
||||
if (strm)
|
||||
return strm;
|
||||
}
|
||||
}
|
||||
auto strm = m_sources.get_stream<source_data_t>(name);
|
||||
if (strm)
|
||||
return strm;
|
||||
log().warning(MW_DATA_1_NOT_FOUND(name));
|
||||
return plib::unique_ptr<std::istream>(nullptr);
|
||||
return plib::psource_t::stream_ptr(nullptr);
|
||||
}
|
||||
|
||||
|
||||
@ -1185,21 +1182,16 @@ void setup_t::prepare_to_run()
|
||||
// base sources
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
bool source_t::parse(nlparse_t &setup, const pstring &name)
|
||||
bool source_netlist_t::parse(nlparse_t &setup, const pstring &name)
|
||||
{
|
||||
if (m_type != SOURCE)
|
||||
return false;
|
||||
auto strm(stream(name));
|
||||
if (strm)
|
||||
return setup.parse_stream(std::move(strm), name);
|
||||
else
|
||||
{
|
||||
auto strm(stream(name));
|
||||
if (strm)
|
||||
return setup.parse_stream(std::move(strm), name);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
plib::unique_ptr<std::istream> source_string_t::stream(const pstring &name)
|
||||
source_string_t::stream_ptr source_string_t::stream(const pstring &name)
|
||||
{
|
||||
plib::unused_var(name);
|
||||
auto ret(plib::make_unique<std::istringstream>(m_str));
|
||||
@ -1207,7 +1199,7 @@ plib::unique_ptr<std::istream> source_string_t::stream(const pstring &name)
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
plib::unique_ptr<std::istream> source_mem_t::stream(const pstring &name)
|
||||
source_mem_t::stream_ptr source_mem_t::stream(const pstring &name)
|
||||
{
|
||||
plib::unused_var(name);
|
||||
auto ret(plib::make_unique<std::istringstream>(m_str, std::ios_base::binary));
|
||||
@ -1215,14 +1207,14 @@ plib::unique_ptr<std::istream> source_mem_t::stream(const pstring &name)
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
plib::unique_ptr<std::istream> source_file_t::stream(const pstring &name)
|
||||
source_file_t::stream_ptr source_file_t::stream(const pstring &name)
|
||||
{
|
||||
plib::unused_var(name);
|
||||
auto ret(plib::make_unique<std::ifstream>(plib::filesystem::u8path(m_filename)));
|
||||
if (ret->is_open())
|
||||
return std::move(ret);
|
||||
else
|
||||
return plib::unique_ptr<std::istream>(nullptr);
|
||||
return stream_ptr(nullptr);
|
||||
}
|
||||
|
||||
bool source_proc_t::parse(nlparse_t &setup, const pstring &name)
|
||||
@ -1236,10 +1228,10 @@ bool source_proc_t::parse(nlparse_t &setup, const pstring &name)
|
||||
return false;
|
||||
}
|
||||
|
||||
plib::unique_ptr<std::istream> source_proc_t::stream(const pstring &name)
|
||||
source_proc_t::stream_ptr source_proc_t::stream(const pstring &name)
|
||||
{
|
||||
plib::unused_var(name);
|
||||
plib::unique_ptr<std::istream> p(nullptr);
|
||||
stream_ptr p(nullptr);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
|
||||
|
||||
#define SUBMODEL(model, name) \
|
||||
setup.namespace_push(# name); \
|
||||
setup.include(# model); \
|
||||
setup.include(# model); \
|
||||
/*NETLIST_NAME(model)(setup);*/ \
|
||||
setup.namespace_pop();
|
||||
|
||||
@ -167,42 +167,38 @@ namespace netlist
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A Generic netlist sources implementation
|
||||
// Specific netlist psource_t implementations
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class source_t
|
||||
class source_netlist_t : public plib::psource_t
|
||||
{
|
||||
public:
|
||||
|
||||
friend class setup_t;
|
||||
|
||||
enum type_t
|
||||
{
|
||||
SOURCE,
|
||||
DATA
|
||||
};
|
||||
|
||||
using list_t = std::vector<plib::unique_ptr<source_t>>;
|
||||
|
||||
source_t(const type_t type = SOURCE)
|
||||
: m_type(type)
|
||||
source_netlist_t()
|
||||
: plib::psource_t()
|
||||
{}
|
||||
|
||||
COPYASSIGNMOVE(source_t, delete)
|
||||
|
||||
virtual ~source_t() noexcept = default;
|
||||
COPYASSIGNMOVE(source_netlist_t, delete)
|
||||
virtual ~source_netlist_t() noexcept = default;
|
||||
|
||||
virtual bool parse(nlparse_t &setup, const pstring &name);
|
||||
|
||||
type_t type() const { return m_type; }
|
||||
|
||||
protected:
|
||||
virtual plib::unique_ptr<std::istream> stream(const pstring &name) = 0;
|
||||
|
||||
private:
|
||||
const type_t m_type;
|
||||
};
|
||||
|
||||
class source_data_t : public plib::psource_t
|
||||
{
|
||||
public:
|
||||
|
||||
friend class setup_t;
|
||||
|
||||
source_data_t()
|
||||
: plib::psource_t()
|
||||
{}
|
||||
|
||||
COPYASSIGNMOVE(source_data_t, delete)
|
||||
virtual ~source_data_t() noexcept = default;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Collection of models
|
||||
@ -253,9 +249,9 @@ namespace netlist
|
||||
void register_frontier(const pstring &attach, const double r_IN, const double r_OUT);
|
||||
|
||||
/* register a source */
|
||||
void register_source(plib::unique_ptr<source_t> &&src)
|
||||
void register_source(plib::unique_ptr<plib::psource_t> &&src)
|
||||
{
|
||||
m_sources.push_back(std::move(src));
|
||||
m_sources.add_source(std::move(src));
|
||||
}
|
||||
|
||||
void tt_factory_create(tt_desc &desc, const pstring &sourcefile);
|
||||
@ -279,7 +275,12 @@ namespace netlist
|
||||
bool device_exists(const pstring &name) const;
|
||||
|
||||
/* FIXME: used by source_t - need a different approach at some time */
|
||||
bool parse_stream(plib::unique_ptr<std::istream> &&istrm, const pstring &name);
|
||||
bool parse_stream(plib::psource_t::stream_ptr &&istrm, const pstring &name);
|
||||
|
||||
void add_include(plib::unique_ptr<plib::psource_t> &&inc)
|
||||
{
|
||||
m_includes.add_source(std::move(inc));
|
||||
}
|
||||
|
||||
void add_define(const pstring &def, const pstring &val)
|
||||
{
|
||||
@ -314,7 +315,7 @@ namespace netlist
|
||||
std::vector<link_t> m_links;
|
||||
std::unordered_map<pstring, pstring> m_param_values;
|
||||
|
||||
source_t::list_t m_sources;
|
||||
plib::psource_collection_t<> m_sources;
|
||||
|
||||
factory::list_t m_factory;
|
||||
|
||||
@ -324,6 +325,7 @@ namespace netlist
|
||||
|
||||
private:
|
||||
plib::ppreprocessor::defines_map_type m_defines;
|
||||
plib::psource_collection_t<> m_includes;
|
||||
|
||||
setup_t &m_setup;
|
||||
log_type &m_log;
|
||||
@ -364,7 +366,7 @@ namespace netlist
|
||||
void register_dynamic_log_devices();
|
||||
void resolve_inputs();
|
||||
|
||||
plib::unique_ptr<std::istream> get_data_stream(const pstring &name);
|
||||
plib::psource_t::stream_ptr get_data_stream(const pstring &name);
|
||||
|
||||
factory::list_t &factory() { return m_factory; }
|
||||
const factory::list_t &factory() const { return m_factory; }
|
||||
@ -432,58 +434,58 @@ namespace netlist
|
||||
// base sources
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class source_string_t : public source_t
|
||||
class source_string_t : public source_netlist_t
|
||||
{
|
||||
public:
|
||||
|
||||
source_string_t(const pstring &source)
|
||||
: source_t(), m_str(source)
|
||||
: source_netlist_t(), m_str(source)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
plib::unique_ptr<std::istream> stream(const pstring &name) override;
|
||||
stream_ptr stream(const pstring &name) override;
|
||||
|
||||
private:
|
||||
pstring m_str;
|
||||
};
|
||||
|
||||
class source_file_t : public source_t
|
||||
class source_file_t : public source_netlist_t
|
||||
{
|
||||
public:
|
||||
|
||||
source_file_t(const pstring &filename)
|
||||
: source_t(), m_filename(filename)
|
||||
: source_netlist_t(), m_filename(filename)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
plib::unique_ptr<std::istream> stream(const pstring &name) override;
|
||||
stream_ptr stream(const pstring &name) override;
|
||||
|
||||
private:
|
||||
pstring m_filename;
|
||||
};
|
||||
|
||||
class source_mem_t : public source_t
|
||||
class source_mem_t : public source_netlist_t
|
||||
{
|
||||
public:
|
||||
source_mem_t(const char *mem)
|
||||
: source_t(), m_str(mem)
|
||||
: source_netlist_t(), m_str(mem)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
plib::unique_ptr<std::istream> stream(const pstring &name) override;
|
||||
stream_ptr stream(const pstring &name) override;
|
||||
|
||||
private:
|
||||
pstring m_str;
|
||||
};
|
||||
|
||||
class source_proc_t : public source_t
|
||||
class source_proc_t : public source_netlist_t
|
||||
{
|
||||
public:
|
||||
source_proc_t(const pstring &name, void (*setup_func)(nlparse_t &))
|
||||
: source_t(),
|
||||
: source_netlist_t(),
|
||||
m_setup_func(setup_func),
|
||||
m_setup_func_name(name)
|
||||
{
|
||||
@ -492,7 +494,7 @@ namespace netlist
|
||||
bool parse(nlparse_t &setup, const pstring &name) override;
|
||||
|
||||
protected:
|
||||
plib::unique_ptr<std::istream> stream(const pstring &name) override;
|
||||
stream_ptr stream(const pstring &name) override;
|
||||
|
||||
private:
|
||||
void (*m_setup_func)(nlparse_t &);
|
||||
|
@ -78,7 +78,7 @@ namespace netlist
|
||||
*
|
||||
*/
|
||||
|
||||
#if (USE_MEMPOOL)
|
||||
#if (NL_USE_MEMPOOL)
|
||||
using nlmempool = plib::mempool;
|
||||
#else
|
||||
using nlmempool = plib::aligned_arena;
|
||||
|
@ -276,7 +276,7 @@ namespace plib {
|
||||
|
||||
static inline void *allocate( size_t alignment, size_t size )
|
||||
{
|
||||
#if (USE_ALIGNED_ALLOCATION)
|
||||
#if (PUSE_ALIGNED_ALLOCATION)
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
return _aligned_malloc(size, alignment);
|
||||
#elif defined(__APPLE__)
|
||||
@ -296,7 +296,7 @@ namespace plib {
|
||||
|
||||
static inline void deallocate( void *ptr )
|
||||
{
|
||||
#if (USE_ALIGNED_ALLOCATION)
|
||||
#if (PUSE_ALIGNED_ALLOCATION)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
|
||||
free(ptr);
|
||||
#else
|
||||
@ -352,7 +352,7 @@ namespace plib {
|
||||
//auto t = reinterpret_cast<std::uintptr_t>(p);
|
||||
//if (t & (ALIGN-1))
|
||||
// printf("alignment error!");
|
||||
#if (USE_ALIGNED_HINTS)
|
||||
#if (PUSE_ALIGNED_HINTS)
|
||||
return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN));
|
||||
#else
|
||||
return p;
|
||||
@ -364,7 +364,7 @@ namespace plib {
|
||||
{
|
||||
static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
|
||||
static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
|
||||
#if (USE_ALIGNED_HINTS)
|
||||
#if (PUSE_ALIGNED_HINTS)
|
||||
return reinterpret_cast<const T *>(__builtin_assume_aligned(p, ALIGN));
|
||||
#else
|
||||
return p;
|
||||
|
@ -38,20 +38,20 @@
|
||||
* netlists like kidniki.
|
||||
*/
|
||||
|
||||
#ifndef USE_OPENMP
|
||||
#define USE_OPENMP (0)
|
||||
#ifndef PUSE_OPENMP
|
||||
#define PUSE_OPENMP (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set this to one if you want to use aligned storage optimizations.
|
||||
*/
|
||||
|
||||
#ifndef USE_ALIGNED_OPTIMIZATIONS
|
||||
#define USE_ALIGNED_OPTIMIZATIONS (0)
|
||||
#ifndef PUSE_ALIGNED_OPTIMIZATIONS
|
||||
#define PUSE_ALIGNED_OPTIMIZATIONS (0)
|
||||
#endif
|
||||
|
||||
#define USE_ALIGNED_ALLOCATION (USE_ALIGNED_OPTIMIZATIONS)
|
||||
#define USE_ALIGNED_HINTS (USE_ALIGNED_OPTIMIZATIONS)
|
||||
#define PUSE_ALIGNED_ALLOCATION (PUSE_ALIGNED_OPTIMIZATIONS)
|
||||
#define PUSE_ALIGNED_HINTS (PUSE_ALIGNED_OPTIMIZATIONS)
|
||||
/*
|
||||
* Standard alignment macros
|
||||
*/
|
||||
@ -114,11 +114,19 @@ typedef __int128_t INT128;
|
||||
//============================================================
|
||||
|
||||
#if defined(OPENMP)
|
||||
#define HAS_OPENMP ( OPENMP >= 200805 )
|
||||
#elif defined(_OPENMP)
|
||||
#define HAS_OPENMP ( _OPENMP >= 200805 )
|
||||
#if ( OPENMP >= 200805 )
|
||||
#define PHAS_OPENMP (1)
|
||||
#else
|
||||
#define HAS_OPENMP (0)
|
||||
#define PHAS_OPENMP (0)
|
||||
#endif
|
||||
#elif defined(_OPENMP)
|
||||
#if ( _OPENMP >= 200805 )
|
||||
#define PHAS_OPENMP (1)
|
||||
#else
|
||||
#define PHAS_OPENMP (0)
|
||||
#endif
|
||||
#else
|
||||
#define PHAS_OPENMP (0)
|
||||
#endif
|
||||
|
||||
|
||||
@ -126,8 +134,8 @@ typedef __int128_t INT128;
|
||||
// WARNINGS
|
||||
//============================================================
|
||||
|
||||
#if (USE_OPENMP)
|
||||
#if (!(HAS_OPENMP))
|
||||
#if (PUSE_OPENMP)
|
||||
#if (!(PHAS_OPENMP))
|
||||
#error To use openmp compile and link with "-fopenmp"
|
||||
#endif
|
||||
#endif
|
||||
|
@ -112,10 +112,10 @@ pfmt::rtype pfmt::setfmt(std::stringstream &strm, char32_t cfmt_spec)
|
||||
else if (pdot != pstring::npos)
|
||||
{
|
||||
strm << std::setprecision(pstonum<int>(fmt.substr(pdot + 1)));
|
||||
r.width = pstonum<pstring::size_type>(left(fmt,pdot));
|
||||
r.width = pstonum<int>(left(fmt,pdot));
|
||||
}
|
||||
else if (fmt != "")
|
||||
r.width = pstonum<pstring::size_type>(fmt);
|
||||
r.width = pstonum<int>(fmt);
|
||||
|
||||
switch (r.pend)
|
||||
{
|
||||
|
@ -227,7 +227,7 @@ protected:
|
||||
pstring::size_type p;
|
||||
pstring::size_type sl;
|
||||
char32_t pend;
|
||||
pstring::size_type width;
|
||||
int width;
|
||||
|
||||
};
|
||||
rtype setfmt(std::stringstream &strm, char32_t cfmt_spec);
|
||||
@ -248,10 +248,14 @@ protected:
|
||||
strm << std::forward<T>(val);
|
||||
const pstring ps(strm.str());
|
||||
pstring pad("");
|
||||
if (ret.width > ps.length())
|
||||
pad = pstring(ret.width - ps.length(), ' ');
|
||||
std::size_t aw(std::abs(ret.width));
|
||||
if (aw > ps.length())
|
||||
pad = pstring(aw - ps.length(), ' ');
|
||||
|
||||
m_str = m_str.substr(0, ret.p) + pad + ps + m_str.substr(ret.p + ret.sl);
|
||||
if (ret.width > 0)
|
||||
m_str = m_str.substr(0, ret.p) + pad + ps + m_str.substr(ret.p + ret.sl);
|
||||
else
|
||||
m_str = m_str.substr(0, ret.p) + ps + pad + m_str.substr(ret.p + ret.sl);
|
||||
}
|
||||
} while (ret.ret == 1);
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#if HAS_OPENMP
|
||||
#if PHAS_OPENMP
|
||||
#include "omp.h"
|
||||
#endif
|
||||
|
||||
@ -26,7 +26,7 @@ void for_static(std::size_t numops, const I start, const I end, const T &what)
|
||||
{
|
||||
if (numops>1000)
|
||||
{
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
#if PHAS_OPENMP && PUSE_OPENMP
|
||||
#pragma omp parallel for schedule(static)
|
||||
#endif
|
||||
for (I i = start; i < end; i++)
|
||||
@ -40,7 +40,7 @@ void for_static(std::size_t numops, const I start, const I end, const T &what)
|
||||
template <typename I, class T>
|
||||
void for_static(const I start, const I end, const T &what)
|
||||
{
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
#if PHAS_OPENMP && PUSE_OPENMP
|
||||
#pragma omp parallel for schedule(static)
|
||||
#endif
|
||||
for (I i = start; i < end; i++)
|
||||
@ -57,7 +57,7 @@ void for_static_np(const I start, const I end, const T &what)
|
||||
|
||||
inline void set_num_threads(const std::size_t threads)
|
||||
{
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
#if PHAS_OPENMP && PUSE_OPENMP
|
||||
omp_set_num_threads(threads);
|
||||
#else
|
||||
plib::unused_var(threads);
|
||||
@ -66,7 +66,7 @@ inline void set_num_threads(const std::size_t threads)
|
||||
|
||||
inline std::size_t get_max_threads()
|
||||
{
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
#if PHAS_OPENMP && PUSE_OPENMP
|
||||
return omp_get_max_threads();
|
||||
#else
|
||||
return 1;
|
||||
|
@ -149,6 +149,23 @@ ptokenizer::token_t ptokenizer::get_token()
|
||||
if (ret.is_type(ENDOFFILE))
|
||||
return ret;
|
||||
|
||||
if (m_support_line_markers && ret.is_type(LINEMARKER))
|
||||
{
|
||||
// FIXME: do something with information gathered
|
||||
ret = get_token_internal();
|
||||
if (!ret.is_type(NUMBER))
|
||||
error(pfmt("Expected line number after line marker but got <{1}>")(ret.str()) );
|
||||
ret = get_token_internal();
|
||||
if (!ret.is_type(STRING))
|
||||
error(pfmt("Expected file name after line marker but got <{1}>")(ret.str()) );
|
||||
ret = get_token_internal();
|
||||
while (ret.is_type(NUMBER))
|
||||
{
|
||||
// FIXME: process flags; actually only 1 (file enter) and 2 (after file exit)
|
||||
ret = get_token_internal();
|
||||
}
|
||||
}
|
||||
|
||||
if (ret.is(m_tok_comment_start))
|
||||
{
|
||||
do {
|
||||
@ -184,7 +201,9 @@ ptokenizer::token_t ptokenizer::get_token_internal()
|
||||
return token_t(ENDOFFILE);
|
||||
}
|
||||
}
|
||||
if (m_number_chars_start.find(c) != pstring::npos)
|
||||
if (m_support_line_markers && c == '#')
|
||||
return token_t(LINEMARKER);
|
||||
else if (m_number_chars_start.find(c) != pstring::npos)
|
||||
{
|
||||
/* read number while we receive number or identifier chars
|
||||
* treat it as an identifier when there are identifier chars in it
|
||||
@ -259,11 +278,11 @@ ptokenizer::token_t ptokenizer::get_token_internal()
|
||||
// A simple preprocessor
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ppreprocessor::ppreprocessor(defines_map_type *defines)
|
||||
ppreprocessor::ppreprocessor(psource_collection_t<> &sources, defines_map_type *defines)
|
||||
: std::istream(new readbuffer(this))
|
||||
, m_sources(sources)
|
||||
, m_if_flag(0)
|
||||
, m_if_level(0)
|
||||
, m_lineno(0)
|
||||
, m_pos(0)
|
||||
, m_state(PROCESS)
|
||||
, m_comment(false)
|
||||
@ -289,7 +308,20 @@ ppreprocessor::ppreprocessor(defines_map_type *defines)
|
||||
|
||||
void ppreprocessor::error(const pstring &err)
|
||||
{
|
||||
throw pexception("PREPRO ERROR: " + err);
|
||||
pstring s("");
|
||||
pstring trail (" from ");
|
||||
pstring trail_first("In file included from ");
|
||||
pstring e = plib::pfmt("PREPRO ERROR: {1}:{2}:0: error: {3}\n")
|
||||
(m_stack.top().m_name, m_stack.top().m_lineno, err);
|
||||
m_stack.pop();
|
||||
while (m_stack.size() > 0)
|
||||
{
|
||||
if (m_stack.size() == 1)
|
||||
trail = trail_first;
|
||||
s = trail + plib::pfmt("{1}:{2}:0\n")(m_stack.top().m_name, m_stack.top().m_lineno) + s;
|
||||
m_stack.pop();
|
||||
}
|
||||
throw pexception("\n" + s + e);
|
||||
}
|
||||
|
||||
#define CHECKTOK2(p_op, p_prio) \
|
||||
@ -504,7 +536,38 @@ pstring ppreprocessor::process_line(pstring line)
|
||||
}
|
||||
else if (lti[0] == "#include")
|
||||
{
|
||||
// ignore
|
||||
if (m_if_flag == 0)
|
||||
{
|
||||
pstring arg("");
|
||||
for (std::size_t i=1; i<lti.size(); i++)
|
||||
arg += (lti[i] + " ");
|
||||
|
||||
arg = plib::trim(arg);
|
||||
|
||||
if (startsWith(arg, "\"") && endsWith(arg, "\""))
|
||||
{
|
||||
arg = arg.substr(1, arg.length() - 2);
|
||||
/* first try local context */
|
||||
auto l(plib::util::buildpath({m_stack.top().m_local_path, arg}));
|
||||
auto lstrm(m_sources.get_stream<>(l));
|
||||
if (lstrm)
|
||||
{
|
||||
m_stack.emplace(input_context(std::move(lstrm), plib::util::path(l), l));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto strm(m_sources.get_stream<>(arg));
|
||||
if (strm)
|
||||
{
|
||||
m_stack.emplace(input_context(std::move(strm), plib::util::path(arg), arg));
|
||||
}
|
||||
else
|
||||
error("include not found:" + arg);
|
||||
}
|
||||
}
|
||||
else
|
||||
error("include misspelled:" + arg);
|
||||
}
|
||||
}
|
||||
else if (lti[0] == "#pragma")
|
||||
{
|
||||
@ -519,7 +582,7 @@ pstring ppreprocessor::process_line(pstring line)
|
||||
if (m_if_flag == 0)
|
||||
{
|
||||
if (lti.size() < 2)
|
||||
error("PREPRO: define needs at least one argument: " + line);
|
||||
error("define needs at least one argument: " + line);
|
||||
else if (lti.size() == 2)
|
||||
m_defines.insert({lti[1], define_t(lti[1], "")});
|
||||
else
|
||||
@ -535,7 +598,7 @@ pstring ppreprocessor::process_line(pstring line)
|
||||
else
|
||||
{
|
||||
if (m_if_flag == 0)
|
||||
error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line)));
|
||||
error(pfmt("unknown directive on line {1}: {2}")(m_stack.top().m_lineno)(replace_macros(line)));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -547,6 +610,28 @@ pstring ppreprocessor::process_line(pstring line)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ppreprocessor::process_stack()
|
||||
{
|
||||
while (m_stack.size() > 0)
|
||||
{
|
||||
pstring line;
|
||||
pstring linemarker = pfmt("# {1} \"{2}\" 1\n")(m_stack.top().m_lineno, m_stack.top().m_name);
|
||||
m_outbuf += decltype(m_outbuf)(linemarker.c_str());
|
||||
while (m_stack.top().m_reader.readline(line))
|
||||
{
|
||||
m_stack.top().m_lineno++;
|
||||
line = process_line(line);
|
||||
m_outbuf += decltype(m_outbuf)(line.c_str()) + static_cast<char>(10);
|
||||
}
|
||||
m_stack.pop();
|
||||
if (m_stack.size() > 0)
|
||||
{
|
||||
linemarker = pfmt("# {1} \"{2}\" 2\n")(m_stack.top().m_lineno, m_stack.top().m_name);
|
||||
m_outbuf += decltype(m_outbuf)(linemarker.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace plib
|
||||
|
@ -12,9 +12,11 @@
|
||||
#include "pstream.h"
|
||||
#include "pstring.h"
|
||||
|
||||
#include "putil.h" // psource_t
|
||||
|
||||
//#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace plib {
|
||||
class ptokenizer
|
||||
@ -28,6 +30,7 @@ public:
|
||||
, m_px(m_cur_line.begin())
|
||||
, m_unget(0)
|
||||
, m_string('"')
|
||||
, m_support_line_markers(true) // FIXME
|
||||
{
|
||||
}
|
||||
|
||||
@ -42,6 +45,7 @@ public:
|
||||
TOKEN,
|
||||
STRING,
|
||||
COMMENT,
|
||||
LINEMARKER,
|
||||
UNKNOWN,
|
||||
ENDOFFILE
|
||||
};
|
||||
@ -156,6 +160,7 @@ private:
|
||||
token_id_t m_tok_comment_start;
|
||||
token_id_t m_tok_comment_end;
|
||||
token_id_t m_tok_line_comment;
|
||||
bool m_support_line_markers;
|
||||
};
|
||||
|
||||
|
||||
@ -174,7 +179,24 @@ public:
|
||||
|
||||
using defines_map_type = std::unordered_map<pstring, define_t>;
|
||||
|
||||
explicit ppreprocessor(defines_map_type *defines = nullptr);
|
||||
explicit ppreprocessor(psource_collection_t<> &sources, defines_map_type *defines = nullptr);
|
||||
|
||||
COPYASSIGN(ppreprocessor, delete)
|
||||
ppreprocessor &operator=(ppreprocessor &&src) = delete;
|
||||
|
||||
ppreprocessor(ppreprocessor &&s) noexcept
|
||||
: std::istream(new readbuffer(this))
|
||||
, m_defines(std::move(s.m_defines))
|
||||
, m_sources(s.m_sources)
|
||||
, m_expr_sep(std::move(s.m_expr_sep))
|
||||
, m_if_flag(s.m_if_flag)
|
||||
, m_if_level(s.m_if_level)
|
||||
, m_outbuf(std::move(s.m_outbuf))
|
||||
, m_pos(s.m_pos)
|
||||
, m_state(s.m_state)
|
||||
, m_comment(s.m_comment)
|
||||
{
|
||||
}
|
||||
|
||||
~ppreprocessor() override
|
||||
{
|
||||
@ -184,34 +206,11 @@ public:
|
||||
template <typename T>
|
||||
ppreprocessor & process(T &&istrm)
|
||||
{
|
||||
putf8_reader reader(std::forward<T>(istrm));
|
||||
pstring line;
|
||||
while (reader.readline(line))
|
||||
{
|
||||
m_lineno++;
|
||||
line = process_line(line);
|
||||
m_outbuf += decltype(m_outbuf)(line.c_str()) + static_cast<char>(10);
|
||||
}
|
||||
m_stack.emplace(input_context(std::forward<T>(istrm),"","<stream>"));
|
||||
process_stack();
|
||||
return *this;
|
||||
}
|
||||
|
||||
COPYASSIGN(ppreprocessor, delete)
|
||||
ppreprocessor &operator=(ppreprocessor &&src) = delete;
|
||||
|
||||
ppreprocessor(ppreprocessor &&s) noexcept
|
||||
: std::istream(new readbuffer(this))
|
||||
, m_defines(std::move(s.m_defines))
|
||||
, m_expr_sep(std::move(s.m_expr_sep))
|
||||
, m_if_flag(s.m_if_flag)
|
||||
, m_if_level(s.m_if_level)
|
||||
, m_lineno(s.m_lineno)
|
||||
, m_outbuf(std::move(s.m_outbuf))
|
||||
, m_pos(s.m_pos)
|
||||
, m_state(s.m_state)
|
||||
, m_comment(s.m_comment)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
class readbuffer : public std::streambuf
|
||||
@ -242,6 +241,7 @@ protected:
|
||||
? std::char_traits<char>::eof()
|
||||
: std::char_traits<char>::to_int_type(*this->gptr());
|
||||
}
|
||||
|
||||
private:
|
||||
ppreprocessor *m_strm;
|
||||
std::array<char_type, 1024> m_buf;
|
||||
@ -261,20 +261,41 @@ private:
|
||||
LINE_CONTINUATION
|
||||
};
|
||||
|
||||
void process_stack();
|
||||
|
||||
pstring process_line(pstring line);
|
||||
pstring process_comments(pstring line);
|
||||
|
||||
defines_map_type m_defines;
|
||||
psource_collection_t<> &m_sources;
|
||||
std::vector<pstring> m_expr_sep;
|
||||
|
||||
std::uint_least64_t m_if_flag; // 31 if levels
|
||||
int m_if_level;
|
||||
int m_lineno;
|
||||
|
||||
struct input_context
|
||||
{
|
||||
template <typename T>
|
||||
input_context(T &&istrm, const pstring &local_path, const pstring &name)
|
||||
: m_reader(std::forward<T>(istrm))
|
||||
, m_lineno(0)
|
||||
, m_local_path(local_path)
|
||||
, m_name(name)
|
||||
{}
|
||||
|
||||
putf8_reader m_reader;
|
||||
int m_lineno;
|
||||
pstring m_local_path;
|
||||
pstring m_name;
|
||||
};
|
||||
|
||||
std::stack<input_context> m_stack;
|
||||
pstring_t<pu8_traits> m_outbuf;
|
||||
std::istream::pos_type m_pos;
|
||||
state_e m_state;
|
||||
pstring m_line;
|
||||
bool m_comment;
|
||||
|
||||
};
|
||||
|
||||
} // namespace plib
|
||||
|
@ -87,6 +87,28 @@ namespace plib
|
||||
return last_found;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename T::size_type find_last_of(const T &str, const T &no)
|
||||
{
|
||||
typename T::size_type last_found = T::npos;
|
||||
typename T::size_type pos = 0;
|
||||
for (auto it = str.begin(); it != str.end(); ++it, ++pos)
|
||||
{
|
||||
bool f = false;
|
||||
for (typename T::value_type const jt : no)
|
||||
{
|
||||
if (*it == jt)
|
||||
{
|
||||
f = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f)
|
||||
last_found = pos;
|
||||
}
|
||||
return last_found;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ltrim(const T &str, const T &ws = T(" \t\n\r"))
|
||||
{
|
||||
|
@ -13,6 +13,32 @@ namespace plib
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
#ifdef _WIN32
|
||||
static constexpr const char PATH_SEP = '\\';
|
||||
#else
|
||||
static constexpr const char PATH_SEP = '/';
|
||||
#endif
|
||||
|
||||
pstring basename(pstring filename)
|
||||
{
|
||||
auto p=find_last_of(filename, pstring(1, PATH_SEP));
|
||||
if (p == pstring::npos)
|
||||
return filename;
|
||||
else
|
||||
return filename.substr(p+1);
|
||||
}
|
||||
|
||||
pstring path(pstring filename)
|
||||
{
|
||||
auto p=find_last_of(filename, pstring(1, PATH_SEP));
|
||||
if (p == pstring::npos)
|
||||
return "";
|
||||
else if (p == 0) // root case
|
||||
return filename.substr(0, 1);
|
||||
else
|
||||
return filename.substr(0, p);
|
||||
}
|
||||
|
||||
pstring buildpath(std::initializer_list<pstring> list )
|
||||
{
|
||||
pstring ret = "";
|
||||
@ -21,11 +47,7 @@ namespace plib
|
||||
if (ret == "")
|
||||
ret = elem;
|
||||
else
|
||||
#ifdef _WIN32
|
||||
ret = ret + '\\' + elem;
|
||||
#else
|
||||
ret += ('/' + elem);
|
||||
#endif
|
||||
ret += (PATH_SEP + elem);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "pexception.h"
|
||||
#include "pstring.h"
|
||||
#include "palloc.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <iostream>
|
||||
@ -24,8 +26,118 @@
|
||||
namespace plib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A Generic netlist sources implementation
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class psource_t
|
||||
{
|
||||
public:
|
||||
|
||||
using stream_ptr = plib::unique_ptr<std::istream>;
|
||||
|
||||
psource_t()
|
||||
{}
|
||||
|
||||
COPYASSIGNMOVE(psource_t, delete)
|
||||
|
||||
virtual ~psource_t() noexcept = default;
|
||||
|
||||
virtual stream_ptr stream(const pstring &name) = 0;
|
||||
private:
|
||||
};
|
||||
|
||||
/**! Generic string source
|
||||
*
|
||||
* Will return the given string when name matches.
|
||||
* Is used in preprocessor code to eliminate inclusion of certain files.
|
||||
*
|
||||
* @tparam TS base stream class. Default is psource_t
|
||||
*/
|
||||
template <typename TS = psource_t>
|
||||
class psource_str_t : public TS
|
||||
{
|
||||
public:
|
||||
psource_str_t(pstring name, pstring str)
|
||||
: m_name(name), m_str(str)
|
||||
{}
|
||||
|
||||
COPYASSIGNMOVE(psource_str_t, delete)
|
||||
virtual ~psource_str_t() noexcept = default;
|
||||
|
||||
typename TS::stream_ptr stream(const pstring &name) override
|
||||
{
|
||||
if (name == m_name)
|
||||
return plib::make_unique<std::stringstream>(m_str);
|
||||
else
|
||||
return typename TS::stream_ptr(nullptr);
|
||||
}
|
||||
private:
|
||||
pstring m_name;
|
||||
pstring m_str;
|
||||
};
|
||||
|
||||
/**! Generic sources collection
|
||||
*
|
||||
* @tparam TS base stream class. Default is psource_t
|
||||
*/
|
||||
template <typename TS = psource_t>
|
||||
class psource_collection_t
|
||||
{
|
||||
public:
|
||||
using source_type = plib::unique_ptr<TS>;
|
||||
using list_t = std::vector<source_type>;
|
||||
|
||||
psource_collection_t()
|
||||
{}
|
||||
|
||||
COPYASSIGNMOVE(psource_collection_t, delete)
|
||||
virtual ~psource_collection_t() noexcept = default;
|
||||
|
||||
void add_source(source_type &&src)
|
||||
{
|
||||
m_collection.push_back(std::move(src));
|
||||
}
|
||||
|
||||
template <typename S = TS>
|
||||
typename S::stream_ptr get_stream(pstring name)
|
||||
{
|
||||
for (auto &s : m_collection)
|
||||
{
|
||||
auto source(dynamic_cast<S *>(s.get()));
|
||||
if (source)
|
||||
{
|
||||
auto strm = source->stream(name);
|
||||
if (strm)
|
||||
return strm;
|
||||
}
|
||||
}
|
||||
return typename S::stream_ptr(nullptr);
|
||||
}
|
||||
|
||||
template <typename S, typename F>
|
||||
bool for_all(pstring name, F lambda)
|
||||
{
|
||||
for (auto &s : m_collection)
|
||||
{
|
||||
auto source(dynamic_cast<S *>(s.get()));
|
||||
if (source)
|
||||
{
|
||||
if (lambda(source))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
list_t m_collection;
|
||||
};
|
||||
|
||||
namespace util
|
||||
{
|
||||
pstring basename(pstring filename);
|
||||
pstring path(pstring filename);
|
||||
pstring buildpath(std::initializer_list<pstring> list );
|
||||
pstring environment(const pstring &var, const pstring &default_val);
|
||||
} // namespace util
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
opt_grp1(*this, "General options", "The following options apply to all commands."),
|
||||
opt_cmd (*this, "c", "cmd", 0, std::vector<pstring>({"run","validate","convert","listdevices","static","header","docheader"}), "run|validate|convert|listdevices|static|header|docheader"),
|
||||
opt_file(*this, "f", "file", "-", "file to process (default is stdin)"),
|
||||
opt_includes(*this, "I", "include", "Add the directory to the list of directories to be searched for header files. This option may be specified repeatedly."),
|
||||
opt_defines(*this, "D", "define", "predefine value as macro, e.g. -Dname=value. If '=value' is omitted predefine it as 1. This option may be specified repeatedly."),
|
||||
opt_rfolders(*this, "r", "rom", "where to look for data files"),
|
||||
opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"),
|
||||
@ -76,6 +77,7 @@ public:
|
||||
plib::option_group opt_grp1;
|
||||
plib::option_str_limit<unsigned> opt_cmd;
|
||||
plib::option_str opt_file;
|
||||
plib::option_vec opt_includes;
|
||||
plib::option_vec opt_defines;
|
||||
plib::option_vec opt_rfolders;
|
||||
plib::option_bool opt_verb;
|
||||
@ -140,21 +142,21 @@ NETLIST_END()
|
||||
CORE IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
class netlist_data_folder_t : public netlist::source_t
|
||||
class netlist_data_folder_t : public netlist::source_data_t
|
||||
{
|
||||
public:
|
||||
netlist_data_folder_t(const pstring &folder)
|
||||
: netlist::source_t(netlist::source_t::DATA)
|
||||
: netlist::source_data_t()
|
||||
, m_folder(folder)
|
||||
{
|
||||
}
|
||||
|
||||
plib::unique_ptr<std::istream> stream(const pstring &file) override
|
||||
stream_ptr stream(const pstring &file) override
|
||||
{
|
||||
pstring name = m_folder + "/" + file;
|
||||
auto strm(plib::make_unique<std::ifstream>(plib::filesystem::u8path(name)));
|
||||
if (strm->fail())
|
||||
return plib::unique_ptr<std::istream>(nullptr);
|
||||
return stream_ptr(nullptr);
|
||||
else
|
||||
{
|
||||
strm->imbue(std::locale::classic());
|
||||
@ -198,7 +200,8 @@ public:
|
||||
void read_netlist(const pstring &filename, const pstring &name,
|
||||
const std::vector<pstring> &logs,
|
||||
const std::vector<pstring> &defines,
|
||||
const std::vector<pstring> &roms)
|
||||
const std::vector<pstring> &roms,
|
||||
const std::vector<pstring> &includes)
|
||||
{
|
||||
// read the netlist ...
|
||||
|
||||
@ -208,6 +211,11 @@ public:
|
||||
for (auto & r : roms)
|
||||
setup().register_source(plib::make_unique<netlist_data_folder_t>(r));
|
||||
|
||||
using a = plib::psource_str_t<plib::psource_t>;
|
||||
setup().add_include(plib::make_unique<a>("netlist/devices/net_lib.h",""));
|
||||
for (auto & i : includes)
|
||||
setup().add_include(plib::make_unique<netlist_data_folder_t>(i));
|
||||
|
||||
setup().register_source(plib::make_unique<netlist::source_file_t>(filename));
|
||||
setup().include(name);
|
||||
create_dynamic_logs(logs);
|
||||
@ -377,7 +385,7 @@ void tool_app_t::run()
|
||||
|
||||
nt.read_netlist(opt_file(), opt_name(),
|
||||
opt_logs(),
|
||||
m_options, opt_rfolders());
|
||||
m_options, opt_rfolders(), opt_includes());
|
||||
|
||||
nt.reset();
|
||||
|
||||
@ -473,7 +481,7 @@ void tool_app_t::validate()
|
||||
|
||||
nt.read_netlist(opt_file(), opt_name(),
|
||||
opt_logs(),
|
||||
m_options, opt_rfolders());
|
||||
m_options, opt_rfolders(), opt_includes());
|
||||
}
|
||||
catch (netlist::nl_exception &e)
|
||||
{
|
||||
@ -507,7 +515,7 @@ void tool_app_t::static_compile()
|
||||
|
||||
nt.read_netlist(opt_file(), opt_name(),
|
||||
opt_logs(),
|
||||
m_options, opt_rfolders());
|
||||
m_options, opt_rfolders(), opt_includes());
|
||||
|
||||
// need to reset ...
|
||||
|
||||
@ -824,8 +832,6 @@ int tool_app_t::execute()
|
||||
|
||||
if (opt_help())
|
||||
{
|
||||
pout(plib::pfmt("{:10.3}\n").f(20.0));
|
||||
//pout(plib::pfmt("{10.3}\n").f(20));
|
||||
pout(usage());
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
|
||||
#include "audio/nl_cheekyms.h"
|
||||
#include "netlist/devices/net_lib.h"
|
||||
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb, Couriersud
|
||||
|
||||
#include "audio/nl_zac1b11142.h"
|
||||
#include "netlist/devices/net_lib.h"
|
||||
|
||||
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user