#include #include #include "maybe.h" #define unless(expr) if (!(expr)) #define between(value, min, max) (({ \ __typeof__(value) _value = (value); \ __typeof__(min) _min = (min); \ __typeof__(max) _max = (max); \ _value >= _min && _value <= _max; \ })) #define unwrap_or_else(option, else_block) ({ \ __typeof__(option) _option_##__LINE__ = (option); \ if (!_option_##__LINE__.tag) else_block; \ _option_##__LINE__.value; \ }) #define unwrap_or_else2(option, else_block) ({ \ __typeof__(option) _option_##__LINE__ = (option); \ if (!_option_##__LINE__.tag) { \ __typeof__(option.err) err = _option_##__LINE__.err; \ else_block; \ } \ _option_##__LINE__.value; \ }) #define unwrap(option) ({ \ __typeof__(option) _option_##__LINE__ = (option); \ if (!_option_##__LINE__.tag) { \ fprintf(stderr, "FATAL: File \"%s\", line %d, in %s\n", __FILE__, __LINE__, __func__); abort(); \ } \ _option_##__LINE__.value; \ }) #define unwrap_err(result) ({ \ __typeof__(result) _result_##__LINE__ = (result); \ if (_result_##__LINE__.tag) { \ fprintf(stderr, "FATAL: File \"%s\", line %d, in %s\n", __FILE__, __LINE__, __func__); abort(); \ } \ _result_##__LINE__.err; \ }) #define result_map(result, func) ({ \ __typeof__(result) _result = (result); \ if (_result.tag) _result.value = func(_result.value); \ _result; \ }) #define result_map_err(result, func) ({ \ __typeof__(result) _result = (result); \ if (!_result.tag) _result.err = func(_result.err); \ _result; \ }) #define unwrap_or_else3(result, var, else_block) ({ \ __typeof__(result) _result = (result); \ var = _result.err; \ _result.tag ? _result.value : (else_block); \ }) Option(int) get_foo(bool a) { printf("get_foo() called\n"); return a ? Some(5) : None(int); } Result(str, int) get_string(bool a) { printf("get_string() called\n"); return a ? Ok("Hello, world!", int) : Err(str, 66); } int foo() { puts("Computing foo"); return 5; } str hello(str value) { printf("hello: %s\n", value); return "foo!"; } int main() { /* unless (i == 0 || i == 1) { printf("Hello!\n"); } */ if between(foo(), 1, 8) { printf("Hello!\n"); } int x = unwrap_or(get_foo(false), 66); printf("x = %d\n", x); int z = unwrap_or_else(get_foo(true), { return 1; }); printf("z = %d\n", z); int a = unwrap(get_foo(true)); printf("a %d\n", a); Result(str, int) b = get_string(false); int c = unwrap_err(b); printf("c %d\n", c); str d = unwrap_or(get_string(true), "foo!"); printf("d %s\n", d); str e = unwrap_or_else2(get_string(false), { printf("> %d\n", err); }); Result(str, int) f = result_map(get_string(false), hello); printf("f %d\n", f.err); str g = unwrap_or_else3(get_string(true), int err, { printf("?? %i\n", err); goto error; ""; }); //Result(str, int) xx = Ok(100, int); //Result(str, int) l = Ok(5, int); /* int c; if unwrap(get_foo(true), c) { printf("Hello, world!\n%d\n", c); } */ //int y = expect(get_foo(true), "the world is collapsing!"); /* int i = unwrap_or( get_foo(true) ) { printf("fuck!\n"); } */ ret: return 0; error: return 1; }