Function declarations in packages

This is still basic. Definitions are still not done.
This commit is contained in:
Stephen Williams 2013-05-05 19:05:46 -07:00
parent 34f6e25b4e
commit d9fea802da
11 changed files with 237 additions and 16 deletions

View File

@ -22,6 +22,7 @@
# include "architec.h"
# include "expression.h"
# include "parse_types.h"
# include "sequential.h"
# include "vsignal.h"
# include "vtype.h"
# include <fstream>
@ -138,6 +139,19 @@ void Scope::dump_scope(ostream&out) const
cur->second->dump(out, 3);
else
out << " signal " << cur->first.str() << ": ???" << endl;
}
// Dump subprograms
for (map<perm_string,Subprogram*>::const_iterator cur = old_subprograms_.begin()
; cur != old_subprograms_.end() ; ++cur) {
out << " subprogram " << cur->first << " is" << endl;
cur->second->dump(out);
out << " end subprogram " << cur->first << endl;
}
for (map<perm_string,Subprogram*>::const_iterator cur = new_subprograms_.begin()
; cur != new_subprograms_.end() ; ++cur) {
out << " subprogram " << cur->first << " is" << endl;
cur->second->dump(out);
out << " end subprogram " << cur->first << endl;
}
// Dump component declarations
for (map<perm_string,ComponentBase*>::const_iterator cur = old_components_.begin()
@ -148,10 +162,11 @@ void Scope::dump_scope(ostream&out) const
out << " end component " << cur->first << endl;
}
for (map<perm_string,ComponentBase*>::const_iterator cur = new_components_.begin()
; cur != new_components_.end() ; ++cur) {
out << " component " << cur->first << " is" << endl;
cur->second->dump_ports(out);
out << " end component " << cur->first << endl;
; cur != new_components_.end() ; ++cur) {
out << " component " << cur->first << " is" << endl;
cur->second->dump_generics(out);
cur->second->dump_ports(out);
out << " end component " << cur->first << endl;
}
}
@ -436,3 +451,41 @@ ostream& ExpInteger::dump_inline(ostream&out) const
out << value_;
return out;
}
void Subprogram::dump(ostream&fd) const
{
fd << " " << name_;
if (ports_->empty()) {
fd << "()";
} else {
fd << "(";
list<InterfacePort*>::const_iterator cur = ports_->begin();
InterfacePort*curp = *cur;
fd << curp->name << ":";
curp->type->show(fd);
for (++ cur ; cur != ports_->end() ; ++ cur) {
curp = *cur;
fd << "; " << curp->name << ":";
curp->type->show(fd);
}
fd << ")";
}
fd << " return ";
return_type_->show(fd);
fd << endl;
if (statements_== 0 || statements_->empty()) {
fd << " <no definition>" << endl;
} else {
for (list<SequentialStmt*>::const_iterator cur = statements_->begin()
; cur != statements_->end() ; ++cur) {
SequentialStmt*curp = *cur;
curp->dump(fd, 8);
}
}
}

View File

