Skip to content

Commit 3fb0917

Browse files
olwangclaude
andcommitted
feat(selfhost): AST producer — let-else, if-let, protocols, tuples → (measuring)
- let-else statement (`let Some(x) = e else { … }`) with the reference's off-by-one else-block (parse_block(open+1)) reproduced for byte parity. - if-let (`if let P = e { } else { }`) desugars to a two-arm match (pattern + wildcard). - Protocols fully supported: methods emit in source order as top-level functions with the parse_protocol_decl transforms (Protocol.method name, public, injected Self:Managed generic); `protocol <name>` (section 3) and `protocol-impl … / mapping` (section 4) emit in later passes matching ast_oracle_dump ordering. impls parsed from `impl P for T { m = target }`; native-modules still deferred. - Tuples: types `(A,B)` → __TupleN + args; expressions `(a,b)` → __TupleN(item0:…) call; let-destructure `let (a,_,c) = …` → destructure=a,_,c. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 83bd3b9 commit 3fb0917

8 files changed

Lines changed: 509 additions & 7 deletions

selfhost/astdump.rss

Lines changed: 344 additions & 7 deletions
Large diffs are not rendered by default.

selfhost/samples/ast/x_if_let.rss

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
struct ToolRequest {
2+
name: String
3+
}
4+
5+
fn dispatch(name: read String) -> String {
6+
match name {
7+
"read_file" => { return "read" }
8+
"write_file" => { return "write" }
9+
_ => { return "unknown" }
10+
}
11+
}
12+
13+
fn bool_label(value: Bool) -> String {
14+
return match value {
15+
true => { "yes" }
16+
false => { "no" }
17+
}
18+
}
19+
20+
fn int_label(value: Int) -> String {
21+
return match value {
22+
0 => { "zero" }
23+
1 => { "one" }
24+
_ => { "many" }
25+
}
26+
}
27+
28+
fn maybe_tool(enabled: Bool) -> Option<ToolRequest> {
29+
if enabled {
30+
return Some(ToolRequest(name: "read_file"))
31+
}
32+
return None
33+
}
34+
35+
fn run(enabled: Bool) -> String {
36+
if let Some(tool) = maybe_tool(enabled: enabled) {
37+
return dispatch(name: read tool.name)
38+
}
39+
return "none"
40+
}
41+
42+
fn main() -> Unit {
43+
let result = run(enabled: true)
44+
Log.write(message: read result)
45+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn unwrap_option(value: read Option<String>) -> String {
2+
let Some(inner) = value else {
3+
return "default"
4+
}
5+
return inner
6+
}
7+
8+
fn main() -> Unit {
9+
let result = unwrap_option(value: read Some("hello"))
10+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
features: local
2+
3+
protocol Formatter {
4+
fn format(self: read Self) -> fresh String
5+
}
6+
7+
struct Point {
8+
x: Int
9+
y: Int
10+
}
11+
12+
fn Point.format(self: read Point) -> fresh String {
13+
return String.concat(left: read "point", right: read "!")
14+
}
15+
16+
impl Formatter for Point {
17+
format = Point.format
18+
}
19+
20+
fn print_item<F: Formatter>(item: read F) -> Unit {
21+
let msg = Formatter.format(self: read item)
22+
Log.write(message: read msg)
23+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// expect: RS0015
2+
protocol Writer {
3+
fn write(self: mut Self, message: read String) -> Unit
4+
effects(retains(message))
5+
{
6+
Log.write(message: read message)
7+
}
8+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
features: local
2+
3+
protocol Writer {
4+
fn write(self: mut Self, message: read String) -> Unit
5+
effects(retains(message))
6+
7+
fn flush(self: mut Self) -> Unit
8+
}
9+
10+
class BufferWriter {
11+
buffer: List<String>
12+
}
13+
14+
fn BufferWriter.write(self: mut BufferWriter, message: read String) -> Unit
15+
effects(retains(message))
16+
{
17+
List.push<String>(list: mut self.buffer, value: read message)
18+
}
19+
20+
fn BufferWriter.flush(self: mut BufferWriter) -> Unit {
21+
let count = List.len<String>(list: read self.buffer)
22+
Log.write(message: read "flushed")
23+
}
24+
25+
impl Writer for BufferWriter {
26+
write = BufferWriter.write
27+
flush = BufferWriter.flush
28+
}
29+
30+
fn write_line<W: Writer>(writer: mut W, message: read String) -> Unit
31+
effects(retains(message))
32+
{
33+
Writer.write(self: mut writer, message: read message)
34+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// expect: RS0206
2+
features: local
3+
4+
protocol Formatter {
5+
fn format(self: read Self) -> fresh String
6+
}
7+
8+
struct Report {
9+
title: String
10+
}
11+
12+
fn Report.format(self: read Report) -> fresh String {
13+
return String.concat(left: read "report:", right: read self.title)
14+
}
15+
16+
impl Formatter for Report {
17+
format = Report.format
18+
}
19+
20+
fn display(report: read Report) -> fresh String {
21+
return read report.format()
22+
}

selfhost/samples/ast/x_tuples.rss

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Tuples desugar to synthetic `__TupleN` generic structs: literals `(a, b)`,
2+
// types `(Int, String)`, `.itemN` field access, tuple patterns in `match`, and
3+
// `let (a, b) = ...` destructuring (with `_` to skip an element).
4+
fn classify(p: read (Int, String)) -> fresh String {
5+
match read p {
6+
(0, name) => { return String.concat(left: read "zero-", right: read name) }
7+
(n, name) => { return String.concat(left: read String.from_int(value: n), right: read name) }
8+
}
9+
}
10+
11+
fn sum_first_two(triple: read (Int, Int, Int)) -> Int {
12+
return triple.item0 + triple.item1
13+
}
14+
15+
fn main() -> Unit {
16+
let pair: (Int, String) = (7, "b")
17+
Log.write(message: read classify(p: read pair))
18+
let counts: (Int, Int, Int) = (1, 2, 3)
19+
Log.write(message: read String.from_int(value: sum_first_two(triple: read counts)))
20+
let (first, _, third) = (1, 2, 3)
21+
Log.write(message: read String.from_int(value: first + third))
22+
return Unit
23+
}

0 commit comments

Comments
 (0)