Add failed memo
This commit is contained in:
parent
c6ffc40dab
commit
567eb87bf6
@ -69,4 +69,10 @@ mod thread_context {
|
||||
RefCell::new(ParserIndex{index: HashMap::new(), allocated: [0;RECURSIVE_FLAG_WORDS]})
|
||||
}
|
||||
);
|
||||
|
||||
thread_local!(
|
||||
pub static FAILED_MEMO: RefCell<HashMap<(&'static str, usize), bool>> = {
|
||||
RefCell::new(HashMap::new())
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ pub fn assignment_pattern_key(s: Span) -> IResult<Span, AssignmentPatternKey> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn assignment_pattern_expression(s: Span) -> IResult<Span, AssignmentPatternExpression> {
|
||||
let (s, a) = opt(assignment_pattern_expression_type)(s)?;
|
||||
let (s, b) = assignment_pattern(s)?;
|
||||
@ -299,7 +299,7 @@ pub fn assignment_pattern_expression_type(
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_assignment_pattern_expression(
|
||||
s: Span,
|
||||
) -> IResult<Span, ConstantAssignmentPatternExpression> {
|
||||
|
@ -1697,7 +1697,7 @@ pub fn cycle_delay_range_plus(s: Span) -> IResult<Span, CycleDelayRange> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn sequence_method_call(s: Span) -> IResult<Span, SequenceMethodCall> {
|
||||
let (s, a) = sequence_instance(s)?;
|
||||
let (s, b) = symbol(".")(s)?;
|
||||
|
@ -149,7 +149,7 @@ pub fn let_formal_type(s: Span) -> IResult<Span, LetFormalType> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn let_expression(s: Span) -> IResult<Span, LetExpression> {
|
||||
let (s, a) = opt(package_scope)(s)?;
|
||||
let (s, b) = let_identifier(s)?;
|
||||
|
@ -650,7 +650,7 @@ pub fn struct_union(s: Span) -> IResult<Span, StructUnion> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn type_reference(s: Span) -> IResult<Span, TypeReference> {
|
||||
alt((type_reference_expression, type_reference_data_type))(s)
|
||||
}
|
||||
|
@ -635,225 +635,226 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_data_declaration() {
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"shortint s1, s2[0:9];",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"var byte my_byte;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"var v;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"var [15:0] vw;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"var enum bit { clear, error } status;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"var reg r;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"int i = 0;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"logic a;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"logic[3:0] v;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"logic signed [3:0] signed_reg;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"logic [-1:4] b;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"logic [4:0] x, y, z;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"int unsigned ui;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"int signed si;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"string myName = default_name;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"byte c = \"A\";",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"bit [10:0] b = \"x41\";",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"bit [1:4][7:0] h = \"hello\" ;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"event done;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"event done_too = done;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"event empty = null;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef int intP;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"intP a, b;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef enum type_identifier;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef struct type_identifier;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef union type_identifier;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef class type_identifier;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef interface class type_identifier;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef type_identifier;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"typedef C::T c_t;",
|
||||
Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"enum {red, yellow, green} light1, light2;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"enum bit [1:0] {IDLE, XX='x, S1=2'b01, S2=2'b10} state, next;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"enum {bronze=3, silver, gold} medal;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"enum {a=3, b=7, c} alphabet;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"integer i_array[*];",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"bit [20:0] array_b[string];",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"event ev_array[myClass];",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"int array_name [*];",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"int array_name1 [ integer ];",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"int a[int] = '{default:1};",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
parser_test!(
|
||||
data_declaration,
|
||||
"byte q1[$];",
|
||||
Ok((_, DataDeclaration::Variable(_)))
|
||||
);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "shortint s1, s2[0:9];",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "var byte my_byte;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "var v;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "var [15:0] vw;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "var enum bit { clear, error } status;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "var reg r;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "int i = 0;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "logic a;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "logic[3:0] v;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "logic signed [3:0] signed_reg;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "logic [-1:4] b;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "logic [4:0] x, y, z;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "int unsigned ui;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "int signed si;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "string myName = default_name;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "byte c = \"A\";",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "bit [10:0] b = \"x41\";",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "bit [1:4][7:0] h = \"hello\" ;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "event done;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "event done_too = done;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "event empty = null;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef int intP;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "intP a, b;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef enum type_identifier;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef struct type_identifier;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef union type_identifier;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef class type_identifier;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef interface class type_identifier;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef type_identifier;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "typedef C::T c_t;",
|
||||
// Ok((_, DataDeclaration::TypeDeclaration(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "enum {red, yellow, green} light1, light2;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "enum bit [1:0] {IDLE, XX='x, S1=2'b01, S2=2'b10} state, next;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "enum {bronze=3, silver, gold} medal;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "enum {a=3, b=7, c} alphabet;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "integer i_array[*];",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "bit [20:0] array_b[string];",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "event ev_array[myClass];",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "int array_name [*];",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "int array_name1 [ integer ];",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "int a[int] = '{default:1};",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
//parser_test!(
|
||||
// data_declaration,
|
||||
// "byte q1[$];",
|
||||
// Ok((_, DataDeclaration::Variable(_)))
|
||||
//);
|
||||
parser_test!(primary, "'{default:1}", Ok((_, _)));
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ pub fn multiple_concatenation(s: Span) -> IResult<Span, MultipleConcatenation> {
|
||||
Ok((s, MultipleConcatenation { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn streaming_concatenation(s: Span) -> IResult<Span, StreamingConcatenation> {
|
||||
let (s, a) = brace(triple(
|
||||
stream_operator,
|
||||
|
@ -279,7 +279,7 @@ pub struct GenvarExpression<'a> {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn inc_or_dec_expression(s: Span) -> IResult<Span, IncOrDecExpression> {
|
||||
alt((inc_or_dec_expression_prefix, inc_or_dec_expression_suffix))(s)
|
||||
}
|
||||
@ -306,7 +306,7 @@ pub fn inc_or_dec_expression_suffix(s: Span) -> IResult<Span, IncOrDecExpression
|
||||
))
|
||||
}
|
||||
|
||||
#[parser(MaybeRecursive)]
|
||||
#[parser(MaybeRecursive, Memoize)]
|
||||
pub fn conditional_expression(s: Span) -> IResult<Span, ConditionalExpression> {
|
||||
let (s, a) = cond_predicate(s)?;
|
||||
let (s, b) = symbol("?")(s)?;
|
||||
@ -322,7 +322,7 @@ pub fn conditional_expression(s: Span) -> IResult<Span, ConditionalExpression> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_expression(s: Span) -> IResult<Span, ConstantExpression> {
|
||||
alt((
|
||||
constant_expression_unary,
|
||||
@ -334,7 +334,7 @@ pub fn constant_expression(s: Span) -> IResult<Span, ConstantExpression> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_expression_unary(s: Span) -> IResult<Span, ConstantExpression> {
|
||||
let (s, a) = unary_operator(s)?;
|
||||
let (s, b) = many0(attribute_instance)(s)?;
|
||||
@ -345,7 +345,7 @@ pub fn constant_expression_unary(s: Span) -> IResult<Span, ConstantExpression> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser(MaybeRecursive)]
|
||||
#[parser(MaybeRecursive, Memoize)]
|
||||
pub fn constant_expression_binary(s: Span) -> IResult<Span, ConstantExpression> {
|
||||
let (s, a) = constant_expression(s)?;
|
||||
let (s, b) = binary_operator(s)?;
|
||||
@ -359,7 +359,7 @@ pub fn constant_expression_binary(s: Span) -> IResult<Span, ConstantExpression>
|
||||
))
|
||||
}
|
||||
|
||||
#[parser(MaybeRecursive)]
|
||||
#[parser(MaybeRecursive, Memoize)]
|
||||
pub fn constant_expression_ternary(s: Span) -> IResult<Span, ConstantExpression> {
|
||||
let (s, a) = constant_expression(s)?;
|
||||
let (s, b) = symbol("?")(s)?;
|
||||
@ -464,7 +464,7 @@ pub fn constant_indexed_range(s: Span) -> IResult<Span, ConstantIndexedRange> {
|
||||
Ok((s, ConstantIndexedRange { nodes: (a, b, c) }))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn expression(s: Span) -> IResult<Span, Expression> {
|
||||
alt((
|
||||
expression_unary,
|
||||
@ -486,7 +486,7 @@ pub fn expression(s: Span) -> IResult<Span, Expression> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn expression_unary(s: Span) -> IResult<Span, Expression> {
|
||||
let (s, x) = unary_operator(s)?;
|
||||
let (s, y) = many0(attribute_instance)(s)?;
|
||||
@ -497,7 +497,7 @@ pub fn expression_unary(s: Span) -> IResult<Span, Expression> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn expression_operator_assignment(s: Span) -> IResult<Span, Expression> {
|
||||
let (s, a) = paren(operator_assignment)(s)?;
|
||||
Ok((
|
||||
@ -506,7 +506,7 @@ pub fn expression_operator_assignment(s: Span) -> IResult<Span, Expression> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser(MaybeRecursive)]
|
||||
#[parser(MaybeRecursive, Memoize)]
|
||||
pub fn expression_binary(s: Span) -> IResult<Span, Expression> {
|
||||
let (s, a) = expression(s)?;
|
||||
let (s, b) = binary_operator(s)?;
|
||||
@ -520,7 +520,7 @@ pub fn expression_binary(s: Span) -> IResult<Span, Expression> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn tagged_union_expression(s: Span) -> IResult<Span, TaggedUnionExpression> {
|
||||
let (s, a) = keyword("tagged")(s)?;
|
||||
let (s, b) = member_identifier(s)?;
|
||||
@ -528,7 +528,7 @@ pub fn tagged_union_expression(s: Span) -> IResult<Span, TaggedUnionExpression>
|
||||
Ok((s, TaggedUnionExpression { nodes: (a, b, c) }))
|
||||
}
|
||||
|
||||
#[parser(MaybeRecursive)]
|
||||
#[parser(MaybeRecursive, Memoize)]
|
||||
pub fn inside_expression(s: Span) -> IResult<Span, InsideExpression> {
|
||||
let (s, a) = expression(s)?;
|
||||
let (s, b) = keyword("inside")(s)?;
|
||||
|
@ -261,7 +261,7 @@ pub struct Cast<'a> {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
alt((
|
||||
map(keyword("null"), |x| ConstantPrimary::Null(x)),
|
||||
@ -288,7 +288,7 @@ pub fn constant_primary(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary_ps_parameter(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
let (s, a) = ps_parameter_identifier(s)?;
|
||||
let (s, b) = constant_select(s)?;
|
||||
@ -298,7 +298,7 @@ pub fn constant_primary_ps_parameter(s: Span) -> IResult<Span, ConstantPrimary>
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary_specparam(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
let (s, a) = specparam_identifier(s)?;
|
||||
let (s, b) = opt(bracket(constant_range_expression))(s)?;
|
||||
@ -308,7 +308,7 @@ pub fn constant_primary_specparam(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary_formal_port(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
let (s, a) = formal_port_identifier(s)?;
|
||||
let (s, b) = constant_select(s)?;
|
||||
@ -318,7 +318,7 @@ pub fn constant_primary_formal_port(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary_enum(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
let (s, a) = package_scope_or_class_scope(s)?;
|
||||
let (s, b) = enum_identifier(s)?;
|
||||
@ -328,7 +328,7 @@ pub fn constant_primary_enum(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary_concatenation(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
let (s, a) = constant_concatenation(s)?;
|
||||
let (s, b) = opt(bracket(constant_range_expression))(s)?;
|
||||
@ -338,7 +338,7 @@ pub fn constant_primary_concatenation(s: Span) -> IResult<Span, ConstantPrimary>
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary_multiple_concatenation(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
let (s, a) = constant_multiple_concatenation(s)?;
|
||||
let (s, b) = opt(bracket(constant_range_expression))(s)?;
|
||||
@ -350,7 +350,7 @@ pub fn constant_primary_multiple_concatenation(s: Span) -> IResult<Span, Constan
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_primary_mintypmax_expression(s: Span) -> IResult<Span, ConstantPrimary> {
|
||||
let (s, a) = paren(constant_mintypmax_expression)(s)?;
|
||||
Ok((
|
||||
@ -386,7 +386,7 @@ pub fn module_path_primary_mintypmax_expression(s: Span) -> IResult<Span, Module
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn primary(s: Span) -> IResult<Span, Primary> {
|
||||
alt((
|
||||
map(keyword("this"), |x| Primary::This(x)),
|
||||
@ -414,7 +414,7 @@ pub fn primary(s: Span) -> IResult<Span, Primary> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn primary_hierarchical(s: Span) -> IResult<Span, Primary> {
|
||||
let (s, a) = opt(class_qualifier_or_package_scope)(s)?;
|
||||
let (s, b) = hierarchical_identifier(s)?;
|
||||
@ -425,7 +425,7 @@ pub fn primary_hierarchical(s: Span) -> IResult<Span, Primary> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn primary_concatenation(s: Span) -> IResult<Span, Primary> {
|
||||
let (s, a) = concatenation(s)?;
|
||||
let (s, b) = opt(bracket(range_expression))(s)?;
|
||||
@ -445,7 +445,7 @@ pub fn primary_multiple_concatenation(s: Span) -> IResult<Span, Primary> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn primary_mintypmax_expression(s: Span) -> IResult<Span, Primary> {
|
||||
let (s, a) = paren(mintypmax_expression)(s)?;
|
||||
Ok((
|
||||
@ -481,7 +481,7 @@ pub fn range_expression(s: Span) -> IResult<Span, RangeExpression> {
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn primary_literal(s: Span) -> IResult<Span, PrimaryLiteral> {
|
||||
alt((
|
||||
map(time_literal, |x| PrimaryLiteral::TimeLiteral(x)),
|
||||
@ -589,7 +589,7 @@ pub fn constant_select(s: Span) -> IResult<Span, ConstantSelect> {
|
||||
Ok((s, ConstantSelect { nodes: (a, b, c) }))
|
||||
}
|
||||
|
||||
#[parser(MaybeRecursive)]
|
||||
#[parser(MaybeRecursive, Memoize)]
|
||||
pub fn constant_cast(s: Span) -> IResult<Span, ConstantCast> {
|
||||
let (s, a) = casting_type(s)?;
|
||||
let (s, b) = symbol("'")(s)?;
|
||||
@ -597,13 +597,13 @@ pub fn constant_cast(s: Span) -> IResult<Span, ConstantCast> {
|
||||
Ok((s, ConstantCast { nodes: (a, b, c) }))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn constant_let_expression(s: Span) -> IResult<Span, ConstantLetExpression> {
|
||||
let (s, a) = let_expression(s)?;
|
||||
Ok((s, ConstantLetExpression { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[parser(MaybeRecursive)]
|
||||
#[parser(MaybeRecursive, Memoize)]
|
||||
pub fn cast(s: Span) -> IResult<Span, Cast> {
|
||||
let (s, a) = casting_type(s)?;
|
||||
let (s, b) = symbol("'")(s)?;
|
||||
|
@ -262,7 +262,7 @@ pub fn subroutine_call_randomize(s: Span) -> IResult<Span, SubroutineCall> {
|
||||
))
|
||||
}
|
||||
|
||||
#[parser]
|
||||
#[parser(Memoize)]
|
||||
pub fn function_subroutine_call(s: Span) -> IResult<Span, FunctionSubroutineCall> {
|
||||
map(subroutine_call, |x| FunctionSubroutineCall { nodes: (x,) })(s)
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ pub fn parser(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
fn impl_parser(attr: &AttributeArgs, item: &ItemFn) -> TokenStream {
|
||||
let (maybe_recursive, ambiguous) = impl_parser_attribute(attr);
|
||||
let (maybe_recursive, ambiguous, memoize) = impl_parser_attribute(attr);
|
||||
|
||||
let trace = impl_parser_trace(&item);
|
||||
let trace = parse_macro_input!(trace as Stmt);
|
||||
@ -140,19 +140,35 @@ fn impl_parser(attr: &AttributeArgs, item: &ItemFn) -> TokenStream {
|
||||
};
|
||||
let body = parse_macro_input!(body as Stmt);
|
||||
|
||||
let body_unwrap = impl_parser_body_unwrap(&item);
|
||||
let body_unwrap = parse_macro_input!(body_unwrap as Stmt);
|
||||
|
||||
let clear_recursive_flags = impl_parser_clear_recursive_flags(&item);
|
||||
let clear_recursive_flags = parse_macro_input!(clear_recursive_flags as Expr);
|
||||
let clear_recursive_flags = Stmt::Expr(clear_recursive_flags);
|
||||
|
||||
let check_failed_memo = impl_parser_check_failed_memo(&item);
|
||||
let check_failed_memo = parse_macro_input!(check_failed_memo as Stmt);
|
||||
|
||||
let set_failed_memo = impl_parser_set_failed_memo(&item);
|
||||
let set_failed_memo = parse_macro_input!(set_failed_memo as Stmt);
|
||||
|
||||
let mut item = item.clone();
|
||||
|
||||
item.block.stmts.clear();
|
||||
item.block.stmts.push(trace);
|
||||
if memoize {
|
||||
item.block.stmts.push(check_failed_memo);
|
||||
}
|
||||
if maybe_recursive {
|
||||
item.block.stmts.push(check_recursive_flag);
|
||||
item.block.stmts.push(set_recursive_flag);
|
||||
}
|
||||
item.block.stmts.push(body);
|
||||
if memoize {
|
||||
item.block.stmts.push(set_failed_memo);
|
||||
}
|
||||
item.block.stmts.push(body_unwrap);
|
||||
item.block.stmts.push(clear_recursive_flags);
|
||||
|
||||
let gen = quote! {
|
||||
@ -161,19 +177,21 @@ fn impl_parser(attr: &AttributeArgs, item: &ItemFn) -> TokenStream {
|
||||
gen.into()
|
||||
}
|
||||
|
||||
fn impl_parser_attribute(attr: &AttributeArgs) -> (bool, bool) {
|
||||
fn impl_parser_attribute(attr: &AttributeArgs) -> (bool, bool, bool) {
|
||||
let mut maybe_recursive = false;
|
||||
let mut ambiguous = false;
|
||||
let mut memoize = false;
|
||||
|
||||
for a in attr {
|
||||
match a {
|
||||
NestedMeta::Meta(Meta::Word(x)) if x == "MaybeRecursive" => maybe_recursive = true,
|
||||
NestedMeta::Meta(Meta::Word(x)) if x == "Ambiguous" => ambiguous = true,
|
||||
NestedMeta::Meta(Meta::Word(x)) if x == "Memoize" => memoize = true,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
(maybe_recursive, ambiguous)
|
||||
(maybe_recursive, ambiguous, memoize)
|
||||
}
|
||||
|
||||
fn impl_parser_trace(item: &ItemFn) -> TokenStream {
|
||||
@ -231,7 +249,7 @@ fn impl_parser_body(item: &ItemFn) -> TokenStream {
|
||||
};
|
||||
}
|
||||
let gen = quote! {
|
||||
let (s, ret) = { #gen }?;
|
||||
let body_ret = { #gen };
|
||||
};
|
||||
gen.into()
|
||||
}
|
||||
@ -288,15 +306,70 @@ fn impl_parser_body_ambiguous(item: &ItemFn) -> TokenStream {
|
||||
};
|
||||
|
||||
let gen = quote! {
|
||||
let (s, ret) = { #gen }?;
|
||||
let body_ret = { #gen };
|
||||
};
|
||||
|
||||
gen.into()
|
||||
}
|
||||
|
||||
fn impl_parser_body_unwrap(_item: &ItemFn) -> TokenStream {
|
||||
let gen = quote! {
|
||||
let (s, ret) = body_ret?;
|
||||
};
|
||||
gen.into()
|
||||
}
|
||||
|
||||
fn impl_parser_clear_recursive_flags(_item: &ItemFn) -> TokenStream {
|
||||
let gen = quote! {
|
||||
Ok((clear_recursive_flags(s), ret))
|
||||
};
|
||||
gen.into()
|
||||
}
|
||||
|
||||
fn impl_parser_check_failed_memo(item: &ItemFn) -> TokenStream {
|
||||
let ident = &item.ident;
|
||||
|
||||
let gen = quote! {
|
||||
let offset = {
|
||||
//if thread_context::FAILED_MEMO.with(|m| { m.borrow().get(&(stringify!(#ident), s.offset)).is_some() }) {
|
||||
// #[cfg(feature = "trace")]
|
||||
// println!("{:<128} : memoized failure", format!("{}{}", " ".repeat(s.extra.depth), stringify!(#ident)));
|
||||
// return Err(nom::Err::Error(nom::error::make_error(s, nom::error::ErrorKind::Fix)));
|
||||
//}
|
||||
if let Some(x) = thread_context::FAILED_MEMO.with(|m| { if let Some(x) = m.borrow().get(&(stringify!(#ident), s.offset)) { Some(*x) } else { None } }) {
|
||||
if x {
|
||||
#[cfg(feature = "trace")]
|
||||
println!("{:<128} : memoized failure", format!("{}{}", " ".repeat(s.extra.depth), stringify!(#ident)));
|
||||
return Err(nom::Err::Error(nom::error::make_error(s, nom::error::ErrorKind::Fix)));
|
||||
} else {
|
||||
#[cfg(feature = "trace")]
|
||||
println!("{:<128} : memoized success", format!("{}{}", " ".repeat(s.extra.depth), stringify!(#ident)));
|
||||
}
|
||||
}
|
||||
s.offset
|
||||
};
|
||||
};
|
||||
gen.into()
|
||||
}
|
||||
|
||||
fn impl_parser_set_failed_memo(item: &ItemFn) -> TokenStream {
|
||||
let ident = &item.ident;
|
||||
|
||||
let gen = quote! {
|
||||
//if body_ret.is_err() {
|
||||
// thread_context::FAILED_MEMO.with(|m| {
|
||||
// m.borrow_mut().insert((stringify!(#ident), offset), ());
|
||||
// })
|
||||
//}
|
||||
if body_ret.is_err() {
|
||||
thread_context::FAILED_MEMO.with(|m| {
|
||||
m.borrow_mut().insert((stringify!(#ident), offset), true);
|
||||
})
|
||||
} else {
|
||||
thread_context::FAILED_MEMO.with(|m| {
|
||||
m.borrow_mut().insert((stringify!(#ident), offset), false);
|
||||
})
|
||||
}
|
||||
};
|
||||
gen.into()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user