@ -322,11 +322,13 @@ const VTypePrimitive* primitive_BOOLEAN = new VTypePrimitive(VTypePrimitive::BO
const VTypePrimitive* primitive_BIT = new VTypePrimitive(VTypePrimitive::BIT);
const VTypePrimitive* primitive_INTEGER = new VTypePrimitive(VTypePrimitive::INTEGER);
const VTypePrimitive* primitive_STDLOGIC = new VTypePrimitive(VTypePrimitive::STDLOGIC);
const VTypePrimitive* primitive_CHARACTER= new VTypePrimitive(VTypePrimitive::CHARACTER);
const VTypeRange* primitive_NATURAL = new VTypeRange(primitive_INTEGER, INT64_MAX, 0);
const VTypeArray* primitive_BIT_VECTOR = new VTypeArray(primitive_BIT, vector<VTypeArray::range_t> (1));
const VTypeArray* primitive_BOOL_VECTOR = new VTypeArray(primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
static const VTypeArray* primitive_BIT_VECTOR = new VTypeArray(primitive_BIT, vector<VTypeArray::range_t> (1));
static const VTypeArray* primitive_BOOL_VECTOR = new VTypeArray(primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
static const VTypeArray* primitive_STRING = new VTypeArray(primitive_CHARACTER, vector<VTypeArray::range_t> (1));
void generate_global_types(ActiveScope*res)
{
@ -334,7 +336,9 @@ void generate_global_types(ActiveScope*res)
res->bind_name(perm_string::literal("bit"), primitive_BIT);
res->bind_name(perm_string::literal("integer"), primitive_INTEGER);
res->bind_name(perm_string::literal("std_logic"), primitive_STDLOGIC);
res->bind_name(perm_string::literal("character"), primitive_CHARACTER);
res->bind_name(perm_string::literal("bit_vector"),primitive_BOOL_VECTOR);
res->bind_name(perm_string::literal("string"), primitive_STRING);
res->bind_name(perm_string::literal("natural"), primitive_NATURAL);
}
@ -344,7 +348,9 @@ bool is_global_type(perm_string name)
if (name == "bit") return true;
if (name == "integer") return true;
if (name == "std_logic") return true;
if (name == "character") return true;
if (name == "bit_vector") return true;
if (name == "string") return true;
if (name == "natural") return true;
return false;
}

View File

@ -104,6 +104,15 @@ void Package::write_to_stream(ostream&fd) const
fd << ";" << endl;
}
for (map<perm_string,Subprogram*>::const_iterator cur = old_subprograms_.begin()
; cur != old_subprograms_.end() ; ++cur) {
cur->second->write_to_stream(fd);
}
for (map<perm_string,Subprogram*>::const_iterator cur = new_subprograms_.begin()
; cur != new_subprograms_.end() ; ++cur) {
cur->second->write_to_stream(fd);
}
for (map<perm_string,ComponentBase*>::const_iterator cur = old_components_.begin()
; cur != old_components_.end() ; ++cur) {

View File

@ -34,7 +34,8 @@
# include "architec.h"
# include "expression.h"
# include "sequential.h"
# include "package.h"
# include "subprogram.h"
# include "package.h"
# include "vsignal.h"
# include "vtype.h"
# include <cstdarg>
@ -234,6 +235,8 @@ static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
Architecture::Statement* arch_statement;
std::list<Architecture::Statement*>* arch_statement_list;
Subprogram*subprogram;
};
/* The keywords are all tokens. */
@ -341,6 +344,8 @@ static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
%type <exp_else> else_when_waveform
%type <exp_else_list> else_when_waveforms
%type <subprogram> function_specification subprogram_specification
%%
/* The design_file is the root for the VHDL parse. This rule is also
@ -1143,6 +1148,15 @@ for_generate_statement
function_specification /* IEEE 1076-2008 P4.2.1 */
: K_function IDENTIFIER '(' interface_list ')' K_return IDENTIFIER
{ perm_string type_name = lex_strings.make($7);
perm_string name = lex_strings.make($2);
const VType*type_mark = active_scope->find_type(type_name);
Subprogram*tmp = new Subprogram(name, $4, type_mark);
FILE_NAME(tmp,@1);
delete[]$2;
delete[]$7;
$$ = tmp;
}
;
generate_statement /* IEEE 1076-2008 P11.8 */
@ -2057,6 +2071,7 @@ subprogram_body /* IEEE 1076-2008 P4.3 */
K_begin subprogram_statement_part K_end
subprogram_kind_opt identifier_opt ';'
{ sorrymsg(@2, "Subprogram bodies not supported.\n");
if ($1) delete $1;
if ($8) delete[]$8;
}
@ -2066,14 +2081,14 @@ subprogram_body /* IEEE 1076-2008 P4.3 */
subprogram_kind_opt identifier_opt ';'
{ errormsg(@2, "Syntax errors in subprogram body.\n");
yyerrok;
if ($1) delete $1;
if ($8) delete[]$8;
}
;
subprogram_declaration
: subprogram_specification ';'
{ sorrymsg(@1, "Subprogram specifications not supported.\n");
}
{ if ($1) active_scope->bind_name($1->name(), $1); }
;
subprogram_declarative_item /* IEEE 1079-2008 P4.3 */
@ -2098,7 +2113,7 @@ subprogram_kind /* IEEE 1076-2008 P4.3 */
subprogram_kind_opt : subprogram_kind | ;
subprogram_specification
: function_specification
: function_specification { $$ = $1; }
;
/* This is an implementation of the rule:

View File

@ -31,6 +31,7 @@
# include "architec.h"
# include "expression.h"
# include "sequential.h"
# include "subprogram.h"
# include "parse_types.h"
class VType;

View File

@ -57,6 +57,11 @@ ScopeBase::ScopeBase(const ScopeBase&ref)
insert_iterator<map<perm_string, const VType*> >(
old_types_, old_types_.end())
);
merge(ref.old_subprograms_.begin(), ref.old_subprograms_.end(),
ref.new_subprograms_.begin(), ref.new_subprograms_.end(),
insert_iterator<map<perm_string,Subprogram*> >(
old_subprograms_, old_subprograms_.end())
);
}
ScopeBase::~ScopeBase()
@ -76,6 +81,7 @@ void ScopeBase::cleanup()
delete_all(new_components_);
delete_all(new_types_);
delete_all(new_constants_);
delete_all(new_subprograms_);
}
const VType*ScopeBase::find_type(perm_string by_name)
@ -146,13 +152,26 @@ void ScopeBase::do_use_from(const ScopeBase*that)
continue;
old_components_[cur->first] = cur->second;
}
for (map<perm_string,ComponentBase*>::const_iterator cur = that->new_components_.begin()
for (map<perm_string,ComponentBase*>::const_iterator cur = that->new_components_.begin()
; cur != that->new_components_.end() ; ++ cur) {
if (cur->second == 0)
continue;
old_components_[cur->first] = cur->second;
}
for (map<perm_string,Subprogram*>::const_iterator cur = that->old_subprograms_.begin()
; cur != that->old_subprograms_.end() ; ++ cur) {
if (cur->second == 0)
continue;
old_subprograms_[cur->first] = cur->second;
}
for (map<perm_string,Subprogram*>::const_iterator cur = that->new_subprograms_.begin()
; cur != that->new_subprograms_.end() ; ++ cur) {
if (cur->second == 0)
continue;
old_subprograms_[cur->first] = cur->second;
}
for (map<perm_string,const VType*>::const_iterator cur = that->old_types_.begin()
; cur != that->old_types_.end() ; ++ cur) {
if (cur->second == 0)

View File

@ -23,12 +23,14 @@
# include <list>
# include <map>
# include "StringHeap.h"
# include "entity.h"
# include "expression.h"
# include "vsignal.h"
# include "entity.h"
# include "expression.h"
# include "subprogram.h"
# include "vsignal.h"
class Architecture;
class ComponentBase;
class Subprogram;
class VType;
template<typename T>
@ -89,6 +91,9 @@ class ScopeBase {
std::map<perm_string, struct const_t*> old_constants_; //previous scopes
std::map<perm_string, struct const_t*> new_constants_; //current scope
std::map<perm_string, Subprogram*> old_subprograms_; //previous scopes
std::map<perm_string, Subprogram*> new_subprograms_; //current scope
void do_use_from(const ScopeBase*that);
};
@ -171,6 +176,13 @@ class ActiveScope : public ScopeBase {
new_constants_[name] = new const_t(obj, val);
}
void bind_name(perm_string name, Subprogram*obj)
{ map<perm_string, Subprogram*>::iterator it;
if((it = old_subprograms_.find(name)) != old_subprograms_.end() )
old_subprograms_.erase(it);
new_subprograms_[name] = obj;;
}
void bind(Entity*ent)
{ context_entity_ = ent; }

54
vhdlpp/subprogram.cc Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / 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 "subprogram.h"
# include "entity.h"
# include "vtype.h"
using namespace std;
Subprogram::Subprogram(perm_string nam, list<InterfacePort*>*ports,
const VType*return_type)
: name_(nam), ports_(ports), return_type_(return_type), statements_(0)
{
}
Subprogram::~Subprogram()
{
}
void Subprogram::write_to_stream(ostream&fd) const
{
fd << " function " << name_ << "(";
if (ports_ && ! ports_->empty()) {
list<InterfacePort*>::const_iterator cur = ports_->begin();
InterfacePort*curp = *cur;
fd << curp->name << " : ";
curp->type->write_to_stream(fd);
for (++cur ; cur != ports_->end() ; ++cur) {
curp = *cur;
fd << "; " << curp->name << " : ";
curp->type->write_to_stream(fd);
}
}
fd << ") return ";
return_type_->write_to_stream(fd);
fd << ";" << endl;
}

51
vhdlpp/subprogram.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef __subprogram_H
#define __subprogram_H
/*
* Copyright (c) 2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / 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 "StringHeap.h"
# include "LineInfo.h"
# include <iostream>
# include <list>
class InterfacePort;
class SequentialStmt;
class VType;
class Subprogram : public LineInfo {
public:
Subprogram(perm_string name, std::list<InterfacePort*>*ports,
const VType*return_type);
~Subprogram();
inline const perm_string&name() const { return name_; }
void write_to_stream(std::ostream&fd) const;
void dump(std::ostream&fd) const;
private:
perm_string name_;
std::list<InterfacePort*>*ports_;
const VType*return_type_;
std::list<SequentialStmt*>*statements_;
};
#endif

View File

@ -32,7 +32,7 @@ VType::~VType()
void VType::show(ostream&out) const
{
out << typeid(*this).name();
write_to_stream(out);
}
VTypePrimitive::VTypePrimitive(VTypePrimitive::type_t tt)

View File

@ -112,7 +112,7 @@ class VTypeERROR : public VType {
class VTypePrimitive : public VType {
public:
enum type_t { BOOLEAN, BIT, INTEGER, STDLOGIC };
enum type_t { BOOLEAN, BIT, INTEGER, STDLOGIC, CHARACTER };
public:
VTypePrimitive(type_t);
@ -134,6 +134,7 @@ extern const VTypePrimitive* primitive_BOOLEAN;
extern const VTypePrimitive* primitive_BIT;
extern const VTypePrimitive* primitive_INTEGER;
extern const VTypePrimitive* primitive_STDLOGIC;
extern const VTypePrimitive* primitive_CHARACTER;
/*
* An array is a compound N-dimensional array of element type. The