mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Got truthtable parsing working in the parser. The plib preprocessor now
defines __PLIB_PREPROCESSOR__. This can be checked in netlist code and allows even more sharing code between compiled (embedded) netlists and external netlists. (nw)
This commit is contained in:
parent
1d99211b55
commit
b67b9ff917
@ -156,7 +156,7 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_analog_net_t::list_t &nets
|
||||
break;
|
||||
}
|
||||
}
|
||||
NL_VERBOSE_OUT(("added net with %d populated connections\n", net->m_core_terms.size()));
|
||||
NL_VERBOSE_OUT(("added net with %" SIZETFMT " populated connections\n", net->m_core_terms.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@
|
||||
#if (NL_VERBOSE)
|
||||
#define NL_VERBOSE_OUT(x) printf x
|
||||
#else
|
||||
#define NL_VERBOSE_OUT(x) do { } while (0)
|
||||
#define NL_VERBOSE_OUT(x) do { if(0) printf x ; } while (0)
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "nl_parser.h"
|
||||
#include "nl_factory.h"
|
||||
#include "devices/nld_truthtable.h"
|
||||
|
||||
//#undef NL_VERBOSE_OUT
|
||||
//#define NL_VERBOSE_OUT(x) printf x
|
||||
@ -33,7 +34,7 @@ bool netlist_parser::parse(const char *buf, const pstring nlname)
|
||||
|
||||
reset(m_buf);
|
||||
set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-");
|
||||
set_number_chars("01234567890eE-."); //FIXME: processing of numbers
|
||||
set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers
|
||||
char ws[5];
|
||||
ws[0] = ' ';
|
||||
ws[1] = 9;
|
||||
@ -54,6 +55,10 @@ bool netlist_parser::parse(const char *buf, const pstring nlname)
|
||||
m_tok_SUBMODEL = register_token("SUBMODEL");
|
||||
m_tok_NETLIST_START = register_token("NETLIST_START");
|
||||
m_tok_NETLIST_END = register_token("NETLIST_END");
|
||||
m_tok_TRUTHTABLE_START = register_token("TRUTHTABLE_START");
|
||||
m_tok_TRUTHTABLE_END = register_token("TRUTHTABLE_END");
|
||||
m_tok_TT_HEAD = register_token("TT_HEAD");
|
||||
m_tok_TT_LINE = register_token("TT_LINE");
|
||||
|
||||
bool in_nl = false;
|
||||
|
||||
@ -119,6 +124,8 @@ void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname)
|
||||
net_submodel();
|
||||
else if (token.is(m_tok_INCLUDE))
|
||||
net_include();
|
||||
else if (token.is(m_tok_TRUTHTABLE_START))
|
||||
net_truthtable_start();
|
||||
else if (token.is(m_tok_NETLIST_END))
|
||||
{
|
||||
netdev_netlist_end();
|
||||
@ -129,6 +136,49 @@ void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname)
|
||||
}
|
||||
}
|
||||
|
||||
void netlist_parser::net_truthtable_start()
|
||||
{
|
||||
pstring name = get_identifier();
|
||||
require_token(m_tok_comma);
|
||||
unsigned ni = get_number_long();
|
||||
require_token(m_tok_comma);
|
||||
unsigned no = get_number_long();
|
||||
require_token(m_tok_comma);
|
||||
unsigned hs = get_number_long();
|
||||
require_token(m_tok_comma);
|
||||
pstring def_param = get_string();
|
||||
require_token(m_tok_param_right);
|
||||
|
||||
netlist_base_factory_truthtable_t *ttd = nl_tt_factory_create(ni, no, hs,
|
||||
name, name, "+" + def_param);
|
||||
|
||||
while (true)
|
||||
{
|
||||
token_t token = get_token();
|
||||
|
||||
if (token.is(m_tok_TT_HEAD))
|
||||
{
|
||||
require_token(m_tok_param_left);
|
||||
ttd->m_desc.add(get_string());
|
||||
require_token(m_tok_param_right);
|
||||
}
|
||||
else if (token.is(m_tok_TT_LINE))
|
||||
{
|
||||
require_token(m_tok_param_left);
|
||||
ttd->m_desc.add(get_string());
|
||||
require_token(m_tok_param_right);
|
||||
}
|
||||
else
|
||||
{
|
||||
require_token(token, m_tok_TRUTHTABLE_END);
|
||||
require_token(m_tok_param_left);
|
||||
require_token(m_tok_param_right);
|
||||
m_setup.factory().register_device(ttd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void netlist_parser::netdev_netlist_start()
|
||||
{
|
||||
@ -198,7 +248,7 @@ void netlist_parser::net_c()
|
||||
{
|
||||
pstring t1 = get_identifier();
|
||||
m_setup.register_link(first , t1);
|
||||
NL_VERBOSE_OUT(("Parser: Connect: %s %s\n", last.cstr(), t1.cstr()));
|
||||
NL_VERBOSE_OUT(("Parser: Connect: %s %s\n", first.cstr(), t1.cstr()));
|
||||
token_t n = get_token();
|
||||
if (n.is(m_tok_param_right))
|
||||
break;
|
||||
@ -293,6 +343,23 @@ nl_double netlist_parser::eval_param(const token_t tok)
|
||||
for (i=1; i<6;i++)
|
||||
if (tok.str().equals(macs[i]))
|
||||
f = i;
|
||||
#if 1
|
||||
if (f>0)
|
||||
{
|
||||
require_token(m_tok_param_left);
|
||||
ret = get_number_double();
|
||||
require_token(m_tok_param_right);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = tok.str();
|
||||
ret = val.as_double(&e);
|
||||
if (e)
|
||||
error("Error with parameter ...\n");
|
||||
}
|
||||
return ret * facs[f];
|
||||
|
||||
#else
|
||||
if (f>0)
|
||||
{
|
||||
require_token(m_tok_param_left);
|
||||
@ -308,4 +375,5 @@ nl_double netlist_parser::eval_param(const token_t tok)
|
||||
if (f>0)
|
||||
require_token(m_tok_param_right);
|
||||
return ret * facs[f];
|
||||
#endif
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
void net_model();
|
||||
void net_submodel();
|
||||
void net_include();
|
||||
void net_truthtable_start();
|
||||
|
||||
protected:
|
||||
virtual void verror(pstring msg, int line_num, pstring line);
|
||||
@ -49,6 +50,10 @@ private:
|
||||
token_id_t m_tok_NETLIST_END;
|
||||
token_id_t m_tok_SUBMODEL;
|
||||
token_id_t m_tok_INCLUDE;
|
||||
token_id_t m_tok_TRUTHTABLE_START;
|
||||
token_id_t m_tok_TRUTHTABLE_END;
|
||||
token_id_t m_tok_TT_HEAD;
|
||||
token_id_t m_tok_TT_LINE;
|
||||
|
||||
netlist_setup_t &m_setup;
|
||||
|
||||
|
@ -777,7 +777,7 @@ void netlist_setup_t::start_devices()
|
||||
{
|
||||
NL_VERBOSE_OUT(("Creating dynamic logs ...\n"));
|
||||
pstring_list_t ll(env, ":");
|
||||
for (std::size_t i=0; i < ll.size(); i++)
|
||||
for (unsigned i=0; i < ll.size(); i++)
|
||||
{
|
||||
NL_VERBOSE_OUT(("%d: <%s>\n",i, ll[i].cstr()));
|
||||
NL_VERBOSE_OUT(("%d: <%s>\n",i, ll[i].cstr()));
|
||||
|
@ -96,6 +96,34 @@ pstring ptokenizer::get_identifier()
|
||||
return tok.str();
|
||||
}
|
||||
|
||||
double ptokenizer::get_number_double()
|
||||
{
|
||||
token_t tok = get_token();
|
||||
if (!tok.is_type(NUMBER))
|
||||
{
|
||||
error("Error: expected a number, got <%s>\n", tok.str().cstr());
|
||||
}
|
||||
bool err = false;
|
||||
double ret = tok.str().as_double(&err);
|
||||
if (err)
|
||||
error("Error: expected a number, got <%s>\n", tok.str().cstr());
|
||||
return ret;
|
||||
}
|
||||
|
||||
long ptokenizer::get_number_long()
|
||||
{
|
||||
token_t tok = get_token();
|
||||
if (!tok.is_type(NUMBER))
|
||||
{
|
||||
error("Error: expected a long int, got <%s>\n", tok.str().cstr());
|
||||
}
|
||||
bool err = false;
|
||||
long ret = tok.str().as_long(&err);
|
||||
if (err)
|
||||
error("Error: expected a long int, got <%s>\n", tok.str().cstr());
|
||||
return ret;
|
||||
}
|
||||
|
||||
ptokenizer::token_t ptokenizer::get_token()
|
||||
{
|
||||
while (true)
|
||||
@ -135,7 +163,26 @@ ptokenizer::token_t ptokenizer::get_token_internal()
|
||||
return token_t(ENDOFFILE);
|
||||
}
|
||||
}
|
||||
if (m_identifier_chars.find(c)>=0)
|
||||
if (m_number_chars_start.find(c)>=0)
|
||||
{
|
||||
/* read number while we receive number or identifier chars
|
||||
* treat it as an identifier when there are identifier chars in it
|
||||
*
|
||||
*/
|
||||
token_type ret = NUMBER;
|
||||
pstring tokstr = "";
|
||||
while (true) {
|
||||
if (m_identifier_chars.find(c)>=0 && m_number_chars.find(c)<0)
|
||||
ret = IDENTIFIER;
|
||||
else if (m_number_chars.find(c)<0)
|
||||
break;
|
||||
tokstr += c;
|
||||
c = getc();
|
||||
}
|
||||
ungetc();
|
||||
return token_t(ret, tokstr);
|
||||
}
|
||||
else if (m_identifier_chars.find(c)>=0)
|
||||
{
|
||||
/* read identifier till non identifier char */
|
||||
pstring tokstr = "";
|
||||
@ -218,6 +265,8 @@ ppreprocessor::ppreprocessor()
|
||||
m_expr_sep.add("==");
|
||||
m_expr_sep.add(" ");
|
||||
m_expr_sep.add("\t");
|
||||
|
||||
m_defines.add(define_t("__PLIB_PREPROCESSOR__", "1"));
|
||||
}
|
||||
|
||||
void ppreprocessor::error(const pstring &err)
|
||||
@ -336,7 +385,7 @@ pstring ppreprocessor::process(const pstring &contents)
|
||||
{
|
||||
pstring line = lines[i];
|
||||
pstring lt = line.replace("\t"," ").trim();
|
||||
lt = replace_macros(lt);
|
||||
// FIXME ... revise and extend macro handling
|
||||
if (lt.startsWith("#"))
|
||||
{
|
||||
pstring_list_t lti(lt, " ", true);
|
||||
@ -344,6 +393,7 @@ pstring ppreprocessor::process(const pstring &contents)
|
||||
{
|
||||
level++;
|
||||
std::size_t start = 0;
|
||||
lt = replace_macros(lt);
|
||||
pstring_list_t t = pstring_list_t::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep);
|
||||
int val = expr(t, start, 0);
|
||||
if (val == 0)
|
||||
@ -398,9 +448,10 @@ pstring ppreprocessor::process(const pstring &contents)
|
||||
{
|
||||
//if (ifflag == 0 && level > 0)
|
||||
// fprintf(stderr, "conditional: %s\n", line.cstr());
|
||||
lt = replace_macros(lt);
|
||||
if (ifflag == 0)
|
||||
{
|
||||
ret.cat(line);
|
||||
ret.cat(lt);
|
||||
ret.cat("\n");
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,8 @@ public:
|
||||
token_t get_token();
|
||||
pstring get_string();
|
||||
pstring get_identifier();
|
||||
double get_number_double();
|
||||
long get_number_long();
|
||||
|
||||
void require_token(const token_id_t &token_num);
|
||||
void require_token(const token_t tok, const token_id_t &token_num);
|
||||
@ -97,7 +99,7 @@ public:
|
||||
}
|
||||
|
||||
void set_identifier_chars(pstring s) { m_identifier_chars = s; }
|
||||
void set_number_chars(pstring s) { m_number_chars = s; }
|
||||
void set_number_chars(pstring st, pstring rem) { m_number_chars_start = st; m_number_chars = rem; }
|
||||
void set_whitespace(pstring s) { m_whitespace = s; }
|
||||
void set_comment(pstring start, pstring end, pstring line)
|
||||
{
|
||||
@ -129,6 +131,7 @@ private:
|
||||
|
||||
pstring m_identifier_chars;
|
||||
pstring m_number_chars;
|
||||
pstring m_number_chars_start;
|
||||
plist_t<pstring> m_tokens;
|
||||
pstring m_whitespace;
|
||||
char m_string;
|
||||
|
@ -11,13 +11,15 @@
|
||||
|
||||
#define FAST_CLOCK (1)
|
||||
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
#define TTL_7400A_NAND(_name, _A, _B) \
|
||||
NET_REGISTER_DEV_X(TTL_7400A_NAND, _name) \
|
||||
NET_CONNECT(_name, A, _A) \
|
||||
NET_CONNECT(_name, B, _B)
|
||||
#endif
|
||||
|
||||
NETLIST_START(lib)
|
||||
TRUTHTABLE_START(TTL_7400A_NAND, 2, 1, 0, "+A,B")
|
||||
TRUTHTABLE_START(TTL_7400A_NAND, 2, 1, 0, "A,B")
|
||||
TT_HEAD(" A , B | Q ")
|
||||
TT_LINE(" 0 , X | 1 |22")
|
||||
TT_LINE(" X , 0 | 1 |22")
|
||||
@ -398,7 +400,7 @@ NETLIST_START(pong_fast)
|
||||
NET_C(ic_b9_RPRE.2, ic_b9.CONT)
|
||||
|
||||
RES(ic_b9_R, RES_K(81)) // Adjustment pot
|
||||
CAP(ic_b9_C, CAP_U(.1))
|
||||
CAP(ic_b9_C, CAP_U(0.1))
|
||||
DIODE(ic_b9_D, "1N914")
|
||||
NE555(ic_b9)
|
||||
|
||||
@ -438,7 +440,7 @@ NETLIST_START(pong_fast)
|
||||
NET_C(ic_a9_RPRE.2, ic_a9.CONT)
|
||||
|
||||
RES(ic_a9_R, RES_K(81)) // Adjustment pot
|
||||
CAP(ic_a9_C, CAP_U(.1))
|
||||
CAP(ic_a9_C, CAP_U(0.1))
|
||||
DIODE(ic_a9_D, "1N914")
|
||||
NE555(ic_a9)
|
||||
|
||||
|
@ -97,7 +97,8 @@ class tool_options_t : public poptions
|
||||
public:
|
||||
tool_options_t() :
|
||||
poptions(),
|
||||
opt_ttr ("t", "time_to_run", 1.0, "time to run the emulation (seconds)", this),
|
||||
opt_ttr ("t", "time_to_run", 1.0, "time to run the emulation (seconds)", this),
|
||||
opt_name("n", "name", "", "netlist in file to run; default is first one", this),
|
||||
opt_logs("l", "logs", "", "colon separated list of terminals to log", this),
|
||||
opt_file("f", "file", "-", "file to process (default is stdin)", this),
|
||||
opt_cmd ("c", "cmd", "run", "run|convert|listdevices", this),
|
||||
@ -106,6 +107,7 @@ public:
|
||||
{}
|
||||
|
||||
poption_double opt_ttr;
|
||||
poption_str opt_name;
|
||||
poption_str opt_logs;
|
||||
poption_str opt_file;
|
||||
poption_str opt_cmd;
|
||||
@ -183,14 +185,14 @@ public:
|
||||
m_setup->init();
|
||||
}
|
||||
|
||||
void read_netlist(const char *buffer)
|
||||
void read_netlist(const char *buffer, pstring name)
|
||||
{
|
||||
// read the netlist ...
|
||||
|
||||
netlist_sources_t sources;
|
||||
|
||||
sources.add(netlist_source_t(buffer));
|
||||
sources.parse(*m_setup,"");
|
||||
sources.parse(*m_setup, name);
|
||||
//m_setup->parse(buffer);
|
||||
log_setup();
|
||||
|
||||
@ -266,7 +268,7 @@ static void run(tool_options_t &opts)
|
||||
nt.init();
|
||||
nt.m_logs = opts.opt_logs();
|
||||
nt.m_verbose = opts.opt_verb();
|
||||
nt.read_netlist(filetobuf(opts.opt_file()));
|
||||
nt.read_netlist(filetobuf(opts.opt_file()), opts.opt_name());
|
||||
double ttr = opts.opt_ttr();
|
||||
|
||||
printf("startup time ==> %5.3f\n", (double) (osd_ticks() - t) / (double) osd_ticks_per_second() );
|
||||
|
Loading…
Reference in New Issue
Block a user