jade-lang 0.4.0 → 0.6.0
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/AGENTS.md +164 -0
- data/CHANGELOG.md +180 -1
- data/README.md +5 -1
- data/docs/interop.md +208 -0
- data/docs/json.md +163 -0
- data/docs/lsp.md +105 -0
- data/docs/stdlib.md +69 -0
- data/docs/syntax.md +458 -0
- data/docs/testing.md +70 -0
- data/lib/jade/api.rb +244 -0
- data/lib/jade/cli/check.rb +97 -0
- data/lib/jade/cli/q.rb +47 -1
- data/lib/jade/cli.rb +4 -2
- data/lib/jade/codegen/boundary/cache.rb +1 -2
- data/lib/jade/codegen/boundary/specialized/list.rb +9 -4
- data/lib/jade/codegen/boundary/specialized/maybe.rb +15 -3
- data/lib/jade/codegen/boundary/specialized/record.rb +7 -3
- data/lib/jade/codegen/boundary/specialized.rb +7 -3
- data/lib/jade/codegen/emitter.rb +11 -2
- data/lib/jade/codegen/function_declaration.rb +7 -6
- data/lib/jade/codegen/helpers.rb +6 -0
- data/lib/jade/codegen/inlines.rb +5 -0
- data/lib/jade/decode.rb +332 -212
- data/lib/jade/frontend/fixity_fixer.rb +3 -2
- data/lib/jade/frontend/semantic_analysis/error/variable_not_found.rb +9 -2
- data/lib/jade/frontend/semantic_analysis/member_access.rb +11 -1
- data/lib/jade/frontend/type_checking/constraints/deriving/decodable.rb +10 -15
- data/lib/jade/frontend/type_checking/constraints/deriving/encodable.rb +7 -16
- data/lib/jade/interop/boundary.rb +12 -4
- data/lib/jade/interop/error.rb +25 -5
- data/lib/jade/lsp/converters.rb +2 -15
- data/lib/jade/lsp/snippets.rb +21 -3
- data/lib/jade/module_loader/module_name.rb +46 -0
- data/lib/jade/module_loader.rb +5 -0
- data/lib/jade/signature.rb +47 -0
- data/lib/jade/stdlib/calendar.rb +20 -19
- data/lib/jade/stdlib/clock.rb +7 -13
- data/lib/jade/stdlib/decimal.rb +3 -16
- data/lib/jade/stdlib/decode.rb +35 -12
- data/lib/jade/stdlib/encode.rb +9 -0
- data/lib/jade/stdlib/intrinsics.rb +9 -1
- data/lib/jade/stdlib/result.rb +1 -1
- data/lib/jade/stdlib/text.rb +131 -0
- data/lib/jade/task.rb +2 -3
- data/lib/jade/version.rb +1 -1
- metadata +14 -2
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Stdlib
|
|
3
|
+
# Text representations of stdlib types, read in Ruby. Lives here rather
|
|
4
|
+
# than in Decimal / Clock / Calendar: those import Decode, so the
|
|
5
|
+
# instance cannot be registered the other way round. The types are
|
|
6
|
+
# compiled Jade, so constants resolve on first use.
|
|
7
|
+
#
|
|
8
|
+
# Accepts exactly what the Jade parsers did, down to `String.to_int`
|
|
9
|
+
# being `Integer(s, 10)` — whitespace and underscores included.
|
|
10
|
+
module Text
|
|
11
|
+
extend self
|
|
12
|
+
|
|
13
|
+
EPOCH_RATA_DIE = 719163
|
|
14
|
+
DAY_MS = 86_400_000
|
|
15
|
+
|
|
16
|
+
def to_decimal(s)
|
|
17
|
+
coefficient, exponent = s.split('e', 2)
|
|
18
|
+
return nil unless exponent
|
|
19
|
+
|
|
20
|
+
m = int(coefficient)
|
|
21
|
+
e = int(exponent)
|
|
22
|
+
|
|
23
|
+
m && e ? Jade::Decimal::Decimal[m, e] : nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# No timezone offsets: `Clock.from_iso` never took them either.
|
|
27
|
+
def to_instant(s)
|
|
28
|
+
date_part, time_part = split_dt(s)
|
|
29
|
+
return nil unless date_part
|
|
30
|
+
|
|
31
|
+
d = to_date(date_part)
|
|
32
|
+
time = split_time(time_part)
|
|
33
|
+
return nil unless d && time
|
|
34
|
+
|
|
35
|
+
hour, minute, second, sub_ms = time
|
|
36
|
+
days = Jade::Calendar::Internal.to_rata_die(d) - EPOCH_RATA_DIE
|
|
37
|
+
|
|
38
|
+
Jade::Clock::Instant[
|
|
39
|
+
days * DAY_MS +
|
|
40
|
+
hour * 3_600_000 + minute * 60_000 + second * 1_000 + sub_ms
|
|
41
|
+
]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_date(s)
|
|
45
|
+
parts = s.split('-')
|
|
46
|
+
return nil unless parts.length == 3
|
|
47
|
+
|
|
48
|
+
year, month, day = parts.map { int(it) }
|
|
49
|
+
return nil unless year && month && day
|
|
50
|
+
|
|
51
|
+
# Answers Jan outside 1..12 and never validates the day — calling
|
|
52
|
+
# it keeps that. Don't cache the Months: a second compile
|
|
53
|
+
# redefines the class.
|
|
54
|
+
Jade::Calendar::Date[
|
|
55
|
+
year,
|
|
56
|
+
Jade::Calendar::Internal.month_from_int(month),
|
|
57
|
+
day,
|
|
58
|
+
]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Seconds precision, always UTC. `rjust` matches `pad_to`, which
|
|
62
|
+
# left-pads without truncating: a negative year renders "00-5".
|
|
63
|
+
def from_instant(instant)
|
|
64
|
+
ms = instant._1
|
|
65
|
+
day_ms = ms % DAY_MS
|
|
66
|
+
d = Jade::Calendar::Internal.from_rata_die(ms / DAY_MS + EPOCH_RATA_DIE)
|
|
67
|
+
|
|
68
|
+
[
|
|
69
|
+
pad(d.year, 4),
|
|
70
|
+
'-', pad(Jade::Calendar::Internal.month_to_int(d.month), 2),
|
|
71
|
+
'-', pad(d.day, 2),
|
|
72
|
+
'T', pad(day_ms / 3_600_000, 2),
|
|
73
|
+
':', pad(day_ms % 3_600_000 / 60_000, 2),
|
|
74
|
+
':', pad(day_ms % 60_000 / 1_000, 2),
|
|
75
|
+
'Z',
|
|
76
|
+
].join
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def int(s) = Integer(s, 10, exception: false)
|
|
82
|
+
|
|
83
|
+
def pad(n, width) = n.to_s.rjust(width, '0')
|
|
84
|
+
|
|
85
|
+
def split_dt(s)
|
|
86
|
+
parts = s.split('T')
|
|
87
|
+
parts = s.split(' ') unless parts.length == 2
|
|
88
|
+
|
|
89
|
+
parts.length == 2 ? parts : nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def split_time(s)
|
|
93
|
+
parts = strip_z(s).split(':')
|
|
94
|
+
return nil unless parts.length == 3
|
|
95
|
+
|
|
96
|
+
hour = int(parts[0])
|
|
97
|
+
minute = int(parts[1])
|
|
98
|
+
second, sub_ms = seconds(parts[2])
|
|
99
|
+
|
|
100
|
+
hour && minute && second && sub_ms ? [hour, minute, second, sub_ms] : nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# A stray second "Z" falls through unstripped, as it did before.
|
|
104
|
+
def strip_z(s)
|
|
105
|
+
parts = s.split('Z')
|
|
106
|
+
|
|
107
|
+
parts.length == 1 || parts.length == 2 ? parts[0] : s
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def seconds(s)
|
|
111
|
+
parts = s.split('.')
|
|
112
|
+
|
|
113
|
+
case parts.length
|
|
114
|
+
when 1 then [int(parts[0]), 0]
|
|
115
|
+
when 2 then [int(parts[0]), millis(int(parts[1]), parts[1].length)]
|
|
116
|
+
else [nil, nil]
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def millis(n, digits)
|
|
121
|
+
return nil unless n
|
|
122
|
+
|
|
123
|
+
case digits <=> 3
|
|
124
|
+
when 0 then n
|
|
125
|
+
when -1 then n * 10.pow(3 - digits)
|
|
126
|
+
else n / 10.pow(digits - 3)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
data/lib/jade/task.rb
CHANGED
|
@@ -92,9 +92,8 @@ module Jade
|
|
|
92
92
|
private
|
|
93
93
|
|
|
94
94
|
def decode(decoder, value)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
in Jade::Result::Err[e] then fail Jade::Interop::DecodeError.new(e, value)
|
|
95
|
+
Jade::Decode::Runner.run!(decoder, value) do |error|
|
|
96
|
+
fail Jade::Interop::DecodeError.new(error, value, source: :port_return)
|
|
98
97
|
end
|
|
99
98
|
end
|
|
100
99
|
end
|
data/lib/jade/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jade-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Agustin Cornu
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-08-
|
|
10
|
+
date: 2026-08-13 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: base64
|
|
@@ -35,17 +35,26 @@ executables:
|
|
|
35
35
|
extensions: []
|
|
36
36
|
extra_rdoc_files: []
|
|
37
37
|
files:
|
|
38
|
+
- AGENTS.md
|
|
38
39
|
- CHANGELOG.md
|
|
39
40
|
- LICENSE
|
|
40
41
|
- README.md
|
|
42
|
+
- docs/interop.md
|
|
43
|
+
- docs/json.md
|
|
44
|
+
- docs/lsp.md
|
|
45
|
+
- docs/stdlib.md
|
|
46
|
+
- docs/syntax.md
|
|
47
|
+
- docs/testing.md
|
|
41
48
|
- exe/jade
|
|
42
49
|
- lib/jade.rb
|
|
50
|
+
- lib/jade/api.rb
|
|
43
51
|
- lib/jade/ast.rb
|
|
44
52
|
- lib/jade/ast/node.rb
|
|
45
53
|
- lib/jade/ast/nodes.rb
|
|
46
54
|
- lib/jade/ast/pretty_printer.rb
|
|
47
55
|
- lib/jade/calendar/runtime.rb
|
|
48
56
|
- lib/jade/cli.rb
|
|
57
|
+
- lib/jade/cli/check.rb
|
|
49
58
|
- lib/jade/cli/fmt.rb
|
|
50
59
|
- lib/jade/cli/lsp.rb
|
|
51
60
|
- lib/jade/cli/q.rb
|
|
@@ -294,6 +303,7 @@ files:
|
|
|
294
303
|
- lib/jade/module_loader/cache.rb
|
|
295
304
|
- lib/jade/module_loader/dependency_graph.rb
|
|
296
305
|
- lib/jade/module_loader/dependency_resolver.rb
|
|
306
|
+
- lib/jade/module_loader/module_name.rb
|
|
297
307
|
- lib/jade/module_loader/normalize.rb
|
|
298
308
|
- lib/jade/module_loader/topological_sort.rb
|
|
299
309
|
- lib/jade/parsing.rb
|
|
@@ -306,6 +316,7 @@ files:
|
|
|
306
316
|
- lib/jade/registry.rb
|
|
307
317
|
- lib/jade/result.rb
|
|
308
318
|
- lib/jade/runtime.rb
|
|
319
|
+
- lib/jade/signature.rb
|
|
309
320
|
- lib/jade/source.rb
|
|
310
321
|
- lib/jade/stdlib.rb
|
|
311
322
|
- lib/jade/stdlib/basics.rb
|
|
@@ -328,6 +339,7 @@ files:
|
|
|
328
339
|
- lib/jade/stdlib/show.rb
|
|
329
340
|
- lib/jade/stdlib/string.rb
|
|
330
341
|
- lib/jade/stdlib/task.rb
|
|
342
|
+
- lib/jade/stdlib/text.rb
|
|
331
343
|
- lib/jade/stdlib/tuple.rb
|
|
332
344
|
- lib/jade/symbol.rb
|
|
333
345
|
- lib/jade/symbol/anonymous_record.rb
|