···11fn main() {
22- let src_dir = std::path::Path::new("../../src");
22+ let src_dir = std::path::Path::new("src");
3344 let mut c_config = cc::Build::new();
55- c_config.include(src_dir);
66- c_config
77- .flag_if_supported("-Wno-unused-parameter")
88- .flag_if_supported("-Wno-unused-but-set-variable")
99- .flag_if_supported("-Wno-trigraphs");
55+ c_config.std("c11").include(src_dir);
66+77+ #[cfg(target_env = "msvc")]
88+ c_config.flag("-utf-8");
99+1010 let parser_path = src_dir.join("parser.c");
1111 c_config.file(&parser_path);
1212-1313- // If your language uses an external scanner written in C,
1414- // then include this block of code:
1515-1616- /*
1717- let scanner_path = src_dir.join("scanner.c");
1818- c_config.file(&scanner_path);
1919- println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
2020- */
1212+ println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
21132214 c_config.compile("tree-sitter-mlf");
2323- println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
2415}
+21-23
tree-sitter-mlf/bindings/rust/lib.rs
···11-//! This crate provides MLF language support for the [tree-sitter][] parsing library.
11+//! This crate provides MLF (Matt's Lexicon Format) language support for the
22+//! [tree-sitter][] parsing library.
23//!
33-//! Typically, you will use the [language][language func] function to add this language to a
44+//! Typically, you will use the [LANGUAGE][] constant to add this language to a
45//! tree-sitter [Parser][], and then use the parser to parse some code:
56//!
67//! ```
88+//! use tree_sitter::Parser;
99+//!
710//! let code = r#"
811//! record post {
912//! text: string,
1010-//! };
1313+//! }
1114//! "#;
1212-//! let mut parser = tree_sitter::Parser::new();
1313-//! parser.set_language(&tree_sitter_mlf::language()).expect("Error loading MLF grammar");
1515+//! let mut parser = Parser::new();
1616+//! let language = tree_sitter_mlf::LANGUAGE;
1717+//! parser
1818+//! .set_language(&language.into())
1919+//! .expect("Error loading MLF parser");
1420//! let tree = parser.parse(code, None).unwrap();
1521//! assert!(!tree.root_node().has_error());
1622//! ```
1723//!
1818-//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
1919-//! [language func]: fn.language.html
2424+//! [LANGUAGE]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html
2025//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
2126//! [tree-sitter]: https://tree-sitter.github.io/
22272323-use tree_sitter::Language;
2828+use tree_sitter_language::LanguageFn;
24292525-extern "C" {
2626- fn tree_sitter_mlf() -> Language;
3030+unsafe extern "C" {
3131+ fn tree_sitter_mlf() -> *const ();
2732}
28332929-/// Get the tree-sitter [Language][] for this grammar.
3030-///
3131-/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
3232-pub fn language() -> Language {
3333- unsafe { tree_sitter_mlf() }
3434-}
3434+/// The tree-sitter [`LanguageFn`] for this grammar.
3535+pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_mlf) };
35363637/// The content of the [`node-types.json`][] file for this grammar.
3738///
3839/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
3940pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
40414141-// Uncomment these to include any queries that your grammar contains
4242-// pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
4343-// pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm");
4444-// pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
4545-// pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
4242+/// The syntax highlighting query for this language.
4343+pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
46444745#[cfg(test)]
4846mod tests {
···5048 fn test_can_load_grammar() {
5149 let mut parser = tree_sitter::Parser::new();
5250 parser
5353- .set_language(&super::language())
5454- .expect("Error loading MLF language");
5151+ .set_language(&super::LANGUAGE.into())
5252+ .expect("Error loading MLF parser");
5553 }
5654}
···11+#ifndef TREE_SITTER_ARRAY_H_
22+#define TREE_SITTER_ARRAY_H_
33+44+#ifdef __cplusplus
55+extern "C" {
66+#endif
77+88+#include "./alloc.h"
99+1010+#include <assert.h>
1111+#include <stdbool.h>
1212+#include <stdint.h>
1313+#include <stdlib.h>
1414+#include <string.h>
1515+1616+#ifdef _MSC_VER
1717+#pragma warning(push)
1818+#pragma warning(disable : 4101)
1919+#elif defined(__GNUC__) || defined(__clang__)
2020+#pragma GCC diagnostic push
2121+#pragma GCC diagnostic ignored "-Wunused-variable"
2222+#endif
2323+2424+#define Array(T) \
2525+ struct { \
2626+ T *contents; \
2727+ uint32_t size; \
2828+ uint32_t capacity; \
2929+ }
3030+3131+/// Initialize an array.
3232+#define array_init(self) \
3333+ ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
3434+3535+/// Create an empty array.
3636+#define array_new() \
3737+ { NULL, 0, 0 }
3838+3939+/// Get a pointer to the element at a given `index` in the array.
4040+#define array_get(self, _index) \
4141+ (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index])
4242+4343+/// Get a pointer to the first element in the array.
4444+#define array_front(self) array_get(self, 0)
4545+4646+/// Get a pointer to the last element in the array.
4747+#define array_back(self) array_get(self, (self)->size - 1)
4848+4949+/// Clear the array, setting its size to zero. Note that this does not free any
5050+/// memory allocated for the array's contents.
5151+#define array_clear(self) ((self)->size = 0)
5252+5353+/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
5454+/// less than the array's current capacity, this function has no effect.
5555+#define array_reserve(self, new_capacity) \
5656+ ((self)->contents = _array__reserve( \
5757+ (void *)(self)->contents, &(self)->capacity, \
5858+ array_elem_size(self), new_capacity) \
5959+ )
6060+6161+/// Free any memory allocated for this array. Note that this does not free any
6262+/// memory allocated for the array's contents.
6363+#define array_delete(self) \
6464+ do { \
6565+ if ((self)->contents) ts_free((self)->contents); \
6666+ (self)->contents = NULL; \
6767+ (self)->size = 0; \
6868+ (self)->capacity = 0; \
6969+ } while (0)
7070+7171+/// Push a new `element` onto the end of the array.
7272+#define array_push(self, element) \
7373+ do { \
7474+ (self)->contents = _array__grow( \
7575+ (void *)(self)->contents, (self)->size, &(self)->capacity, \
7676+ 1, array_elem_size(self) \
7777+ ); \
7878+ (self)->contents[(self)->size++] = (element); \
7979+ } while(0)
8080+8181+/// Increase the array's size by `count` elements.
8282+/// New elements are zero-initialized.
8383+#define array_grow_by(self, count) \
8484+ do { \
8585+ if ((count) == 0) break; \
8686+ (self)->contents = _array__grow( \
8787+ (self)->contents, (self)->size, &(self)->capacity, \
8888+ count, array_elem_size(self) \
8989+ ); \
9090+ memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \
9191+ (self)->size += (count); \
9292+ } while (0)
9393+9494+/// Append all elements from one array to the end of another.
9595+#define array_push_all(self, other) \
9696+ array_extend((self), (other)->size, (other)->contents)
9797+9898+/// Append `count` elements to the end of the array, reading their values from the
9999+/// `contents` pointer.
100100+#define array_extend(self, count, other_contents) \
101101+ (self)->contents = _array__splice( \
102102+ (void*)(self)->contents, &(self)->size, &(self)->capacity, \
103103+ array_elem_size(self), (self)->size, 0, count, other_contents \
104104+ )
105105+106106+/// Remove `old_count` elements from the array starting at the given `index`. At
107107+/// the same index, insert `new_count` new elements, reading their values from the
108108+/// `new_contents` pointer.
109109+#define array_splice(self, _index, old_count, new_count, new_contents) \
110110+ (self)->contents = _array__splice( \
111111+ (void *)(self)->contents, &(self)->size, &(self)->capacity, \
112112+ array_elem_size(self), _index, old_count, new_count, new_contents \
113113+ )
114114+115115+/// Insert one `element` into the array at the given `index`.
116116+#define array_insert(self, _index, element) \
117117+ (self)->contents = _array__splice( \
118118+ (void *)(self)->contents, &(self)->size, &(self)->capacity, \
119119+ array_elem_size(self), _index, 0, 1, &(element) \
120120+ )
121121+122122+/// Remove one element from the array at the given `index`.
123123+#define array_erase(self, _index) \
124124+ _array__erase((void *)(self)->contents, &(self)->size, array_elem_size(self), _index)
125125+126126+/// Pop the last element off the array, returning the element by value.
127127+#define array_pop(self) ((self)->contents[--(self)->size])
128128+129129+/// Assign the contents of one array to another, reallocating if necessary.
130130+#define array_assign(self, other) \
131131+ (self)->contents = _array__assign( \
132132+ (void *)(self)->contents, &(self)->size, &(self)->capacity, \
133133+ (const void *)(other)->contents, (other)->size, array_elem_size(self) \
134134+ )
135135+136136+/// Swap one array with another
137137+#define array_swap(self, other) \
138138+ do { \
139139+ void *_array_swap_tmp = (void *)(self)->contents; \
140140+ (self)->contents = (other)->contents; \
141141+ (other)->contents = _array_swap_tmp; \
142142+ _array__swap(&(self)->size, &(self)->capacity, \
143143+ &(other)->size, &(other)->capacity); \
144144+ } while (0)
145145+146146+/// Get the size of the array contents
147147+#define array_elem_size(self) (sizeof *(self)->contents)
148148+149149+/// Search a sorted array for a given `needle` value, using the given `compare`
150150+/// callback to determine the order.
151151+///
152152+/// If an existing element is found to be equal to `needle`, then the `index`
153153+/// out-parameter is set to the existing value's index, and the `exists`
154154+/// out-parameter is set to true. Otherwise, `index` is set to an index where
155155+/// `needle` should be inserted in order to preserve the sorting, and `exists`
156156+/// is set to false.
157157+#define array_search_sorted_with(self, compare, needle, _index, _exists) \
158158+ _array__search_sorted(self, 0, compare, , needle, _index, _exists)
159159+160160+/// Search a sorted array for a given `needle` value, using integer comparisons
161161+/// of a given struct field (specified with a leading dot) to determine the order.
162162+///
163163+/// See also `array_search_sorted_with`.
164164+#define array_search_sorted_by(self, field, needle, _index, _exists) \
165165+ _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists)
166166+167167+/// Insert a given `value` into a sorted array, using the given `compare`
168168+/// callback to determine the order.
169169+#define array_insert_sorted_with(self, compare, value) \
170170+ do { \
171171+ unsigned _index, _exists; \
172172+ array_search_sorted_with(self, compare, &(value), &_index, &_exists); \
173173+ if (!_exists) array_insert(self, _index, value); \
174174+ } while (0)
175175+176176+/// Insert a given `value` into a sorted array, using integer comparisons of
177177+/// a given struct field (specified with a leading dot) to determine the order.
178178+///
179179+/// See also `array_search_sorted_by`.
180180+#define array_insert_sorted_by(self, field, value) \
181181+ do { \
182182+ unsigned _index, _exists; \
183183+ array_search_sorted_by(self, field, (value) field, &_index, &_exists); \
184184+ if (!_exists) array_insert(self, _index, value); \
185185+ } while (0)
186186+187187+// Private
188188+189189+// Pointers to individual `Array` fields (rather than the entire `Array` itself)
190190+// are passed to the various `_array__*` functions below to address strict aliasing
191191+// violations that arises when the _entire_ `Array` struct is passed as `Array(void)*`.
192192+//
193193+// The `Array` type itself was not altered as a solution in order to avoid breakage
194194+// with existing consumers (in particular, parsers with external scanners).
195195+196196+/// This is not what you're looking for, see `array_erase`.
197197+static inline void _array__erase(void* self_contents, uint32_t *size,
198198+ size_t element_size, uint32_t index) {
199199+ assert(index < *size);
200200+ char *contents = (char *)self_contents;
201201+ memmove(contents + index * element_size, contents + (index + 1) * element_size,
202202+ (*size - index - 1) * element_size);
203203+ (*size)--;
204204+}
205205+206206+/// This is not what you're looking for, see `array_reserve`.
207207+static inline void *_array__reserve(void *contents, uint32_t *capacity,
208208+ size_t element_size, uint32_t new_capacity) {
209209+ void *new_contents = contents;
210210+ if (new_capacity > *capacity) {
211211+ if (contents) {
212212+ new_contents = ts_realloc(contents, new_capacity * element_size);
213213+ } else {
214214+ new_contents = ts_malloc(new_capacity * element_size);
215215+ }
216216+ *capacity = new_capacity;
217217+ }
218218+ return new_contents;
219219+}
220220+221221+/// This is not what you're looking for, see `array_assign`.
222222+static inline void *_array__assign(void* self_contents, uint32_t *self_size, uint32_t *self_capacity,
223223+ const void *other_contents, uint32_t other_size, size_t element_size) {
224224+ void *new_contents = _array__reserve(self_contents, self_capacity, element_size, other_size);
225225+ *self_size = other_size;
226226+ memcpy(new_contents, other_contents, *self_size * element_size);
227227+ return new_contents;
228228+}
229229+230230+/// This is not what you're looking for, see `array_swap`.
231231+static inline void _array__swap(uint32_t *self_size, uint32_t *self_capacity,
232232+ uint32_t *other_size, uint32_t *other_capacity) {
233233+ uint32_t tmp_size = *self_size;
234234+ uint32_t tmp_capacity = *self_capacity;
235235+ *self_size = *other_size;
236236+ *self_capacity = *other_capacity;
237237+ *other_size = tmp_size;
238238+ *other_capacity = tmp_capacity;
239239+}
240240+241241+/// This is not what you're looking for, see `array_push` or `array_grow_by`.
242242+static inline void *_array__grow(void *contents, uint32_t size, uint32_t *capacity,
243243+ uint32_t count, size_t element_size) {
244244+ void *new_contents = contents;
245245+ uint32_t new_size = size + count;
246246+ if (new_size > *capacity) {
247247+ uint32_t new_capacity = *capacity * 2;
248248+ if (new_capacity < 8) new_capacity = 8;
249249+ if (new_capacity < new_size) new_capacity = new_size;
250250+ new_contents = _array__reserve(contents, capacity, element_size, new_capacity);
251251+ }
252252+ return new_contents;
253253+}
254254+255255+/// This is not what you're looking for, see `array_splice`.
256256+static inline void *_array__splice(void *self_contents, uint32_t *size, uint32_t *capacity,
257257+ size_t element_size,
258258+ uint32_t index, uint32_t old_count,
259259+ uint32_t new_count, const void *elements) {
260260+ uint32_t new_size = *size + new_count - old_count;
261261+ uint32_t old_end = index + old_count;
262262+ uint32_t new_end = index + new_count;
263263+ assert(old_end <= *size);
264264+265265+ void *new_contents = _array__reserve(self_contents, capacity, element_size, new_size);
266266+267267+ char *contents = (char *)new_contents;
268268+ if (*size > old_end) {
269269+ memmove(
270270+ contents + new_end * element_size,
271271+ contents + old_end * element_size,
272272+ (*size - old_end) * element_size
273273+ );
274274+ }
275275+ if (new_count > 0) {
276276+ if (elements) {
277277+ memcpy(
278278+ (contents + index * element_size),
279279+ elements,
280280+ new_count * element_size
281281+ );
282282+ } else {
283283+ memset(
284284+ (contents + index * element_size),
285285+ 0,
286286+ new_count * element_size
287287+ );
288288+ }
289289+ }
290290+ *size += new_count - old_count;
291291+292292+ return new_contents;
293293+}
294294+295295+/// A binary search routine, based on Rust's `std::slice::binary_search_by`.
296296+/// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`.
297297+#define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \
298298+ do { \
299299+ *(_index) = start; \
300300+ *(_exists) = false; \
301301+ uint32_t size = (self)->size - *(_index); \
302302+ if (size == 0) break; \
303303+ int comparison; \
304304+ while (size > 1) { \
305305+ uint32_t half_size = size / 2; \
306306+ uint32_t mid_index = *(_index) + half_size; \
307307+ comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \
308308+ if (comparison <= 0) *(_index) = mid_index; \
309309+ size -= half_size; \
310310+ } \
311311+ comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
312312+ if (comparison == 0) *(_exists) = true; \
313313+ else if (comparison < 0) *(_index) += 1; \
314314+ } while (0)
315315+316316+/// Helper macro for the `_sorted_by` routines below. This takes the left (existing)
317317+/// parameter by reference in order to work with the generic sorting function above.
318318+#define _compare_int(a, b) ((int)*(a) - (int)(b))
319319+320320+#ifdef _MSC_VER
321321+#pragma warning(pop)
322322+#elif defined(__GNUC__) || defined(__clang__)
323323+#pragma GCC diagnostic pop
324324+#endif
325325+326326+#ifdef __cplusplus
327327+}
328328+#endif
329329+330330+#endif // TREE_SITTER_ARRAY_H_