From 62be9c5b462645fbeffbe613b9d23f620cd3870a Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 21 Oct 2012 11:42:19 -0700 Subject: [PATCH] Parse (with sorry message) package declarations. --- Makefile.in | 6 +-- PPackage.cc | 30 ++++++++++++++ PPackage.h | 40 ++++++++++++++++++ parse.y | 104 ++++++++++++++++++++++++++++++++++++----------- pform.cc | 15 ++++++- pform.h | 6 +++ pform_package.cc | 42 +++++++++++++++++++ 7 files changed, 215 insertions(+), 28 deletions(-) create mode 100644 PPackage.cc create mode 100644 PPackage.h create mode 100644 pform_package.cc diff --git a/Makefile.in b/Makefile.in index 1a177aa13..93263909a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -112,11 +112,11 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \ net_link.o net_modulo.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ - pform_disciplines.o pform_dump.o pform_pclass.o pform_string_type.o \ - pform_struct_type.o pform_types.o \ + pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \ + pform_string_type.o pform_struct_type.o pform_types.o \ symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \ Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \ - PGenerate.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \ + PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \ Statement.o AStatement.o $M $(FF) $(TT) all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man diff --git a/PPackage.cc b/PPackage.cc new file mode 100644 index 000000000..e235dafc7 --- /dev/null +++ b/PPackage.cc @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012 Picture Elements, Inc. + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +# include "PPackage.h" + +PPackage::PPackage(perm_string name, LexicalScope*parent) +: PScopeExtra(name, parent) +{ +} + +PPackage::~PPackage() +{ +} diff --git a/PPackage.h b/PPackage.h new file mode 100644 index 000000000..f828384ae --- /dev/null +++ b/PPackage.h @@ -0,0 +1,40 @@ +#ifndef __PPackage_H +#define __PPackage_H +/* + * Copyright (c) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +# include "PScope.h" +# include "LineInfo.h" +# include "StringHeap.h" + +/* + * SystemVerilog supports class declarations with their own lexical + * scope, etc. The parser arranges for these to be created and + * collected. + */ + +class PPackage : public PScopeExtra, public LineInfo { + + public: + explicit PPackage (perm_string name, LexicalScope*parent); + ~PPackage(); + +}; + +#endif diff --git a/parse.y b/parse.y index b0675235a..3cfc0ca2d 100644 --- a/parse.y +++ b/parse.y @@ -622,13 +622,10 @@ static void current_function_set_statement(const YYLTYPE&loc, vector %% - /* A degenerate source file can be completely empty. */ -main : source_file | ; -source_file - : description - | source_file description - ; + /* IEEE1800-2005: A.1.2 */ + /* source_text ::= [ timeunits_declaration ] { description } */ +source_text : description_list | ; assignment_pattern /* IEEE1800-2005: A.6.7.1 */ : K_LP expression_list_proper '}' @@ -930,6 +927,37 @@ data_type_or_implicit /* IEEE1800-2005: A.2.2.1 */ { $$ = 0; } ; + + /* NOTE 1: We pull the "timeunits_declaration" into the description + here in order to be a little more flexible with where timeunits + statements may go. This may be a bad idea, but it is legacy now. */ + + /* NOTE 2: The "module" rule of the description combines the + module_declaration and program_declaration rules from the + standard description. */ + +description /* IEEE1800-2005: A.1.2 */ + : module + | udp_primitive + | config_declaration + | nature_declaration + | package_declaration + | discipline_declaration + | timeunits_declaration + | KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' + { perm_string tmp3 = lex_strings.make($3); + pform_set_type_attrib(tmp3, $5, $7); + delete[] $3; + delete[] $5; + } + ; + +description_list + : description + | description_list description + ; + + /* This implements the [ : INDENTIFIER ] part of the constructure rule documented in IEEE1800-2005: A.1.8 */ endnew_opt : ':' K_new | ; @@ -1286,6 +1314,41 @@ open_range_list /* IEEE1800-2005 A.2.11 */ | value_range ; +package_declaration /* IEEE1800-2005 A.1.2 */ + : K_package IDENTIFIER ';' + { pform_start_package_declaration(@1, $2); + } + package_item_list_opt + K_endpackage + { pform_end_package_declaration(@1); } + endname_opt + { // Last step: check any closing name. This is done late so + // that the parser can look ahead to detect the present + // endname_opt but still have the pform_endmodule() called + // early enough that the lexor can know we are outside the + // module. + if ($8 && (strcmp($2,$8) != 0)) { + yyerror(@8, "error: End name doesn't match package name"); + } + delete[]$2; + if ($8) delete[]$8; + } + ; + +package_item /* IEEE1800-2005 A.1.10 */ + : timeunits_declaration + | K_localparam param_type localparam_assign_list ';' + | type_declaration + | function_declaration + ; + +package_item_list + : package_item_list package_item + | package_item + ; + +package_item_list_opt : package_item_list | ; + port_direction /* IEEE1800-2005 A.1.3 */ : K_input { $$ = NetNet::PINPUT; } | K_output { $$ = NetNet::POUTPUT; } @@ -1713,6 +1776,17 @@ tf_port_list /* IEEE1800-2005: A.2.7 */ } ; + /* NOTE: Icarus Verilog is a little more generous with the + timeunits declarations by allowing them to happen in multiple + places in the file. So the rule is adjusted to be invoked by the + "description" rule. This theoretically allows files to be + concatenated together and still compile. */ +timeunits_declaration /* IEEE1800-2005: A.1.2 */ + : K_timeunit TIME_LITERAL ';' + { pform_set_timeunit($2, false, false); } + | K_timeprecision TIME_LITERAL ';' + { pform_set_timeprecision($2, false, false); } + ; value_range /* IEEE1800-2005: A.8.3 */ : expression @@ -2294,24 +2368,6 @@ delay_value_simple } ; -description - : module - | udp_primitive - | config_declaration - | nature_declaration - | discipline_declaration - | KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' - { perm_string tmp3 = lex_strings.make($3); - pform_set_type_attrib(tmp3, $5, $7); - delete[] $3; - delete[] $5; - } - | K_timeunit TIME_LITERAL ';' - { pform_set_timeunit($2, false, false); } - | K_timeprecision TIME_LITERAL ';' - { pform_set_timeprecision($2, false, false); } - ; - /* The discipline and nature declarations used to take no ';' after the identifier. The 2.3 LRM adds the ';', but since there are programs written to the 2.1 and 2.2 standard that don't, we diff --git a/pform.cc b/pform.cc index bdf89b653..30678a04e 100644 --- a/pform.cc +++ b/pform.cc @@ -25,6 +25,7 @@ # include "parse_api.h" # include "PClass.h" # include "PEvent.h" +# include "PPackage.h" # include "PUdp.h" # include "PGenerate.h" # include "PSpec.h" @@ -292,6 +293,15 @@ PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name) return class_scope; } +PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name) +{ + PPackage*pkg_scope = new PPackage(name, lexical_scope); + FILE_NAME(pkg_scope, loc); + + lexical_scope = pkg_scope; + return pkg_scope; +} + PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) { perm_string task_name = lex_strings.make(name); @@ -2495,6 +2505,7 @@ void pform_set_localparam(const struct vlltype&loc, bool signed_flag, list*range, PExpr*expr) { LexicalScope*scope = lexical_scope; + ivl_assert(loc, scope); // Check if the localparam name is already in the dictionary. if (scope->localparams.find(name) != scope->localparams.end()) { @@ -2513,7 +2524,9 @@ void pform_set_localparam(const struct vlltype&loc, << "' have the same name '" << name << "'." << endl; error_count += 1; } - if ((scope == pform_cur_module.front()) && + + if ((pform_cur_module.size() > 0) && + (scope == pform_cur_module.front()) && (pform_cur_module.front()->specparams.find(name) != pform_cur_module.front()->specparams.end())) { LineInfo tloc; FILE_NAME(&tloc, loc); diff --git a/pform.h b/pform.h index d4fbb4e53..95ec884cc 100644 --- a/pform.h +++ b/pform.h @@ -59,6 +59,7 @@ class PGate; class PExpr; class PSpecPath; class PClass; +class PPackage; struct vlltype; /* @@ -182,6 +183,10 @@ extern void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type); extern void pform_end_class_declaration(void); +extern void pform_start_package_declaration(const struct vlltype&loc, + const char*type); +extern void pform_end_package_declaration(const struct vlltype&loc); + extern void pform_make_udp(perm_string name, list*parms, svector*decl, list*table, Statement*init, @@ -202,6 +207,7 @@ extern void pform_make_udp(perm_string name, extern void pform_pop_scope(); extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name); +extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name); extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto); extern PFunction*pform_push_function_scope(const struct vlltype&loc, char*name, diff --git a/pform_package.cc b/pform_package.cc new file mode 100644 index 000000000..e760c578e --- /dev/null +++ b/pform_package.cc @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +# include "pform.h" +# include "PPackage.h" +# include "parse_misc.h" +# include "ivl_assert.h" + +static PPackage*pform_cur_package = 0; + +void pform_start_package_declaration(const struct vlltype&loc, const char*name) +{ + VLerror(loc, "sorry: Package declarations not supported."); + ivl_assert(loc, pform_cur_package == 0); + + perm_string use_name = lex_strings.make(name); + PPackage*pkg_scope = pform_push_package_scope(loc, use_name); + pform_cur_package = pkg_scope; +} + +void pform_end_package_declaration(const struct vlltype&loc) +{ + ivl_assert(loc, pform_cur_package); + pform_cur_package = 0; + pform_pop_scope(); +}