mt-lang 0.3.27 → 0.3.30
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/README.md +28 -3
- data/docs/index.html +2 -2
- data/docs/language-design.md +2 -2
- data/docs/language-manual.md +38 -2
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/c_backend/feature_detection.rb +8 -0
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +21 -0
- data/lib/milk_tea/core/c_backend.rb +4 -0
- data/lib/milk_tea/core/lowering/expressions.rb +4 -0
- data/lib/milk_tea/core/parser/declarations.rb +40 -5
- data/lib/milk_tea/core/parser.rb +12 -2
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +2 -2
- metadata +2 -5
- data/docs/self-host-contract.md +0 -1091
- data/docs/self-host-plan.md +0 -768
- data/docs/self-host-progress.md +0 -130
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d6d13cde9fca875b324ff3e0cb3b892c371e2445ac5e061d138bd0dc8b284b88
|
|
4
|
+
data.tar.gz: 2a91eedc02120e0d042bc6bafbfc783a4eefb5bbc44c34940e1ee9be6917405e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 478dc59b852c703b5cf63ce3cd77a92d6de305424c96cfa7dbeda97ed1882f2d8c52f5770893dc99a3077cb1599cbf0602c6e54b773f219ce859b8b9275c7258
|
|
7
|
+
data.tar.gz: d221d15fe3c3192ee0b10b61101f5234e8b92830f878051c6e2641aca334b7d165c9668bf410a727b4964f02d45805322044470a9e406b971ab7508650d60a00
|
data/README.md
CHANGED
|
@@ -94,7 +94,7 @@ Supported literals:
|
|
|
94
94
|
- floats: `3.14`, `1.2e-3`, `1.0f` (float suffix), `1.0d` (double suffix)
|
|
95
95
|
- character: `'a'`, `'\n'`, `'\t'`, `'\\'`, `'\''`, `'\0'`, `'\x41'`. Type is `ubyte`. Escape sequences: `\n`, `\r`, `\t`, `\\`, `\'`, `\"`, `\0` (null byte), `\xNN` (hex byte).
|
|
96
96
|
- booleans: `true`, `false`
|
|
97
|
-
- string: `"hello"` -> `str`
|
|
97
|
+
- string: `"hello"` -> `str`. The `+` operator concatenates `str` values: `"hello" + " " + "world"` produces `"hello world"`. For loops or repeated concatenation, prefer `string.String`.
|
|
98
98
|
- cstring: `c"hello"` -> `cstr`
|
|
99
99
|
- heredoc string: `<<-TAG ... TAG`
|
|
100
100
|
- heredoc cstring: `c<<-TAG ... TAG`
|
|
@@ -106,7 +106,7 @@ Common punctuation and operators:
|
|
|
106
106
|
- delimiters: `(` `)` `[` `]`
|
|
107
107
|
- access and separators: `:` `,` `.`
|
|
108
108
|
- type markers: `->` `?`
|
|
109
|
-
- arithmetic: `+ - * / %`
|
|
109
|
+
- arithmetic: `+ - * / %` (additionally, `+` on `str` concatenates)
|
|
110
110
|
- bitwise: `~ & | ^ << >>`
|
|
111
111
|
- comparison: `== != < <= > >=`
|
|
112
112
|
- assignment: `= += -= *= /= %= &= |= ^= <<= >>=`
|
|
@@ -249,6 +249,10 @@ struct Vec2:
|
|
|
249
249
|
x: float
|
|
250
250
|
y: float
|
|
251
251
|
|
|
252
|
+
# Methods may also be defined directly inside the struct body:
|
|
253
|
+
function length_sq() -> float:
|
|
254
|
+
return this.x * this.x + this.y * this.y
|
|
255
|
+
|
|
252
256
|
@[packed]
|
|
253
257
|
struct Header:
|
|
254
258
|
tag: ubyte
|
|
@@ -310,6 +314,7 @@ variant Token:
|
|
|
310
314
|
Rules:
|
|
311
315
|
|
|
312
316
|
- `struct` and `opaque` may declare nominal interface conformance with `implements`.
|
|
317
|
+
- `struct` bodies may contain `function`, `editable function`, and `static function` declarations directly — they desugar to `extending` blocks targeting the enclosing struct. This is pure syntactic sugar; the compiler emits identical code as a separate `extending` block.
|
|
313
318
|
- `attribute[target, ...]` declares reusable declaration attributes for `struct`, `field`, `callable`, `const`, `event`, `enum`, `flags`, `union`, and `variant` targets.
|
|
314
319
|
- Attributes are applied with one or more leading `@[name(...)]` blocks. Built-in `packed`, `align(bytes)`, and `deprecated(message)` are predefined attributes.
|
|
315
320
|
- `variant` arms may carry named payload fields.
|
|
@@ -358,11 +363,31 @@ Method kinds:
|
|
|
358
363
|
- `editable function` -> editable receiver
|
|
359
364
|
- `static function` -> no receiver
|
|
360
365
|
|
|
366
|
+
Methods may appear inside a struct body (desugared to an `extending` block) or in a separate
|
|
367
|
+
`extending` declaration:
|
|
368
|
+
|
|
369
|
+
```mt
|
|
370
|
+
struct Counter:
|
|
371
|
+
value: int
|
|
372
|
+
|
|
373
|
+
function read() -> int:
|
|
374
|
+
return this.value
|
|
375
|
+
|
|
376
|
+
editable function bump() -> void:
|
|
377
|
+
this.value += 1
|
|
378
|
+
|
|
379
|
+
static function zero() -> Counter:
|
|
380
|
+
return Counter(value = 0)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Both inline and `extending` forms lower to identical C code.
|
|
384
|
+
|
|
361
385
|
Method notes:
|
|
362
386
|
|
|
363
387
|
- Async methods are supported.
|
|
364
388
|
- Generic methods are supported.
|
|
365
389
|
- There is no constructor keyword. Names like `init` and `default` are ordinary static methods.
|
|
390
|
+
- Methods may be defined inside struct bodies directly (as syntactic sugar for `extending`) or in separate `extending` blocks. Both forms lower to the same C code; the inline form is preferred when the struct and its core methods appear in the same file.
|
|
366
391
|
|
|
367
392
|
## 7. Functions, Externals, And Foreign Functions
|
|
368
393
|
|
|
@@ -912,7 +937,7 @@ See module source for full method surface. Iterator forms:
|
|
|
912
937
|
|
|
913
938
|
Text categories:
|
|
914
939
|
|
|
915
|
-
- `str` -> string view
|
|
940
|
+
- `str` -> string view. The `+` operator concatenates two `str` values, allocating a new heap-backed string. For loops or repeated concatenation, prefer `string.String` for amortized performance.
|
|
916
941
|
- `cstr` -> C ABI string
|
|
917
942
|
- `str_buffer[N]` -> fixed-capacity mutable UTF-8 text buffer
|
|
918
943
|
|
data/docs/index.html
CHANGED
|
@@ -961,7 +961,7 @@ let total = (
|
|
|
961
961
|
<tr><td>Delimiters</td><td><code>( ) [ ]</code></td></tr>
|
|
962
962
|
<tr><td>Separators / Access</td><td><code>: , .</code></td></tr>
|
|
963
963
|
<tr><td>Type markers</td><td><code>-></code> <code>?</code></td></tr>
|
|
964
|
-
<tr><td>Arithmetic</td><td><code>+ - * / %</code
|
|
964
|
+
<tr><td>Arithmetic</td><td><code>+ - * / %</code> (the <code>+</code> operator on <code>str</code> concatenates, allocating a new heap-backed string)</td></tr>
|
|
965
965
|
<tr><td>Bitwise</td><td><code>~ & | ^ << >></code></td></tr>
|
|
966
966
|
<tr><td>Comparison</td><td><code>== != < <= > >=</code></td></tr>
|
|
967
967
|
<tr><td>Assignment</td><td><code>= += -= *= /= %= &= |= ^= <<= >>=</code></td></tr>
|
|
@@ -1243,7 +1243,7 @@ let d: dyn[Drawable] = adapt[Drawable](ref_of(entity))</code></pre>
|
|
|
1243
1243
|
<tr><td><code>ptr_int</code> <code>ptr_uint</code></td><td>Pointer-sized integers</td></tr>
|
|
1244
1244
|
<tr><td><code>float</code> <code>double</code></td><td>Floating-point</td></tr>
|
|
1245
1245
|
<tr><td><code>void</code></td><td>No value</td></tr>
|
|
1246
|
-
<tr><td><code>str</code></td><td>UTF-8 string view (borrowed)</td></tr>
|
|
1246
|
+
<tr><td><code>str</code></td><td>UTF-8 string view (borrowed). The <code>+</code> operator concatenates two <code>str</code> values, allocating a new heap-backed string.</td></tr>
|
|
1247
1247
|
<tr><td><code>cstr</code></td><td>NUL-terminated C string</td></tr>
|
|
1248
1248
|
<tr><td><code>vec2</code> <code>vec3</code> <code>vec4</code></td><td>Float vectors with <code>.x .y .z .w</code></td></tr>
|
|
1249
1249
|
<tr><td><code>ivec2</code> <code>ivec3</code> <code>ivec4</code></td><td>Integer vectors</td></tr>
|
data/docs/language-design.md
CHANGED
|
@@ -38,7 +38,7 @@ If code allocates, takes an address, dereferences a raw pointer, performs an FFI
|
|
|
38
38
|
|
|
39
39
|
FFI visibility belongs at the declaration site. Raw `external` files expose exact ABI types. Imported foreign declarations may project those raw types into ordinary Milk Tea types, but the projection rule, temporary-storage rule, and ownership rule must be declared there instead of repeated at every call site.
|
|
40
40
|
|
|
41
|
-
The same rule applies to text construction. Plain string literals and format string literals are borrowed `str` values. Any surface that builds owned text must say so explicitly, for example `std.fmt.format(f"...")` when ownership must escape.
|
|
41
|
+
The same rule applies to text construction. Plain string literals and format string literals are borrowed `str` values. The `+` operator on `str` allocates a new heap-backed `str` — the one everyday convenience that does allocate. For loops or amortized building, `string.String` and `str_buffer[N]` remain the explicit surfaces with visible cost. Any other surface that builds owned text must say so explicitly, for example `std.fmt.format(f"...")` when ownership must escape.
|
|
42
42
|
|
|
43
43
|
### 2. C is the ABI ground truth
|
|
44
44
|
|
|
@@ -755,7 +755,7 @@ Explicit specialization arguments may be type references like `bytes_for[int](4)
|
|
|
755
755
|
|
|
756
756
|
Built-in operators should match familiar C behavior where possible:
|
|
757
757
|
|
|
758
|
-
- arithmetic: `+ - * / %`
|
|
758
|
+
- arithmetic: `+ - * / %` (the `+` operator on `str` concatenates, allocating a new heap-backed string)
|
|
759
759
|
- comparison: `== != < <= > >=`
|
|
760
760
|
- boolean: `and or not`
|
|
761
761
|
- bitwise: `& | ^ ~ << >>`
|
data/docs/language-manual.md
CHANGED
|
@@ -124,7 +124,7 @@ Supported literals:
|
|
|
124
124
|
- integer: `42`, `0xff`, `0b1010`, with `_` separators. Integer type suffixes: `42u` (`uint`), `0xFFub` (`ubyte`), `100z` (`ptr_uint`), `7i` (`int`), `-1l` (`long`), etc.
|
|
125
125
|
- float: `3.14`, `1.2e-3`, `1.1920929E-7`, `1.0f` (float suffix), `1.0d` (double suffix)
|
|
126
126
|
- character: `'a'`, `'\n'`, `'\t'`, `'\\'`, `'\''`, `'\0'`, `'\x41'`. Type is `ubyte`. Escape sequences: `\n`, `\r`, `\t`, `\\`, `\'`, `\"`, `\0` (null), `\xNN` (hex byte).
|
|
127
|
-
- string: `"hello"` (`str`). Supported string escapes are `\n`, `\r`, `\t`, `\0` (null), `\"`, `\'`, and `\\`; any other `\x` sequence is taken literally. Hex byte escapes (`\xNN`) are character-literal only, not string-literal.
|
|
127
|
+
- string: `"hello"` (`str`). Supported string escapes are `\n`, `\r`, `\t`, `\0` (null), `\"`, `\'`, and `\\`; any other `\x` sequence is taken literally. Hex byte escapes (`\xNN`) are character-literal only, not string-literal. The `+` operator concatenates `str` values: `"hello" + " " + "world"` produces `"hello world"`. Each `+` allocates a new heap-backed `str`; for loops or repeated concatenation, prefer `string.String` for amortized performance.
|
|
128
128
|
- cstring: `c"hello"` (`cstr`)
|
|
129
129
|
- heredoc string: `<<-TAG ... TAG` (`str`)
|
|
130
130
|
- heredoc cstring: `c<<-TAG ... TAG` (`cstr`)
|
|
@@ -300,7 +300,25 @@ Callable and `ref[...]` rules:
|
|
|
300
300
|
struct Vec2:
|
|
301
301
|
x: float
|
|
302
302
|
y: float
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
`struct` bodies may also contain `function`, `editable function`, and `static function` declarations directly — they desugar to `extending` blocks targeting the enclosing struct. This is pure syntactic sugar and produces identical C code. See §3.6 for the method kind rules.
|
|
306
|
+
|
|
307
|
+
```mt
|
|
308
|
+
struct Counter:
|
|
309
|
+
value: int
|
|
310
|
+
|
|
311
|
+
function read() -> int:
|
|
312
|
+
return this.value
|
|
313
|
+
|
|
314
|
+
editable function bump() -> void:
|
|
315
|
+
this.value += 1
|
|
316
|
+
|
|
317
|
+
static function zero() -> Counter:
|
|
318
|
+
return Counter(value = 0)
|
|
319
|
+
```
|
|
303
320
|
|
|
321
|
+
```mt
|
|
304
322
|
union Number:
|
|
305
323
|
i: int
|
|
306
324
|
f: float
|
|
@@ -417,7 +435,25 @@ Rules:
|
|
|
417
435
|
|
|
418
436
|
### 3.6 Methods
|
|
419
437
|
|
|
438
|
+
Methods may appear directly inside a struct body (desugared to an `extending` block) or in a separate `extending` declaration. Both forms lower to identical C code.
|
|
439
|
+
|
|
440
|
+
```mt
|
|
441
|
+
# Inline form (sugar)
|
|
442
|
+
struct Counter:
|
|
443
|
+
value: int
|
|
444
|
+
|
|
445
|
+
function read() -> int:
|
|
446
|
+
return this.value
|
|
447
|
+
|
|
448
|
+
editable function bump() -> void:
|
|
449
|
+
this.value += 1
|
|
450
|
+
|
|
451
|
+
static function zero() -> Counter:
|
|
452
|
+
return Counter(value = 0)
|
|
453
|
+
```
|
|
454
|
+
|
|
420
455
|
```mt
|
|
456
|
+
# Equivalent extending form
|
|
421
457
|
extending Counter:
|
|
422
458
|
function read() -> int:
|
|
423
459
|
return this.value
|
|
@@ -979,7 +1015,7 @@ Rules:
|
|
|
979
1015
|
8. `==`, `!=`
|
|
980
1016
|
9. `<`, `<=`, `>`, `>=`
|
|
981
1017
|
10. `<<`, `>>`
|
|
982
|
-
11. `+`, `-`
|
|
1018
|
+
11. `+`, `-` (additionally, `+` on `str` concatenates; each `+` allocates a new heap-backed `str`)
|
|
983
1019
|
12. `*`, `/`, `%`
|
|
984
1020
|
|
|
985
1021
|
### 5.4 Assignment operators
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -289,6 +289,14 @@ module MilkTea
|
|
|
289
289
|
emitted_functions.any? { |function| function_uses_str_equality?(function) }
|
|
290
290
|
end
|
|
291
291
|
|
|
292
|
+
def uses_str_concat_helper?
|
|
293
|
+
return @uses_str_concat if defined?(@uses_str_concat)
|
|
294
|
+
|
|
295
|
+
@uses_str_concat = emitted_functions.any? do |function|
|
|
296
|
+
function_uses_named_call?(function, %w[mt_str_concat])
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
292
300
|
def uses_variant_equality_helper?
|
|
293
301
|
emitted_functions.any? { |function| function_uses_variant_equality?(function) }
|
|
294
302
|
end
|
|
@@ -42,6 +42,27 @@ module MilkTea
|
|
|
42
42
|
]
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
def emit_str_concat_helper
|
|
46
|
+
[
|
|
47
|
+
"#define MT_STR_CONCAT_BUF_SIZE 65536",
|
|
48
|
+
"",
|
|
49
|
+
"static _Thread_local char mt_str_concat_buf[MT_STR_CONCAT_BUF_SIZE];",
|
|
50
|
+
"static _Thread_local uintptr_t mt_str_concat_offset = 0;",
|
|
51
|
+
"",
|
|
52
|
+
"static mt_str mt_str_concat(mt_str a, mt_str b) {",
|
|
53
|
+
"#{INDENT}uintptr_t total = a.len + b.len;",
|
|
54
|
+
"#{INDENT}if (mt_str_concat_offset + total > MT_STR_CONCAT_BUF_SIZE) {",
|
|
55
|
+
"#{INDENT * 2}mt_str_concat_offset = 0;",
|
|
56
|
+
"#{INDENT}}",
|
|
57
|
+
"#{INDENT}char* buf = mt_str_concat_buf + mt_str_concat_offset;",
|
|
58
|
+
"#{INDENT}if (a.len > 0) memcpy(buf, a.data, a.len);",
|
|
59
|
+
"#{INDENT}if (b.len > 0) memcpy(buf + a.len, b.data, b.len);",
|
|
60
|
+
"#{INDENT}mt_str_concat_offset += total;",
|
|
61
|
+
"#{INDENT}return (mt_str){ .data = buf, .len = total };",
|
|
62
|
+
"}",
|
|
63
|
+
]
|
|
64
|
+
end
|
|
65
|
+
|
|
45
66
|
def emit_variant_equality_helpers
|
|
46
67
|
emitted_aggregate_variants.flat_map { |variant_decl| emit_variant_equality_helper(variant_decl) }
|
|
47
68
|
end
|
|
@@ -146,6 +146,10 @@ module MilkTea
|
|
|
146
146
|
lines.concat(emit_str_equality_helper)
|
|
147
147
|
lines << ""
|
|
148
148
|
end
|
|
149
|
+
if uses_str_concat_helper?
|
|
150
|
+
lines.concat(emit_str_concat_helper)
|
|
151
|
+
lines << ""
|
|
152
|
+
end
|
|
149
153
|
if uses_str_buffer_helpers?
|
|
150
154
|
lines.concat(emit_utf8_validation_helpers)
|
|
151
155
|
lines << ""
|
|
@@ -1387,6 +1387,10 @@ module MilkTea
|
|
|
1387
1387
|
left = cast_expression(left, operand_type) if operand_type
|
|
1388
1388
|
right = cast_expression(right, operand_type) if operand_type
|
|
1389
1389
|
|
|
1390
|
+
if expression.operator == "+" && left_type == @ctx.types.fetch("str") && right_type == @ctx.types.fetch("str")
|
|
1391
|
+
return IR::Call.new(callee: "mt_str_concat", arguments: [left, right], type:)
|
|
1392
|
+
end
|
|
1393
|
+
|
|
1390
1394
|
expanded = lower_vector_binary_operation(expression.operator, left, left_type, right, right_type, type)
|
|
1391
1395
|
return expanded if expanded
|
|
1392
1396
|
|
|
@@ -369,7 +369,7 @@ module MilkTea
|
|
|
369
369
|
AST::AttributeDecl.new(name: name_token.lexeme, targets:, params:, visibility:, line:, column: name_token.column)
|
|
370
370
|
end
|
|
371
371
|
|
|
372
|
-
def parse_struct_decl(packed: false, alignment: nil, visibility: :private, attributes: [])
|
|
372
|
+
def parse_struct_decl(packed: false, alignment: nil, visibility: :private, attributes: [], inline_methods: true)
|
|
373
373
|
line = previous.line
|
|
374
374
|
name_token = consume_name("expected struct name")
|
|
375
375
|
name = name_token.lexeme
|
|
@@ -377,13 +377,32 @@ module MilkTea
|
|
|
377
377
|
implements = parse_implements_clause
|
|
378
378
|
c_name = parse_optional_c_name
|
|
379
379
|
packed, alignment = parse_struct_layout_attributes(attributes) if attributes.any?
|
|
380
|
-
|
|
381
|
-
|
|
380
|
+
receiver_type_param_names = type_params.map(&:name)
|
|
381
|
+
members = with_type_param_names(receiver_type_param_names) do
|
|
382
|
+
parse_recoverable_block do
|
|
383
|
+
parse_struct_member
|
|
384
|
+
end
|
|
382
385
|
end
|
|
383
386
|
fields = members.filter_map { |kind, member| member if kind == :field }
|
|
384
387
|
events = members.filter_map { |kind, member| member if kind == :event }
|
|
385
388
|
nested_types = members.filter_map { |kind, member| member if kind == :nested_type }
|
|
386
|
-
|
|
389
|
+
methods = members.filter_map { |kind, member| member if kind == :method }
|
|
390
|
+
struct_decl = AST::StructDecl.new(name:, type_params:, implements:, c_name:, fields:, events:, nested_types:, attributes:, packed:, alignment:, visibility:, lifetime_params:, line:, column: name_token.column)
|
|
391
|
+
|
|
392
|
+
if inline_methods && methods.any?
|
|
393
|
+
type_ref_args = type_params.map do |tp|
|
|
394
|
+
AST::TypeArgument.new(
|
|
395
|
+
value: AST::TypeRef.new(name: AST::QualifiedName.new(parts: [tp.name]), arguments: [], nullable: false, line: tp.line, column: tp.column),
|
|
396
|
+
line: tp.line,
|
|
397
|
+
column: tp.column,
|
|
398
|
+
)
|
|
399
|
+
end
|
|
400
|
+
type_ref = AST::TypeRef.new(name: AST::QualifiedName.new(parts: [name]), arguments: type_ref_args, nullable: false, line: name_token.line, column: name_token.column)
|
|
401
|
+
extending_block = AST::ExtendingBlock.new(type_name: type_ref, methods:, line: name_token.line, column: name_token.column)
|
|
402
|
+
[struct_decl, extending_block]
|
|
403
|
+
else
|
|
404
|
+
struct_decl
|
|
405
|
+
end
|
|
387
406
|
end
|
|
388
407
|
|
|
389
408
|
def parse_struct_decl_params
|
|
@@ -429,8 +448,24 @@ module MilkTea
|
|
|
429
448
|
[lifetime_params, type_params]
|
|
430
449
|
end
|
|
431
450
|
|
|
451
|
+
def check_method_start?
|
|
452
|
+
saved = @current
|
|
453
|
+
match(:public)
|
|
454
|
+
match(:async)
|
|
455
|
+
match(:editable) if check(:editable)
|
|
456
|
+
match(:static) if check(:static)
|
|
457
|
+
result = check(:function)
|
|
458
|
+
@current = saved
|
|
459
|
+
result
|
|
460
|
+
end
|
|
461
|
+
|
|
432
462
|
def parse_struct_member
|
|
433
463
|
field_attributes = parse_attribute_applications
|
|
464
|
+
|
|
465
|
+
if check_method_start?
|
|
466
|
+
return [:method, parse_method_def(attributes: field_attributes)]
|
|
467
|
+
end
|
|
468
|
+
|
|
434
469
|
visibility, visibility_token = parse_visibility
|
|
435
470
|
|
|
436
471
|
if match(:event)
|
|
@@ -438,7 +473,7 @@ module MilkTea
|
|
|
438
473
|
end
|
|
439
474
|
|
|
440
475
|
if match(:struct)
|
|
441
|
-
return [:nested_type, parse_struct_decl(visibility:, attributes: field_attributes)]
|
|
476
|
+
return [:nested_type, parse_struct_decl(visibility:, attributes: field_attributes, inline_methods: false)]
|
|
442
477
|
end
|
|
443
478
|
|
|
444
479
|
raise error(visibility_token, "public is only allowed on struct events") if visibility == :public
|
data/lib/milk_tea/core/parser.rb
CHANGED
|
@@ -154,13 +154,23 @@ module MilkTea
|
|
|
154
154
|
until eof?
|
|
155
155
|
if errors
|
|
156
156
|
begin
|
|
157
|
-
|
|
157
|
+
result = parse_declaration
|
|
158
|
+
if result.is_a?(Array)
|
|
159
|
+
declarations.concat(result)
|
|
160
|
+
else
|
|
161
|
+
declarations << result
|
|
162
|
+
end
|
|
158
163
|
rescue ParseError => e
|
|
159
164
|
errors << e
|
|
160
165
|
synchronize_to_top_level_boundary
|
|
161
166
|
end
|
|
162
167
|
else
|
|
163
|
-
|
|
168
|
+
result = parse_declaration
|
|
169
|
+
if result.is_a?(Array)
|
|
170
|
+
declarations.concat(result)
|
|
171
|
+
else
|
|
172
|
+
declarations << result
|
|
173
|
+
end
|
|
164
174
|
end
|
|
165
175
|
skip_newlines
|
|
166
176
|
end
|
|
@@ -612,8 +612,8 @@ module MilkTea
|
|
|
612
612
|
|
|
613
613
|
left_type
|
|
614
614
|
when "+", "-", "*", "/"
|
|
615
|
-
if expression.operator == "+" && (
|
|
616
|
-
|
|
615
|
+
if expression.operator == "+" && left_type == @ctx.types.fetch("str") && right_type == @ctx.types.fetch("str")
|
|
616
|
+
return left_type
|
|
617
617
|
end
|
|
618
618
|
|
|
619
619
|
pointer_result = pointer_arithmetic_result(expression.operator, left_type, right_type)
|
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.3.
|
|
4
|
+
version: 0.3.30
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -149,9 +149,6 @@ files:
|
|
|
149
149
|
- docs/index.html
|
|
150
150
|
- docs/language-design.md
|
|
151
151
|
- docs/language-manual.md
|
|
152
|
-
- docs/self-host-contract.md
|
|
153
|
-
- docs/self-host-plan.md
|
|
154
|
-
- docs/self-host-progress.md
|
|
155
152
|
- lib/milk_tea.rb
|
|
156
153
|
- lib/milk_tea/base.rb
|
|
157
154
|
- lib/milk_tea/bindings.rb
|
|
@@ -627,7 +624,7 @@ metadata:
|
|
|
627
624
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
628
625
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
629
626
|
post_install_message: |
|
|
630
|
-
Milk Tea 0.3.
|
|
627
|
+
Milk Tea 0.3.30 installed!
|
|
631
628
|
|
|
632
629
|
System requirements:
|
|
633
630
|
- A C compiler (gcc or clang) must be available on PATH
|