mt-lang 0.2.10 → 0.2.12
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/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/parser/statements.rb +2 -1
- data/lib/milk_tea/lsp/server/hover.rb +118 -12
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 28dc7f8c8824f11189bdd3cf704d10eefa2e144d466b218b5b34b1693531fe94
|
|
4
|
+
data.tar.gz: 73dcea75aeb6fb9c460e6b574e0bb64dc118ca9cd0a028586bd526d7b00acb49
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c3286442bbca94bd51b9c7aa4166f2b854d9f6bd48da3f6860648f303c30c90e39f2ac531315a5f13a148f3591eab1a5a02dabfd935f6ea136dfe0018012db9d
|
|
7
|
+
data.tar.gz: 53cc3240a7b226d152f831775e508a1db5c030f533d4fb6a88084f6564fcffa86954614e86b37f2c0b7650ae5ef27486e9aea05a6eaffe14b2aa5b2be9be0c8a
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -87,6 +87,7 @@ module MilkTea
|
|
|
87
87
|
|
|
88
88
|
def parse_local_decl(kind)
|
|
89
89
|
line = previous.line
|
|
90
|
+
column = previous.column
|
|
90
91
|
name_token = nil
|
|
91
92
|
name = nil
|
|
92
93
|
var_type = nil
|
|
@@ -145,7 +146,7 @@ module MilkTea
|
|
|
145
146
|
consume_end_of_statement
|
|
146
147
|
end
|
|
147
148
|
|
|
148
|
-
AST::LocalDecl.new(kind:, name:, type: var_type, value:, else_binding:, else_body:, line:, column: name_token&.column ||
|
|
149
|
+
AST::LocalDecl.new(kind:, name:, type: var_type, value:, else_binding:, else_body:, line:, column: name_token&.column || column, destructure_bindings:, destructure_type_name:)
|
|
149
150
|
rescue ParseError => e
|
|
150
151
|
raise unless @recovery_errors && name
|
|
151
152
|
|
|
@@ -224,6 +224,76 @@ module MilkTea
|
|
|
224
224
|
},
|
|
225
225
|
}.freeze
|
|
226
226
|
|
|
227
|
+
BUILTIN_TYPE_DOCS = {
|
|
228
|
+
'bool' => '1-byte boolean: `true` or `false`.',
|
|
229
|
+
'byte' => '8-bit signed integer. Range: -128 to 127.',
|
|
230
|
+
'ubyte' => '8-bit unsigned integer. Range: 0 to 255. Also used for `char` literals like `\'A\'`.',
|
|
231
|
+
'char' => '8-bit character type (alias for `ubyte`).',
|
|
232
|
+
'short' => '16-bit signed integer. Range: -32,768 to 32,767.',
|
|
233
|
+
'ushort' => '16-bit unsigned integer. Range: 0 to 65,535.',
|
|
234
|
+
'int' => '32-bit signed integer. Range: -2,147,483,648 to 2,147,483,647. Default enum backing type.',
|
|
235
|
+
'uint' => '32-bit unsigned integer. Range: 0 to 4,294,967,295.',
|
|
236
|
+
'long' => '64-bit signed integer.',
|
|
237
|
+
'ulong' => '64-bit unsigned integer.',
|
|
238
|
+
'ptr_int' => 'Pointer-sized signed integer. Width matches the target platform pointer size.',
|
|
239
|
+
'ptr_uint' => 'Pointer-sized unsigned integer. Return type for `size_of`, `align_of`, `offset_of`.',
|
|
240
|
+
'float' => '32-bit IEEE 754 single-precision float.',
|
|
241
|
+
'double' => '64-bit IEEE 754 double-precision float.',
|
|
242
|
+
'void' => 'Empty type for functions with no return value. Not a storable type.',
|
|
243
|
+
'str' => 'Non-owning UTF-8 string view (pointer + length). Not null-terminated.',
|
|
244
|
+
'cstr' => 'Null-terminated C string. Used at FFI boundaries.',
|
|
245
|
+
'vec2' => '2-component float vector. Fields: `.x`, `.y`. Supports component-wise arithmetic.',
|
|
246
|
+
'vec3' => '3-component float vector. Fields: `.x`, `.y`, `.z`. Supports component-wise arithmetic and `dot`/`cross`/`length` via `std.linear_algebra`.',
|
|
247
|
+
'vec4' => '4-component float vector. Fields: `.x`, `.y`, `.z`, `.w`. Supports component-wise arithmetic.',
|
|
248
|
+
'ivec2' => '2-component integer vector. Fields: `.x`, `.y`. Supports component-wise arithmetic.',
|
|
249
|
+
'ivec3' => '3-component integer vector. Fields: `.x`, `.y`, `.z`. Supports component-wise arithmetic.',
|
|
250
|
+
'ivec4' => '4-component integer vector. Fields: `.x`, `.y`, `.z`, `.w`. Supports component-wise arithmetic.',
|
|
251
|
+
'mat3' => '3×3 column-major float matrix. Columns: `.col0`–`.col2` (each `vec3`). Supports `identity`, `transpose` via `std.linear_algebra`.',
|
|
252
|
+
'mat4' => '4×4 column-major float matrix. Columns: `.col0`–`.col3` (each `vec4`). Supports `identity`, `transpose` via `std.linear_algebra`.',
|
|
253
|
+
'quat' => 'Quaternion. Fields: `.x`, `.y`, `.z`, `.w`. Layout-compatible with `vec4`. Supports `identity`, `conjugate` via `std.linear_algebra`.',
|
|
254
|
+
'ptr' => 'Generic pointer type: `ptr[T]`. Raw mutable pointer. Requires `unsafe` for indexing, dereference, and arithmetic.',
|
|
255
|
+
'const_ptr' => 'Read-only pointer type: `const_ptr[T]`. Immutable pointer, does not require `unsafe` for dereference.',
|
|
256
|
+
'own' => 'Owning heap pointer: `own[T]`. Auto-dereferences like `ref`. Storable, returnable, and nullable. Allocated via `heap.must_alloc[T](count)`.',
|
|
257
|
+
'ref' => 'Non-null borrow reference: `ref[T]`. Auto-dereferences for member access and method calls. Cannot be stored in module variables or constants.',
|
|
258
|
+
'span' => 'Borrowed pointer-plus-length view: `span[T]`. Constructed via `span[T](data = ..., len = ...)`. Arrays coerce implicitly.',
|
|
259
|
+
'array' => 'Fixed-length array: `array[T, N]`. Constructed via `array[T, N](elements...)`. Omitted trailing elements default to zero.',
|
|
260
|
+
'str_buffer' => 'Fixed-capacity mutable UTF-8 text buffer: `str_buffer[N]`. Methods: `assign`, `append`, `assign_format`, `append_format`, `clear`, `as_str`, `as_cstr`.',
|
|
261
|
+
'atomic' => 'Atomic value for lock-free concurrent access: `atomic[T]`. `T` must be a primitive integer or `bool`. Methods: `load`, `store`, `add`, `sub`, `exchange`. Uses C11 `_Atomic`.',
|
|
262
|
+
'Task' => 'Async task future: `Task[T]`. Returned by `async function`. Use `await` to unwrap, or `aio.wait`/`aio.run` to drive.',
|
|
263
|
+
'Option' => 'Built-in optional type: `Option[T]`. Arms: `some(value: T)` and `none`. Use `let ... else:` or `?` for safe unwrapping.',
|
|
264
|
+
'Result' => 'Built-in result type: `Result[T, E]`. Arms: `success(value: T)` and `failure(error: E)`. Use `let ... else:` or `?` for error propagation.',
|
|
265
|
+
'SoA' => 'Struct-of-Arrays: `SoA[T, N]`. Each struct field becomes a separate array of length `N`. Access `soa[i].field` reads from column `field` at row `i`.',
|
|
266
|
+
'struct_handle' => 'Compile-time handle for a struct type. Obtained via reflection builtins like `fields_of`.',
|
|
267
|
+
'field_handle' => 'Compile-time handle for a struct field. Exposes `.name` and `.type`. Obtained via `field_of` and `fields_of`.',
|
|
268
|
+
'callable_handle' => 'Compile-time handle for a callable declaration. Obtained via `callable_of`. Used with `has_attribute`, `attribute_of`.',
|
|
269
|
+
'attribute_handle' => 'Compile-time handle for an applied attribute. Obtained via `attribute_of` and `attributes_of`. Use `attribute_arg[T]` to read arguments.',
|
|
270
|
+
'member_handle' => 'Compile-time handle for an enum or flags member. Exposes `.name` and `.value`. Obtained via `members_of`.',
|
|
271
|
+
'EventError' => 'Built-in enum returned when event listener capacity is exhausted. Single member: `full`.',
|
|
272
|
+
'Subscription' => 'Opaque handle returned by `event.subscribe`. Pass to `event.unsubscribe` to remove a listener.',
|
|
273
|
+
}.freeze
|
|
274
|
+
|
|
275
|
+
BUILTIN_TYPE_METHOD_SIGNATURES = {
|
|
276
|
+
'atomic' => {
|
|
277
|
+
'load' => 'function load() -> T',
|
|
278
|
+
'store' => 'static function store(value: T) -> void',
|
|
279
|
+
'add' => 'static function add(value: T) -> T',
|
|
280
|
+
'sub' => 'static function sub(value: T) -> T',
|
|
281
|
+
'exchange' => 'static function exchange(value: T) -> T',
|
|
282
|
+
'compare_exchange' => 'static function compare_exchange(expected: T, desired: T) -> bool',
|
|
283
|
+
},
|
|
284
|
+
'str_buffer' => {
|
|
285
|
+
'assign' => 'static function assign(value: str) -> void',
|
|
286
|
+
'append' => 'static function append(value: str) -> void',
|
|
287
|
+
'assign_format' => 'static function assign_format(fmt: str) -> void',
|
|
288
|
+
'append_format' => 'static function append_format(fmt: str) -> void',
|
|
289
|
+
'clear' => 'static function clear() -> void',
|
|
290
|
+
'len' => 'static function len() -> ptr_uint',
|
|
291
|
+
'capacity' => 'static function capacity() -> ptr_uint',
|
|
292
|
+
'as_str' => 'static function as_str() -> str',
|
|
293
|
+
'as_cstr' => 'static function as_cstr() -> cstr',
|
|
294
|
+
},
|
|
295
|
+
}.freeze
|
|
296
|
+
|
|
227
297
|
def handle_hover(params)
|
|
228
298
|
stages = new_perf_stages
|
|
229
299
|
total_start = stages ? monotonic_time : nil
|
|
@@ -238,7 +308,16 @@ module MilkTea
|
|
|
238
308
|
token_kind = token&.type || :none
|
|
239
309
|
unless token&.type == :identifier
|
|
240
310
|
info = builtin_keyword_hover_info(token)
|
|
241
|
-
|
|
311
|
+
if info
|
|
312
|
+
result_state = 'hit'
|
|
313
|
+
return {
|
|
314
|
+
contents: {
|
|
315
|
+
kind: 'markdown',
|
|
316
|
+
value: render_hover_markdown(info)
|
|
317
|
+
},
|
|
318
|
+
range: token_to_range(token)
|
|
319
|
+
}
|
|
320
|
+
end
|
|
242
321
|
|
|
243
322
|
result_state = 'not-identifier'
|
|
244
323
|
return nil
|
|
@@ -369,6 +448,7 @@ module MilkTea
|
|
|
369
448
|
elsif facts.types.key?(name)
|
|
370
449
|
type = facts.types[name]
|
|
371
450
|
signature = type_hover_signature(name, type)
|
|
451
|
+
docs ||= BUILTIN_TYPE_DOCS[name]
|
|
372
452
|
elsif (binding = facts.values[name])
|
|
373
453
|
signature = value_hover_signature(binding)
|
|
374
454
|
elsif (import_binding = facts.imports[name])
|
|
@@ -386,6 +466,7 @@ module MilkTea
|
|
|
386
466
|
signature = value_hover_signature(val)
|
|
387
467
|
elsif module_binding.types.key?(name)
|
|
388
468
|
signature = "type #{name}"
|
|
469
|
+
docs ||= BUILTIN_TYPE_DOCS[name]
|
|
389
470
|
elsif (binding = module_binding.interfaces[name])
|
|
390
471
|
signature = interface_signature(binding)
|
|
391
472
|
source_location = module_member_definition_location(uri, module_binding.name, name)
|
|
@@ -406,6 +487,27 @@ module MilkTea
|
|
|
406
487
|
end
|
|
407
488
|
end
|
|
408
489
|
|
|
490
|
+
unless signature
|
|
491
|
+
if dot_receiver
|
|
492
|
+
receiver_name = dot_receiver
|
|
493
|
+
receiver_binding = resolve_local_hover_binding(facts, receiver_name, lsp_line + 1, lsp_char + 1) ||
|
|
494
|
+
facts.values[receiver_name] ||
|
|
495
|
+
facts.functions[receiver_name]
|
|
496
|
+
if receiver_binding && receiver_binding.type
|
|
497
|
+
receiver_type = receiver_binding.respond_to?(:storage_type) ? receiver_binding.storage_type : receiver_binding.type
|
|
498
|
+
methods = methods_for_receiver_type(facts, receiver_type)
|
|
499
|
+
if (method_binding = methods[name])
|
|
500
|
+
signature = method_signature(method_binding)
|
|
501
|
+
else
|
|
502
|
+
type_base = receiver_type.to_s[/^([a-z_]+)/, 1]
|
|
503
|
+
if type_base && (method_sigs = BUILTIN_TYPE_METHOD_SIGNATURES[type_base])
|
|
504
|
+
signature = method_sigs[name]
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
409
511
|
unless signature
|
|
410
512
|
if token_index && (builtin_info = builtin_hover_info(name, tokens, token_index))
|
|
411
513
|
signature = builtin_info[:signature]
|
|
@@ -414,14 +516,16 @@ module MilkTea
|
|
|
414
516
|
end
|
|
415
517
|
|
|
416
518
|
unless signature
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
519
|
+
unless token_index && tokens && tokens[previous_non_trivia_token_index(tokens, token_index)]&.type == :dot
|
|
520
|
+
local_def = @workspace.find_definition_token_global(
|
|
521
|
+
name,
|
|
522
|
+
preferred_uri: uri,
|
|
523
|
+
before_line: lsp_line + 1,
|
|
524
|
+
before_char: lsp_char + 1,
|
|
525
|
+
)
|
|
526
|
+
if local_def
|
|
527
|
+
signature = resolve_lexical_local_hover_signature(local_def[:uri], name, local_def[:token])
|
|
528
|
+
end
|
|
425
529
|
end
|
|
426
530
|
end
|
|
427
531
|
end
|
|
@@ -1335,7 +1439,7 @@ module MilkTea
|
|
|
1335
1439
|
end
|
|
1336
1440
|
|
|
1337
1441
|
def builtin_type_constructor_hover_info(name, tokens, token_index)
|
|
1338
|
-
return nil unless %w[array span Option Result SoA].include?(name)
|
|
1442
|
+
return nil unless %w[array span Option Result SoA str_buffer].include?(name)
|
|
1339
1443
|
|
|
1340
1444
|
lbracket_index = next_non_trivia_token_index(tokens, token_index + 1)
|
|
1341
1445
|
return nil unless lbracket_index && tokens[lbracket_index].type == :lbracket
|
|
@@ -1387,8 +1491,10 @@ module MilkTea
|
|
|
1387
1491
|
when 'Option'
|
|
1388
1492
|
'`Option[T]` is the built-in optional value type with `some(value = ...)` and `none` arms.'
|
|
1389
1493
|
when 'Result'
|
|
1390
|
-
|
|
1391
|
-
|
|
1494
|
+
'`Result[T, E]` is the built-in success/failure type with `success(value = ...)` and `failure(error = ...)` arms.'
|
|
1495
|
+
when 'str_buffer'
|
|
1496
|
+
'`str_buffer[N]` is a fixed-capacity mutable UTF-8 text buffer. Methods: `assign`, `append`, `assign_format`, `append_format`, `clear`, `len`, `as_str`, `as_cstr`.'
|
|
1497
|
+
end
|
|
1392
1498
|
|
|
1393
1499
|
{
|
|
1394
1500
|
signature: "builtin type #{specialization}",
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mt-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -583,7 +583,7 @@ metadata:
|
|
|
583
583
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
584
584
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
585
585
|
post_install_message: |
|
|
586
|
-
Milk Tea 0.2.
|
|
586
|
+
Milk Tea 0.2.12 installed!
|
|
587
587
|
|
|
588
588
|
System requirements:
|
|
589
589
|
- A C compiler (gcc or clang) must be available on PATH
|