diff --git a/LineInfo.cc b/LineInfo.cc new file mode 100644 index 000000000..20c13afa2 --- /dev/null +++ b/LineInfo.cc @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) && !defined(macintosh) +#ident "$Id: LineInfo.cc,v 1.1 2000/11/30 17:31:42 steve Exp $" +#endif + +# include "LineInfo.h" +# include + +LineInfo::~LineInfo() +{ +} + +string LineInfo::get_line() const +{ + char buf[8]; + sprintf(buf, "%u", lineno_); + return string(file_? file_ : "") + ":" + buf; +} + +void LineInfo::set_line(const LineInfo&that) +{ + file_ = that.file_; + lineno_ = that.lineno_; +} + +/* + * $Log: LineInfo.cc,v $ + * Revision 1.1 2000/11/30 17:31:42 steve + * Change LineInfo to store const C strings. + * + */ + diff --git a/LineInfo.h b/LineInfo.h index 3255b7d34..46dd5e102 100644 --- a/LineInfo.h +++ b/LineInfo.h @@ -19,61 +19,46 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: LineInfo.h,v 1.4 2000/02/23 02:56:53 steve Exp $" +#ident "$Id: LineInfo.h,v 1.5 2000/11/30 17:31:42 steve Exp $" #endif -# include # include +/* + * This class holds line information for an internal object. + * + * Note that the file names are C-style strings that are allocated by + * the lexor (which parses the line directives) and are never + * deallocated. We can therefore safely store the pointer and never + * delete the string, even if LineInfo objects are destroyed. + */ + class LineInfo { public: - LineInfo() : lineno_(0) { } + LineInfo() : file_(0), lineno_(0) { } + ~LineInfo(); - string get_line() const - { char buf[8]; - sprintf(buf, "%u", lineno_); - return file_ + ":" + buf; - } + string get_line() const; - void set_line(const LineInfo&that) - { file_ = that.file_; - lineno_ = that.lineno_; - } + void set_line(const LineInfo&that); - void set_file(const string&f) { file_ = f; } + void set_file(const char*f) { file_ = f; } void set_lineno(unsigned n) { lineno_ = n; } private: - string file_; + const char* file_; unsigned lineno_; }; /* * $Log: LineInfo.h,v $ + * Revision 1.5 2000/11/30 17:31:42 steve + * Change LineInfo to store const C strings. + * * Revision 1.4 2000/02/23 02:56:53 steve * Macintosh compilers do not support ident. * * Revision 1.3 1999/02/15 02:06:15 steve * Elaborate gate ranges. - * - * Revision 1.2 1999/02/01 00:26:48 steve - * Carry some line info to the netlist, - * Dump line numbers for processes. - * Elaborate prints errors about port vector - * width mismatch - * Emit better handles null statements. - * - * Revision 1.1 1999/01/25 05:45:56 steve - * Add the LineInfo class to carry the source file - * location of things. PGate, Statement and PProcess. - * - * elaborate handles module parameter mismatches, - * missing or incorrect lvalues for procedural - * assignment, and errors are propogated to the - * top of the elaboration call tree. - * - * Attach line numbers to processes, gates and - * assignment statements. - * */ #endif diff --git a/Makefile.in b/Makefile.in index 31f6c2ad4..cbd3dc339 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.81 2000/11/29 23:59:29 steve Exp $" +#ident "$Id: Makefile.in,v 1.82 2000/11/30 17:31:42 steve Exp $" # # SHELL = /bin/sh @@ -92,7 +92,8 @@ net_scope.o net_udp.o \ pad_to_width.o \ parse.o parse_misc.o pform.o pform_dump.o \ set_width.o \ -verinum.o verireal.o target.o targets.o util.o Module.o PDelays.o PEvent.o \ +verinum.o verireal.o target.o targets.o util.o \ +LineInfo.o Module.o PDelays.o PEvent.o \ PExpr.o PGate.o \ PTask.o PFunction.o PWire.o Statement.o \ $(FF) $(TT) diff --git a/lexor.lex b/lexor.lex index adf846d39..5a72c129a 100644 --- a/lexor.lex +++ b/lexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: lexor.lex,v 1.52 2000/11/04 01:54:01 steve Exp $" +#ident "$Id: lexor.lex,v 1.53 2000/11/30 17:31:42 steve Exp $" #endif //# define YYSTYPE lexval @@ -37,8 +37,42 @@ extern string vl_file; # define YY_USER_INIT reset_lexor(); # define yylval VLlval + +/* + * Lexical location information is passed in the yylloc variable to th + * parser. The file names, strings, are kept in a list so that I can + * re-use them. The set_file_name function will return a pointer to + * the name as it exists in the list (and delete the passed string.) + * If the name is new, it will be added to the list. + */ extern YYLTYPE yylloc; +struct file_name_cell { + const char*text; + struct file_name_cell*next; +}; + +static struct file_name_cell*file_names = 0; + +static const char* set_file_name(char*text) +{ + struct file_name_cell*cur = file_names; + while (cur) { + if (strcmp(cur->text, text) == 0) { + delete[]text; + return cur->text; + } + + cur = cur->next; + } + + cur = new struct file_name_cell; + cur->text = text; + cur->next = file_names; + return text; +} + + extern void pform_set_timescale(int, int); static void reset_lexor(); @@ -989,8 +1023,7 @@ static void line_directive() strncpy(buf, qt1, qt2-qt1); buf[qt2-qt1] = 0; - delete[]yylloc.text; - yylloc.text = buf; + yylloc.text = set_file_name(buf); qt2 += 1; yylloc.first_line = strtoul(qt2,0,0); @@ -1017,13 +1050,19 @@ static void line_directive2() strncpy(buf, qt1, qt2-qt1); buf[qt2-qt1] = 0; - delete[]yylloc.text; - yylloc.text = buf; + yylloc.text = set_file_name(buf); } static void reset_lexor() { yyrestart(vl_input); yylloc.first_line = 1; - yylloc.text = strdup(vl_file.c_str()); + + /* Start the file_names list. From here on, as I get a file + name, I will add it to this list. Only add the name if it + is not already in the list. */ + file_names = new struct file_name_cell; + file_names->text = strdup(vl_file.c_str()); + file_names->next = 0; + yylloc.text = file_names->text; } diff --git a/pform.cc b/pform.cc index 7459f4e7b..78b0e0940 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.cc,v 1.66 2000/10/31 17:49:02 steve Exp $" +#ident "$Id: pform.cc,v 1.67 2000/11/30 17:31:42 steve Exp $" #endif # include "compiler.h" @@ -364,7 +364,7 @@ void pform_set_net_range(list*names, svector*range) * This is invoked to make a named event. This is the declaration of * the event, and not necessarily the use of it. */ -static void pform_make_event(const char*name, const string&fn, unsigned ln) +static void pform_make_event(const char*name, const char*fn, unsigned ln) { PEvent*event = new PEvent(name); event->set_file(fn); @@ -372,7 +372,7 @@ static void pform_make_event(const char*name, const string&fn, unsigned ln) pform_cur_module->events[name] = event; } -void pform_make_events(list*names, const string&fn, unsigned ln) +void pform_make_events(list*names, const char*fn, unsigned ln) { list::iterator cur; for (cur = names->begin() ; cur != names->end() ; cur++) { @@ -436,7 +436,7 @@ static void pform_make_modgate(const string&type, struct parmvalue_t*overrides, svector*wires, PExpr*msb, PExpr*lsb, - const string&fn, unsigned ln) + const char*fn, unsigned ln) { if (name == "") { cerr << fn << ":" << ln << ": Instantiation of " << type @@ -474,7 +474,7 @@ static void pform_make_modgate(const string&type, struct parmvalue_t*overrides, svector*bind, PExpr*msb, PExpr*lsb, - const string&fn, unsigned ln) + const char*fn, unsigned ln) { if (name == "") { cerr << fn << ":" << ln << ": Instantiation of " << type @@ -588,7 +588,7 @@ PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval, void pform_make_pgassign_list(svector*alist, svector*del, struct str_pair_t str, - const string& text, + const char* fn, unsigned lineno) { PGAssign*tmp; @@ -596,7 +596,7 @@ void pform_make_pgassign_list(svector*alist, tmp = pform_make_pgassign((*alist)[2*idx], (*alist)[2*idx+1], del, str); - tmp->set_file(text); + tmp->set_file(fn); tmp->set_lineno(lineno); } } @@ -740,7 +740,7 @@ void pform_set_port_type(const string&nm, NetNet::PortType pt) svector*pform_make_task_ports(NetNet::PortType pt, svector*range, list*names, - const string& file, + const char* file, unsigned lineno) { assert(names); @@ -1002,6 +1002,9 @@ int pform_parse(const char*path, map&modules, /* * $Log: pform.cc,v $ + * Revision 1.67 2000/11/30 17:31:42 steve + * Change LineInfo to store const C strings. + * * Revision 1.66 2000/10/31 17:49:02 steve * Support time variables. * diff --git a/pform.h b/pform.h index b3ca5c76f..2e5f248de 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.h,v 1.43 2000/10/31 17:49:02 steve Exp $" +#ident "$Id: pform.h,v 1.44 2000/11/30 17:31:42 steve Exp $" #endif # include "netlist.h" @@ -99,7 +99,7 @@ struct lgate { PExpr*range[2]; - string file; + const char* file; unsigned lineno; }; @@ -157,7 +157,7 @@ extern svector* pform_make_udp_input_ports(list*); extern bool pform_expression_is_constant(const PExpr*); extern void pform_make_events(list*names, - const string&file, unsigned lineno); + const char*file, unsigned lineno); /* * The makegate function creates a new gate (which need not have a @@ -179,15 +179,14 @@ extern PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval, extern void pform_make_pgassign_list(svector*alist, svector*del, struct str_pair_t str, - const string& text, - unsigned lineno); + const char* fn, unsigned lineno); /* Given a port type and a list of names, make a list of wires that can be used as task port information. */ extern svector*pform_make_task_ports(NetNet::PortType pt, svector*range, list*names, - const string& file, + const char* file, unsigned lineno); @@ -203,6 +202,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.44 2000/11/30 17:31:42 steve + * Change LineInfo to store const C strings. + * * Revision 1.43 2000/10/31 17:49:02 steve * Support time variables. * diff --git a/t-vvm.cc b/t-vvm.cc index 042f0fa7f..98f0556d5 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-vvm.cc,v 1.185 2000/11/20 00:58:40 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.186 2000/11/30 17:31:42 steve Exp $" #endif # include @@ -27,6 +27,7 @@ # include # include # include +# include # include "netlist.h" # include "netmisc.h" # include "target.h" @@ -396,7 +397,7 @@ void vvm_proc_rval::expr_concat(const NetEConcat*expr) << expr->expr_width() << ");" << endl; unsigned pos = 0; - for (unsigned rep = 0 ; rep < expr->repeat() ; rep += 1) + for (unsigned rept = 0 ; rept < expr->repeat() ; rept += 1) for (unsigned idx = 0 ; idx < expr->nparms() ; idx += 1) { NetExpr*pp = expr->parm(expr->nparms() - idx - 1); @@ -414,7 +415,7 @@ void vvm_proc_rval::expr_concat(const NetEConcat*expr) /* Check that the positions came out to the right number of bits. */ if (pos != expr->expr_width()) { - tgt_->defn << "#error \"" << expr->get_line() << ": vvm eror: " + tgt_->defn << "#error \"" << expr->get_line() << ": vvm error: " << "width is " << expr->expr_width() << ", but I count " << pos << " bits.\"" << endl; } @@ -3357,6 +3358,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.186 2000/11/30 17:31:42 steve + * Change LineInfo to store const C strings. + * * Revision 1.185 2000/11/20 00:58:40 steve * Add support for supply nets (PR#17) *