extract_rust_hdl_interface/extract_verilog_interface/
get_constant_number.rs1use sv_parser::{unwrap_node, RefNode, SyntaxTree};
2
3pub fn get_constant_number(node: RefNode, ast: &SyntaxTree) -> Option<i64> {
4 let value = match unwrap_node!(node, IntegralNumber, RealNumber) {
6 Some(RefNode::IntegralNumber(x)) => {
7 match unwrap_node!(x, DecimalNumber, OctalNumber, BinaryNumber, HexNumber) {
8 Some(RefNode::DecimalNumber(x)) => {
9 let RefNode::UnsignedNumber(unsigned_number) =
10 unwrap_node!(x, UnsignedNumber).unwrap() else {
11 panic!("No UnsignedNumber found");
12 };
13 let locate = unsigned_number.nodes.0;
14 let unsigned_value = ast.get_str(&locate).unwrap();
15 Some(i64::from_str_radix(unsigned_value, 10).unwrap())
16 }
17 Some(RefNode::OctalNumber(octal_number)) => {
18 let octal_value_node = &octal_number.nodes.2;
19 let locate = octal_value_node.nodes.0;
20 let octal_value = ast.get_str(&locate).unwrap();
21 Some(i64::from_str_radix(octal_value, 8).unwrap())
22 }
23 Some(RefNode::BinaryNumber(binary_number)) => {
24 let binary_value_node = &binary_number.nodes.2;
25 let locate = binary_value_node.nodes.0;
26 let binary_value = ast.get_str(&locate).unwrap();
27 Some(i64::from_str_radix(binary_value, 2).unwrap())
28 }
29 Some(RefNode::HexNumber(hex_number)) => {
30 let hex_value_node = &hex_number.nodes.2;
31 let locate = hex_value_node.nodes.0;
32 let hex_value = ast.get_str(&locate).unwrap();
33 Some(i64::from_str_radix(hex_value, 16).unwrap())
34 }
35 _ => panic!("Should not happen"),
36 }
37 }
38
39 Some(RefNode::RealNumber(_x)) => {
40 panic!("RealNumber not supported yet")
41 }
42 _ => None,
43 };
44 value
45}
46
47#[cfg(test)]
48mod tests {
49 use crate::verilog_parser::parse_verilog_string;
50
51 use super::*;
52
53 #[test]
54 fn should_return_first_number_constant() {
55 let result =
56 parse_verilog_string("module counter(input clock, output [5:0] led); endmodule");
57 let syntax_tree = result.unwrap();
58 let number =
59 get_constant_number(syntax_tree.into_iter().next().unwrap(), &syntax_tree).unwrap();
60 assert_eq!(number, 5);
61 }
62
63 #[test]
64 fn works_with_hex_numbers() {
65 let result = parse_verilog_string("reg a = 64'h0F;");
66 let syntax_tree = result.unwrap();
67 let number =
68 get_constant_number(syntax_tree.into_iter().next().unwrap(), &syntax_tree).unwrap();
69 assert_eq!(number, 0xf);
70 }
71
72 #[test]
73 fn works_with_octal_numbers() {
74 let result = parse_verilog_string("reg a = 64'o07;");
75 let syntax_tree = result.unwrap();
76 let number =
77 get_constant_number(syntax_tree.into_iter().next().unwrap(), &syntax_tree).unwrap();
78 assert_eq!(number, 7);
79 }
80
81 #[test]
82 fn works_with_binary_numbers() {
83 let result = parse_verilog_string("reg a = 64'b11010;");
84 let syntax_tree = result.unwrap();
85 let number =
86 get_constant_number(syntax_tree.into_iter().next().unwrap(), &syntax_tree).unwrap();
87 assert_eq!(number, 0b11010);
88 }
89
90 #[test]
91 fn works_without_number() {
92 let result = parse_verilog_string("reg a;");
93 let syntax_tree = result.unwrap();
94 let number = get_constant_number(syntax_tree.into_iter().next().unwrap(), &syntax_tree);
95 assert_eq!(number, None);
96 }
97}