Skip to content

Commit 2e30555

Browse files
committed
wip tryreturn
See #340
1 parent a5c509c commit 2e30555

30 files changed

+321
-350
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ Zig instead of e.g. cmake.
1616

1717
* Compatible with C libraries with no wrapper necessary. Directly include
1818
C .h files and get access to the functions and symbols therein.
19-
* Compile units do not depend on libc unless explicitly linked.
2019
* Provides standard library which competes with the C standard library and is
21-
always compiled against statically in source form.
20+
always compiled against statically in source form. Compile units do not
21+
depend on libc unless explicitly linked.
2222
* Nullable type instead of null pointers.
2323
* Tagged union type instead of raw unions.
2424
* Generics so that one can write efficient data structures that work for any
@@ -45,12 +45,12 @@ Zig instead of e.g. cmake.
4545
* Zig Build System competes with make, cmake, autotools, SCons, etc.
4646
* In addition to creating executables, creating a C library is a primary use
4747
case. You can export an auto-generated .h file.
48-
* Standard library supports OS abstractions for:
48+
* Standard library supports Operating System abstractions for:
4949
* `x86_64` `linux`
5050
* Support for all popular operating systems and architectures is planned.
51-
* For Operating System development, Zig supports all architectures that LLVM
52-
does. All the standard library that does not depend on an OS is available
53-
to you in freestanding mode.
51+
* For OS development, Zig supports all architectures that LLVM does. All the
52+
standard library that does not depend on an OS is available to you in
53+
freestanding mode.
5454

5555
## Community
5656

