Skip to content

Commit e58a5e9

Browse files
feat: add VHDL language support (#213)
Add VHDL as a supported language for spell checking using tree-sitter-vhdl grammar from jpt13653903/tree-sitter-vhdl (v1.3.1, git dependency). Changes: - Add tree-sitter-vhdl workspace and crate dependencies - Add VHDL variant to LanguageType enum with language setting - Create vhdl.scm query capturing comments, strings, identifiers (entity, architecture, signal, variable, constant, function, procedure, component, type, subtype, port, label, alias) - Add example.vhd with intentional spelling errors - Add test_vhdl.rs with simple and location verification tests - Add VHDL to supported languages table in README Co-authored-by: AmbatiThrinay <[email protected]>
1 parent 7af4608 commit e58a5e9

File tree

8 files changed

+212
-0
lines changed

8 files changed

+212
-0
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ tree-sitter-swift = "<0.8.0"
6565
tree-sitter-toml-ng = "<0.8.0"
6666
tree-sitter-typescript = "0.23.2"
6767
tree-sitter-yaml = "0.7.2"
68+
tree-sitter-vhdl = { git = "https://github.com/jpt13653903/tree-sitter-vhdl", tag = "v1.3.1" }
6869
tree-sitter-zig = "<2"
6970
tree-sitter-c-sharp= "<0.24.0"
7071
codebook-tree-sitter-latex = "<0.7.0"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ Codebook is in active development. As better dictionaries are added, words that
158158
| TOML ||
159159
| TypeScript ||
160160
| Typst | ⚠️ |
161+
| VHDL | ⚠️ |
161162
| YAML | ⚠️ |
162163
| Zig ||
163164

crates/codebook/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ tree-sitter-rust.workspace = true
5151
tree-sitter-swift.workspace = true
5252
tree-sitter-toml-ng.workspace = true
5353
tree-sitter-typescript.workspace = true
54+
tree-sitter-vhdl.workspace = true
5455
codebook-tree-sitter-typst.workspace = true
5556
tree-sitter-yaml.workspace = true
5657
tree-sitter-zig.workspace = true

crates/codebook/src/queries.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub enum LanguageType {
2929
Text,
3030
Typescript,
3131
Typst,
32+
VHDL,
3233
YAML,
3334
Zig,
3435
}
@@ -246,6 +247,13 @@ pub static LANGUAGE_SETTINGS: &[LanguageSetting] = &[
246247
query: include_str!("queries/typst.scm"),
247248
extensions: &["typ"],
248249
},
250+
LanguageSetting {
251+
type_: LanguageType::VHDL,
252+
ids: &["vhdl"],
253+
dictionary_ids: &["vhdl"],
254+
query: include_str!("queries/vhdl.scm"),
255+
extensions: &["vhd", "vhdl"],
256+
},
249257
];
250258

