Parse/decorate sequential statements.
Get to the point where our sample program parses completely, and the sequential statements generate SequentialStmt objects and a process object in the architecture. Also add a few missing expression types.
This commit is contained in:
parent
7afd4210db
commit
3e419dc854
|
|
@ -60,7 +60,7 @@ LIBS = @LIBS@ @EXTRALIBS@
|
|||
M = StringHeap.o LineInfo.o
|
||||
|
||||
O = main.o architec.o architec_elaborate.o compiler.o entity.o entity_elaborate.o \
|
||||
expression.o package.o scope.o vsignal.o vtype.o vtype_elaborate.o \
|
||||
expression.o package.o scope.o sequential.o vsignal.o vtype.o vtype_elaborate.o \
|
||||
lexor.o lexor_keyword.o parse.o \
|
||||
parse_misc.o library.o vhdlreal.o vhdlint.o debug.o \
|
||||
architec_emit.o entity_emit.o expression_emit.o vtype_emit.o \
|
||||
|
|
|
|||
|
|
@ -70,3 +70,12 @@ ComponentInstantiation::ComponentInstantiation(perm_string i, perm_string c,
|
|||
ComponentInstantiation::~ComponentInstantiation()
|
||||
{
|
||||
}
|
||||
|
||||
ProcessStatement::ProcessStatement(perm_string iname)
|
||||
: iname_(iname)
|
||||
{
|
||||
}
|
||||
|
||||
ProcessStatement::~ProcessStatement()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,4 +122,15 @@ class ComponentInstantiation : public Architecture::Statement {
|
|||
std::map<perm_string,Expression*> port_map_;
|
||||
};
|
||||
|
||||
class ProcessStatement : public Architecture::Statement {
|
||||
|
||||
public:
|
||||
ProcessStatement(perm_string iname);
|
||||
~ProcessStatement();
|
||||
|
||||
private:
|
||||
perm_string iname_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -213,12 +213,25 @@ void ExpArithmetic::dump(ostream&out, int indent) const
|
|||
dump_operands(out, indent+4);
|
||||
}
|
||||
|
||||
void ExpAttribute::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Attribute " << name_
|
||||
<< " at " << get_fileline() << endl;
|
||||
base_->dump(out, indent+4);
|
||||
}
|
||||
|
||||
void ExpBinary::dump_operands(ostream&out, int indent) const
|
||||
{
|
||||
operand1_->dump(out, indent);
|
||||
operand2_->dump(out, indent);
|
||||
}
|
||||
|
||||
void ExpCharacter::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Character '" << value_ << "'"
|
||||
<< " at " << get_fileline() << endl;
|
||||
}
|
||||
|
||||
void ExpInteger::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Integer " << value_
|
||||
|
|
@ -262,6 +275,33 @@ void ExpName::dump(ostream&out, int indent) const
|
|||
index_->dump(out, indent+6);
|
||||
}
|
||||
|
||||
void ExpRelation::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Relation ";
|
||||
switch (fun_) {
|
||||
case EQ:
|
||||
out << "=";
|
||||
break;
|
||||
case LT:
|
||||
out << "<";
|
||||
break;
|
||||
case GT:
|
||||
out << ">";
|
||||
break;
|
||||
case NEQ:
|
||||
out << "/=";
|
||||
break;
|
||||
case LE:
|
||||
out << "<=";
|
||||
break;
|
||||
case GE:
|
||||
out << ">=";
|
||||
break;
|
||||
}
|
||||
out << endl;
|
||||
dump_operands(out, indent+4);
|
||||
}
|
||||
|
||||
void ExpUAbs::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "abs() at " << get_fileline() << endl;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,16 @@ bool Expression::evaluate(ScopeBase*, int64_t&) const
|
|||
return false;
|
||||
}
|
||||
|
||||
ExpAttribute::ExpAttribute(ExpName*bas, perm_string nam)
|
||||
: base_(bas), name_(nam)
|
||||
{
|
||||
}
|
||||
|
||||
ExpAttribute::~ExpAttribute()
|
||||
{
|
||||
delete base_;
|
||||
}
|
||||
|
||||
ExpBinary::ExpBinary(Expression*op1, Expression*op2)
|
||||
: operand1_(op1), operand2_(op2)
|
||||
{
|
||||
|
|
@ -118,6 +128,15 @@ bool ExpArithmetic::evaluate(ScopeBase*scope, int64_t&val) const
|
|||
return true;
|
||||
}
|
||||
|
||||
ExpCharacter::ExpCharacter(char val)
|
||||
: value_(val)
|
||||
{
|
||||
}
|
||||
|
||||
ExpCharacter::~ExpCharacter()
|
||||
{
|
||||
}
|
||||
|
||||
ExpInteger::ExpInteger(int64_t val)
|
||||
: value_(val)
|
||||
{
|
||||
|
|
@ -176,6 +195,15 @@ bool ExpName::evaluate(ScopeBase*scope, int64_t&val) const
|
|||
return exp->evaluate(scope, val);
|
||||
}
|
||||
|
||||
ExpRelation::ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2)
|
||||
: ExpBinary(op1, op2), fun_(ty)
|
||||
{
|
||||
}
|
||||
|
||||
ExpRelation::~ExpRelation()
|
||||
{
|
||||
}
|
||||
|
||||
ExpUAbs::ExpUAbs(Expression*op1)
|
||||
: ExpUnary(op1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ class Entity;
|
|||
class Architecture;
|
||||
class ScopeBase;
|
||||
|
||||
class ExpName;
|
||||
|
||||
/*
|
||||
* The Expression class represents parsed expressions from the parsed
|
||||
* VHDL input. The Expression class is a virtual class that holds more
|
||||
|
|
@ -122,6 +124,34 @@ class ExpArithmetic : public ExpBinary {
|
|||
fun_t fun_;
|
||||
};
|
||||
|
||||
class ExpAttribute : public Expression {
|
||||
|
||||
public:
|
||||
ExpAttribute(ExpName*base, perm_string name);
|
||||
~ExpAttribute();
|
||||
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
ExpName*base_;
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
class ExpCharacter : public Expression {
|
||||
|
||||
public:
|
||||
ExpCharacter(char val);
|
||||
~ExpCharacter();
|
||||
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
bool is_primary(void) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
char value_;
|
||||
};
|
||||
|
||||
class ExpInteger : public Expression {
|
||||
|
||||
public:
|
||||
|
|
@ -176,6 +206,22 @@ class ExpName : public Expression {
|
|||
Expression*index_;
|
||||
};
|
||||
|
||||
class ExpRelation : public ExpBinary {
|
||||
|
||||
public:
|
||||
enum fun_t { EQ, LT, GT, NEQ, LE, GE };
|
||||
|
||||
public:
|
||||
ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2);
|
||||
~ExpRelation();
|
||||
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
fun_t fun_;
|
||||
};
|
||||
|
||||
class ExpUAbs : public ExpUnary {
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -63,6 +63,15 @@ int ExpUnary::emit_operand1(ostream&out, Entity*ent, Architecture*arc)
|
|||
return errors;
|
||||
}
|
||||
|
||||
int ExpAttribute::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
out << "$ivl_attribute(";
|
||||
errors += base_->emit(out, ent, arc);
|
||||
out << ", \"" << name_ << "\")";
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ExpArithmetic::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
@ -98,6 +107,17 @@ int ExpArithmetic::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
return errors;
|
||||
}
|
||||
|
||||
int ExpCharacter::emit(ostream&out, Entity*, Architecture*)
|
||||
{
|
||||
out << "\"" << value_ << "\"";
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ExpCharacter::is_primary(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int ExpInteger::emit(ostream&out, Entity*, Architecture*)
|
||||
{
|
||||
out << value_;
|
||||
|
|
@ -160,6 +180,36 @@ bool ExpName::is_primary(void) const
|
|||
return true;
|
||||
}
|
||||
|
||||
int ExpRelation::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
errors += emit_operand1(out, ent, arc);
|
||||
|
||||
switch (fun_) {
|
||||
case EQ:
|
||||
out << " == ";
|
||||
break;
|
||||
case LT:
|
||||
out << " < ";
|
||||
break;
|
||||
case GT:
|
||||
out << " > ";
|
||||
break;
|
||||
case NEQ:
|
||||
out << " != ";
|
||||
break;
|
||||
case LE:
|
||||
out << " <= ";
|
||||
break;
|
||||
case GE:
|
||||
out << " >= ";
|
||||
break;
|
||||
}
|
||||
|
||||
errors += emit_operand2(out, ent, arc);
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ExpUAbs::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
|
|||
100
vhdlpp/parse.y
100
vhdlpp/parse.y
|
|
@ -27,6 +27,7 @@
|
|||
# include "parse_misc.h"
|
||||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include "sequential.h"
|
||||
# include "package.h"
|
||||
# include "vsignal.h"
|
||||
# include "vtype.h"
|
||||
|
|
@ -122,6 +123,9 @@ const VType*parse_type_by_name(perm_string name)
|
|||
Expression*expr;
|
||||
std::list<Expression*>* expr_list;
|
||||
|
||||
SequentialStmt* sequ;
|
||||
std::list<SequentialStmt*>*sequ_list;
|
||||
|
||||
named_expr_t*named_expr;
|
||||
std::list<named_expr_t*>*named_expr_list;
|
||||
entity_aspect_t* entity_aspect;
|
||||
|
|
@ -204,6 +208,9 @@ const VType*parse_type_by_name(perm_string name)
|
|||
%type <compound_name> prefix selected_name
|
||||
%type <compound_name_list> selected_names use_clause
|
||||
|
||||
%type <sequ_list> sequence_of_statements if_statement_else
|
||||
%type <sequ> sequential_statement if_statement signal_assignment_statement
|
||||
|
||||
%%
|
||||
|
||||
/* The design_file is the root for the VHDL parse. */
|
||||
|
|
@ -748,28 +755,38 @@ if_statement
|
|||
: K_if expression K_then sequence_of_statements
|
||||
if_statement_else
|
||||
K_end K_if ';'
|
||||
{ IfSequential*tmp = new IfSequential($2, $4, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
| K_if error K_then sequence_of_statements
|
||||
if_statement_else
|
||||
K_end K_if ';'
|
||||
{ errormsg(@2, "Error in if_statement condition expression.\n");
|
||||
yyerrok;
|
||||
$$ = 0;
|
||||
delete $4;
|
||||
}
|
||||
|
||||
| K_if expression K_then error K_end K_if ';'
|
||||
{ errormsg(@2, "Too many errors in sequence within if_statement.\n");
|
||||
yyerrok;
|
||||
$$ = 0;
|
||||
}
|
||||
|
||||
| K_if error K_end K_if ';'
|
||||
{ errormsg(@2, "Too many errors in if_statement.\n");
|
||||
yyerrok;
|
||||
$$ = 0;
|
||||
}
|
||||
;
|
||||
|
||||
if_statement_else
|
||||
: K_else sequence_of_statements
|
||||
{ $$ = $2; }
|
||||
|
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
instantiation_list
|
||||
|
|
@ -1008,13 +1025,14 @@ primary
|
|||
: name
|
||||
{ $$ = $1; }
|
||||
| name '\'' IDENTIFIER
|
||||
{ sorrymsg(@3, "Identifier attributes not supported.\n");
|
||||
{ perm_string name = lex_strings.make($3);
|
||||
ExpName*base = dynamic_cast<ExpName*> ($1);
|
||||
ExpAttribute*tmp = new ExpAttribute(base, name);
|
||||
delete[]$3;
|
||||
$$ = $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| CHARACTER_LITERAL
|
||||
{ sorrymsg(@1, "Character literals not supported.\n");
|
||||
ExpInteger*tmp = new ExpInteger($1[0]);
|
||||
{ ExpCharacter*tmp = new ExpCharacter($1[0]);
|
||||
FILE_NAME(tmp,@1);
|
||||
delete[]$1;
|
||||
$$ = tmp;
|
||||
|
|
@ -1037,10 +1055,19 @@ primary_unit
|
|||
process_statement
|
||||
: IDENTIFIER ':' K_postponed_opt K_process
|
||||
process_sensitivity_list_opt K_is_opt
|
||||
K_begin process_statement_part
|
||||
K_begin sequence_of_statements
|
||||
K_end K_postponed_opt K_process identifier_opt ';'
|
||||
{ sorrymsg(@4, "Concurrent processes not implemented yet.\n");
|
||||
$$ = 0;
|
||||
{ perm_string iname = lex_strings.make($1);
|
||||
if ($12) {
|
||||
if (iname != $12)
|
||||
errormsg(@12, "Process name %s does not match opening name %s.\n",
|
||||
$12, $1);
|
||||
delete[]$12;
|
||||
}
|
||||
|
||||
ProcessStatement*tmp = new ProcessStatement(iname);
|
||||
FILE_NAME(tmp, @4);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
| IDENTIFIER ':' K_postponed_opt K_process
|
||||
|
|
@ -1053,11 +1080,6 @@ process_statement
|
|||
}
|
||||
;
|
||||
|
||||
process_statement_part
|
||||
: process_statement_part sequential_statement
|
||||
| sequential_statement
|
||||
;
|
||||
|
||||
process_sensitivity_list_opt
|
||||
: '(' process_sensitivity_list ')'
|
||||
| '(' error ')'
|
||||
|
|
@ -1074,34 +1096,34 @@ relation
|
|||
: shift_expression
|
||||
{ $$ = $1; }
|
||||
| shift_expression '=' shift_expression
|
||||
{ sorrymsg(@2, "Expression operator '=' not implemented.\n");
|
||||
delete $3;
|
||||
$$ = $1;
|
||||
{ ExpRelation*tmp = new ExpRelation(ExpRelation::EQ, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| shift_expression '<' shift_expression
|
||||
{ sorrymsg(@2, "Expression operator '<' not implemented.\n");
|
||||
delete $3;
|
||||
$$ = $1;
|
||||
{ ExpRelation*tmp = new ExpRelation(ExpRelation::LT, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| shift_expression '>' shift_expression
|
||||
{ sorrymsg(@2, "Expression operator '>' not implemented.\n");
|
||||
delete $3;
|
||||
$$ = $1;
|
||||
{ ExpRelation*tmp = new ExpRelation(ExpRelation::GT, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| shift_expression LEQ shift_expression
|
||||
{ sorrymsg(@2, "Expression operator '<=' not implemented.\n");
|
||||
delete $3;
|
||||
$$ = $1;
|
||||
{ ExpRelation*tmp = new ExpRelation(ExpRelation::LE, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| shift_expression GEQ shift_expression
|
||||
{ sorrymsg(@2, "Expression operator '>=' not implemented.\n");
|
||||
delete $3;
|
||||
$$ = $1;
|
||||
{ ExpRelation*tmp = new ExpRelation(ExpRelation::GE, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| shift_expression NE shift_expression
|
||||
{ sorrymsg(@2, "Expression operator '/=' not implemented.\n");
|
||||
delete $3;
|
||||
$$ = $1;
|
||||
{ ExpRelation*tmp = new ExpRelation(ExpRelation::NEQ, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1165,12 +1187,20 @@ selected_names_use
|
|||
|
||||
sequence_of_statements
|
||||
: sequence_of_statements sequential_statement
|
||||
{ std::list<SequentialStmt*>*tmp = $1;
|
||||
tmp->push_back($2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| sequential_statement
|
||||
{ std::list<SequentialStmt*>*tmp = new std::list<SequentialStmt*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
sequential_statement
|
||||
: if_statement
|
||||
| signal_assignment_statement
|
||||
: if_statement { $$ = $1; }
|
||||
| signal_assignment_statement { $$ = $1; }
|
||||
;
|
||||
|
||||
shift_expression : simple_expression { $$ = $1; } ;
|
||||
|
|
@ -1192,7 +1222,11 @@ simple_expression
|
|||
|
||||
signal_assignment_statement
|
||||
: name LEQ waveform ';'
|
||||
{ sorrymsg(@1, "Signal assignment statements not implemented.\n"); }
|
||||
{ SignalSeqAssignment*tmp = new SignalSeqAssignment($1, $3);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
subtype_declaration
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
# include "vhdlreal.h"
|
||||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include "sequential.h"
|
||||
# include "parse_types.h"
|
||||
|
||||
class VType;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2011 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
|
||||
*/
|
||||
|
||||
# include "sequential.h"
|
||||
# include "expression.h"
|
||||
|
||||
SequentialStmt::SequentialStmt()
|
||||
{
|
||||
}
|
||||
|
||||
SequentialStmt::~SequentialStmt()
|
||||
{
|
||||
}
|
||||
|
||||
IfSequential::IfSequential(Expression*cond, std::list<SequentialStmt*>*tr,
|
||||
std::list<SequentialStmt*>*fa)
|
||||
{
|
||||
cond_ = cond;
|
||||
if (tr) if_.splice(if_.end(), *tr);
|
||||
if (fa) else_.splice(else_.end(), *fa);
|
||||
}
|
||||
|
||||
IfSequential::~IfSequential()
|
||||
{
|
||||
delete cond_;
|
||||
}
|
||||
|
||||
SignalSeqAssignment::SignalSeqAssignment(Expression*sig, std::list<Expression*>*wav)
|
||||
{
|
||||
lval_ = sig;
|
||||
if (wav) waveform_.splice(waveform_.end(), *wav);
|
||||
}
|
||||
|
||||
SignalSeqAssignment::~SignalSeqAssignment()
|
||||
{
|
||||
delete lval_;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef __sequential_H
|
||||
#define __sequential_H
|
||||
/*
|
||||
* Copyright (c) 2011 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
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <list>
|
||||
|
||||
class Expression;
|
||||
|
||||
class SequentialStmt : public LineInfo {
|
||||
|
||||
public:
|
||||
SequentialStmt();
|
||||
~SequentialStmt();
|
||||
|
||||
};
|
||||
|
||||
class IfSequential : public SequentialStmt {
|
||||
|
||||
public:
|
||||
IfSequential(Expression*cond, std::list<SequentialStmt*>*tr,
|
||||
std::list<SequentialStmt*>*fa);
|
||||
~IfSequential();
|
||||
|
||||
private:
|
||||
Expression*cond_;
|
||||
std::list<SequentialStmt*> if_;
|
||||
std::list<SequentialStmt*> else_;
|
||||
};
|
||||
|
||||
class SignalSeqAssignment : public SequentialStmt {
|
||||
public:
|
||||
SignalSeqAssignment(Expression*sig, std::list<Expression*>*wav);
|
||||
~SignalSeqAssignment();
|
||||
|
||||
private:
|
||||
Expression*lval_;
|
||||
std::list<Expression*> waveform_;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue