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.cs
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// Line comment
|
|
2
|
+
/* Block comment */
|
|
3
|
+
|
|
4
|
+
using System;
|
|
5
|
+
using System.Collections.Generic;
|
|
6
|
+
using System.Linq;
|
|
7
|
+
using System.Threading.Tasks;
|
|
8
|
+
|
|
9
|
+
namespace SampleNamespace
|
|
10
|
+
{
|
|
11
|
+
// --- Enums ---
|
|
12
|
+
public enum Color
|
|
13
|
+
{
|
|
14
|
+
Red,
|
|
15
|
+
Green,
|
|
16
|
+
Blue
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// --- Interfaces ---
|
|
20
|
+
public interface IGreetable
|
|
21
|
+
{
|
|
22
|
+
string Greet();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// --- Abstract class ---
|
|
26
|
+
public abstract class Animal
|
|
27
|
+
{
|
|
28
|
+
public abstract string Speak();
|
|
29
|
+
public virtual string Name { get; set; } = "Unknown";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// --- Struct ---
|
|
33
|
+
public struct Point
|
|
34
|
+
{
|
|
35
|
+
public double X { get; init; }
|
|
36
|
+
public double Y { get; init; }
|
|
37
|
+
|
|
38
|
+
public double Distance(Point other)
|
|
39
|
+
{
|
|
40
|
+
return Math.Sqrt(Math.Pow(X - other.X, 2) + Math.Pow(Y - other.Y, 2));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// --- Record ---
|
|
45
|
+
public record Person(string Name, int Age);
|
|
46
|
+
|
|
47
|
+
// --- Sealed class ---
|
|
48
|
+
public sealed class Dog : Animal, IGreetable
|
|
49
|
+
{
|
|
50
|
+
public override string Speak() => "Woof!";
|
|
51
|
+
|
|
52
|
+
public string Greet() => $"I'm {Name}";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// --- Generic class ---
|
|
56
|
+
public class Container<T> where T : class, new()
|
|
57
|
+
{
|
|
58
|
+
private readonly List<T> _items = new();
|
|
59
|
+
|
|
60
|
+
public void Add(T item) => _items.Add(item);
|
|
61
|
+
public T? Get(int index) => index < _items.Count ? _items[index] : null;
|
|
62
|
+
public int Count => _items.Count;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// --- Static class ---
|
|
66
|
+
public static class MathHelper
|
|
67
|
+
{
|
|
68
|
+
public const double Pi = 3.14159;
|
|
69
|
+
public static readonly int MaxValue = int.MaxValue;
|
|
70
|
+
|
|
71
|
+
public static int Add(int a, int b) => a + b;
|
|
72
|
+
public static async Task<int> AddAsync(int a, int b)
|
|
73
|
+
{
|
|
74
|
+
await Task.Delay(100);
|
|
75
|
+
return a + b;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// --- Main class ---
|
|
80
|
+
public class Program
|
|
81
|
+
{
|
|
82
|
+
// --- Delegate & Event ---
|
|
83
|
+
public delegate void MessageHandler(string message);
|
|
84
|
+
public event MessageHandler? OnMessage;
|
|
85
|
+
|
|
86
|
+
public static void Main(string[] args)
|
|
87
|
+
{
|
|
88
|
+
// --- Strings ---
|
|
89
|
+
string simple = "Hello, World!";
|
|
90
|
+
string interpolated = $"Result: {1 + 2}";
|
|
91
|
+
string verbatim = @"C:\Users\test\file.txt";
|
|
92
|
+
string raw = """
|
|
93
|
+
Raw string literal
|
|
94
|
+
with "quotes" inside
|
|
95
|
+
""";
|
|
96
|
+
char ch = 'A';
|
|
97
|
+
string escaped = "tab\tnewline\n";
|
|
98
|
+
|
|
99
|
+
// --- Numbers ---
|
|
100
|
+
int integer = 42;
|
|
101
|
+
long big = 1234567890L;
|
|
102
|
+
float f = 3.14f;
|
|
103
|
+
double d = 2.71828;
|
|
104
|
+
decimal money = 19.99m;
|
|
105
|
+
int hex = 0xFF;
|
|
106
|
+
int bin = 0b1010;
|
|
107
|
+
|
|
108
|
+
// --- Booleans & Null ---
|
|
109
|
+
bool flag = true;
|
|
110
|
+
bool nope = false;
|
|
111
|
+
string? nullable = null;
|
|
112
|
+
|
|
113
|
+
// --- var ---
|
|
114
|
+
var inferred = "inferred type";
|
|
115
|
+
|
|
116
|
+
// --- Control flow ---
|
|
117
|
+
if (integer > 0)
|
|
118
|
+
{
|
|
119
|
+
Console.WriteLine("positive");
|
|
120
|
+
}
|
|
121
|
+
else if (integer < 0)
|
|
122
|
+
{
|
|
123
|
+
Console.WriteLine("negative");
|
|
124
|
+
}
|
|
125
|
+
else
|
|
126
|
+
{
|
|
127
|
+
Console.WriteLine("zero");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
switch (integer)
|
|
131
|
+
{
|
|
132
|
+
case 1:
|
|
133
|
+
Console.WriteLine("one");
|
|
134
|
+
break;
|
|
135
|
+
case 2:
|
|
136
|
+
Console.WriteLine("two");
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
Console.WriteLine("other");
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// --- Switch expression ---
|
|
144
|
+
string result = integer switch
|
|
145
|
+
{
|
|
146
|
+
> 0 => "positive",
|
|
147
|
+
< 0 => "negative",
|
|
148
|
+
_ => "zero"
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// --- Loops ---
|
|
152
|
+
for (int i = 0; i < 10; i++)
|
|
153
|
+
{
|
|
154
|
+
if (i == 5) break;
|
|
155
|
+
if (i == 3) continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
foreach (var item in new[] { 1, 2, 3 })
|
|
159
|
+
{
|
|
160
|
+
Console.WriteLine(item);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
int j = 10;
|
|
164
|
+
while (j > 0)
|
|
165
|
+
{
|
|
166
|
+
j--;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
do
|
|
170
|
+
{
|
|
171
|
+
j++;
|
|
172
|
+
} while (j < 5);
|
|
173
|
+
|
|
174
|
+
// --- Operators ---
|
|
175
|
+
int sum = 1 + 2;
|
|
176
|
+
bool logic = true && false || !true;
|
|
177
|
+
int ternary = sum > 0 ? sum : -sum;
|
|
178
|
+
string coalesce = nullable ?? "default";
|
|
179
|
+
int? nullableInt = null;
|
|
180
|
+
int safe = nullableInt ?? 0;
|
|
181
|
+
|
|
182
|
+
// --- Type checks ---
|
|
183
|
+
object obj = "test";
|
|
184
|
+
if (obj is string s)
|
|
185
|
+
{
|
|
186
|
+
Console.WriteLine(s.Length);
|
|
187
|
+
}
|
|
188
|
+
var cast = obj as string;
|
|
189
|
+
var typeOf = typeof(string);
|
|
190
|
+
var sizeOf = sizeof(int);
|
|
191
|
+
|
|
192
|
+
// --- Exception handling ---
|
|
193
|
+
try
|
|
194
|
+
{
|
|
195
|
+
throw new InvalidOperationException("oops");
|
|
196
|
+
}
|
|
197
|
+
catch (InvalidOperationException ex) when (ex.Message.Contains("oops"))
|
|
198
|
+
{
|
|
199
|
+
Console.WriteLine(ex.Message);
|
|
200
|
+
}
|
|
201
|
+
catch (Exception)
|
|
202
|
+
{
|
|
203
|
+
Console.WriteLine("unexpected");
|
|
204
|
+
}
|
|
205
|
+
finally
|
|
206
|
+
{
|
|
207
|
+
Console.WriteLine("cleanup");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// --- Pattern matching ---
|
|
211
|
+
object value = 42;
|
|
212
|
+
if (value is int n and > 0)
|
|
213
|
+
{
|
|
214
|
+
Console.WriteLine($"Positive int: {n}");
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// --- LINQ ---
|
|
218
|
+
var numbers = new List<int> { 1, 2, 3, 4, 5 };
|
|
219
|
+
var evens = from num in numbers
|
|
220
|
+
where num % 2 == 0
|
|
221
|
+
orderby num descending
|
|
222
|
+
select num;
|
|
223
|
+
|
|
224
|
+
// --- Lambda ---
|
|
225
|
+
Func<int, int> square = x => x * x;
|
|
226
|
+
Action<string> print = msg => Console.WriteLine(msg);
|
|
227
|
+
|
|
228
|
+
// --- Async/Await ---
|
|
229
|
+
RunAsync().Wait();
|
|
230
|
+
|
|
231
|
+
// --- Record usage ---
|
|
232
|
+
var person = new Person("Alice", 30);
|
|
233
|
+
var older = person with { Age = 31 };
|
|
234
|
+
|
|
235
|
+
// --- Struct usage ---
|
|
236
|
+
var p1 = new Point { X = 1.0, Y = 2.0 };
|
|
237
|
+
var p2 = new Point { X = 4.0, Y = 6.0 };
|
|
238
|
+
Console.WriteLine(p1.Distance(p2));
|
|
239
|
+
|
|
240
|
+
// --- Using/lock ---
|
|
241
|
+
lock (obj)
|
|
242
|
+
{
|
|
243
|
+
Console.WriteLine("synchronized");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// --- Goto ---
|
|
247
|
+
goto end;
|
|
248
|
+
end:
|
|
249
|
+
Console.WriteLine("done");
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private static async Task RunAsync()
|
|
253
|
+
{
|
|
254
|
+
var result = await MathHelper.AddAsync(1, 2);
|
|
255
|
+
Console.WriteLine(result);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// --- Yield ---
|
|
259
|
+
public static IEnumerable<int> Fibonacci()
|
|
260
|
+
{
|
|
261
|
+
int a = 0, b = 1;
|
|
262
|
+
while (true)
|
|
263
|
+
{
|
|
264
|
+
yield return a;
|
|
265
|
+
(a, b) = (b, a + b);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// --- Operator overloading ---
|
|
270
|
+
public static implicit operator string(Program p) => "Program";
|
|
271
|
+
public static explicit operator int(Program p) => 0;
|
|
272
|
+
}
|
|
273
|
+
}
|
data/samples/sample.ex
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Single line comment
|
|
2
|
+
|
|
3
|
+
# Elixir sample - functional programming on the BEAM
|
|
4
|
+
|
|
5
|
+
# --- Module ---
|
|
6
|
+
defmodule Sample do
|
|
7
|
+
@moduledoc """
|
|
8
|
+
Sample module demonstrating Elixir syntax.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# --- Module attributes ---
|
|
12
|
+
@max_size 100
|
|
13
|
+
@pi 3.14159
|
|
14
|
+
@greeting "Hello, World!"
|
|
15
|
+
|
|
16
|
+
# --- Structs ---
|
|
17
|
+
defmodule Point do
|
|
18
|
+
@enforce_keys [:x, :y]
|
|
19
|
+
defstruct [:x, :y, z: 0.0]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
defmodule User do
|
|
23
|
+
defstruct [:name, :age, active: true]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# --- Types ---
|
|
27
|
+
@type color :: :red | :green | :blue
|
|
28
|
+
@type result :: {:ok, any()} | {:error, String.t()}
|
|
29
|
+
|
|
30
|
+
# --- Functions ---
|
|
31
|
+
@doc "Add two numbers"
|
|
32
|
+
@spec add(number(), number()) :: number()
|
|
33
|
+
def add(a, b) do
|
|
34
|
+
a + b
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@spec greet(String.t(), String.t()) :: String.t()
|
|
38
|
+
def greet(name, greeting \\ "Hello") do
|
|
39
|
+
"#{greeting}, #{name}!"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# --- Pattern matching in function heads ---
|
|
43
|
+
def describe(:red), do: "Red color"
|
|
44
|
+
def describe(:green), do: "Green color"
|
|
45
|
+
def describe(:blue), do: "Blue color"
|
|
46
|
+
def describe(_), do: "Unknown color"
|
|
47
|
+
|
|
48
|
+
# --- Guards ---
|
|
49
|
+
def classify(n) when is_integer(n) and n > 0, do: :positive
|
|
50
|
+
def classify(n) when is_integer(n) and n < 0, do: :negative
|
|
51
|
+
def classify(0), do: :zero
|
|
52
|
+
def classify(_), do: :not_a_number
|
|
53
|
+
|
|
54
|
+
# --- Private functions ---
|
|
55
|
+
defp helper(value) do
|
|
56
|
+
value * 2
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# --- Default arguments ---
|
|
60
|
+
def repeat(str, times \\ 3) do
|
|
61
|
+
String.duplicate(str, times)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# --- Multi-clause with when ---
|
|
65
|
+
def safe_divide(a, b) when b != 0 do
|
|
66
|
+
{:ok, a / b}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def safe_divide(_a, 0) do
|
|
70
|
+
{:error, "Division by zero"}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# --- Main function ---
|
|
74
|
+
def run do
|
|
75
|
+
# --- Atoms ---
|
|
76
|
+
status = :ok
|
|
77
|
+
error = :error
|
|
78
|
+
module_atom = Sample
|
|
79
|
+
|
|
80
|
+
# --- Strings ---
|
|
81
|
+
simple = "Hello, World!"
|
|
82
|
+
interpolated = "Sum: #{1 + 2}"
|
|
83
|
+
escaped = "tab\tnewline\n"
|
|
84
|
+
heredoc = """
|
|
85
|
+
This is a heredoc
|
|
86
|
+
with #{interpolated}
|
|
87
|
+
"""
|
|
88
|
+
charlist = 'charlist (list of integers)'
|
|
89
|
+
sigil_string = ~s(sigil string with #{interpolated})
|
|
90
|
+
sigil_raw = ~S(raw sigil, no #{interpolation})
|
|
91
|
+
regex = ~r/pattern[a-z]+/i
|
|
92
|
+
wordlist = ~w(apple banana cherry)a
|
|
93
|
+
|
|
94
|
+
# --- Numbers ---
|
|
95
|
+
integer = 42
|
|
96
|
+
negative = -17
|
|
97
|
+
hex = 0xFF
|
|
98
|
+
octal = 0o77
|
|
99
|
+
binary = 0b1010
|
|
100
|
+
float_val = 3.14
|
|
101
|
+
scientific = 1.5e10
|
|
102
|
+
underscore = 1_000_000
|
|
103
|
+
|
|
104
|
+
# --- Booleans & Nil ---
|
|
105
|
+
yes = true
|
|
106
|
+
no = false
|
|
107
|
+
nothing = nil
|
|
108
|
+
|
|
109
|
+
# --- Collections ---
|
|
110
|
+
list = [1, 2, 3, 4, 5]
|
|
111
|
+
tuple = {1, "hello", true}
|
|
112
|
+
map = %{name: "Alice", age: 30}
|
|
113
|
+
keyword = [name: "Alice", age: 30]
|
|
114
|
+
mapset = MapSet.new([1, 2, 3])
|
|
115
|
+
range = 1..10
|
|
116
|
+
struct = %Point{x: 1.0, y: 2.0}
|
|
117
|
+
|
|
118
|
+
# --- Operators ---
|
|
119
|
+
sum = 1 + 2
|
|
120
|
+
diff = 5 - 3
|
|
121
|
+
prod = 4 * 2
|
|
122
|
+
quot = 10 / 3
|
|
123
|
+
int_div = div(10, 3)
|
|
124
|
+
modulo = rem(10, 3)
|
|
125
|
+
concat = "Hello" <> " " <> "World"
|
|
126
|
+
list_concat = [1, 2] ++ [3, 4]
|
|
127
|
+
list_diff = [1, 2, 3] -- [2]
|
|
128
|
+
logic = true and false
|
|
129
|
+
logic2 = true or false
|
|
130
|
+
logic3 = not false
|
|
131
|
+
strict_and = true && false
|
|
132
|
+
strict_or = true || false
|
|
133
|
+
strict_not = !nil
|
|
134
|
+
pipe = "hello" |> String.upcase() |> String.reverse()
|
|
135
|
+
equality = 1 == 1.0
|
|
136
|
+
strict_eq = 1 === 1
|
|
137
|
+
|
|
138
|
+
# --- Pattern matching ---
|
|
139
|
+
{a, b, c} = {1, 2, 3}
|
|
140
|
+
[head | tail] = [1, 2, 3, 4]
|
|
141
|
+
%{name: name} = %{name: "Alice", age: 30}
|
|
142
|
+
^integer = 42 # Pin operator
|
|
143
|
+
|
|
144
|
+
# --- Control flow ---
|
|
145
|
+
# If/else
|
|
146
|
+
if integer > 0 do
|
|
147
|
+
IO.puts("positive")
|
|
148
|
+
else
|
|
149
|
+
IO.puts("non-positive")
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Unless
|
|
153
|
+
unless integer == 0 do
|
|
154
|
+
IO.puts("not zero")
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Case
|
|
158
|
+
case {1, 2, 3} do
|
|
159
|
+
{1, x, 3} when x > 0 ->
|
|
160
|
+
IO.puts("matched: #{x}")
|
|
161
|
+
_ ->
|
|
162
|
+
IO.puts("no match")
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Cond
|
|
166
|
+
cond do
|
|
167
|
+
integer > 100 -> IO.puts("big")
|
|
168
|
+
integer > 0 -> IO.puts("positive")
|
|
169
|
+
true -> IO.puts("other")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# With
|
|
173
|
+
with {:ok, result} <- safe_divide(10, 3),
|
|
174
|
+
formatted <- Float.round(result, 2) do
|
|
175
|
+
IO.puts("Result: #{formatted}")
|
|
176
|
+
else
|
|
177
|
+
{:error, reason} -> IO.puts("Error: #{reason}")
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# --- Loops (recursion + Enum) ---
|
|
181
|
+
Enum.each(1..5, fn i ->
|
|
182
|
+
IO.puts(i)
|
|
183
|
+
end)
|
|
184
|
+
|
|
185
|
+
doubled = Enum.map(list, &(&1 * 2))
|
|
186
|
+
evens = Enum.filter(list, &(rem(&1, 2) == 0))
|
|
187
|
+
total = Enum.reduce(list, 0, &(&1 + &2))
|
|
188
|
+
|
|
189
|
+
# Comprehension
|
|
190
|
+
for x <- 1..10, rem(x, 2) == 0, do: x * x
|
|
191
|
+
for {k, v} <- map, into: %{}, do: {k, "#{v}!"}
|
|
192
|
+
|
|
193
|
+
# --- Anonymous functions ---
|
|
194
|
+
square = fn x -> x * x end
|
|
195
|
+
result = square.(5)
|
|
196
|
+
|
|
197
|
+
multi = fn
|
|
198
|
+
0 -> "zero"
|
|
199
|
+
n when n > 0 -> "positive"
|
|
200
|
+
_ -> "negative"
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Capture operator
|
|
204
|
+
double = &(&1 * 2)
|
|
205
|
+
add_fn = &add/2
|
|
206
|
+
|
|
207
|
+
# --- Try / Rescue / Catch ---
|
|
208
|
+
try do
|
|
209
|
+
raise "Something went wrong"
|
|
210
|
+
rescue
|
|
211
|
+
e in RuntimeError ->
|
|
212
|
+
IO.puts("Caught: #{e.message}")
|
|
213
|
+
catch
|
|
214
|
+
:throw, value ->
|
|
215
|
+
IO.puts("Caught throw: #{value}")
|
|
216
|
+
after
|
|
217
|
+
IO.puts("cleanup")
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# --- Processes ---
|
|
221
|
+
pid = spawn(fn -> IO.puts("spawned") end)
|
|
222
|
+
send(pid, {:hello, "world"})
|
|
223
|
+
|
|
224
|
+
receive do
|
|
225
|
+
{:hello, msg} ->
|
|
226
|
+
IO.puts("Got: #{msg}")
|
|
227
|
+
after
|
|
228
|
+
1000 ->
|
|
229
|
+
IO.puts("timeout")
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# --- Structs ---
|
|
233
|
+
user = %User{name: "Alice", age: 30}
|
|
234
|
+
updated = %{user | age: 31}
|
|
235
|
+
IO.puts("#{user.name} is #{user.age}")
|
|
236
|
+
|
|
237
|
+
# --- Bitstrings ---
|
|
238
|
+
<<a::8, b::8, rest::binary>> = "Hello"
|
|
239
|
+
bits = <<1::1, 0::1, 1::1>>
|
|
240
|
+
|
|
241
|
+
# --- Protocols ---
|
|
242
|
+
# (defined separately)
|
|
243
|
+
|
|
244
|
+
:ok
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# --- Protocol ---
|
|
249
|
+
defprotocol Displayable do
|
|
250
|
+
@doc "Convert to display string"
|
|
251
|
+
def display(value)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
defimpl Displayable, for: Integer do
|
|
255
|
+
def display(value), do: "Integer: #{value}"
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
defimpl Displayable, for: BitString do
|
|
259
|
+
def display(value), do: "String: #{value}"
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# --- Macros ---
|
|
263
|
+
defmodule MyMacro do
|
|
264
|
+
defmacro unless(condition, do: block) do
|
|
265
|
+
quote do
|
|
266
|
+
if !unquote(condition) do
|
|
267
|
+
unquote(block)
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# --- Use / Import / Alias / Require ---
|
|
274
|
+
defmodule Consumer do
|
|
275
|
+
alias Sample.Point
|
|
276
|
+
alias Sample.User, as: U
|
|
277
|
+
import Enum, only: [map: 2, filter: 2]
|
|
278
|
+
require Logger
|
|
279
|
+
use GenServer
|
|
280
|
+
|
|
281
|
+
def init(state) do
|
|
282
|
+
{:ok, state}
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# --- GenServer example ---
|
|
287
|
+
defmodule Counter do
|
|
288
|
+
use GenServer
|
|
289
|
+
|
|
290
|
+
# Client API
|
|
291
|
+
def start_link(initial \\ 0) do
|
|
292
|
+
GenServer.start_link(__MODULE__, initial, name: __MODULE__)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def increment, do: GenServer.cast(__MODULE__, :increment)
|
|
296
|
+
def get_count, do: GenServer.call(__MODULE__, :get)
|
|
297
|
+
|
|
298
|
+
# Server callbacks
|
|
299
|
+
@impl true
|
|
300
|
+
def init(count), do: {:ok, count}
|
|
301
|
+
|
|
302
|
+
@impl true
|
|
303
|
+
def handle_cast(:increment, count), do: {:noreply, count + 1}
|
|
304
|
+
|
|
305
|
+
@impl true
|
|
306
|
+
def handle_call(:get, _from, count), do: {:reply, count, count}
|
|
307
|
+
end
|