251259
#[derive(Debug)]
@@ -286,6 +294,7 @@ impl LanguageSetting {
286294
LanguageType::Text => None,
287295
LanguageType::Typescript => Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
288296
LanguageType::Typst => Some(codebook_tree_sitter_typst::LANGUAGE.into()),
297+
LanguageType::VHDL => Some(tree_sitter_vhdl::LANGUAGE.into()),
289298
LanguageType::YAML => Some(tree_sitter_yaml::LANGUAGE.into()),
290299
LanguageType::Zig => Some(tree_sitter_zig::LANGUAGE.into()),
291300
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
; Comments - capture comment content for spell checking
2+
(line_comment
3+
(comment_content) @comment)
4+
(block_comment
5+
(comment_content) @comment)
6+
7+
; String literals
8+
(string_literal) @string
9+
10+
; Entity declarations
11+
(entity_declaration
12+
entity: (identifier) @identifier)
13+
14+
; Architecture definitions
15+
(architecture_definition
16+
architecture: (identifier) @identifier)
17+
18+
; Signal declarations
19+
(signal_declaration
20+
(identifier_list
21+
(identifier) @identifier))
22+
23+
; Variable declarations
24+
(variable_declaration
25+
(identifier_list
26+
(identifier) @identifier))
27+
28+
; Constant declarations
29+
(constant_declaration
30+
(identifier_list
31+
(identifier) @identifier))
32+
33+
; Function specifications
34+
(function_specification
35+
function: (identifier) @identifier)
36+
37+
; Procedure specifications
38+
(procedure_specification
39+
procedure: (identifier) @identifier)
40+
41+
; Component declarations
42+
(component_declaration
43+
component: (identifier) @identifier)
44+
45+
; Type declarations
46+
(type_declaration
47+
type: (identifier) @identifier)
48+
49+
; Subtype declarations
50+
(subtype_declaration
51+
type: (identifier) @identifier)
52+
53+
; Port/generic interface declarations
54+
(interface_declaration
55+
(identifier_list
56+
(identifier) @identifier))
57+
(interface_signal_declaration
58+
(identifier_list
59+
(identifier) @identifier))
60+
(interface_variable_declaration
61+
(identifier_list
62+
(identifier) @identifier))
63+
(interface_constant_declaration
64+
(identifier_list
65+
(identifier) @identifier))
66+
67+
; Labels
68+
(label) @identifier
69+
70+
; Alias declarations
71+
(alias_declaration
72+
(identifier) @identifier)

crates/codebook/tests/test_vhdl.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use codebook::{
2+
parser::{TextRange, WordLocation},
3+
queries::LanguageType,
4+
};
5+
6+
mod utils;
7+
8+
#[test]
9+
fn test_vhdl_simple() {
10+
utils::init_logging();
11+
let processor = utils::get_processor();
12+
let sample_text = r#"
13+
-- This is an exmple comment with speling errors
14+
entity calculatr is
15+
port (
16+
clk : in std_logic;
17+
resett : in std_logic;
18+
inputt : in std_logic_vector(7 downto 0)
19+
);
20+
end entity calculatr;
21+
"#;
22+
let expected = vec![
23+
"calculatr",
24+
"clk",
25+
"exmple",
26+
"inputt",
27+
"resett",
28+
"speling",
29+
];
30+
let binding = processor
31+
.spell_check(sample_text, Some(LanguageType::VHDL), None)
32+
.to_vec();
33+
let mut misspelled = binding
34+
.iter()
35+
.map(|r| r.word.as_str())
36+
.collect::<Vec<&str>>();
37+
misspelled.sort();
38+
println!("Misspelled words: {misspelled:?}");
39+
assert_eq!(misspelled, expected);
40+
}
41+
42+
#[test]
43+
fn test_vhdl_comment_location() {
44+
utils::init_logging();
45+
let sample_text = r#"
46+
-- A calculater for numbrs
47+
"#;
48+
let expected = vec![
49+
WordLocation::new(
50+
"calculater".to_string(),
51+
vec![TextRange {
52+
start_byte: 6,
53+
end_byte: 16,
54+
}],
55+
),
56+
WordLocation::new(
57+
"numbrs".to_string(),
58+
vec![TextRange {
59+
start_byte: 21,
60+
end_byte: 27,
61+
}],
62+
),
63+
];
64+
let not_expected = ["std_logic", "entity", "port", "signal"];
65+
let processor = utils::get_processor();
66+
let misspelled = processor
67+
.spell_check(sample_text, Some(LanguageType::VHDL), None)
68+
.to_vec();
69+
println!("Misspelled words: {misspelled:?}");
70+
for e in &expected {
71+
println!("Expecting: {e:?}");
72+
let miss = misspelled.iter().find(|r| r.word == e.word).unwrap();
73+
assert!(miss.locations.len() == e.locations.len());
74+
for location in &miss.locations {
75+
assert!(e.locations.contains(location));
76+
}
77+
}
78+
for result in misspelled {
79+
assert!(!not_expected.contains(&result.word.as_str()));
80+
}
81+
}

examples/example.vhd

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
-- This is an exmple VHDL file with speling errors
2+
-- for testing the codebook spell checker
3+
4+
library ieee;
5+
use ieee.std_logic_1164.all;
6+
use ieee.numeric_std.all;
7+
8+
-- Entity declarashun for a simple calculater
9+
entity calculatr is
10+
port (
11+
clk : in std_logic;
12+
resett : in std_logic;
13+
inputt : in std_logic_vector(7 downto 0);
14+
outpuut : out std_logic_vector(7 downto 0)
15+
);
16+
end entity calculatr;
17+
18+
-- Architectur definition
19+
architecture behavorial of calculatr is
20+
signal intrnal_data : std_logic_vector(7 downto 0);
21+
constant max_valuue : integer := 255;
22+
variable tmp_resullt : integer := 0;
23+
begin
24+
25+
-- Main proccess block
26+
main_proccess : process(clk, resett)
27+
begin
28+
if resett = '1' then
29+
intrnal_data <= (others => '0');
30+
elsif rising_edge(clk) then
31+
intrnal_data <= inputt;
32+
end if;
33+
end process main_proccess;
34+
35+
outpuut <= intrnal_data;
36+
37+
end architecture behavorial;

0 commit comments

Comments
 (0)