Function declarations in packages
This is still basic. Definitions are still not done.
This commit is contained in:
parent
34f6e25b4e
commit
d9fea802da
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include "sequential.h"
|
||||
# include "subprogram.h"
|
||||
# include "parse_types.h"
|
||||
|
||||
class VType;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue