Add initial parsing for let construct
This commit is contained in:
parent
a19caf4fe6
commit
d1eb4befcc
13
PFunction.cc
13
PFunction.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2021 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
|
||||
|
|
@ -89,3 +89,14 @@ PNamedItem::SymbolType PFunction::symbol_type() const
|
|||
{
|
||||
return FUNCTION;
|
||||
}
|
||||
|
||||
|
||||
PLet::PLet(perm_string name, LexicalScope*parent, list<let_port_t*>*ports,
|
||||
PExpr*expr)
|
||||
: PTaskFunc(name, parent), ports_(ports), expr_(expr)
|
||||
{
|
||||
}
|
||||
|
||||
PLet::~PLet()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
29
PTask.h
29
PTask.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_PTask_H
|
||||
#define IVL_PTask_H
|
||||
/*
|
||||
* Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2021 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
|
||||
|
|
@ -158,4 +158,31 @@ class PFunction : public PTaskFunc {
|
|||
bool is_auto_;
|
||||
};
|
||||
|
||||
// A let is like a simple function that is expanded in the compiler
|
||||
class PLet : public PTaskFunc {
|
||||
public:
|
||||
typedef struct let_port {
|
||||
data_type_t*type_;
|
||||
perm_string name_;
|
||||
list<pform_range_t>*range_;
|
||||
PExpr*def_;
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
} let_port_t;
|
||||
|
||||
// FIXME: Should the port list be a vector. Check once implemented completely
|
||||
explicit PLet(perm_string name, LexicalScope*parent,
|
||||
list<let_port_t*>*ports, PExpr*expr);
|
||||
~PLet();
|
||||
|
||||
void elaborate_sig(Design*des, NetScope*scope) const { (void)des; (void)scope; }
|
||||
void elaborate(Design*des, NetScope*scope) const { (void)des; (void)scope; }
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
list<let_port_t*>*ports_;
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
#endif /* IVL_PTask_H */
|
||||
|
|
|
|||
58
parse.y
58
parse.y
|
|
@ -394,6 +394,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
LexicalScope::range_t* value_range;
|
||||
vector<Module::port_t*>*mports;
|
||||
|
||||
list<PLet::let_port_t*>*let_port_lst;
|
||||
PLet::let_port_t*let_port_itm;
|
||||
|
||||
named_number_t* named_number;
|
||||
list<named_number_t>* named_numbers;
|
||||
|
||||
|
|
@ -613,11 +616,13 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
|
||||
%type <gate> gate_instance
|
||||
%type <gates> gate_instance_list
|
||||
%type <let_port_lst> let_port_list_opt let_port_list
|
||||
%type <let_port_itm> let_port_item
|
||||
|
||||
%type <pform_name> hierarchy_identifier implicit_class_handle
|
||||
%type <expr> assignment_pattern expression expr_mintypmax
|
||||
%type <expr> expr_primary_or_typename expr_primary
|
||||
%type <expr> class_new dynamic_array_new
|
||||
%type <expr> class_new dynamic_array_new let_default_opt
|
||||
%type <expr> inc_or_dec_expression inside_expression lpvalue
|
||||
%type <expr> branch_probe_expression streaming_concatenation
|
||||
%type <expr> delay_value delay_value_simple
|
||||
|
|
@ -629,7 +634,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <decl_assignments> list_of_variable_decl_assignments
|
||||
|
||||
%type <data_type> data_type data_type_or_implicit data_type_or_implicit_or_void
|
||||
%type <data_type> simple_type_or_string
|
||||
%type <data_type> simple_type_or_string let_formal_type
|
||||
%type <class_type> class_identifier
|
||||
%type <struct_member> struct_union_member
|
||||
%type <struct_members> struct_union_member_list
|
||||
|
|
@ -5169,6 +5174,11 @@ module_item
|
|||
yyerrok;
|
||||
}
|
||||
|
||||
| K_let IDENTIFIER let_port_list_opt '=' expression ';'
|
||||
{ perm_string tmp2 = lex_strings.make($2);
|
||||
pform_make_let(@1, tmp2, $3, $5);
|
||||
}
|
||||
|
||||
/* Maybe this is a discipline declaration? If so, then the lexor
|
||||
will see the discipline name as an identifier. We match it to the
|
||||
discipline or type name semantically. */
|
||||
|
|
@ -5424,6 +5434,50 @@ module_item
|
|||
|
||||
;
|
||||
|
||||
let_port_list_opt
|
||||
: '(' let_port_list ')'
|
||||
{ $$ = $2; }
|
||||
| '(' ')'
|
||||
{ $$ = 0; }
|
||||
|
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
let_port_list
|
||||
: let_port_item
|
||||
{ list<PLet::let_port_t*>*tmp = new list<PLet::let_port_t*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| let_port_list ',' let_port_item
|
||||
{ list<PLet::let_port_t*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
// FIXME: What about the attributes?
|
||||
let_port_item
|
||||
: attribute_list_opt let_formal_type IDENTIFIER dimensions_opt let_default_opt
|
||||
{ perm_string tmp3 = lex_strings.make($3);
|
||||
$$ = pform_make_let_port($2, tmp3, $4, $5);
|
||||
}
|
||||
;
|
||||
|
||||
let_default_opt
|
||||
: '=' expression
|
||||
{ $$ = $2; }
|
||||
|
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
let_formal_type
|
||||
: data_type_or_implicit
|
||||
{ $$ = $1; }
|
||||
| K_untyped
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
module_item_list
|
||||
: module_item_list module_item
|
||||
| module_item
|
||||
|
|
|
|||
40
pform.cc
40
pform.cc
|
|
@ -3273,6 +3273,46 @@ void pform_set_param_from_type(const struct vlltype&loc,
|
|||
<< data_type->get_fileline() << "." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
|
||||
void pform_make_let(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
list<PLet::let_port*>*ports,
|
||||
PExpr*expr)
|
||||
{
|
||||
LexicalScope*scope = pform_peek_scope();
|
||||
|
||||
cerr << loc.get_fileline() << ": sorry: let declarations ("
|
||||
<< name << ") are not currently supported." << endl;
|
||||
error_count += 1;
|
||||
|
||||
PLet*res = new PLet(name, scope, ports, expr);
|
||||
FILE_NAME(res, loc);
|
||||
|
||||
/*
|
||||
cerr << "Found: ";
|
||||
res->dump(cerr, 0);
|
||||
*/
|
||||
|
||||
delete res;
|
||||
delete ports;
|
||||
delete expr;
|
||||
}
|
||||
|
||||
PLet::let_port_t* pform_make_let_port(data_type_t*data_type,
|
||||
perm_string name,
|
||||
list<pform_range_t>*range,
|
||||
PExpr*def)
|
||||
{
|
||||
PLet::let_port_t*res = new PLet::let_port_t;
|
||||
|
||||
res->type_ = data_type;
|
||||
res->name_ = name;
|
||||
res->range_ = range;
|
||||
res->def_ = def;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify paths.
|
||||
*/
|
||||
|
|
|
|||
12
pform.h
12
pform.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_pform_H
|
||||
#define IVL_pform_H
|
||||
/*
|
||||
* Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2021 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
|
||||
|
|
@ -437,6 +437,16 @@ extern void pform_set_param_from_type(const struct vlltype&loc,
|
|||
bool ¶m_signed,
|
||||
ivl_variable_type_t ¶m_type);
|
||||
|
||||
extern void pform_make_let(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
list<PLet::let_port_t*>*ports,
|
||||
PExpr*expr);
|
||||
|
||||
extern PLet::let_port_t* pform_make_let_port(data_type_t*data_type,
|
||||
perm_string name,
|
||||
list<pform_range_t>*range,
|
||||
PExpr*def);
|
||||
|
||||
/*
|
||||
* Functions related to specify blocks.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1144,6 +1144,33 @@ void PFunction::dump(ostream&out, unsigned ind) const
|
|||
out << setw(ind+2) << "" << "/* NOOP */" << endl;
|
||||
}
|
||||
|
||||
void PLet::let_port_t::dump(ostream&out, unsigned) const
|
||||
{
|
||||
if (type_) out << *type_ << " ";
|
||||
out << name_;
|
||||
// FIXME: This has not been tested and is likely wrong!
|
||||
if (range_) out << " " << range_;
|
||||
if (def_) out << "=" << *def_;
|
||||
}
|
||||
|
||||
void PLet::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "let ";
|
||||
out << pscope_name();
|
||||
if (ports_) {
|
||||
out << "(";
|
||||
typedef std::list<let_port_t*>::const_iterator port_itr_t;
|
||||
port_itr_t idx = ports_->begin();
|
||||
(*idx)->dump(out, 0);
|
||||
for (++idx; idx != ports_->end(); ++idx ) {
|
||||
out << ", ";
|
||||
(*idx)->dump(out, 0);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
out << " = " << *expr_ << ";" << endl;
|
||||
}
|
||||
|
||||
void PRelease::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "release " << *lval_ << "; /* "
|
||||
|
|
|
|||
Loading…
Reference in New Issue