forked from chipsalliance/verible
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpression.h
111 lines (91 loc) · 4.45 KB
/
expression.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VERIBLE_VERILOG_CST_EXPRESSION_H_
#define VERIBLE_VERILOG_CST_EXPRESSION_H_
// See comment at the top of
// verilog/CST/verilog_treebuilder_utils.h that explains use
// of std::forward in Make* helper functions.
#include <utility>
#include "common/analysis/syntax_tree_search.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/symbol.h"
#include "common/text/tree_utils.h"
#include "verilog/CST/verilog_nonterminals.h"
#include "verilog/parser/verilog_token_classifications.h"
namespace verilog {
// Example usage: $$ = MakeBinaryExpression($1, $2, $3);
template <typename T1, typename T2, typename T3>
verible::SymbolPtr MakeBinaryExpression(T1&& lhs, T2&& op, T3&& rhs) {
const verible::SyntaxTreeLeaf& this_op(SymbolCastToLeaf(*op));
const auto this_tag = verilog_tokentype(this_op.Tag().tag);
// If parent (lhs) operator is associative and matches this one,
// then flatten them into the same set of siblings.
// This prevents excessive tree depth for long associative expressions.
if (IsAssociativeOperator(this_tag) &&
lhs->Kind() == verible::SymbolKind::kNode) {
const auto& lhs_node =
verible::down_cast<const verible::SyntaxTreeNode&>(*lhs);
if (lhs_node.MatchesTag(NodeEnum::kBinaryExpression)) {
const verible::SyntaxTreeLeaf& lhs_op =
verible::SymbolCastToLeaf(*lhs_node[1]);
const auto lhs_tag = verilog_tokentype(lhs_op.Tag().tag);
if (lhs_tag == this_tag) {
return verible::ExtendNode(std::forward<T1>(lhs), std::forward<T2>(op),
std::forward<T3>(rhs));
}
}
}
return verible::MakeTaggedNode(NodeEnum::kBinaryExpression,
std::forward<T1>(lhs), std::forward<T2>(op),
std::forward<T3>(rhs));
}
// Returns true if symbol is a kNode tagged with kExpression
// Does not match other Expression tags
bool IsExpression(const verible::SymbolPtr&);
// Returns true if expression is a literal 0.
// Does not evaluate constant expressions for equivalence to 0.
bool IsZero(const verible::Symbol&);
// Returns true if integer value is successfully interpreted.
bool ConstantIntegerValue(const verible::Symbol&, int*);
// Returns the Symbol directly underneath a `kExpression` node, otherwise
// returns itself.
const verible::Symbol* UnwrapExpression(const verible::Symbol&);
// Returns the predicate expression of a kConditionExpression.
const verible::Symbol* GetConditionExpressionPredicate(const verible::Symbol&);
// Returns the true-case expression of a kConditionExpression.
const verible::Symbol* GetConditionExpressionTrueCase(const verible::Symbol&);
// Returns the false-case expression of a kConditionExpression.
const verible::Symbol* GetConditionExpressionFalseCase(const verible::Symbol&);
// From binary expression operations, e.g. "a + b".
// Associative binary operators may span more than two operands, e.g. "a+b+c".
std::vector<verible::TreeSearchMatch> FindAllBinaryOperations(
const verible::Symbol&);
// TODO(fangism): evaluate constant expressions
// From a statement like "assign foo = condition_a ? a : b;", returns condition
// expressions "condition_a ? a : b".
std::vector<verible::TreeSearchMatch> FindAllConditionExpressions(
const verible::Symbol&);
// TODO(fangism): evaluate constant expressions
// From a statement like "a[i].j[k] = p[q].r(s);", returns full references
// expressions "a[i].j[k]" and "p[q].r(s)".
// References include any indexing [], hierarchy ".x" or call "(...)"
// extensions.
std::vector<verible::TreeSearchMatch> FindAllReferenceFullExpressions(
const verible::Symbol&);
// Returns true if reference expression is a plain variable reference with no
// hierarchy, no indexing, no calls.
const verible::TokenInfo* ReferenceIsSimpleIdentifier(
const verible::Symbol& reference);
} // namespace verilog
#endif // VERIBLE_VERILOG_CST_EXPRESSION_H_