mt-lang 0.3.11 → 0.3.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/README.md +29 -9
- data/docs/index.html +38 -12
- data/docs/language-design.md +1 -0
- data/docs/language-manual.md +12 -1
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/lexer.rb +2 -10
- data/lib/milk_tea/core/parser/expressions.rb +2 -2
- data/lib/milk_tea/core/parser/statements.rb +11 -0
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +32 -1
- data/lib/milk_tea/core/token.rb +17 -0
- data/lib/milk_tea/tooling/linter/reserved_names.rb +1 -1
- data/lib/milk_tea/tooling/linter/visitors.rb +13 -1
- 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: bc80c3a3240cbcf4770dd067aa33559e74e3f139322b8fdb757316f3c7faf8af
|
|
4
|
+
data.tar.gz: a623e5ecaa9617aa161a83e96c4cb0e7a75b08855edae27fb56c8ddc47c7cd75
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c90aa51a21411fdcfe612f2ded69afdde6e055a012a4e886f5aa9ac69110d39a8bf93a36dde0543d1375a8bfa75ffd2f287eb082833a28b42efe19ab45c62ae6
|
|
7
|
+
data.tar.gz: a87ac20f1228f059e3508818be58e11e5491a90299e56d5ab569ab3ebf1ae3dc1f7ddff8761321754bd2bfc8c520dc9ac3876360714ced2baf6e06a82bbf635d
|
data/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Blocks are indentation-based:
|
|
|
43
43
|
- Tabs are rejected.
|
|
44
44
|
- Indentation must be a multiple of 4 spaces.
|
|
45
45
|
- Indentation can increase by only one level at a time.
|
|
46
|
-
- Newlines end statements except inside `()` and `[]`, or when the previous physical line ends with a binary operator such as `+`, `and`, or
|
|
46
|
+
- Newlines end statements except inside `()` and `[]`, or when the previous physical line ends with a binary operator such as `+`, `and`, `==`, or `is`.
|
|
47
47
|
- Comma-separated lists inside `()` and `[]` accept trailing commas. Prefer them for multiline parameters, arguments, and type lists.
|
|
48
48
|
|
|
49
49
|
Long expressions should usually be wrapped with delimiters, following the same broad shape as Python's implicit line joining:
|
|
@@ -71,7 +71,15 @@ let values = 1 ..
|
|
|
71
71
|
4
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
Starting a physical line with an operator is a hard parse error (`operator '<op>' cannot start a statement`). Continue by ending the previous line with the operator, or wrap the expression in `()` if that layout reads better. The continuation operator set is closed: `+` `-` `*` `/` `%`, `|` `&` `^`, `<<` `>>`, `==` `!=` `<` `<=` `>` `>=`, `and` `or` `is`, and `..`. Member-access chains that exceed one line wrap in `()` with leading dots:
|
|
75
|
+
|
|
76
|
+
```mt
|
|
77
|
+
let total = (
|
|
78
|
+
values.iter()
|
|
79
|
+
.filter(pred)
|
|
80
|
+
.fold(0, add)
|
|
81
|
+
)
|
|
82
|
+
```
|
|
75
83
|
|
|
76
84
|
Comments:
|
|
77
85
|
|
|
@@ -315,7 +323,7 @@ Rules:
|
|
|
315
323
|
- Compile-time reflection over validated attributes uses `has_attribute`, `attribute_of`, `attribute_arg[T]`, `field_of`, and `callable_of`.
|
|
316
324
|
- `field_of(...)`, `callable_of(...)`, and `attribute_of(...)` produce compile-time handle values with source-visible handle types `field_handle`, `callable_handle`, and `attribute_handle`.
|
|
317
325
|
- The current C backend lowers `packed` / `align(...)` attributes with GNU-style `__attribute__((...))`, so these layout controls currently require a Clang/GCC-family compiler. On Windows that means Clang or GCC-family toolchains such as MinGW; `cl.exe` is not a supported backend for these attributes today. On wasm/browser targets the same feature works through Emscripten `emcc`, which is Clang-based.
|
|
318
|
-
- Keywords and reserved words are accepted as variant arm names, struct/union field names, enum/flags member names, lifetime parameters (`@return`), type parameters (`Box[return]`),
|
|
326
|
+
- Keywords and reserved words are accepted as variant arm names, struct/union field names, enum/flags member names, lifetime parameters (`@return`), type parameters (`Box[return]`), named constructor arguments (`Meta(return = 1)`), and named tuple fields (`(return = 1, let = 2)`). Primitive type names (`int`, `str`, `ref`, etc.) remain reserved and cannot be used in these positions.
|
|
319
327
|
|
|
320
328
|
Enum and flags values support the full set of comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`) against values of the same enum type and against their backing integer type. Comparisons use the underlying integer backing values. Flags also support bitwise operators (`|`, `&`, `^`, `~`).
|
|
321
329
|
|
|
@@ -869,9 +877,9 @@ Core modules in `std/`:
|
|
|
869
877
|
|
|
870
878
|
- `std.linear_algebra` — extends native vector/matrix/quaternion types with `dot`, `cross`, `length`, `normalized`, `lerp`, `identity`, `transpose`, `conjugate` (pure Mt, no C dependency beyond `std.math` for `sqrt`)
|
|
871
879
|
- `std.graph.Graph[T]` — adjacency-list graph with `add_node`, `add_edge`, `has_edge`, `remove_edge`, `neighbors`, `bfs`, `dfs`, `toposort`; directed or undirected; `compile()` converts to CSR-based `DenseGraph[T]` for O(degree) neighbor iteration
|
|
872
|
-
- `std.str` — extends `str` with `byte_at`, `equal`, `starts_with`, `ends_with`, `find_substring`, `is_valid_utf8`, `slice`, `to_cstr`, `hash`, `order`
|
|
880
|
+
- `std.str` — extends `str` with `byte_at`, `equal`, `starts_with`, `ends_with`, `find_substring`, `is_valid_utf8`, `slice`, `to_cstr`, `hash`, `order`; also provides C-string conversion helpers (`cstr_len`, `cstr_as_str`, `chars_as_str`, `nullable_cstr_as_str`)
|
|
873
881
|
- `std.hash` — extends the primitive integer types (`byte`/`ubyte`/`short`/`ushort`/`int`/`uint`/`long`/`ulong`/`ptr_int`/`ptr_uint`), `bool`, `float`, `double`, and `char` with canonical `hash`/`equal`/`order` hooks; import once to use primitives as Map/Set/BinaryHeap/OrderedMap keys (`str` keys come from `std.str`). Also provides generic `hash_struct[T]`, `equal_struct[T]`, `order_struct[T]` that dispatch each field through its own canonical hook via `field.type` (content-correct, including `str` and nested-struct fields).
|
|
874
|
-
- `std.cstring` — C
|
|
882
|
+
- `std.cstring` — low-level byte and C-string helpers (`copy_bytes`, `move_bytes`, `set_bytes`, `compare_bytes`, `find_byte`, `length`, `compare`, `compare_prefix`, `find_char`, `find_last_char`, `find_substring`)
|
|
875
883
|
- `std.math` — `sqrt`, `sin`, `cos`, `abs`, `pow`, etc. via C math
|
|
876
884
|
- `std.encoding` — UTF-8 validation (`is_valid_utf8`, `utf8_codepoint_count`, `decode_utf8_codepoint`, `utf8_overlong_check`)
|
|
877
885
|
- `std.string.String` — growable owned UTF-8 text
|
|
@@ -1113,6 +1121,7 @@ Current compiler rejects:
|
|
|
1113
1121
|
- range expressions are restricted to `for`-loop iterables and range-index assignment targets
|
|
1114
1122
|
- functions, methods, generic functions, and variant arms must be called — they are not usable as bare values
|
|
1115
1123
|
- `read(...)` of a raw pointer requires `unsafe`
|
|
1124
|
+
- a statement cannot begin with a binary operator (including `+`, `-`, `and`, `or`, `is`, `..`); continuation requires ending the previous line with the operator or wrapping in `()`
|
|
1116
1125
|
|
|
1117
1126
|
### Control flow restrictions
|
|
1118
1127
|
|
|
@@ -1163,11 +1172,12 @@ mtc build <path> # Build only (emit C, compile, link, --no-cache to
|
|
|
1163
1172
|
mtc run <path> # Build and execute (--no-cache to build and run without cache)
|
|
1164
1173
|
mtc debug <file.mt> # Print debug info (tokens, AST, facts, bindings, diagnostics)
|
|
1165
1174
|
mtc emit-c <path> # Emit generated C to stdout
|
|
1166
|
-
mtc format <path> # Format
|
|
1175
|
+
mtc format <path> # Format source to stdout (--write rewrites in place, --check verifies)
|
|
1167
1176
|
mtc lint <path> # Run linter (--fix to apply fixes, --select/--ignore to filter)
|
|
1168
1177
|
mtc test <path> # Discover and run @[test] functions (--timeout, --mem, --jobs)
|
|
1169
1178
|
mtc new <name> # Scaffold a new package (package.toml + src/main.mt)
|
|
1170
1179
|
mtc cache status # Show build cache stats
|
|
1180
|
+
mtc cache purge # Remove the entire build cache
|
|
1171
1181
|
mtc lex <file.mt> # Print lexer token stream
|
|
1172
1182
|
mtc parse <path> # Print parsed AST
|
|
1173
1183
|
mtc lower <path> # Print lowered IR
|
|
@@ -1185,10 +1195,10 @@ mtc deps publish <path> # Publish a package to the local registry
|
|
|
1185
1195
|
mtc deps fetch <path> # Materialize cache-backed sources
|
|
1186
1196
|
```
|
|
1187
1197
|
|
|
1188
|
-
|
|
1198
|
+
Resolve a module by name, build it, and run it:
|
|
1189
1199
|
|
|
1190
1200
|
```
|
|
1191
|
-
mtc run-module <module> #
|
|
1201
|
+
mtc run-module <module> # Resolve, build, and run a module by name (e.g. std.http.server)
|
|
1192
1202
|
```
|
|
1193
1203
|
|
|
1194
1204
|
Toolchain maintenance:
|
|
@@ -1199,9 +1209,19 @@ mtc toolchain doctor # Diagnose toolchain setup
|
|
|
1199
1209
|
mtc toolchain tools # List available native tools
|
|
1200
1210
|
```
|
|
1201
1211
|
|
|
1212
|
+
Tooling and editors:
|
|
1213
|
+
|
|
1214
|
+
```
|
|
1215
|
+
mtc bindgen <header.h> # Generate an external binding module from a C header
|
|
1216
|
+
mtc snapshot <path> # Render a highlighted HTML snapshot of a source file
|
|
1217
|
+
mtc lsp # Start the Language Server Protocol server
|
|
1218
|
+
mtc dap # Start the Debug Adapter Protocol server
|
|
1219
|
+
mtc docs [--open] [--port P] # Serve the local documentation site
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1202
1222
|
Build and run commands support `--profile`, `--platform`, `--cc`, `--keep-c`, `--locked`, `--frozen`, and `-I` include paths. Dependency-locked flows support `--locked` (use package.lock) and `--frozen` (require current package.lock).
|
|
1203
1223
|
|
|
1204
|
-
Global options work with any command (before or after the subcommand, up to a `--` separator): `-h`/`--help` (also `mtc help <command>` for command-specific help), `-V`/`--version`, `-q`/`--quiet` (suppress informational output), `-v`/`--verbose` (per-file progress), and `--color auto|always|never`. Generate shell completions with `mtc completions bash|zsh|fish`. Timing breakdowns use `--timings` (on `format
|
|
1224
|
+
Global options work with any command (before or after the subcommand, up to a `--` separator): `-h`/`--help` (also `mtc help <command>` for command-specific help), `-V`/`--version`, `-q`/`--quiet` (suppress informational output), `-v`/`--verbose` (per-file progress), and `--color auto|always|never`. Generate shell completions with `mtc completions bash|zsh|fish`. Timing breakdowns use `--timings` (on `format` and `lint`); `lint` reports warnings with per-file progress.
|
|
1205
1225
|
|
|
1206
1226
|
Diagnostic output uses standard compiler format (file:line:column with source context, error codes, and caret highlighting):
|
|
1207
1227
|
|
data/docs/index.html
CHANGED
|
@@ -343,7 +343,7 @@ function main() -> int:
|
|
|
343
343
|
<tr><td><code>mtc check <path></code></td><td>Type-check + lint; reports all diagnostics sorted by line</td></tr>
|
|
344
344
|
<tr><td><code>mtc run <path></code></td><td>Build and execute</td></tr>
|
|
345
345
|
<tr><td><code>mtc build <path></code></td><td>Build only (emit C, compile, link)</td></tr>
|
|
346
|
-
<tr><td><code>mtc format <path></code></td><td>Format
|
|
346
|
+
<tr><td><code>mtc format <path></code></td><td>Format source to stdout (<code>--write</code> rewrites in place, <code>--check</code> verifies)</td></tr>
|
|
347
347
|
<tr><td><code>mtc lint <path></code></td><td>Run linter (<code>--fix</code> to apply fixes)</td></tr>
|
|
348
348
|
<tr><td><code>mtc test <path></code></td><td>Discover and run <code>@[test]</code> functions</td></tr>
|
|
349
349
|
<tr><td><code>mtc new <name></code></td><td>Scaffold a new package</td></tr>
|
|
@@ -403,6 +403,7 @@ void main_Vec2_scale(main_Vec2* this, float factor) {
|
|
|
403
403
|
<pre><code>## ── Imports ──────────────────────────────────────────────────────────
|
|
404
404
|
import std.stdio as io
|
|
405
405
|
import std.hash
|
|
406
|
+
import std.str
|
|
406
407
|
import std.vec
|
|
407
408
|
import std.map
|
|
408
409
|
import std.math
|
|
@@ -888,6 +889,7 @@ import mylib.utils</code></pre>
|
|
|
888
889
|
<li>Indentation must be a multiple of <strong>4 spaces</strong></li>
|
|
889
890
|
<li>Indentation increases by <strong>one level at a time</strong></li>
|
|
890
891
|
<li>Newlines end statements except inside <code>()</code> and <code>[]</code>, or when the previous line ends with a binary operator</li>
|
|
892
|
+
<li>Starting a line with an operator is a hard parse error (<code>operator '<op>' cannot start a statement</code>); continuation is signaled by ending the previous line with the operator, never by starting the next one with it</li>
|
|
891
893
|
</ul>
|
|
892
894
|
|
|
893
895
|
<div class="code-wrap">
|
|
@@ -902,7 +904,16 @@ let total = (
|
|
|
902
904
|
## Also accepted: operator-led continuation.
|
|
903
905
|
let total = subtotal +
|
|
904
906
|
tax -
|
|
905
|
-
discount
|
|
907
|
+
discount
|
|
908
|
+
|
|
909
|
+
## The continuation operator set is closed:
|
|
910
|
+
## + - * / % | & ^ << >> == != < <= > >= and or is ..
|
|
911
|
+
## Member-access chains exceeding one line wrap in () with leading dots:
|
|
912
|
+
let total = (
|
|
913
|
+
values.iter()
|
|
914
|
+
.filter(pred)
|
|
915
|
+
.fold(0, add)
|
|
916
|
+
)</code></pre>
|
|
906
917
|
</div>
|
|
907
918
|
|
|
908
919
|
<h3>Naming Conventions</h3>
|
|
@@ -1733,14 +1744,16 @@ let sized = name[32]</code></pre>
|
|
|
1733
1744
|
<tr><th>Precedence</th><th>Operators</th></tr>
|
|
1734
1745
|
<tr><td>1 (lowest)</td><td><code>or</code></td></tr>
|
|
1735
1746
|
<tr><td>2</td><td><code>and</code></td></tr>
|
|
1736
|
-
<tr><td>3</td><td><code
|
|
1737
|
-
<tr><td>4</td><td><code
|
|
1738
|
-
<tr><td>5</td><td><code
|
|
1739
|
-
<tr><td>6</td><td><code
|
|
1740
|
-
<tr><td>7</td><td><code>&
|
|
1741
|
-
<tr><td>8</td><td><code
|
|
1742
|
-
<tr><td>9</td><td><code
|
|
1743
|
-
<tr><td>10
|
|
1747
|
+
<tr><td>3</td><td><code>not</code> (unary prefix)</td></tr>
|
|
1748
|
+
<tr><td>4</td><td><code>is</code></td></tr>
|
|
1749
|
+
<tr><td>5</td><td><code>|</code></td></tr>
|
|
1750
|
+
<tr><td>6</td><td><code>^</code></td></tr>
|
|
1751
|
+
<tr><td>7</td><td><code>&</code></td></tr>
|
|
1752
|
+
<tr><td>8</td><td><code>==</code> <code>!=</code></td></tr>
|
|
1753
|
+
<tr><td>9</td><td><code><</code> <code><=</code> <code>></code> <code>>=</code></td></tr>
|
|
1754
|
+
<tr><td>10</td><td><code><<</code> <code>>></code></td></tr>
|
|
1755
|
+
<tr><td>11</td><td><code>+</code> <code>-</code></td></tr>
|
|
1756
|
+
<tr><td>12 (highest)</td><td><code>*</code> <code>/</code> <code>%</code></td></tr>
|
|
1744
1757
|
</table>
|
|
1745
1758
|
</div>
|
|
1746
1759
|
|
|
@@ -2169,7 +2182,7 @@ function attach(window: ref[Window]) -> Result[void, EventError]:
|
|
|
2169
2182
|
<tr><td><code>std.spatial</code></td><td><code>SpatialGrid[T]</code></td><td>—</td><td>Uniform spatial hash grid (returns Vec)</td></tr>
|
|
2170
2183
|
<tr><td><code>std.ring_buffer</code></td><td><code>RingBuffer[T]</code></td><td>Mutable <code>ptr[T]?</code></td><td>Fixed-capacity circular buffer</td></tr>
|
|
2171
2184
|
<tr><td><code>std.sparse_set</code></td><td><code>SparseSet[T]</code></td><td>Mutable <code>ptr[T]?</code></td><td>O(1) insert/remove; dense iteration</td></tr>
|
|
2172
|
-
<tr><td><code>std.lru_cache</code></td><td><code>LruCache[K,V]</code></td><td><code>
|
|
2185
|
+
<tr><td><code>std.lru_cache</code></td><td><code>LruCache[K,V]</code></td><td><code>iter()</code> → <code>linked_map.Entries[K, V]</code></td><td>Capacity-bounded LRU eviction map</td></tr>
|
|
2173
2186
|
</table>
|
|
2174
2187
|
</div>
|
|
2175
2188
|
|
|
@@ -2236,7 +2249,7 @@ function attach(window: ref[Window]) -> Result[void, EventError]:
|
|
|
2236
2249
|
<tr><td><code>mtc lint <path></code></td><td>Run linter (<code>--fix</code>, <code>--select</code>, <code>--ignore</code>)</td></tr>
|
|
2237
2250
|
<tr><td><code>mtc test <path></code></td><td>Discover and run <code>@[test]</code> functions</td></tr>
|
|
2238
2251
|
<tr><td><code>mtc new <name></code></td><td>Scaffold a new package (<code>package.toml</code> + <code>src/main.mt</code>)</td></tr>
|
|
2239
|
-
<tr><td><code>mtc run-module <module></code></td><td>
|
|
2252
|
+
<tr><td><code>mtc run-module <module></code></td><td>Resolve a module by name, build it, and run it</td></tr>
|
|
2240
2253
|
<tr><td><code>mtc completions <shell></code></td><td>Print a bash/zsh/fish completion script</td></tr>
|
|
2241
2254
|
</table>
|
|
2242
2255
|
</div>
|
|
@@ -2263,10 +2276,22 @@ function attach(window: ref[Window]) -> Result[void, EventError]:
|
|
|
2263
2276
|
<tr><td><code>mtc toolchain doctor</code></td><td>Diagnose toolchain setup</td></tr>
|
|
2264
2277
|
<tr><td><code>mtc toolchain tools</code></td><td>List available native tools</td></tr>
|
|
2265
2278
|
<tr><td><code>mtc cache status</code></td><td>Show build cache stats</td></tr>
|
|
2279
|
+
<tr><td><code>mtc cache purge</code></td><td>Remove the entire build cache</td></tr>
|
|
2266
2280
|
<tr><td><code>mtc docs [--open] [--port PORT]</code></td><td>Start a local HTTP server serving the language reference</td></tr>
|
|
2267
2281
|
</table>
|
|
2268
2282
|
</div>
|
|
2269
2283
|
|
|
2284
|
+
<h3>Tooling</h3>
|
|
2285
|
+
<div class="table-wrap">
|
|
2286
|
+
<table class="attr-table">
|
|
2287
|
+
<tr><th>Command</th><th>Description</th></tr>
|
|
2288
|
+
<tr><td><code>mtc bindgen <header.h></code></td><td>Generate an external binding module from a C header</td></tr>
|
|
2289
|
+
<tr><td><code>mtc snapshot <path></code></td><td>Render a highlighted HTML snapshot of a source file</td></tr>
|
|
2290
|
+
<tr><td><code>mtc lsp</code></td><td>Start the Language Server Protocol server (editor IntelliSense)</td></tr>
|
|
2291
|
+
<tr><td><code>mtc dap</code></td><td>Start the Debug Adapter Protocol server (debugging)</td></tr>
|
|
2292
|
+
</table>
|
|
2293
|
+
</div>
|
|
2294
|
+
|
|
2270
2295
|
<h3>Build Flags</h3>
|
|
2271
2296
|
<p>Build and run commands support: <code>--profile</code>, <code>--platform</code>, <code>--cc</code>, <code>--keep-c</code>, <code>--locked</code>, <code>--frozen</code>, and <code>-I</code> include paths.</p>
|
|
2272
2297
|
|
|
@@ -2385,6 +2410,7 @@ import std.math # intentionally available for downstream</code></pre>
|
|
|
2385
2410
|
<li>Enum and flags values do not implicitly coerce to backing integers</li>
|
|
2386
2411
|
<li><code>+</code> does not support <code>str</code>/<code>cstr</code> concatenation</li>
|
|
2387
2412
|
<li><code>==</code> and <code>!=</code> not supported on struct types; use <code>equal[T]</code></li>
|
|
2413
|
+
<li>A statement cannot begin with a binary operator (including <code>+</code>, <code>-</code>, <code>and</code>, <code>or</code>, <code>is</code>, <code>..</code>); continuation requires ending the previous line with the operator or wrapping in <code>()</code></li>
|
|
2388
2414
|
<li>Bare function and method names are not usable as values (cannot be assigned or passed without calling). Use <code>fn(...)</code> function pointer types or <code>proc(...)</code> closures for callable values.</li>
|
|
2389
2415
|
</ul>
|
|
2390
2416
|
|
data/docs/language-design.md
CHANGED
|
@@ -88,6 +88,7 @@ The compile-time evaluation surface is described in [Compile-Time Evaluation](co
|
|
|
88
88
|
- Newlines terminate statements.
|
|
89
89
|
- Newlines inside `()` and `[]` do not terminate statements.
|
|
90
90
|
- A physical line that ends with a binary operator also continues onto the next line.
|
|
91
|
+
- A physical line that begins with an operator is a hard parse error; continuation is signaled by ending the previous line with the operator, never by starting the next one with it.
|
|
91
92
|
- Tabs are illegal in source files; indentation is 4 spaces.
|
|
92
93
|
- Trailing commas are allowed in multiline call arguments and aggregate literals. The linter additionally flags a redundant trailing comma in a call-argument list (`trailing-list-comma` hint); aggregate and array literals keep them for diff-friendliness.
|
|
93
94
|
- Comments use `#`.
|
data/docs/language-manual.md
CHANGED
|
@@ -83,7 +83,17 @@ let total = subtotal +
|
|
|
83
83
|
discount
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
The continuation operator set is closed: `+` `-` `*` `/` `%`, `|` `&` `^`, `<<` `>>`, `==` `!=` `<` `<=` `>` `>=`, `and` `or` `is`, and `..`. Assignment operators and unary `not` are excluded — wrap in `()` when a break is needed there.
|
|
87
|
+
|
|
88
|
+
Starting a new physical line with an operator is a hard error (`operator '<op>' cannot start a statement`); end the previous line with the operator, or wrap the expression in `()` if that layout is clearer. Member-access chains that exceed one line wrap in `()` with leading dots:
|
|
89
|
+
|
|
90
|
+
```mt
|
|
91
|
+
let total = (
|
|
92
|
+
values.iter()
|
|
93
|
+
.filter(pred)
|
|
94
|
+
.fold(0, add)
|
|
95
|
+
)
|
|
96
|
+
```
|
|
87
97
|
|
|
88
98
|
### 2.2 Comments
|
|
89
99
|
|
|
@@ -369,6 +379,7 @@ Language-level keywords and reserved words are accepted as:
|
|
|
369
379
|
- lifetime parameter names (`struct Buf[@return]`)
|
|
370
380
|
- type parameter names (`struct Box[return]`, `identity[type]`)
|
|
371
381
|
- named arguments in struct/variant literals (`Meta(return = 1)`)
|
|
382
|
+
- named tuple fields (`(return = 1, let = 2)`)
|
|
372
383
|
|
|
373
384
|
Primitive type names (`int`, `str`, `bool`, `ref`, `ptr`, `span`, `type`, etc.) remain reserved and cannot be used as names.
|
|
374
385
|
|
data/lib/milk_tea/base.rb
CHANGED
data/lib/milk_tea/core/lexer.rb
CHANGED
|
@@ -42,15 +42,7 @@ module MilkTea
|
|
|
42
42
|
link opaque public static_assert struct type union var variant extending event
|
|
43
43
|
].freeze
|
|
44
44
|
|
|
45
|
-
LINE_CONTINUATION_OPERATORS =
|
|
46
|
-
dot_dot
|
|
47
|
-
plus minus star slash percent
|
|
48
|
-
pipe amp caret
|
|
49
|
-
or and
|
|
50
|
-
equal_equal bang_equal
|
|
51
|
-
less less_equal greater greater_equal
|
|
52
|
-
shift_left shift_right
|
|
53
|
-
].freeze
|
|
45
|
+
LINE_CONTINUATION_OPERATORS = Token::LINE_CONTINUATION_OPERATORS
|
|
54
46
|
|
|
55
47
|
THREE_CHAR_TOKENS = {
|
|
56
48
|
"..." => :ellipsis,
|
|
@@ -358,7 +350,7 @@ module MilkTea
|
|
|
358
350
|
newline_start = line_offset + line.length
|
|
359
351
|
newline_end = has_newline ? (newline_start + 1) : newline_start
|
|
360
352
|
if @grouping_depth.zero?
|
|
361
|
-
if LINE_CONTINUATION_OPERATORS.include?(@tokens.last&.type)
|
|
353
|
+
if Token::LINE_CONTINUATION_OPERATORS.include?(@tokens.last&.type)
|
|
362
354
|
@continuation_pending = true
|
|
363
355
|
else
|
|
364
356
|
@tokens << token(:newline, "\n", nil, line_number, line.length + 1, start_offset: newline_start, end_offset: newline_end)
|
|
@@ -394,7 +394,7 @@ module MilkTea
|
|
|
394
394
|
elsif match(:lparen)
|
|
395
395
|
line = previous.line
|
|
396
396
|
column = previous.column
|
|
397
|
-
first = if check_name && check_next(:equal)
|
|
397
|
+
first = if (check_name || keyword_token?(peek)) && check_next(:equal)
|
|
398
398
|
name_token = advance
|
|
399
399
|
consume(:equal, "expected '=' after named tuple field")
|
|
400
400
|
AST::Argument.new(name: name_token.lexeme, value: parse_expression)
|
|
@@ -404,7 +404,7 @@ module MilkTea
|
|
|
404
404
|
if match(:comma)
|
|
405
405
|
elements = [first]
|
|
406
406
|
loop do
|
|
407
|
-
if check_name && check_next(:equal)
|
|
407
|
+
if (check_name || keyword_token?(peek)) && check_next(:equal)
|
|
408
408
|
name_token = advance
|
|
409
409
|
consume(:equal, "expected '=' after named tuple field")
|
|
410
410
|
value = parse_expression
|
|
@@ -35,7 +35,18 @@ module MilkTea
|
|
|
35
35
|
check(:when)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
def reject_operator_statement_start!
|
|
39
|
+
return unless Token::LINE_START_OPERATOR_TYPES.include?(peek.type)
|
|
40
|
+
|
|
41
|
+
operator = peek.lexeme
|
|
42
|
+
raise error(
|
|
43
|
+
peek,
|
|
44
|
+
"operator '#{operator}' cannot start a statement; end the previous line with it or wrap the expression in ( )"
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
38
48
|
def parse_statement
|
|
49
|
+
reject_operator_statement_start!
|
|
39
50
|
if match(:let)
|
|
40
51
|
parse_local_decl(:let)
|
|
41
52
|
elsif match(:var)
|
|
@@ -314,6 +314,12 @@ module MilkTea
|
|
|
314
314
|
expanded_declarations.grep(AST::AttributeDecl).each do |decl|
|
|
315
315
|
with_error_node(decl) do
|
|
316
316
|
raise_sema_error("duplicate attribute #{decl.name}") if @ctx.attributes.key?(decl.name)
|
|
317
|
+
ensure_non_reserved_value_type_name!(
|
|
318
|
+
decl.name,
|
|
319
|
+
kind_label: "attribute",
|
|
320
|
+
line: decl.line,
|
|
321
|
+
column: decl.column,
|
|
322
|
+
)
|
|
317
323
|
|
|
318
324
|
params = []
|
|
319
325
|
seen = {}
|
|
@@ -463,6 +469,15 @@ module MilkTea
|
|
|
463
469
|
{}
|
|
464
470
|
end
|
|
465
471
|
decl.lifetime_params.each do |lt|
|
|
472
|
+
raw_name = lt.delete_prefix("@")
|
|
473
|
+
unless raw_module?
|
|
474
|
+
ensure_non_reserved_value_type_name!(
|
|
475
|
+
raw_name,
|
|
476
|
+
kind_label: "lifetime parameter #{decl.name}",
|
|
477
|
+
line: decl.line,
|
|
478
|
+
column: decl.column,
|
|
479
|
+
)
|
|
480
|
+
end
|
|
466
481
|
type_params[lt] = Types::LifetimeRef.new(lt)
|
|
467
482
|
end if decl.respond_to?(:lifetime_params)
|
|
468
483
|
type_param_constraints = struct_type.is_a?(Types::GenericStructDefinition) ? struct_type.type_param_constraints : {}
|
|
@@ -528,7 +543,7 @@ module MilkTea
|
|
|
528
543
|
raise_sema_error("duplicate event #{decl.name}.#{event_decl.name}") if events.key?(event_decl.name)
|
|
529
544
|
raise_sema_error("duplicate member #{decl.name}.#{event_decl.name}") if fields.key?(event_decl.name)
|
|
530
545
|
unless raw_module?
|
|
531
|
-
|
|
546
|
+
ensure_non_reserved_value_type_name!(
|
|
532
547
|
event_decl.name,
|
|
533
548
|
kind_label: "event #{decl.name}",
|
|
534
549
|
line: event_decl.line,
|
|
@@ -811,6 +826,14 @@ module MilkTea
|
|
|
811
826
|
fields = {}
|
|
812
827
|
nested.fields.each do |field|
|
|
813
828
|
raise_sema_error("duplicate field #{qualified_name}.#{field.name}") if fields.key?(field.name)
|
|
829
|
+
unless raw_module?
|
|
830
|
+
ensure_non_reserved_value_type_name!(
|
|
831
|
+
field.name,
|
|
832
|
+
kind_label: "field #{qualified_name}",
|
|
833
|
+
line: field.line || nested.line,
|
|
834
|
+
column: field.column,
|
|
835
|
+
)
|
|
836
|
+
end
|
|
814
837
|
begin
|
|
815
838
|
field_type = resolve_type_ref(field.type, type_params:, type_param_constraints:, nested_types: nested_scope)
|
|
816
839
|
validate_stored_ref_type!(field_type, "field #{qualified_name}.#{field.name}")
|
|
@@ -824,6 +847,14 @@ module MilkTea
|
|
|
824
847
|
nested_events = {}
|
|
825
848
|
nested.events.each do |event_decl|
|
|
826
849
|
raise_sema_error("duplicate event #{qualified_name}.#{event_decl.name}") if nested_events.key?(event_decl.name)
|
|
850
|
+
unless raw_module?
|
|
851
|
+
ensure_non_reserved_value_type_name!(
|
|
852
|
+
event_decl.name,
|
|
853
|
+
kind_label: "event #{qualified_name}",
|
|
854
|
+
line: event_decl.line,
|
|
855
|
+
column: event_decl.column,
|
|
856
|
+
)
|
|
857
|
+
end
|
|
827
858
|
begin
|
|
828
859
|
nested_events[event_decl.name] = resolve_event_decl_type(event_decl, type_params:, type_param_constraints:, owner_type_name: qualified_name, nested_types: nested_scope)
|
|
829
860
|
rescue SemanticError => e
|
data/lib/milk_tea/core/token.rb
CHANGED
|
@@ -11,6 +11,23 @@ module MilkTea
|
|
|
11
11
|
amp_equal pipe_equal caret_equal shift_left_equal shift_right_equal
|
|
12
12
|
].freeze
|
|
13
13
|
|
|
14
|
+
# Operator token types that may never begin a statement. A statement
|
|
15
|
+
# that spans multiple lines must end the previous line with one of
|
|
16
|
+
# LINE_CONTINUATION_OPERATORS or wrap the expression in ( ) — it must
|
|
17
|
+
# never start the next line with an operator.
|
|
18
|
+
LINE_START_OPERATOR_TYPES = %i[
|
|
19
|
+
dot_dot plus minus star slash percent
|
|
20
|
+
pipe amp caret tilde
|
|
21
|
+
or and is
|
|
22
|
+
equal_equal bang_equal
|
|
23
|
+
less less_equal greater greater_equal
|
|
24
|
+
shift_left shift_right
|
|
25
|
+
].freeze
|
|
26
|
+
|
|
27
|
+
# Binary operators that continue a statement when they end a physical
|
|
28
|
+
# line. Unary-only `~` is excluded because it has no left operand.
|
|
29
|
+
LINE_CONTINUATION_OPERATORS = (LINE_START_OPERATOR_TYPES - [:tilde]).freeze
|
|
30
|
+
|
|
14
31
|
def assignment?
|
|
15
32
|
ASSIGNMENT_TYPES.include?(type)
|
|
16
33
|
end
|
|
@@ -150,7 +150,19 @@ module MilkTea
|
|
|
150
150
|
column: statement.column,
|
|
151
151
|
var: statement.kind == :var
|
|
152
152
|
)
|
|
153
|
-
|
|
153
|
+
if statement.else_body || statement.else_binding
|
|
154
|
+
with_scope do
|
|
155
|
+
if statement.else_binding
|
|
156
|
+
declare_local(
|
|
157
|
+
statement.else_binding.name,
|
|
158
|
+
statement.else_binding.line,
|
|
159
|
+
column: statement.else_binding.column,
|
|
160
|
+
var: false
|
|
161
|
+
)
|
|
162
|
+
end
|
|
163
|
+
visit_statement_list(statement.else_body) if statement.else_body
|
|
164
|
+
end
|
|
165
|
+
end
|
|
154
166
|
check_redundant_type_annotation(statement)
|
|
155
167
|
flag_redundant_widening_cast(statement.value) if statement.type && statement.value
|
|
156
168
|
record_ptr_candidate(statement)
|
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.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -603,7 +603,7 @@ metadata:
|
|
|
603
603
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
604
604
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
605
605
|
post_install_message: |
|
|
606
|
-
Milk Tea 0.3.
|
|
606
|
+
Milk Tea 0.3.12 installed!
|
|
607
607
|
|
|
608
608
|
System requirements:
|
|
609
609
|
- A C compiler (gcc or clang) must be available on PATH
|