New faults and syntax (#2034)

- Remove `[?]` syntax.
- Change `int!` to `int?` syntax.
- New `fault` declarations.
- Enum associated values can reference the calling enum.
This commit is contained in:
Christoffer Lerno
2025-03-10 00:11:35 +01:00
committed by GitHub
parent fefce25081
commit 25bccf4883
392 changed files with 3129 additions and 3658 deletions

View File

@@ -4,15 +4,8 @@ import libc;
import std::io;
import std::collections::maybe;
fault TitleResult
{
TITLE_MISSING
}
fault ReadError
{
BAD_READ,
}
fault TITLE_MISSING;
fault BAD_READ;
struct Doc
{
@@ -30,14 +23,14 @@ struct Summary
bool ok;
}
fn void! Summary.print(Summary* s, OutStream out)
fn void? Summary.print(Summary* s, OutStream out)
{
io::fprintf(out, "Summary({ .title = %s, .ok = %s})", s.title.get() ?? "missing", s.ok)!;
}
fn Doc! read_doc(String url)
fn Doc? read_doc(String url)
{
if (url.contains("fail")) return ReadError.BAD_READ?;
if (url.contains("fail")) return BAD_READ?;
if (url.contains("head-missing")) return { };
if (url.contains("title-missing")) return { .head = maybe::value{Head}({}) };
if (url.contains("title-empty")) return { .head = maybe::value{Head}({ .title = maybe::value{String}("")}) };
@@ -57,14 +50,14 @@ fn Summary read_and_build_summary(String url)
return build_summary(read_doc(url)) ?? {};
}
fn bool! is_title_non_empty(Doc doc)
fn bool? is_title_non_empty(Doc doc)
{
String! title = doc.head.get().title.get();
if (catch title) return TitleResult.TITLE_MISSING?;
String? title = doc.head.get().title.get();
if (catch title) return TITLE_MISSING?;
return title.len > 0;
}
fn bool! read_whether_title_non_empty(String url)
fn bool? read_whether_title_non_empty(String url)
{
return is_title_non_empty(read_doc(url));
}
@@ -90,7 +83,7 @@ fn void main()
summary.print(out)!!;
io::fprintn(out, "")!!;
io::fprintf(out, " Title: %s\n", summary.title.get() ?? "")!!;
bool! has_title = read_whether_title_non_empty(url);
bool? has_title = read_whether_title_non_empty(url);
// This looks a bit less than elegant, but as you see it's mostly due to having to
// use printf here.
io::fprintf(out, " Has title: %s vs %s\n", bool_to_string(has_title) ?? (@catch(has_title)).nameof, has_title ?? false)!!;

View File

@@ -6,12 +6,9 @@ struct Resource
String name;
}
fault Error
{
WELCOME_TO_YOUR_DOOM
}
fault WELCOME_TO_YOUR_DOOM;
fn Resource! resource_init(String name)
fn Resource? resource_init(String name)
{
io::printfn("open %s", name);
return { name };
@@ -19,7 +16,7 @@ fn Resource! resource_init(String name)
fn void Resource.deinit(Resource this) => io::printfn("close %s", this.name);
macro void! @open_with(String name; @body(Resource resource))
macro void? @open_with(String name; @body(Resource resource))
{
Resource resource = resource_init(name)!;
defer
@@ -30,7 +27,7 @@ macro void! @open_with(String name; @body(Resource resource))
@body(resource);
}
fn Resource! prep_out(String out_name, String[] prep_names)
fn Resource? prep_out(String out_name, String[] prep_names)
{
Resource writer = resource_init(out_name)!; // Rethrow the optional result
defer catch writer.deinit();
@@ -39,7 +36,7 @@ fn Resource! prep_out(String out_name, String[] prep_names)
@open_with(name; Resource reader)
{
io::printfn("use %s", reader.name);
// if (true) return Error.WELCOME_TO_YOUR_DOOM?;
// if (true) return WELCOME_TO_YOUR_DOOM?;
}!;
}
return writer;

View File

@@ -11,27 +11,23 @@ struct Game
int high;
}
fault InputResult
{
NOT_AN_INT,
FAILED_TO_READ,
}
fault NOT_AN_INT, FAILED_TO_READ;
int err_count = 0;
fn int! ask_guess(int high)
fn int? ask_guess(int high)
{
io::printf("Guess a number between 1 and %d: ", high);
String text = io::treadline() ?? InputResult.FAILED_TO_READ?!;
return text.to_int() ?? InputResult.NOT_AN_INT?;
String text = io::treadline() ?? FAILED_TO_READ?!;
return text.to_int() ?? NOT_AN_INT?;
}
fn int! ask_guess_multi(int high)
fn int? ask_guess_multi(int high)
{
while (true)
{
int! result = ask_guess(high);
if (@catch(result) == InputResult.NOT_AN_INT)
int? result = ask_guess(high);
if (@catch(result) == NOT_AN_INT)
{
io::printn("I didn't understand that.");
err_count++;
@@ -41,7 +37,7 @@ fn int! ask_guess_multi(int high)
}
}
fn void! Game.play(Game *game)
fn void? Game.play(Game *game)
{
while (!game.done)
{