doc/langref.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ TypeExpr = PrefixOpExpression | "var"
4545
4646
BlockOrExpression = Block | Expression
4747
48-
Expression = ReturnExpression | AssignmentExpression
48+
Expression = "return" option(Expression) | AssignmentExpression
4949
5050
AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")"
5151
@@ -85,8 +85,6 @@ ForExpression(body) = "for" "(" Expression ")" option("|" option("*") Symbol opt
8585
8686
BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression
8787
88-
ReturnExpression = option("%") "return" option(Expression)
89-
9088
Defer(body) = option("%") "defer" body
9189
9290
IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
@@ -141,7 +139,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
141139
142140
StructLiteralField = "." Symbol "=" Expression
143141
144-
PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
142+
PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "tryreturn"
145143
146144
PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
147145
@@ -161,7 +159,7 @@ ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" ma
161159
```
162160
inline x
163161
x() x[] x.y
164-
!x -x -%x ~x *x &x ?x %x %%x ??x
162+
!x -x -%x ~x *x &x ?x %x %%x ??x tryreturn x
165163
x{}
166164
* / % ** *%
167165
+ - ++ +% -%

example/cat/main.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub fn main() -> %void {
1111
const arg = os.args.at(arg_i);
1212
if (mem.eql(u8, arg, "-")) {
1313
catted_anything = true;
14-
%return cat_stream(&io.stdin);
14+
tryreturn cat_stream(&io.stdin);
1515
} else if (arg[0] == '-') {
1616
return usage(exe);
1717
} else {
@@ -22,13 +22,13 @@ pub fn main() -> %void {
2222
defer is.close();
2323

2424
catted_anything = true;
25-
%return cat_stream(&is);
25+
tryreturn cat_stream(&is);
2626
}
2727
}
2828
if (!catted_anything) {
29-
%return cat_stream(&io.stdin);
29+
tryreturn cat_stream(&io.stdin);
3030
}
31-
%return io.stdout.flush();
31+
tryreturn io.stdout.flush();
3232
}
3333

3434
fn usage(exe: []const u8) -> %void {

src/all_types.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -414,15 +414,8 @@ struct AstNodeBlock {
414414
bool last_statement_is_result_expression;
415415
};
416416

417-
enum ReturnKind {
418-
ReturnKindUnconditional,
419-
ReturnKindError,
420-
};
421-
422417
struct AstNodeReturnExpr {
423-
ReturnKind kind;
424-
// might be null in case of return void;
425-
AstNode *expr;
418+
AstNode *expr; // might be null
426419
};
427420

428421
struct AstNodeDefer {
@@ -562,6 +555,7 @@ enum PrefixOp {
562555
PrefixOpError,
563556
PrefixOpUnwrapError,
564557
PrefixOpUnwrapMaybe,
558+
PrefixOpTryReturn,
565559
};
566560

567561
struct AstNodePrefixOpExpr {

src/ast_render.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
7575
case PrefixOpError: return "%";
7676
case PrefixOpUnwrapError: return "%%";
7777
case PrefixOpUnwrapMaybe: return "??";
78+
case PrefixOpTryReturn: return "tryreturn ";
7879
}
7980
zig_unreachable();
8081
}
@@ -91,7 +92,7 @@ static const char *visib_mod_string(VisibMod mod) {
9192
static const char *return_string(ReturnKind kind) {
9293
switch (kind) {
9394
case ReturnKindUnconditional: return "return";
94-
case ReturnKindError: return "%return";
95+
case ReturnKindError: return "tryreturn";
9596
}
9697
zig_unreachable();
9798
}

src/parser.cpp

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,6 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool
220220
static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, bool mandatory);
221221
static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory);
222222
static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod);
223-
static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index);
224223
static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory);
225224
static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);
226225

@@ -1063,6 +1062,7 @@ static PrefixOp tok_to_prefix_op(Token *token) {
10631062
case TokenIdPercentPercent: return PrefixOpUnwrapError;
10641063
case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;
10651064
case TokenIdStarStar: return PrefixOpDereference;
1065+
case TokenIdTryReturn: return PrefixOpTryReturn;
10661066
default: return PrefixOpInvalid;
10671067
}
10681068
}
@@ -1078,13 +1078,6 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
10781078
return ast_parse_suffix_op_expr(pc, token_index, mandatory);
10791079
}
10801080

1081-
if (prefix_op == PrefixOpError || prefix_op == PrefixOpMaybe) {
1082-
Token *maybe_return = &pc->tokens->at(*token_index + 1);
1083-
if (maybe_return->id == TokenIdKeywordReturn) {
1084-
return ast_parse_return_expr(pc, token_index);
1085-
}
1086-
}
1087-
10881081
*token_index += 1;
10891082

10901083

@@ -1464,33 +1457,15 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
14641457
}
14651458

14661459
/*
1467-
ReturnExpression : option("%") "return" option(Expression)
1460+
ReturnExpression = "return" option(Expression)
14681461
*/
14691462
static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) {
14701463
Token *token = &pc->tokens->at(*token_index);
1471-
1472-
NodeType node_type;
1473-
ReturnKind kind;
1474-
1475-
if (token->id == TokenIdPercent) {
1476-
Token *next_token = &pc->tokens->at(*token_index + 1);
1477-
if (next_token->id == TokenIdKeywordReturn) {
1478-
kind = ReturnKindError;
1479-
node_type = NodeTypeReturnExpr;
1480-
*token_index += 2;
1481-
} else {
1482-
return nullptr;
1483-
}
1484-
} else if (token->id == TokenIdKeywordReturn) {
1485-
kind = ReturnKindUnconditional;
1486-
node_type = NodeTypeReturnExpr;
1487-
*token_index += 1;
1488-
} else {
1464+
if (token->id != TokenIdKeywordReturn)
14891465
return nullptr;
1490-
}
1466+
*token_index += 1;
14911467

1492-
AstNode *node = ast_create_node(pc, node_type, token);
1493-
node->data.return_expr.kind = kind;
1468+
AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token);
14941469
node->data.return_expr.expr = ast_parse_expression(pc, token_index, false);
14951470

14961471
return node;
@@ -2010,7 +1985,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in
20101985
}
20111986

20121987
/*
2013-
Expression = ReturnExpression | AssignmentExpression
1988+
Expression = "return" option(Expression) | AssignmentExpression
20141989
*/
20151990
static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory) {
20161991
Token *token = &pc->tokens->at(*token_index);

src/tokenizer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ static const struct ZigKeyword zig_keywords[] = {
139139
{"this", TokenIdKeywordThis},
140140
{"true", TokenIdKeywordTrue},
141141
{"try", TokenIdKeywordTry},
142+
{"tryreturn", TokenIdKeywordTryReturn},
142143
{"undefined", TokenIdKeywordUndefined},
143144
{"union", TokenIdKeywordUnion},
144145
{"unreachable", TokenIdKeywordUnreachable},
@@ -1473,6 +1474,7 @@ const char * token_name(TokenId id) {
14731474
case TokenIdKeywordThis: return "this";
14741475
case TokenIdKeywordTrue: return "true";
14751476
case TokenIdKeywordTry: return "try";
1477+
case TokenIdKeywordTryReturn: return "tryreturn";
14761478
case TokenIdKeywordUndefined: return "undefined";
14771479
case TokenIdKeywordUnion: return "union";
14781480
case TokenIdKeywordUnreachable: return "unreachable";

src/tokenizer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ enum TokenId {
7676
TokenIdKeywordThis,
7777
TokenIdKeywordTrue,
7878
TokenIdKeywordTry,
79+
TokenIdKeywordTryReturn,
7980
TokenIdKeywordUndefined,
8081
TokenIdKeywordUnion,
8182
TokenIdKeywordUnreachable,

std/buf_map.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ pub const BufMap = struct {
2929

3030
pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void {
3131
test (self.hash_map.get(key)) |entry| {
32-
const value_copy = %return self.copy(value);
32+
const value_copy = tryreturn self.copy(value);
3333
%defer self.free(value_copy);
34-
_ = %return self.hash_map.put(key, value_copy);
34+
_ = tryreturn self.hash_map.put(key, value_copy);
3535
self.free(entry.value);
3636
} else {
37-
const key_copy = %return self.copy(key);
37+
const key_copy = tryreturn self.copy(key);
3838
%defer self.free(key_copy);
39-
const value_copy = %return self.copy(value);
39+
const value_copy = tryreturn self.copy(value);
4040
%defer self.free(value_copy);
41-
_ = %return self.hash_map.put(key_copy, value_copy);
41+
_ = tryreturn self.hash_map.put(key_copy, value_copy);
4242
}
4343
}
4444

@@ -63,7 +63,7 @@ pub const BufMap = struct {
6363
}
6464

6565
fn copy(self: &BufMap, value: []const u8) -> %[]const u8 {
66-
const result = %return self.hash_map.allocator.alloc(u8, value.len);
66+
const result = tryreturn self.hash_map.allocator.alloc(u8, value.len);
6767
mem.copy(u8, result, value);
6868
return result;
6969
}

std/buf_set.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ pub const BufSet = struct {
2626

2727
pub fn put(self: &BufSet, key: []const u8) -> %void {
2828
if (self.hash_map.get(key) == null) {
29-
const key_copy = %return self.copy(key);
29+
const key_copy = tryreturn self.copy(key);
3030
%defer self.free(key_copy);
31-
_ = %return self.hash_map.put(key_copy, {});
31+
_ = tryreturn self.hash_map.put(key_copy, {});
3232
}
3333
}
3434

@@ -52,7 +52,7 @@ pub const BufSet = struct {
5252
}
5353

5454
fn copy(self: &BufSet, value: []const u8) -> %[]const u8 {
55-
const result = %return self.hash_map.allocator.alloc(u8, value.len);
55+
const result = tryreturn self.hash_map.allocator.alloc(u8, value.len);
5656
mem.copy(u8, result, value);
5757
return result;
5858
}

std/buffer.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ pub const Buffer = struct {
1010

1111
/// Must deinitialize with deinit.
1212
pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer {
13-
var self = %return initSize(allocator, m.len);
13+
var self = tryreturn initSize(allocator, m.len);
1414
mem.copy(u8, self.list.items, m);
1515
return self;
1616
}
1717

1818
/// Must deinitialize with deinit.
1919
pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer {
2020
var self = initNull(allocator);
21-
%return self.resize(size);
21+
tryreturn self.resize(size);
2222
return self;
2323
}
2424

@@ -51,7 +51,7 @@ pub const Buffer = struct {
5151
}
5252

5353
pub fn resize(self: &Buffer, new_len: usize) -> %void {
54-
%return self.list.resize(new_len + 1);
54+
tryreturn self.list.resize(new_len + 1);
5555
self.list.items[self.len()] = 0;
5656
}
5757

@@ -65,12 +65,12 @@ pub const Buffer = struct {
6565

6666
pub fn append(self: &Buffer, m: []const u8) -> %void {
6767
const old_len = self.len();
68-
%return self.resize(old_len + m.len);
68+
tryreturn self.resize(old_len + m.len);
6969
mem.copy(u8, self.list.toSlice()[old_len...], m);
7070
}
7171

7272
pub fn appendByte(self: &Buffer, byte: u8) -> %void {
73-
%return self.resize(self.len() + 1);
73+
tryreturn self.resize(self.len() + 1);
7474
self.list.items[self.len() - 1] = byte;
7575
}
7676

@@ -91,7 +91,7 @@ pub const Buffer = struct {
9191
}
9292

9393
pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void {
94-
%return self.resize(m.len);
94+
tryreturn self.resize(m.len);
9595
mem.copy(u8, self.list.toSlice(), m);
9696
}
9797
};

0 commit comments

Comments
 (0)