textbringer-tree-sitter 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CLAUDE.md +8 -0
- data/lib/textbringer/tree_sitter/node_maps/ruby.rb +4 -79
- data/lib/textbringer/tree_sitter/node_maps/sql.rb +14 -21
- data/lib/textbringer/tree_sitter/version.rb +1 -1
- data/lib/textbringer/tree_sitter_adapter.rb +7 -5
- data/samples/Sample.java +289 -0
- data/samples/sample.c +176 -0
- data/samples/sample.cob +174 -0
- data/samples/sample.cr +321 -0
- data/samples/sample.cs +273 -0
- data/samples/sample.ex +307 -0
- data/samples/sample.groovy +258 -0
- data/samples/sample.haml +154 -0
- data/samples/sample.html +168 -0
- data/samples/sample.js +266 -0
- data/samples/sample.json +68 -0
- data/samples/sample.pas +276 -0
- data/samples/sample.php +303 -0
- data/samples/sample.py +290 -0
- data/samples/sample.rb +160 -0
- data/samples/sample.rs +391 -0
- data/samples/sample.sh +142 -0
- data/samples/sample.sql +352 -0
- data/samples/sample.swift +482 -0
- data/samples/sample.tf +150 -0
- data/samples/sample.yaml +182 -0
- metadata +22 -1
data/samples/sample.rb
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Single line comment
|
|
4
|
+
|
|
5
|
+
=begin
|
|
6
|
+
Multi-line
|
|
7
|
+
comment block
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
# --- Keywords ---
|
|
11
|
+
module SampleModule
|
|
12
|
+
class SampleClass
|
|
13
|
+
def initialize(name)
|
|
14
|
+
@name = name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def greet
|
|
18
|
+
if @name
|
|
19
|
+
puts "Hello, #{@name}!"
|
|
20
|
+
elsif @name.nil?
|
|
21
|
+
puts "No name"
|
|
22
|
+
else
|
|
23
|
+
puts "Unknown"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
unless @name.empty?
|
|
27
|
+
yield self if block_given?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
case @name
|
|
31
|
+
when "Alice" then "A"
|
|
32
|
+
when "Bob" then "B"
|
|
33
|
+
else "?"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.singleton_example
|
|
38
|
+
super
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# --- Loops ---
|
|
44
|
+
i = 0
|
|
45
|
+
while i < 10
|
|
46
|
+
break if i == 5
|
|
47
|
+
next if i == 3
|
|
48
|
+
i += 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
until i <= 0
|
|
52
|
+
i -= 1
|
|
53
|
+
redo if false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
for x in [1, 2, 3]
|
|
57
|
+
puts x
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
10.times do |n|
|
|
61
|
+
retry if false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# --- Strings ---
|
|
65
|
+
single = 'single quoted'
|
|
66
|
+
double = "double quoted with #{1 + 2} interpolation"
|
|
67
|
+
heredoc = <<~HEREDOC
|
|
68
|
+
This is a heredoc
|
|
69
|
+
with multiple lines
|
|
70
|
+
HEREDOC
|
|
71
|
+
heredoc_squiggly = <<~'SQUIGGLY'
|
|
72
|
+
No interpolation here
|
|
73
|
+
SQUIGGLY
|
|
74
|
+
bare_string = %q(bare string)
|
|
75
|
+
regex_literal = /pattern[a-z]+/i
|
|
76
|
+
escaped = "tab\tnewline\n"
|
|
77
|
+
char = ?a
|
|
78
|
+
subshell = `echo hello`
|
|
79
|
+
chained = "hello" \
|
|
80
|
+
"world"
|
|
81
|
+
symbol = :simple_symbol
|
|
82
|
+
fancy_symbol = :"delimited symbol"
|
|
83
|
+
symbol_array = %i[foo bar baz]
|
|
84
|
+
string_array = %w[hello world]
|
|
85
|
+
|
|
86
|
+
# --- Numbers ---
|
|
87
|
+
integer_val = 42
|
|
88
|
+
negative = -17
|
|
89
|
+
hex = 0xFF
|
|
90
|
+
octal = 0o77
|
|
91
|
+
binary = 0b1010
|
|
92
|
+
float_val = 3.14
|
|
93
|
+
scientific = 1.5e10
|
|
94
|
+
complex_val = 1i
|
|
95
|
+
rational_val = 3/4r
|
|
96
|
+
|
|
97
|
+
# --- Constants & Builtins ---
|
|
98
|
+
PI = 3.14159
|
|
99
|
+
CONST_VAL = true
|
|
100
|
+
nothing = nil
|
|
101
|
+
falsy = false
|
|
102
|
+
|
|
103
|
+
# --- Variables ---
|
|
104
|
+
local_var = "local"
|
|
105
|
+
@instance_var = "instance"
|
|
106
|
+
@@class_var = "class"
|
|
107
|
+
$global_var = "global"
|
|
108
|
+
|
|
109
|
+
# --- Operators ---
|
|
110
|
+
sum = 1 + 2
|
|
111
|
+
diff = 5 - 3
|
|
112
|
+
prod = 4 * 2
|
|
113
|
+
quot = 10 / 3
|
|
114
|
+
modulo = 10 % 3
|
|
115
|
+
power = 2 ** 8
|
|
116
|
+
comparison = (1 <=> 2)
|
|
117
|
+
logical = true && false || !nil
|
|
118
|
+
bitwise = 0xFF & 0x0F | 0x10 ^ 0x01
|
|
119
|
+
shift = 1 << 4
|
|
120
|
+
range = (1..10)
|
|
121
|
+
exclusive_range = (1...10)
|
|
122
|
+
ternary = true ? "yes" : "no"
|
|
123
|
+
|
|
124
|
+
# --- Method definitions ---
|
|
125
|
+
def standalone_method(a, b = 10, *args, key:, **opts, &block)
|
|
126
|
+
return a + b
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# --- Exception handling ---
|
|
130
|
+
begin
|
|
131
|
+
raise StandardError, "oops"
|
|
132
|
+
rescue StandardError => e
|
|
133
|
+
puts e.message
|
|
134
|
+
ensure
|
|
135
|
+
puts "cleanup"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# --- Special keywords ---
|
|
139
|
+
alias new_method greet
|
|
140
|
+
defined?(local_var)
|
|
141
|
+
self
|
|
142
|
+
BEGIN { puts "begin block" }
|
|
143
|
+
END { puts "end block" }
|
|
144
|
+
|
|
145
|
+
# --- Lambda / Proc ---
|
|
146
|
+
my_lambda = lambda { |x| x * 2 }
|
|
147
|
+
my_proc = ->(x) { x + 1 }
|
|
148
|
+
|
|
149
|
+
# --- Pattern matching (Ruby 3.x) ---
|
|
150
|
+
case [1, 2, 3]
|
|
151
|
+
in [Integer => a, Integer => b, *]
|
|
152
|
+
puts a + b
|
|
153
|
+
in { name: String => name }
|
|
154
|
+
puts name
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# --- Encoding constants ---
|
|
158
|
+
enc = __ENCODING__
|
|
159
|
+
file = __FILE__
|
|
160
|
+
line = __LINE__
|
data/samples/sample.rs
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
// Line comment
|
|
2
|
+
/* Block comment */
|
|
3
|
+
/// Doc comment for the module
|
|
4
|
+
//! Inner doc comment
|
|
5
|
+
|
|
6
|
+
// --- Modules & Imports ---
|
|
7
|
+
use std::collections::HashMap;
|
|
8
|
+
use std::fmt::{self, Display};
|
|
9
|
+
use std::io::{self, Read, Write};
|
|
10
|
+
|
|
11
|
+
mod helper {
|
|
12
|
+
pub fn add(a: i32, b: i32) -> i32 {
|
|
13
|
+
a + b
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// --- Constants & Statics ---
|
|
18
|
+
const MAX_SIZE: usize = 100;
|
|
19
|
+
static GREETING: &str = "Hello, World!";
|
|
20
|
+
static mut COUNTER: i32 = 0;
|
|
21
|
+
|
|
22
|
+
// --- Enums ---
|
|
23
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
24
|
+
enum Color {
|
|
25
|
+
Red,
|
|
26
|
+
Green,
|
|
27
|
+
Blue,
|
|
28
|
+
Custom(u8, u8, u8),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#[derive(Debug)]
|
|
32
|
+
enum Shape {
|
|
33
|
+
Circle { radius: f64 },
|
|
34
|
+
Rectangle { width: f64, height: f64 },
|
|
35
|
+
Triangle(f64, f64, f64),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// --- Structs ---
|
|
39
|
+
#[derive(Debug, Clone)]
|
|
40
|
+
struct Point {
|
|
41
|
+
x: f64,
|
|
42
|
+
y: f64,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
struct Container<T> {
|
|
46
|
+
items: Vec<T>,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Tuple struct
|
|
50
|
+
struct Pair<T>(T, T);
|
|
51
|
+
|
|
52
|
+
// Unit struct
|
|
53
|
+
struct Unit;
|
|
54
|
+
|
|
55
|
+
// --- Traits ---
|
|
56
|
+
trait Animal: Display {
|
|
57
|
+
fn name(&self) -> &str;
|
|
58
|
+
fn speak(&self) -> String;
|
|
59
|
+
|
|
60
|
+
fn greet(&self) -> String {
|
|
61
|
+
format!("Hi, I'm {} and I say {}", self.name(), self.speak())
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
trait Drawable {
|
|
66
|
+
fn draw(&self);
|
|
67
|
+
fn area(&self) -> f64;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// --- Implementations ---
|
|
71
|
+
impl Point {
|
|
72
|
+
fn new(x: f64, y: f64) -> Self {
|
|
73
|
+
Self { x, y }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fn distance(&self, other: &Point) -> f64 {
|
|
77
|
+
((self.x - other.x).powi(2) + (self.y - other.y).powi(2)).sqrt()
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
impl Display for Point {
|
|
82
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
83
|
+
write!(f, "({}, {})", self.x, self.y)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
impl<T> Container<T> {
|
|
88
|
+
fn new() -> Self {
|
|
89
|
+
Container { items: Vec::new() }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fn add(&mut self, item: T) {
|
|
93
|
+
self.items.push(item);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
fn get(&self, index: usize) -> Option<&T> {
|
|
97
|
+
self.items.get(index)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fn len(&self) -> usize {
|
|
101
|
+
self.items.len()
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
impl Drawable for Shape {
|
|
106
|
+
fn draw(&self) {
|
|
107
|
+
println!("Drawing {:?}", self);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
fn area(&self) -> f64 {
|
|
111
|
+
match self {
|
|
112
|
+
Shape::Circle { radius } => std::f64::consts::PI * radius * radius,
|
|
113
|
+
Shape::Rectangle { width, height } => width * height,
|
|
114
|
+
Shape::Triangle(a, b, c) => {
|
|
115
|
+
let s = (a + b + c) / 2.0;
|
|
116
|
+
(s * (s - a) * (s - b) * (s - c)).sqrt()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// --- Functions ---
|
|
123
|
+
fn add(a: i32, b: i32) -> i32 {
|
|
124
|
+
a + b
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
fn greet(name: &str) -> String {
|
|
128
|
+
format!("Hello, {}!", name)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
fn divide(a: f64, b: f64) -> Result<f64, String> {
|
|
132
|
+
if b == 0.0 {
|
|
133
|
+
Err("Division by zero".to_string())
|
|
134
|
+
} else {
|
|
135
|
+
Ok(a / b)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Generic function with trait bounds
|
|
140
|
+
fn largest<T: PartialOrd>(list: &[T]) -> Option<&T> {
|
|
141
|
+
let mut max = list.first()?;
|
|
142
|
+
for item in list {
|
|
143
|
+
if item > max {
|
|
144
|
+
max = item;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
Some(max)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Async function
|
|
151
|
+
async fn fetch_data(url: &str) -> Result<String, Box<dyn std::error::Error>> {
|
|
152
|
+
Ok(format!("Data from {}", url))
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
fn main() {
|
|
156
|
+
// --- Strings ---
|
|
157
|
+
let simple = "Hello, World!";
|
|
158
|
+
let escaped = "tab\tnewline\nnull\0";
|
|
159
|
+
let raw = r"raw string \n no escape";
|
|
160
|
+
let raw_hash = r#"raw with "quotes" inside"#;
|
|
161
|
+
let byte_str = b"byte string";
|
|
162
|
+
let char_val = 'A';
|
|
163
|
+
let unicode_char = '\u{1F600}';
|
|
164
|
+
|
|
165
|
+
// --- Numbers ---
|
|
166
|
+
let integer: i32 = 42;
|
|
167
|
+
let unsigned: u64 = 100;
|
|
168
|
+
let float: f64 = 3.14;
|
|
169
|
+
let hex = 0xFF;
|
|
170
|
+
let octal = 0o77;
|
|
171
|
+
let binary = 0b1010;
|
|
172
|
+
let separator = 1_000_000;
|
|
173
|
+
let byte = b'A';
|
|
174
|
+
let inferred = 42;
|
|
175
|
+
|
|
176
|
+
// --- Booleans ---
|
|
177
|
+
let yes: bool = true;
|
|
178
|
+
let no: bool = false;
|
|
179
|
+
|
|
180
|
+
// --- Variables ---
|
|
181
|
+
let immutable = "can't change";
|
|
182
|
+
let mut mutable = "can change";
|
|
183
|
+
mutable = "changed";
|
|
184
|
+
|
|
185
|
+
let (a, b, c) = (1, 2, 3);
|
|
186
|
+
let Point { x, y } = Point::new(1.0, 2.0);
|
|
187
|
+
|
|
188
|
+
// --- References ---
|
|
189
|
+
let reference = &integer;
|
|
190
|
+
let mut_ref = &mut mutable;
|
|
191
|
+
let deref = *reference;
|
|
192
|
+
|
|
193
|
+
// --- Control flow ---
|
|
194
|
+
if integer > 0 {
|
|
195
|
+
println!("positive");
|
|
196
|
+
} else if integer < 0 {
|
|
197
|
+
println!("negative");
|
|
198
|
+
} else {
|
|
199
|
+
println!("zero");
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// --- Match ---
|
|
203
|
+
match integer {
|
|
204
|
+
0 => println!("zero"),
|
|
205
|
+
1..=10 => println!("small"),
|
|
206
|
+
n if n > 100 => println!("big: {}", n),
|
|
207
|
+
_ => println!("other"),
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
match Color::Custom(255, 0, 0) {
|
|
211
|
+
Color::Red => println!("red"),
|
|
212
|
+
Color::Custom(r, g, b) => println!("rgb({}, {}, {})", r, g, b),
|
|
213
|
+
_ => println!("other"),
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// --- Loops ---
|
|
217
|
+
for i in 0..10 {
|
|
218
|
+
if i == 5 {
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
if i == 3 {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
println!("{}", i);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
for item in &[1, 2, 3] {
|
|
228
|
+
println!("{}", item);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
let mut j = 10;
|
|
232
|
+
while j > 0 {
|
|
233
|
+
j -= 1;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
loop {
|
|
237
|
+
j += 1;
|
|
238
|
+
if j >= 5 {
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Loop with label
|
|
244
|
+
'outer: for i in 0..3 {
|
|
245
|
+
for j in 0..3 {
|
|
246
|
+
if j == 1 {
|
|
247
|
+
continue 'outer;
|
|
248
|
+
}
|
|
249
|
+
if i == 2 {
|
|
250
|
+
break 'outer;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Loop as expression
|
|
256
|
+
let result = loop {
|
|
257
|
+
j += 1;
|
|
258
|
+
if j > 10 {
|
|
259
|
+
break j * 2;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// --- Operators ---
|
|
264
|
+
let sum = 1 + 2;
|
|
265
|
+
let diff = 5 - 3;
|
|
266
|
+
let prod = 4 * 2;
|
|
267
|
+
let quot = 10 / 3;
|
|
268
|
+
let modulo = 10 % 3;
|
|
269
|
+
let neg = -sum;
|
|
270
|
+
let bit_and = 0xFF & 0x0F;
|
|
271
|
+
let bit_or = 0x10 | 0x01;
|
|
272
|
+
let bit_xor = 0xFF ^ 0x0F;
|
|
273
|
+
let bit_not = !0u32;
|
|
274
|
+
let lshift = 1 << 4;
|
|
275
|
+
let rshift = 16 >> 2;
|
|
276
|
+
let logic = true && false || !true;
|
|
277
|
+
let range = 0..10;
|
|
278
|
+
let range_inclusive = 0..=10;
|
|
279
|
+
|
|
280
|
+
// --- Option & Result ---
|
|
281
|
+
let some_val: Option<i32> = Some(42);
|
|
282
|
+
let none_val: Option<i32> = None;
|
|
283
|
+
let unwrapped = some_val.unwrap_or(0);
|
|
284
|
+
|
|
285
|
+
let ok_val: Result<i32, String> = Ok(42);
|
|
286
|
+
let err_val: Result<i32, String> = Err("error".to_string());
|
|
287
|
+
|
|
288
|
+
// --- Error handling ---
|
|
289
|
+
match divide(10.0, 3.0) {
|
|
290
|
+
Ok(result) => println!("Result: {}", result),
|
|
291
|
+
Err(e) => println!("Error: {}", e),
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Try operator
|
|
295
|
+
fn try_divide() -> Result<(), String> {
|
|
296
|
+
let result = divide(10.0, 0.0)?;
|
|
297
|
+
println!("{}", result);
|
|
298
|
+
Ok(())
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// --- Closures ---
|
|
302
|
+
let closure = |x: i32| x * 2;
|
|
303
|
+
let closure_block = |x: i32, y: i32| -> i32 {
|
|
304
|
+
let sum = x + y;
|
|
305
|
+
sum * 2
|
|
306
|
+
};
|
|
307
|
+
let capture = move || println!("{}", integer);
|
|
308
|
+
|
|
309
|
+
// --- Iterators ---
|
|
310
|
+
let doubled: Vec<i32> = (0..5).map(|x| x * 2).collect();
|
|
311
|
+
let evens: Vec<i32> = (0..10).filter(|x| x % 2 == 0).collect();
|
|
312
|
+
let sum: i32 = (1..=100).sum();
|
|
313
|
+
|
|
314
|
+
// --- Collections ---
|
|
315
|
+
let mut vec = vec![1, 2, 3];
|
|
316
|
+
vec.push(4);
|
|
317
|
+
|
|
318
|
+
let mut map = HashMap::new();
|
|
319
|
+
map.insert("key", "value");
|
|
320
|
+
map.entry("key2").or_insert("default");
|
|
321
|
+
|
|
322
|
+
// --- Box, Rc, Arc ---
|
|
323
|
+
let boxed: Box<i32> = Box::new(42);
|
|
324
|
+
let _deref = *boxed;
|
|
325
|
+
|
|
326
|
+
// --- Type casting ---
|
|
327
|
+
let float_val = integer as f64;
|
|
328
|
+
let truncated = 3.99f64 as i32;
|
|
329
|
+
|
|
330
|
+
// --- Unsafe ---
|
|
331
|
+
unsafe {
|
|
332
|
+
COUNTER += 1;
|
|
333
|
+
println!("Counter: {}", COUNTER);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// --- Macros ---
|
|
337
|
+
println!("Hello, {}!", "World");
|
|
338
|
+
format!("formatted {}", integer);
|
|
339
|
+
vec![1, 2, 3];
|
|
340
|
+
assert!(true);
|
|
341
|
+
assert_eq!(1 + 1, 2);
|
|
342
|
+
dbg!(integer);
|
|
343
|
+
|
|
344
|
+
// --- Struct initialization ---
|
|
345
|
+
let p1 = Point { x: 1.0, y: 2.0 };
|
|
346
|
+
let p2 = Point { x: 4.0, ..p1 };
|
|
347
|
+
|
|
348
|
+
// --- If let / While let ---
|
|
349
|
+
if let Some(val) = some_val {
|
|
350
|
+
println!("Got: {}", val);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
let mut stack = vec![1, 2, 3];
|
|
354
|
+
while let Some(top) = stack.pop() {
|
|
355
|
+
println!("{}", top);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// --- Let chain ---
|
|
359
|
+
if let Some(x) = some_val && x > 0 {
|
|
360
|
+
println!("positive some: {}", x);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
println!("Done!");
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// --- Macro definition ---
|
|
367
|
+
macro_rules! say_hello {
|
|
368
|
+
() => {
|
|
369
|
+
println!("Hello!");
|
|
370
|
+
};
|
|
371
|
+
($name:expr) => {
|
|
372
|
+
println!("Hello, {}!", $name);
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// --- Tests ---
|
|
377
|
+
#[cfg(test)]
|
|
378
|
+
mod tests {
|
|
379
|
+
use super::*;
|
|
380
|
+
|
|
381
|
+
#[test]
|
|
382
|
+
fn test_add() {
|
|
383
|
+
assert_eq!(add(1, 2), 3);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
#[test]
|
|
387
|
+
#[should_panic(expected = "Division by zero")]
|
|
388
|
+
fn test_divide_by_zero() {
|
|
389
|
+
divide(1.0, 0.0).unwrap();
|
|
390
|
+
}
|
|
391
|
+
}
|
data/samples/sample.sh
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Single line comment
|
|
4
|
+
|
|
5
|
+
# --- Variables ---
|
|
6
|
+
NAME="world"
|
|
7
|
+
readonly CONSTANT="immutable"
|
|
8
|
+
local_var="local"
|
|
9
|
+
export EXPORTED_VAR="exported"
|
|
10
|
+
|
|
11
|
+
# --- Strings ---
|
|
12
|
+
single='single quoted string'
|
|
13
|
+
double="Hello, ${NAME}!"
|
|
14
|
+
raw_string=$'escape\tsequence\n'
|
|
15
|
+
heredoc_str=$(cat <<'EOF'
|
|
16
|
+
This is a heredoc
|
|
17
|
+
with no interpolation
|
|
18
|
+
EOF
|
|
19
|
+
)
|
|
20
|
+
heredoc_interp=$(cat <<EOF
|
|
21
|
+
Hello, ${NAME}
|
|
22
|
+
EOF
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# --- Numbers ---
|
|
26
|
+
integer=42
|
|
27
|
+
hex=0xFF
|
|
28
|
+
octal=077
|
|
29
|
+
|
|
30
|
+
# --- Conditionals ---
|
|
31
|
+
if [ "$NAME" = "world" ]; then
|
|
32
|
+
echo "Hello!"
|
|
33
|
+
elif [ "$NAME" = "earth" ]; then
|
|
34
|
+
echo "Hi!"
|
|
35
|
+
else
|
|
36
|
+
echo "Unknown"
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# --- Case ---
|
|
40
|
+
case "$NAME" in
|
|
41
|
+
"world")
|
|
42
|
+
echo "Known"
|
|
43
|
+
;;
|
|
44
|
+
"earth"|"mars")
|
|
45
|
+
echo "Planet"
|
|
46
|
+
;;
|
|
47
|
+
*)
|
|
48
|
+
echo "Unknown"
|
|
49
|
+
;;
|
|
50
|
+
esac
|
|
51
|
+
|
|
52
|
+
# --- Loops ---
|
|
53
|
+
for i in 1 2 3 4 5; do
|
|
54
|
+
echo "$i"
|
|
55
|
+
done
|
|
56
|
+
|
|
57
|
+
for ((i = 0; i < 10; i++)); do
|
|
58
|
+
echo "$i"
|
|
59
|
+
done
|
|
60
|
+
|
|
61
|
+
while [ "$i" -gt 0 ]; do
|
|
62
|
+
i=$((i - 1))
|
|
63
|
+
done
|
|
64
|
+
|
|
65
|
+
until [ "$i" -ge 10 ]; do
|
|
66
|
+
i=$((i + 1))
|
|
67
|
+
done
|
|
68
|
+
|
|
69
|
+
select opt in "Option1" "Option2" "Quit"; do
|
|
70
|
+
case "$opt" in
|
|
71
|
+
"Quit") break ;;
|
|
72
|
+
*) echo "Selected: $opt" ;;
|
|
73
|
+
esac
|
|
74
|
+
done
|
|
75
|
+
|
|
76
|
+
# --- Functions ---
|
|
77
|
+
function greet() {
|
|
78
|
+
local greeting="Hello"
|
|
79
|
+
echo "${greeting}, $1!"
|
|
80
|
+
return 0
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
say_hi() {
|
|
84
|
+
echo "Hi, $1!"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
greet "World"
|
|
88
|
+
say_hi "Earth"
|
|
89
|
+
|
|
90
|
+
# --- Arrays ---
|
|
91
|
+
declare -a fruits=("apple" "banana" "cherry")
|
|
92
|
+
echo "${fruits[0]}"
|
|
93
|
+
echo "${#fruits[@]}"
|
|
94
|
+
|
|
95
|
+
declare -A colors
|
|
96
|
+
colors[red]="#FF0000"
|
|
97
|
+
colors[green]="#00FF00"
|
|
98
|
+
|
|
99
|
+
# --- Command substitution ---
|
|
100
|
+
current_date=$(date +%Y-%m-%d)
|
|
101
|
+
files=`ls -la`
|
|
102
|
+
|
|
103
|
+
# --- Process substitution ---
|
|
104
|
+
diff <(ls dir1) <(ls dir2)
|
|
105
|
+
|
|
106
|
+
# --- Arithmetic ---
|
|
107
|
+
result=$((2 + 3 * 4))
|
|
108
|
+
((count++))
|
|
109
|
+
|
|
110
|
+
# --- Redirects ---
|
|
111
|
+
echo "output" > /tmp/out.txt
|
|
112
|
+
echo "append" >> /tmp/out.txt
|
|
113
|
+
cat < /tmp/out.txt
|
|
114
|
+
command 2>&1
|
|
115
|
+
|
|
116
|
+
# --- Pipes ---
|
|
117
|
+
ls -la | grep ".sh" | wc -l
|
|
118
|
+
|
|
119
|
+
# --- Test operators ---
|
|
120
|
+
[ -f "/etc/passwd" ] && echo "exists"
|
|
121
|
+
[[ "$NAME" =~ ^w.*d$ ]] && echo "matches"
|
|
122
|
+
[ -d "/tmp" -a -w "/tmp" ] && echo "writable dir"
|
|
123
|
+
|
|
124
|
+
# --- Special variables ---
|
|
125
|
+
echo "Script: $0"
|
|
126
|
+
echo "Args: $@"
|
|
127
|
+
echo "Count: $#"
|
|
128
|
+
echo "Exit: $?"
|
|
129
|
+
echo "PID: $$"
|
|
130
|
+
|
|
131
|
+
# --- Brace expansion ---
|
|
132
|
+
echo {1..5}
|
|
133
|
+
echo {a..z}
|
|
134
|
+
|
|
135
|
+
# --- Subshell ---
|
|
136
|
+
(cd /tmp && ls)
|
|
137
|
+
|
|
138
|
+
# --- Declare/typeset ---
|
|
139
|
+
declare -i number=42
|
|
140
|
+
declare -r readonly_var="can't change"
|
|
141
|
+
typeset -l lowercase="HELLO"
|
|
142
|
+
unset NAME
|