authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-12 11:20:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-12 11:20:38-04:00
log29e0e4088e7b742190c0fc9d841ef74764020584
treeadfdacbced5d6cab03d75311c2a657ed94500cc1
parent7b2cb7e679b114057f95692a88a666669246131f
parent0d8646d262ebc3db6631421db8fc79228b6622f8

Merge remote-tracking branch 'origin/master' into self-hosted-cli


6 files changed, 461 insertions(+), 301 deletions(-)

deps/lld/ELF/MarkLive.cpp+9
...@@ -301,6 +301,15 @@ template <class ELFT> void elf::markLive() {...@@ -301,6 +301,15 @@ template <class ELFT> void elf::markLive() {
301 // Follow the graph to mark all live sections.301 // Follow the graph to mark all live sections.
302 doGcSections<ELFT>();302 doGcSections<ELFT>();
303303
304 // If all references to a DSO happen to be weak, the DSO is removed from
305 // DT_NEEDED, which creates dangling shared symbols to non-existent DSO.
306 // We'll replace such symbols with undefined ones to fix it.
307 for (Symbol *Sym : Symtab->getSymbols())
308 if (auto *S = dyn_cast<SharedSymbol>(Sym))
309 if (S->isWeak() && !S->getFile<ELFT>().IsNeeded)
310 replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
311 S->Type);
312
304 // Report garbage-collected sections.313 // Report garbage-collected sections.
305 if (Config->PrintGcSections)314 if (Config->PrintGcSections)
306 for (InputSectionBase *Sec : InputSections)315 for (InputSectionBase *Sec : InputSections)
src/ir.cpp+8-1
...@@ -11804,7 +11804,8 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -11804,7 +11804,8 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
11804 }11804 }
11805 }11805 }
1180611806
11807 bool comptime_arg = param_decl_node->data.param_decl.is_inline;11807 bool comptime_arg = param_decl_node->data.param_decl.is_inline ||
11808 casted_arg->value.type->id == TypeTableEntryIdNumLitInt || casted_arg->value.type->id == TypeTableEntryIdNumLitFloat;
1180811809
11809 ConstExprValue *arg_val;11810 ConstExprValue *arg_val;
1181011811
...@@ -11829,6 +11830,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -11829,6 +11830,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
11829 var->shadowable = !comptime_arg;11830 var->shadowable = !comptime_arg;
1183011831
11831 *next_proto_i += 1;11832 *next_proto_i += 1;
11833 } else if (casted_arg->value.type->id == TypeTableEntryIdNumLitInt ||
11834 casted_arg->value.type->id == TypeTableEntryIdNumLitFloat)
11835 {
11836 ir_add_error(ira, casted_arg,
11837 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/zig-lang/zig/issues/557"));
11838 return false;
11832 }11839 }
1183311840
11834 if (!comptime_arg) {11841 if (!comptime_arg) {
std/zig/ast.zig+13-13
...@@ -214,7 +214,7 @@ pub const NodeVarDecl = struct {...@@ -214,7 +214,7 @@ pub const NodeVarDecl = struct {
214 eq_token: Token,214 eq_token: Token,
215 mut_token: Token,215 mut_token: Token,
216 comptime_token: ?Token,216 comptime_token: ?Token,
217 extern_token: ?Token,217 extern_export_token: ?Token,
218 lib_name: ?&Node,218 lib_name: ?&Node,
219 type_node: ?&Node,219 type_node: ?&Node,
220 align_node: ?&Node,220 align_node: ?&Node,
...@@ -245,7 +245,7 @@ pub const NodeVarDecl = struct {...@@ -245,7 +245,7 @@ pub const NodeVarDecl = struct {
245 pub fn firstToken(self: &NodeVarDecl) Token {245 pub fn firstToken(self: &NodeVarDecl) Token {
246 if (self.visib_token) |visib_token| return visib_token;246 if (self.visib_token) |visib_token| return visib_token;
247 if (self.comptime_token) |comptime_token| return comptime_token;247 if (self.comptime_token) |comptime_token| return comptime_token;
248 if (self.extern_token) |extern_token| return extern_token;248 if (self.extern_export_token) |extern_export_token| return extern_export_token;
249 assert(self.lib_name == null);249 assert(self.lib_name == null);
250 return self.mut_token;250 return self.mut_token;
251 }251 }
...@@ -360,6 +360,7 @@ pub const NodeContainerDecl = struct {...@@ -360,6 +360,7 @@ pub const NodeContainerDecl = struct {
360360
361pub const NodeStructField = struct {361pub const NodeStructField = struct {
362 base: Node,362 base: Node,
363 visib_token: ?Token,
363 name_token: Token,364 name_token: Token,
364 type_expr: &Node,365 type_expr: &Node,
365366
...@@ -373,6 +374,7 @@ pub const NodeStructField = struct {...@@ -373,6 +374,7 @@ pub const NodeStructField = struct {
373 }374 }
374375
375 pub fn firstToken(self: &NodeStructField) Token {376 pub fn firstToken(self: &NodeStructField) Token {
377 if (self.visib_token) |visib_token| return visib_token;
376 return self.name_token;378 return self.name_token;
377 }379 }
378380
...@@ -494,8 +496,7 @@ pub const NodeFnProto = struct {...@@ -494,8 +496,7 @@ pub const NodeFnProto = struct {
494 params: ArrayList(&Node),496 params: ArrayList(&Node),
495 return_type: ReturnType,497 return_type: ReturnType,
496 var_args_token: ?Token,498 var_args_token: ?Token,
497 extern_token: ?Token,499 extern_export_inline_token: ?Token,
498 inline_token: ?Token,
499 cc_token: ?Token,500 cc_token: ?Token,
500 async_attr: ?&NodeAsyncAttribute,501 async_attr: ?&NodeAsyncAttribute,
501 body_node: ?&Node,502 body_node: ?&Node,
...@@ -545,9 +546,8 @@ pub const NodeFnProto = struct {...@@ -545,9 +546,8 @@ pub const NodeFnProto = struct {
545546
546 pub fn firstToken(self: &NodeFnProto) Token {547 pub fn firstToken(self: &NodeFnProto) Token {
547 if (self.visib_token) |visib_token| return visib_token;548 if (self.visib_token) |visib_token| return visib_token;
548 if (self.extern_token) |extern_token| return extern_token;549 if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
549 assert(self.lib_name == null);550 assert(self.lib_name == null);
550 if (self.inline_token) |inline_token| return inline_token;
551 if (self.cc_token) |cc_token| return cc_token;551 if (self.cc_token) |cc_token| return cc_token;
552 return self.fn_token;552 return self.fn_token;
553 }553 }
...@@ -1606,7 +1606,7 @@ pub const NodeThisLiteral = struct {...@@ -1606,7 +1606,7 @@ pub const NodeThisLiteral = struct {
1606pub const NodeAsmOutput = struct {1606pub const NodeAsmOutput = struct {
1607 base: Node,1607 base: Node,
1608 symbolic_name: &NodeIdentifier,1608 symbolic_name: &NodeIdentifier,
1609 constraint: &NodeStringLiteral,1609 constraint: &Node,
1610 kind: Kind,1610 kind: Kind,
16111611
1612 const Kind = union(enum) {1612 const Kind = union(enum) {
...@@ -1620,7 +1620,7 @@ pub const NodeAsmOutput = struct {...@@ -1620,7 +1620,7 @@ pub const NodeAsmOutput = struct {
1620 if (i < 1) return &self.symbolic_name.base;1620 if (i < 1) return &self.symbolic_name.base;
1621 i -= 1;1621 i -= 1;
16221622
1623 if (i < 1) return &self.constraint.base;1623 if (i < 1) return self.constraint;
1624 i -= 1;1624 i -= 1;
16251625
1626 switch (self.kind) {1626 switch (self.kind) {
...@@ -1652,7 +1652,7 @@ pub const NodeAsmOutput = struct {...@@ -1652,7 +1652,7 @@ pub const NodeAsmOutput = struct {
1652pub const NodeAsmInput = struct {1652pub const NodeAsmInput = struct {
1653 base: Node,1653 base: Node,
1654 symbolic_name: &NodeIdentifier,1654 symbolic_name: &NodeIdentifier,
1655 constraint: &NodeStringLiteral,1655 constraint: &Node,
1656 expr: &Node,1656 expr: &Node,
16571657
1658 pub fn iterate(self: &NodeAsmInput, index: usize) ?&Node {1658 pub fn iterate(self: &NodeAsmInput, index: usize) ?&Node {
...@@ -1661,7 +1661,7 @@ pub const NodeAsmInput = struct {...@@ -1661,7 +1661,7 @@ pub const NodeAsmInput = struct {
1661 if (i < 1) return &self.symbolic_name.base;1661 if (i < 1) return &self.symbolic_name.base;
1662 i -= 1;1662 i -= 1;
16631663
1664 if (i < 1) return &self.constraint.base;1664 if (i < 1) return self.constraint;
1665 i -= 1;1665 i -= 1;
16661666
1667 if (i < 1) return self.expr;1667 if (i < 1) return self.expr;
...@@ -1683,11 +1683,11 @@ pub const NodeAsm = struct {...@@ -1683,11 +1683,11 @@ pub const NodeAsm = struct {
1683 base: Node,1683 base: Node,
1684 asm_token: Token,1684 asm_token: Token,
1685 is_volatile: bool,1685 is_volatile: bool,
1686 template: Token,1686 template: &Node,
1687 //tokens: ArrayList(AsmToken),1687 //tokens: ArrayList(AsmToken),
1688 outputs: ArrayList(&NodeAsmOutput),1688 outputs: ArrayList(&NodeAsmOutput),
1689 inputs: ArrayList(&NodeAsmInput),1689 inputs: ArrayList(&NodeAsmInput),
1690 cloppers: ArrayList(&NodeStringLiteral),1690 cloppers: ArrayList(&Node),
1691 rparen: Token,1691 rparen: Token,
16921692
1693 pub fn iterate(self: &NodeAsm, index: usize) ?&Node {1693 pub fn iterate(self: &NodeAsm, index: usize) ?&Node {
...@@ -1699,7 +1699,7 @@ pub const NodeAsm = struct {...@@ -1699,7 +1699,7 @@ pub const NodeAsm = struct {
1699 if (i < self.inputs.len) return &self.inputs.at(index).base;1699 if (i < self.inputs.len) return &self.inputs.at(index).base;
1700 i -= self.inputs.len;1700 i -= self.inputs.len;
17011701
1702 if (i < self.cloppers.len) return &self.cloppers.at(index).base;1702 if (i < self.cloppers.len) return self.cloppers.at(index);
1703 i -= self.cloppers.len;1703 i -= self.cloppers.len;
17041704
1705 return null;1705 return null;
std/zig/parser.zig+420-286
...@@ -55,7 +55,7 @@ pub const Parser = struct {...@@ -55,7 +55,7 @@ pub const Parser = struct {
55 const TopLevelDeclCtx = struct {55 const TopLevelDeclCtx = struct {
56 decls: &ArrayList(&ast.Node),56 decls: &ArrayList(&ast.Node),
57 visib_token: ?Token,57 visib_token: ?Token,
58 extern_token: ?Token,58 extern_export_inline_token: ?Token,
59 lib_name: ?&ast.Node,59 lib_name: ?&ast.Node,
60 };60 };
6161
...@@ -142,6 +142,7 @@ pub const Parser = struct {...@@ -142,6 +142,7 @@ pub const Parser = struct {
142 const State = union(enum) {142 const State = union(enum) {
143 TopLevel,143 TopLevel,
144 TopLevelExtern: TopLevelDeclCtx,144 TopLevelExtern: TopLevelDeclCtx,
145 TopLevelLibname: TopLevelDeclCtx,
145 TopLevelDecl: TopLevelDeclCtx,146 TopLevelDecl: TopLevelDeclCtx,
146 ContainerExtern: ContainerExternCtx,147 ContainerExtern: ContainerExternCtx,
147 ContainerDecl: &ast.NodeContainerDecl,148 ContainerDecl: &ast.NodeContainerDecl,
...@@ -171,12 +172,14 @@ pub const Parser = struct {...@@ -171,12 +172,14 @@ pub const Parser = struct {
171 Semicolon: &const &const ast.Node,172 Semicolon: &const &const ast.Node,
172 AsmOutputItems: &ArrayList(&ast.NodeAsmOutput),173 AsmOutputItems: &ArrayList(&ast.NodeAsmOutput),
173 AsmInputItems: &ArrayList(&ast.NodeAsmInput),174 AsmInputItems: &ArrayList(&ast.NodeAsmInput),
174 AsmClopperItems: &ArrayList(&ast.NodeStringLiteral),175 AsmClopperItems: &ArrayList(&ast.Node),
175 ExprListItemOrEnd: ExprListCtx,176 ExprListItemOrEnd: ExprListCtx,
176 ExprListCommaOrEnd: ExprListCtx,177 ExprListCommaOrEnd: ExprListCtx,
177 FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),178 FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),
178 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),179 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
179 FieldListCommaOrEnd: &ast.NodeContainerDecl,180 FieldListCommaOrEnd: &ast.NodeContainerDecl,
181 IdentifierListItemOrEnd: ListSave(&ast.NodeIdentifier),
182 IdentifierListCommaOrEnd: ListSave(&ast.NodeIdentifier),
180 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),183 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
181 SuspendBody: &ast.NodeSuspend,184 SuspendBody: &ast.NodeSuspend,
182 AsyncEnd: AsyncEndCtx,185 AsyncEnd: AsyncEndCtx,
...@@ -299,7 +302,11 @@ pub const Parser = struct {...@@ -299,7 +302,11 @@ pub const Parser = struct {
299 Token.Id.Keyword_test => {302 Token.Id.Keyword_test => {
300 stack.append(State.TopLevel) catch unreachable;303 stack.append(State.TopLevel) catch unreachable;
301304
302 const name_token = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;305 const name_token = self.getNextToken();
306 const name = (try self.parseStringLiteral(arena, name_token)) ?? {
307 try self.parseError(&stack, name_token, "expected string literal, found {}", @tagName(name_token.id));
308 continue;
309 };
303 const lbrace = (try self.expectToken(&stack, Token.Id.LBrace)) ?? continue;310 const lbrace = (try self.expectToken(&stack, Token.Id.LBrace)) ?? continue;
304311
305 const block = try self.createNode(arena, ast.NodeBlock,312 const block = try self.createNode(arena, ast.NodeBlock,
...@@ -315,7 +322,7 @@ pub const Parser = struct {...@@ -315,7 +322,7 @@ pub const Parser = struct {
315 ast.NodeTestDecl {322 ast.NodeTestDecl {
316 .base = undefined,323 .base = undefined,
317 .test_token = token,324 .test_token = token,
318 .name = &(try self.createLiteral(arena, ast.NodeStringLiteral, name_token)).base,325 .name = name,
319 .body_node = &block.base,326 .body_node = &block.base,
320 }327 }
321 );328 );
...@@ -326,13 +333,13 @@ pub const Parser = struct {...@@ -326,13 +333,13 @@ pub const Parser = struct {
326 root_node.eof_token = token;333 root_node.eof_token = token;
327 return Tree {.root_node = root_node, .arena_allocator = arena_allocator};334 return Tree {.root_node = root_node, .arena_allocator = arena_allocator};
328 },335 },
329 Token.Id.Keyword_pub, Token.Id.Keyword_export => {336 Token.Id.Keyword_pub => {
330 stack.append(State.TopLevel) catch unreachable;337 stack.append(State.TopLevel) catch unreachable;
331 try stack.append(State {338 try stack.append(State {
332 .TopLevelExtern = TopLevelDeclCtx {339 .TopLevelExtern = TopLevelDeclCtx {
333 .decls = &root_node.decls,340 .decls = &root_node.decls,
334 .visib_token = token,341 .visib_token = token,
335 .extern_token = null,342 .extern_export_inline_token = null,
336 .lib_name = null,343 .lib_name = null,
337 }344 }
338 });345 });
...@@ -357,7 +364,7 @@ pub const Parser = struct {...@@ -357,7 +364,7 @@ pub const Parser = struct {
357 .TopLevelExtern = TopLevelDeclCtx {364 .TopLevelExtern = TopLevelDeclCtx {
358 .decls = &root_node.decls,365 .decls = &root_node.decls,
359 .visib_token = null,366 .visib_token = null,
360 .extern_token = null,367 .extern_export_inline_token = null,
361 .lib_name = null,368 .lib_name = null,
362 }369 }
363 });370 });
...@@ -368,42 +375,24 @@ pub const Parser = struct {...@@ -368,42 +375,24 @@ pub const Parser = struct {
368 State.TopLevelExtern => |ctx| {375 State.TopLevelExtern => |ctx| {
369 const token = self.getNextToken();376 const token = self.getNextToken();
370 switch (token.id) {377 switch (token.id) {
371 Token.Id.Keyword_use => {378 Token.Id.Keyword_export, Token.Id.Keyword_inline => {
372 const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
373 ast.NodeUse {
374 .base = undefined,
375 .visib_token = ctx.visib_token,
376 .expr = undefined,
377 .semicolon_token = undefined,
378 }
379 );
380 stack.append(State {379 stack.append(State {
381 .ExpectTokenSave = ExpectTokenSave {380 .TopLevelDecl = TopLevelDeclCtx {
382 .id = Token.Id.Semicolon,381 .decls = ctx.decls,
383 .ptr = &node.semicolon_token,382 .visib_token = ctx.visib_token,
384 }383 .extern_export_inline_token = token,
384 .lib_name = null,
385 },
385 }) catch unreachable;386 }) catch unreachable;
386 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
387 continue;387 continue;
388 },388 },
389 Token.Id.Keyword_extern => {389 Token.Id.Keyword_extern => {
390 const lib_name_token = self.getNextToken();
391 const lib_name = blk: {
392 if (lib_name_token.id == Token.Id.StringLiteral) {
393 const res = try self.createLiteral(arena, ast.NodeStringLiteral, lib_name_token);
394 break :blk &res.base;
395 } else {
396 self.putBackToken(lib_name_token);
397 break :blk null;
398 }
399 };
400
401 stack.append(State {390 stack.append(State {
402 .TopLevelDecl = TopLevelDeclCtx {391 .TopLevelLibname = TopLevelDeclCtx {
403 .decls = ctx.decls,392 .decls = ctx.decls,
404 .visib_token = ctx.visib_token,393 .visib_token = ctx.visib_token,
405 .extern_token = token,394 .extern_export_inline_token = token,
406 .lib_name = lib_name,395 .lib_name = null,
407 },396 },
408 }) catch unreachable;397 }) catch unreachable;
409 continue;398 continue;
...@@ -415,17 +404,67 @@ pub const Parser = struct {...@@ -415,17 +404,67 @@ pub const Parser = struct {
415 }404 }
416 }405 }
417 },406 },
407
408 State.TopLevelLibname => |ctx| {
409 const lib_name = blk: {
410 const lib_name_token = self.getNextToken();
411 break :blk (try self.parseStringLiteral(arena, lib_name_token)) ?? {
412 self.putBackToken(lib_name_token);
413 break :blk null;
414 };
415 };
416
417 stack.append(State {
418 .TopLevelDecl = TopLevelDeclCtx {
419 .decls = ctx.decls,
420 .visib_token = ctx.visib_token,
421 .extern_export_inline_token = ctx.extern_export_inline_token,
422 .lib_name = lib_name,
423 },
424 }) catch unreachable;
425 },
426
418 State.TopLevelDecl => |ctx| {427 State.TopLevelDecl => |ctx| {
419 const token = self.getNextToken();428 const token = self.getNextToken();
420 switch (token.id) {429 switch (token.id) {
430 Token.Id.Keyword_use => {
431 if (ctx.extern_export_inline_token != null) {
432 try self.parseError(&stack, token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
433 continue;
434 }
435
436 const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
437 ast.NodeUse {
438 .base = undefined,
439 .visib_token = ctx.visib_token,
440 .expr = undefined,
441 .semicolon_token = undefined,
442 }
443 );
444 stack.append(State {
445 .ExpectTokenSave = ExpectTokenSave {
446 .id = Token.Id.Semicolon,
447 .ptr = &node.semicolon_token,
448 }
449 }) catch unreachable;
450 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
451 continue;
452 },
421 Token.Id.Keyword_var, Token.Id.Keyword_const => {453 Token.Id.Keyword_var, Token.Id.Keyword_const => {
454 if (ctx.extern_export_inline_token) |extern_export_inline_token| {
455 if (extern_export_inline_token.id == Token.Id.Keyword_inline) {
456 try self.parseError(&stack, token, "Invalid token {}", @tagName(extern_export_inline_token.id));
457 continue;
458 }
459 }
460
422 const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl,461 const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl,
423 ast.NodeVarDecl {462 ast.NodeVarDecl {
424 .base = undefined,463 .base = undefined,
425 .visib_token = ctx.visib_token,464 .visib_token = ctx.visib_token,
426 .mut_token = token,465 .mut_token = token,
427 .comptime_token = null,466 .comptime_token = null,
428 .extern_token = ctx.extern_token,467 .extern_export_token = ctx.extern_export_inline_token,
429 .type_node = null,468 .type_node = null,
430 .align_node = null,469 .align_node = null,
431 .init_node = null,470 .init_node = null,
...@@ -449,8 +488,7 @@ pub const Parser = struct {...@@ -449,8 +488,7 @@ pub const Parser = struct {
449 .params = ArrayList(&ast.Node).init(arena),488 .params = ArrayList(&ast.Node).init(arena),
450 .return_type = undefined,489 .return_type = undefined,
451 .var_args_token = null,490 .var_args_token = null,
452 .extern_token = ctx.extern_token,491 .extern_export_inline_token = ctx.extern_export_inline_token,
453 .inline_token = null,
454 .cc_token = null,492 .cc_token = null,
455 .async_attr = null,493 .async_attr = null,
456 .body_node = null,494 .body_node = null,
...@@ -472,8 +510,7 @@ pub const Parser = struct {...@@ -472,8 +510,7 @@ pub const Parser = struct {
472 .params = ArrayList(&ast.Node).init(arena),510 .params = ArrayList(&ast.Node).init(arena),
473 .return_type = undefined,511 .return_type = undefined,
474 .var_args_token = null,512 .var_args_token = null,
475 .extern_token = ctx.extern_token,513 .extern_export_inline_token = ctx.extern_export_inline_token,
476 .inline_token = null,
477 .cc_token = token,514 .cc_token = token,
478 .async_attr = null,515 .async_attr = null,
479 .body_node = null,516 .body_node = null,
...@@ -510,8 +547,7 @@ pub const Parser = struct {...@@ -510,8 +547,7 @@ pub const Parser = struct {
510 .params = ArrayList(&ast.Node).init(arena),547 .params = ArrayList(&ast.Node).init(arena),
511 .return_type = undefined,548 .return_type = undefined,
512 .var_args_token = null,549 .var_args_token = null,
513 .extern_token = ctx.extern_token,550 .extern_export_inline_token = ctx.extern_export_inline_token,
514 .inline_token = null,
515 .cc_token = null,551 .cc_token = null,
516 .async_attr = async_node,552 .async_attr = async_node,
517 .body_node = null,553 .body_node = null,
...@@ -667,6 +703,7 @@ pub const Parser = struct {...@@ -667,6 +703,7 @@ pub const Parser = struct {
667 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,703 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,
668 ast.NodeStructField {704 ast.NodeStructField {
669 .base = undefined,705 .base = undefined,
706 .visib_token = null,
670 .name_token = token,707 .name_token = token,
671 .type_expr = undefined,708 .type_expr = undefined,
672 }709 }
...@@ -719,13 +756,48 @@ pub const Parser = struct {...@@ -719,13 +756,48 @@ pub const Parser = struct {
719 },756 },
720 }757 }
721 },758 },
722 Token.Id.Keyword_pub, Token.Id.Keyword_export => {759 Token.Id.Keyword_pub => {
760 if (self.eatToken(Token.Id.Identifier)) |identifier| {
761 switch (container_decl.kind) {
762 ast.NodeContainerDecl.Kind.Struct => {
763 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,
764 ast.NodeStructField {
765 .base = undefined,
766 .visib_token = token,
767 .name_token = identifier,
768 .type_expr = undefined,
769 }
770 );
771
772 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
773 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });
774 try stack.append(State { .ExpectToken = Token.Id.Colon });
775 continue;
776 },
777 else => {
778 self.putBackToken(identifier);
779 }
780 }
781 }
782
783 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
784 try stack.append(State {
785 .TopLevelExtern = TopLevelDeclCtx {
786 .decls = &container_decl.fields_and_decls,
787 .visib_token = token,
788 .extern_export_inline_token = null,
789 .lib_name = null,
790 }
791 });
792 continue;
793 },
794 Token.Id.Keyword_export => {
723 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;795 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
724 try stack.append(State {796 try stack.append(State {
725 .TopLevelExtern = TopLevelDeclCtx {797 .TopLevelExtern = TopLevelDeclCtx {
726 .decls = &container_decl.fields_and_decls,798 .decls = &container_decl.fields_and_decls,
727 .visib_token = token,799 .visib_token = token,
728 .extern_token = null,800 .extern_export_inline_token = null,
729 .lib_name = null,801 .lib_name = null,
730 }802 }
731 });803 });
...@@ -742,7 +814,7 @@ pub const Parser = struct {...@@ -742,7 +814,7 @@ pub const Parser = struct {
742 .TopLevelExtern = TopLevelDeclCtx {814 .TopLevelExtern = TopLevelDeclCtx {
743 .decls = &container_decl.fields_and_decls,815 .decls = &container_decl.fields_and_decls,
744 .visib_token = null,816 .visib_token = null,
745 .extern_token = null,817 .extern_export_inline_token = null,
746 .lib_name = null,818 .lib_name = null,
747 }819 }
748 });820 });
...@@ -862,111 +934,11 @@ pub const Parser = struct {...@@ -862,111 +934,11 @@ pub const Parser = struct {
862 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;934 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
863 continue;935 continue;
864 },936 },
865 Token.Id.Keyword_suspend => {
866 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuspend,
867 ast.NodeSuspend {
868 .base = undefined,
869 .suspend_token = token,
870 .payload = null,
871 .body = null,
872 }
873 );
874
875 stack.append(State { .SuspendBody = node }) catch unreachable;
876 try stack.append(State { .Payload = &node.payload });
877 continue;
878 },
879 Token.Id.Keyword_if => {
880 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeIf,
881 ast.NodeIf {
882 .base = undefined,
883 .if_token = token,
884 .condition = undefined,
885 .payload = null,
886 .body = undefined,
887 .@"else" = null,
888 }
889 );
890
891 stack.append(State { .Else = &node.@"else" }) catch unreachable;
892 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
893 try stack.append(State { .PointerPayload = &node.payload });
894 try stack.append(State { .ExpectToken = Token.Id.RParen });
895 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
896 try stack.append(State { .ExpectToken = Token.Id.LParen });
897 continue;
898 },
899 Token.Id.Keyword_while => {
900 stack.append(State {
901 .While = LoopCtx {
902 .label = null,
903 .inline_token = null,
904 .loop_token = token,
905 .dest_ptr = dest_ptr,
906 }
907 }) catch unreachable;
908 continue;
909 },
910 Token.Id.Keyword_for => {
911 stack.append(State {
912 .For = LoopCtx {
913 .label = null,
914 .inline_token = null,
915 .loop_token = token,
916 .dest_ptr = dest_ptr,
917 }
918 }) catch unreachable;
919 continue;
920 },
921 Token.Id.Keyword_switch => {
922 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSwitch,
923 ast.NodeSwitch {
924 .base = undefined,
925 .switch_token = token,
926 .expr = undefined,
927 .cases = ArrayList(&ast.NodeSwitchCase).init(arena),
928 .rbrace = undefined,
929 }
930 );
931
932 stack.append(State {
933 .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) {
934 .list = &node.cases,
935 .ptr = &node.rbrace,
936 },
937 }) catch unreachable;
938 try stack.append(State { .ExpectToken = Token.Id.LBrace });
939 try stack.append(State { .ExpectToken = Token.Id.RParen });
940 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
941 try stack.append(State { .ExpectToken = Token.Id.LParen });
942 },
943 Token.Id.Keyword_comptime => {
944 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeComptime,
945 ast.NodeComptime {
946 .base = undefined,
947 .comptime_token = token,
948 .expr = undefined,
949 }
950 );
951 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
952 continue;
953 },
954 Token.Id.LBrace => {
955 const block = try self.createToDestNode(arena, dest_ptr, ast.NodeBlock,
956 ast.NodeBlock {
957 .base = undefined,
958 .label = null,
959 .lbrace = token,
960 .statements = ArrayList(&ast.Node).init(arena),
961 .rbrace = undefined,
962 }
963 );
964 stack.append(State { .Block = block }) catch unreachable;
965 continue;
966 },
967 else => {937 else => {
968 self.putBackToken(token);938 if (!try self.parseBlockExpr(&stack, arena, dest_ptr, token)) {
969 stack.append(State { .UnwrapExpressionBegin = dest_ptr }) catch unreachable;939 self.putBackToken(token);
940 stack.append(State { .UnwrapExpressionBegin = dest_ptr }) catch unreachable;
941 }
970 continue;942 continue;
971 }943 }
972 }944 }
...@@ -1405,7 +1377,7 @@ pub const Parser = struct {...@@ -1405,7 +1377,7 @@ pub const Parser = struct {
1405 State.PrefixOpExpression => |dest_ptr| {1377 State.PrefixOpExpression => |dest_ptr| {
1406 const token = self.getNextToken();1378 const token = self.getNextToken();
1407 if (tokenIdToPrefixOp(token.id)) |prefix_id| {1379 if (tokenIdToPrefixOp(token.id)) |prefix_id| {
1408 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,1380 var node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1409 ast.NodePrefixOp {1381 ast.NodePrefixOp {
1410 .base = undefined,1382 .base = undefined,
1411 .op_token = token,1383 .op_token = token,
...@@ -1413,6 +1385,20 @@ pub const Parser = struct {...@@ -1413,6 +1385,20 @@ pub const Parser = struct {
1413 .rhs = undefined,1385 .rhs = undefined,
1414 }1386 }
1415 );1387 );
1388
1389 if (token.id == Token.Id.AsteriskAsterisk) {
1390 const child = try self.createNode(arena, ast.NodePrefixOp,
1391 ast.NodePrefixOp {
1392 .base = undefined,
1393 .op_token = token,
1394 .op = prefix_id,
1395 .rhs = undefined,
1396 }
1397 );
1398 node.rhs = &child.base;
1399 node = child;
1400 }
1401
1416 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;1402 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1417 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {1403 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
1418 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });1404 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
...@@ -1515,17 +1501,23 @@ pub const Parser = struct {...@@ -1515,17 +1501,23 @@ pub const Parser = struct {
1515 continue;1501 continue;
1516 },1502 },
1517 Token.Id.Period => {1503 Token.Id.Period => {
1504 const identifier = try self.createLiteral(arena, ast.NodeIdentifier, Token(undefined));
1518 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,1505 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1519 ast.NodeInfixOp {1506 ast.NodeInfixOp {
1520 .base = undefined,1507 .base = undefined,
1521 .lhs = dest_ptr.get(),1508 .lhs = dest_ptr.get(),
1522 .op_token = token,1509 .op_token = token,
1523 .op = ast.NodeInfixOp.InfixOp.Period,1510 .op = ast.NodeInfixOp.InfixOp.Period,
1524 .rhs = undefined,1511 .rhs = &identifier.base,
1525 }1512 }
1526 );1513 );
1527 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;1514 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1528 try stack.append(State { .SuffixOpExpressionBegin = DestPtr { .Field = &node.rhs }});1515 try stack.append(State {
1516 .ExpectTokenSave = ExpectTokenSave {
1517 .id = Token.Id.Identifier,
1518 .ptr = &identifier.token
1519 }
1520 });
1529 continue;1521 continue;
1530 },1522 },
1531 else => {1523 else => {
...@@ -1546,10 +1538,6 @@ pub const Parser = struct {...@@ -1546,10 +1538,6 @@ pub const Parser = struct {
1546 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeFloatLiteral, token)).base);1538 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeFloatLiteral, token)).base);
1547 continue;1539 continue;
1548 },1540 },
1549 Token.Id.StringLiteral => {
1550 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base);
1551 continue;
1552 },
1553 Token.Id.CharLiteral => {1541 Token.Id.CharLiteral => {
1554 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeCharLiteral, token)).base);1542 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeCharLiteral, token)).base);
1555 continue;1543 continue;
...@@ -1578,24 +1566,8 @@ pub const Parser = struct {...@@ -1578,24 +1566,8 @@ pub const Parser = struct {
1578 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base);1566 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base);
1579 continue;1567 continue;
1580 },1568 },
1581 Token.Id.MultilineStringLiteralLine => {1569 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
1582 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeMultilineStringLiteral,1570 dest_ptr.store((try self.parseStringLiteral(arena, token)) ?? unreachable);
1583 ast.NodeMultilineStringLiteral {
1584 .base = undefined,
1585 .tokens = ArrayList(Token).init(arena),
1586 }
1587 );
1588 try node.tokens.append(token);
1589 while (true) {
1590 const multiline_str = self.getNextToken();
1591 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {
1592 self.putBackToken(multiline_str);
1593 break;
1594 }
1595
1596 try node.tokens.append(multiline_str);
1597 }
1598 continue;
1599 },1571 },
1600 Token.Id.LParen => {1572 Token.Id.LParen => {
1601 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeGroupedExpression,1573 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeGroupedExpression,
...@@ -1677,11 +1649,8 @@ pub const Parser = struct {...@@ -1677,11 +1649,8 @@ pub const Parser = struct {
16771649
1678 },1650 },
1679 Token.Id.Keyword_error => {1651 Token.Id.Keyword_error => {
1680 const next = self.getNextToken();1652 if (self.eatToken(Token.Id.LBrace) == null) {
1681
1682 if (next.id != Token.Id.LBrace) {
1683 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeErrorType, token)).base);1653 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeErrorType, token)).base);
1684 self.putBackToken(next);
1685 continue;1654 continue;
1686 }1655 }
16871656
...@@ -1694,43 +1663,12 @@ pub const Parser = struct {...@@ -1694,43 +1663,12 @@ pub const Parser = struct {
1694 }1663 }
1695 );1664 );
16961665
1697 while (true) {1666 stack.append(State {
1698 const t = self.getNextToken();1667 .IdentifierListItemOrEnd = ListSave(&ast.NodeIdentifier) {
1699 switch (t.id) {1668 .list = &node.decls,
1700 Token.Id.RBrace => {1669 .ptr = &node.rbrace_token,
1701 node.rbrace_token = t;
1702 break;
1703 },
1704 Token.Id.Identifier => {
1705 try node.decls.append(
1706 try self.createLiteral(arena, ast.NodeIdentifier, t)
1707 );
1708 },
1709 else => {
1710 try self.parseError(&stack, token, "expected {} or {}, found {}",
1711 @tagName(Token.Id.RBrace),
1712 @tagName(Token.Id.Identifier),
1713 @tagName(token.id));
1714 continue;
1715 }
1716 }
1717
1718 const t2 = self.getNextToken();
1719 switch (t2.id) {
1720 Token.Id.RBrace => {
1721 node.rbrace_token = t;
1722 break;
1723 },
1724 Token.Id.Comma => continue,
1725 else => {
1726 try self.parseError(&stack, token, "expected {} or {}, found {}",
1727 @tagName(Token.Id.RBrace),
1728 @tagName(Token.Id.Comma),
1729 @tagName(token.id));
1730 continue;
1731 }
1732 }1670 }
1733 }1671 }) catch unreachable;
1734 continue;1672 continue;
1735 },1673 },
1736 Token.Id.Keyword_packed => {1674 Token.Id.Keyword_packed => {
...@@ -1754,8 +1692,7 @@ pub const Parser = struct {...@@ -1754,8 +1692,7 @@ pub const Parser = struct {
1754 .params = ArrayList(&ast.Node).init(arena),1692 .params = ArrayList(&ast.Node).init(arena),
1755 .return_type = undefined,1693 .return_type = undefined,
1756 .var_args_token = null,1694 .var_args_token = null,
1757 .extern_token = token,1695 .extern_export_inline_token = token,
1758 .inline_token = null,
1759 .cc_token = null,1696 .cc_token = null,
1760 .async_attr = null,1697 .async_attr = null,
1761 .body_node = null,1698 .body_node = null,
...@@ -1812,8 +1749,7 @@ pub const Parser = struct {...@@ -1812,8 +1749,7 @@ pub const Parser = struct {
1812 .params = ArrayList(&ast.Node).init(arena),1749 .params = ArrayList(&ast.Node).init(arena),
1813 .return_type = undefined,1750 .return_type = undefined,
1814 .var_args_token = null,1751 .var_args_token = null,
1815 .extern_token = null,1752 .extern_export_inline_token = null,
1816 .inline_token = null,
1817 .cc_token = null,1753 .cc_token = null,
1818 .async_attr = null,1754 .async_attr = null,
1819 .body_node = null,1755 .body_node = null,
...@@ -1835,8 +1771,7 @@ pub const Parser = struct {...@@ -1835,8 +1771,7 @@ pub const Parser = struct {
1835 .params = ArrayList(&ast.Node).init(arena),1771 .params = ArrayList(&ast.Node).init(arena),
1836 .return_type = undefined,1772 .return_type = undefined,
1837 .var_args_token = null,1773 .var_args_token = null,
1838 .extern_token = null,1774 .extern_export_inline_token = null,
1839 .inline_token = null,
1840 .cc_token = token,1775 .cc_token = token,
1841 .async_attr = null,1776 .async_attr = null,
1842 .body_node = null,1777 .body_node = null,
...@@ -1857,7 +1792,12 @@ pub const Parser = struct {...@@ -1857,7 +1792,12 @@ pub const Parser = struct {
1857 break :blk true;1792 break :blk true;
1858 };1793 };
1859 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;1794 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
1860 const template = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;1795
1796 const template_token = self.getNextToken();
1797 const template = (try self.parseStringLiteral(arena, template_token)) ?? {
1798 try self.parseError(&stack, template_token, "expected string literal, found {}", @tagName(template_token.id));
1799 continue;
1800 };
1861 // TODO parse template1801 // TODO parse template
18621802
1863 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeAsm,1803 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeAsm,
...@@ -1869,7 +1809,7 @@ pub const Parser = struct {...@@ -1869,7 +1809,7 @@ pub const Parser = struct {
1869 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),1809 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
1870 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),1810 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),
1871 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),1811 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),
1872 .cloppers = ArrayList(&ast.NodeStringLiteral).init(arena),1812 .cloppers = ArrayList(&ast.Node).init(arena),
1873 .rparen = undefined,1813 .rparen = undefined,
1874 }1814 }
1875 );1815 );
...@@ -1897,7 +1837,9 @@ pub const Parser = struct {...@@ -1897,7 +1837,9 @@ pub const Parser = struct {
1897 continue;1837 continue;
1898 },1838 },
1899 else => {1839 else => {
1900 try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id));1840 if (!try self.parseBlockExpr(&stack, arena, dest_ptr, token)) {
1841 try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id));
1842 }
1901 continue;1843 continue;
1902 }1844 }
1903 }1845 }
...@@ -1955,7 +1897,12 @@ pub const Parser = struct {...@@ -1955,7 +1897,12 @@ pub const Parser = struct {
19551897
1956 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;1898 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
1957 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;1899 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;
1958 const constraint = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;1900
1901 const constraint_token = self.getNextToken();
1902 const constraint = (try self.parseStringLiteral(arena, constraint_token)) ?? {
1903 try self.parseError(&stack, constraint_token, "expected string literal, found {}", @tagName(constraint_token.id));
1904 continue;
1905 };
19591906
1960 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;1907 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
1961 try stack.append(State { .ExpectToken = Token.Id.RParen });1908 try stack.append(State { .ExpectToken = Token.Id.RParen });
...@@ -1964,7 +1911,7 @@ pub const Parser = struct {...@@ -1964,7 +1911,7 @@ pub const Parser = struct {
1964 ast.NodeAsmOutput {1911 ast.NodeAsmOutput {
1965 .base = undefined,1912 .base = undefined,
1966 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),1913 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
1967 .constraint = try self.createLiteral(arena, ast.NodeStringLiteral, constraint),1914 .constraint = constraint,
1968 .kind = undefined,1915 .kind = undefined,
1969 }1916 }
1970 );1917 );
...@@ -2000,7 +1947,12 @@ pub const Parser = struct {...@@ -2000,7 +1947,12 @@ pub const Parser = struct {
20001947
2001 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;1948 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
2002 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;1949 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;
2003 const constraint = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;1950
1951 const constraint_token = self.getNextToken();
1952 const constraint = (try self.parseStringLiteral(arena, constraint_token)) ?? {
1953 try self.parseError(&stack, constraint_token, "expected string literal, found {}", @tagName(constraint_token.id));
1954 continue;
1955 };
20041956
2005 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;1957 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
2006 try stack.append(State { .ExpectToken = Token.Id.RParen });1958 try stack.append(State { .ExpectToken = Token.Id.RParen });
...@@ -2009,7 +1961,7 @@ pub const Parser = struct {...@@ -2009,7 +1961,7 @@ pub const Parser = struct {
2009 ast.NodeAsmInput {1961 ast.NodeAsmInput {
2010 .base = undefined,1962 .base = undefined,
2011 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),1963 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
2012 .constraint = try self.createLiteral(arena, ast.NodeStringLiteral, constraint),1964 .constraint = constraint,
2013 .expr = undefined,1965 .expr = undefined,
2014 }1966 }
2015 );1967 );
...@@ -2018,13 +1970,13 @@ pub const Parser = struct {...@@ -2018,13 +1970,13 @@ pub const Parser = struct {
2018 },1970 },
20191971
2020 State.AsmClopperItems => |items| {1972 State.AsmClopperItems => |items| {
2021 const string = self.getNextToken();1973 const string_token = self.getNextToken();
2022 if (string.id != Token.Id.StringLiteral) {1974 const string = (try self.parseStringLiteral(arena, string_token)) ?? {
2023 self.putBackToken(string);1975 self.putBackToken(string_token);
2024 continue;1976 continue;
2025 }1977 };
1978 try items.append(string);
20261979
2027 try items.append(try self.createLiteral(arena, ast.NodeStringLiteral, string));
2028 stack.append(State { .AsmClopperItems = items }) catch unreachable;1980 stack.append(State { .AsmClopperItems = items }) catch unreachable;
2029 try stack.append(State { .IfToken = Token.Id.Comma });1981 try stack.append(State { .IfToken = Token.Id.Comma });
2030 },1982 },
...@@ -2076,6 +2028,24 @@ pub const Parser = struct {...@@ -2076,6 +2028,24 @@ pub const Parser = struct {
2076 });2028 });
2077 },2029 },
20782030
2031 State.IdentifierListItemOrEnd => |list_state| {
2032 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
2033 *list_state.ptr = rbrace;
2034 continue;
2035 }
2036
2037 const node = try self.createLiteral(arena, ast.NodeIdentifier, Token(undefined));
2038 try list_state.list.append(node);
2039
2040 stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable;
2041 try stack.append(State {
2042 .ExpectTokenSave = ExpectTokenSave {
2043 .id = Token.Id.Identifier,
2044 .ptr = &node.token,
2045 }
2046 });
2047 },
2048
2079 State.SwitchCaseOrEnd => |list_state| {2049 State.SwitchCaseOrEnd => |list_state| {
2080 if (self.eatToken(Token.Id.RBrace)) |rbrace| {2050 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
2081 *list_state.ptr = rbrace;2051 *list_state.ptr = rbrace;
...@@ -2092,7 +2062,7 @@ pub const Parser = struct {...@@ -2092,7 +2062,7 @@ pub const Parser = struct {
2092 );2062 );
2093 try list_state.list.append(node);2063 try list_state.list.append(node);
2094 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;2064 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
2095 try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } });2065 try stack.append(State { .AssignmentExpressionBegin = DestPtr{ .Field = &node.expr } });
2096 try stack.append(State { .PointerPayload = &node.payload });2066 try stack.append(State { .PointerPayload = &node.payload });
20972067
2098 const maybe_else = self.getNextToken();2068 const maybe_else = self.getNextToken();
...@@ -2133,6 +2103,11 @@ pub const Parser = struct {...@@ -2133,6 +2103,11 @@ pub const Parser = struct {
2133 continue;2103 continue;
2134 },2104 },
21352105
2106 State.IdentifierListCommaOrEnd => |list_state| {
2107 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .IdentifierListItemOrEnd = list_state });
2108 continue;
2109 },
2110
2136 State.SwitchCaseCommaOrEnd => |list_state| {2111 State.SwitchCaseCommaOrEnd => |list_state| {
2137 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state });2112 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state });
2138 continue;2113 continue;
...@@ -2355,12 +2330,14 @@ pub const Parser = struct {...@@ -2355,12 +2330,14 @@ pub const Parser = struct {
2355 },2330 },
23562331
2357 State.FnProtoAlign => |fn_proto| {2332 State.FnProtoAlign => |fn_proto| {
2333 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;
2334
2358 if (self.eatToken(Token.Id.Keyword_align)) |align_token| {2335 if (self.eatToken(Token.Id.Keyword_align)) |align_token| {
2359 @panic("TODO fn proto align");2336 try stack.append(State { .ExpectToken = Token.Id.RParen });
2337 try stack.append(State { .Expression = DestPtr { .NullableField = &fn_proto.align_expr } });
2338 try stack.append(State { .ExpectToken = Token.Id.LParen });
2360 }2339 }
2361 stack.append(State {2340
2362 .FnProtoReturnType = fn_proto,
2363 }) catch unreachable;
2364 continue;2341 continue;
2365 },2342 },
23662343
...@@ -2374,11 +2351,17 @@ pub const Parser = struct {...@@ -2374,11 +2351,17 @@ pub const Parser = struct {
2374 }) catch unreachable;2351 }) catch unreachable;
2375 continue;2352 continue;
2376 },2353 },
2377 Token.Id.Keyword_align => {
2378 @panic("TODO fn proto align");
2379 continue;
2380 },
2381 else => {2354 else => {
2355 // TODO: this is a special case. Remove this when #760 is fixed
2356 if (token.id == Token.Id.Keyword_error) {
2357 if (self.isPeekToken(Token.Id.LBrace)) {
2358 fn_proto.return_type = ast.NodeFnProto.ReturnType {
2359 .Explicit = &(try self.createLiteral(arena, ast.NodeErrorType, token)).base
2360 };
2361 continue;
2362 }
2363 }
2364
2382 self.putBackToken(token);2365 self.putBackToken(token);
2383 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };2366 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
2384 stack.append(State {2367 stack.append(State {
...@@ -2628,7 +2611,7 @@ pub const Parser = struct {...@@ -2628,7 +2611,7 @@ pub const Parser = struct {
2628 .visib_token = null,2611 .visib_token = null,
2629 .mut_token = mut_token,2612 .mut_token = mut_token,
2630 .comptime_token = next,2613 .comptime_token = next,
2631 .extern_token = null,2614 .extern_export_token = null,
2632 .type_node = null,2615 .type_node = null,
2633 .align_node = null,2616 .align_node = null,
2634 .init_node = null,2617 .init_node = null,
...@@ -2656,7 +2639,7 @@ pub const Parser = struct {...@@ -2656,7 +2639,7 @@ pub const Parser = struct {
2656 .visib_token = null,2639 .visib_token = null,
2657 .mut_token = next,2640 .mut_token = next,
2658 .comptime_token = null,2641 .comptime_token = null,
2659 .extern_token = null,2642 .extern_export_token = null,
2660 .type_node = null,2643 .type_node = null,
2661 .align_node = null,2644 .align_node = null,
2662 .init_node = null,2645 .init_node = null,
...@@ -2747,7 +2730,7 @@ pub const Parser = struct {...@@ -2747,7 +2730,7 @@ pub const Parser = struct {
2747 continue;2730 continue;
2748 }2731 }
27492732
2750 n = while_node.body;2733 return while_node.body.id != ast.Node.Id.Block;
2751 },2734 },
2752 ast.Node.Id.For => {2735 ast.Node.Id.For => {
2753 const for_node = @fieldParentPtr(ast.NodeFor, "base", n);2736 const for_node = @fieldParentPtr(ast.NodeFor, "base", n);
...@@ -2756,7 +2739,7 @@ pub const Parser = struct {...@@ -2756,7 +2739,7 @@ pub const Parser = struct {
2756 continue;2739 continue;
2757 }2740 }
27582741
2759 n = for_node.body;2742 return for_node.body.id != ast.Node.Id.Block;
2760 },2743 },
2761 ast.Node.Id.If => {2744 ast.Node.Id.If => {
2762 const if_node = @fieldParentPtr(ast.NodeIf, "base", n);2745 const if_node = @fieldParentPtr(ast.NodeIf, "base", n);
...@@ -2765,25 +2748,25 @@ pub const Parser = struct {...@@ -2765,25 +2748,25 @@ pub const Parser = struct {
2765 continue;2748 continue;
2766 }2749 }
27672750
2768 n = if_node.body;2751 return if_node.body.id != ast.Node.Id.Block;
2769 },2752 },
2770 ast.Node.Id.Else => {2753 ast.Node.Id.Else => {
2771 const else_node = @fieldParentPtr(ast.NodeElse, "base", n);2754 const else_node = @fieldParentPtr(ast.NodeElse, "base", n);
2772 n = else_node.body;2755 n = else_node.body;
2756 continue;
2773 },2757 },
2774 ast.Node.Id.Defer => {2758 ast.Node.Id.Defer => {
2775 const defer_node = @fieldParentPtr(ast.NodeDefer, "base", n);2759 const defer_node = @fieldParentPtr(ast.NodeDefer, "base", n);
2776 n = defer_node.expr;2760 return defer_node.expr.id != ast.Node.Id.Block;
2777 },2761 },
2778 ast.Node.Id.Comptime => {2762 ast.Node.Id.Comptime => {
2779 const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n);2763 const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n);
2780 n = comptime_node.expr;2764 return comptime_node.expr.id != ast.Node.Id.Block;
2781 },2765 },
2782 ast.Node.Id.Suspend => {2766 ast.Node.Id.Suspend => {
2783 const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", n);2767 const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", n);
2784 if (suspend_node.body) |body| {2768 if (suspend_node.body) |body| {
2785 n = body;2769 return body.id != ast.Node.Id.Block;
2786 continue;
2787 }2770 }
27882771
2789 return true;2772 return true;
...@@ -2793,6 +2776,148 @@ pub const Parser = struct {...@@ -2793,6 +2776,148 @@ pub const Parser = struct {
2793 }2776 }
2794 }2777 }
27952778
2779 fn parseStringLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !?&ast.Node {
2780 switch (token.id) {
2781 Token.Id.StringLiteral => {
2782 return &(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base;
2783 },
2784 Token.Id.MultilineStringLiteralLine => {
2785 const node = try self.createNode(arena, ast.NodeMultilineStringLiteral,
2786 ast.NodeMultilineStringLiteral {
2787 .base = undefined,
2788 .tokens = ArrayList(Token).init(arena),
2789 }
2790 );
2791 try node.tokens.append(token);
2792 while (true) {
2793 const multiline_str = self.getNextToken();
2794 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {
2795 self.putBackToken(multiline_str);
2796 break;
2797 }
2798
2799 try node.tokens.append(multiline_str);
2800 }
2801
2802 return &node.base;
2803 },
2804 // TODO: We shouldn't need a cast, but:
2805 // zig: /home/jc/Documents/zig/src/ir.cpp:7962: TypeTableEntry* ir_resolve_peer_types(IrAnalyze*, AstNode*, IrInstruction**, size_t): Assertion `err_set_type != nullptr' failed.
2806 else => return (?&ast.Node)(null),
2807 }
2808 }
2809
2810 fn parseBlockExpr(self: &Parser, stack: &ArrayList(State), arena: &mem.Allocator, dest_ptr: &const DestPtr, token: &const Token) !bool {
2811 switch (token.id) {
2812 Token.Id.Keyword_suspend => {
2813 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuspend,
2814 ast.NodeSuspend {
2815 .base = undefined,
2816 .suspend_token = *token,
2817 .payload = null,
2818 .body = null,
2819 }
2820 );
2821
2822 stack.append(State { .SuspendBody = node }) catch unreachable;
2823 try stack.append(State { .Payload = &node.payload });
2824 return true;
2825 },
2826 Token.Id.Keyword_if => {
2827 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeIf,
2828 ast.NodeIf {
2829 .base = undefined,
2830 .if_token = *token,
2831 .condition = undefined,
2832 .payload = null,
2833 .body = undefined,
2834 .@"else" = null,
2835 }
2836 );
2837
2838 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2839 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2840 try stack.append(State { .PointerPayload = &node.payload });
2841 try stack.append(State { .ExpectToken = Token.Id.RParen });
2842 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
2843 try stack.append(State { .ExpectToken = Token.Id.LParen });
2844 return true;
2845 },
2846 Token.Id.Keyword_while => {
2847 stack.append(State {
2848 .While = LoopCtx {
2849 .label = null,
2850 .inline_token = null,
2851 .loop_token = *token,
2852 .dest_ptr = *dest_ptr,
2853 }
2854 }) catch unreachable;
2855 return true;
2856 },
2857 Token.Id.Keyword_for => {
2858 stack.append(State {
2859 .For = LoopCtx {
2860 .label = null,
2861 .inline_token = null,
2862 .loop_token = *token,
2863 .dest_ptr = *dest_ptr,
2864 }
2865 }) catch unreachable;
2866 return true;
2867 },
2868 Token.Id.Keyword_switch => {
2869 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSwitch,
2870 ast.NodeSwitch {
2871 .base = undefined,
2872 .switch_token = *token,
2873 .expr = undefined,
2874 .cases = ArrayList(&ast.NodeSwitchCase).init(arena),
2875 .rbrace = undefined,
2876 }
2877 );
2878
2879 stack.append(State {
2880 .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) {
2881 .list = &node.cases,
2882 .ptr = &node.rbrace,
2883 },
2884 }) catch unreachable;
2885 try stack.append(State { .ExpectToken = Token.Id.LBrace });
2886 try stack.append(State { .ExpectToken = Token.Id.RParen });
2887 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2888 try stack.append(State { .ExpectToken = Token.Id.LParen });
2889 return true;
2890 },
2891 Token.Id.Keyword_comptime => {
2892 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeComptime,
2893 ast.NodeComptime {
2894 .base = undefined,
2895 .comptime_token = *token,
2896 .expr = undefined,
2897 }
2898 );
2899 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2900 return true;
2901 },
2902 Token.Id.LBrace => {
2903 const block = try self.createToDestNode(arena, dest_ptr, ast.NodeBlock,
2904 ast.NodeBlock {
2905 .base = undefined,
2906 .label = null,
2907 .lbrace = *token,
2908 .statements = ArrayList(&ast.Node).init(arena),
2909 .rbrace = undefined,
2910 }
2911 );
2912 stack.append(State { .Block = block }) catch unreachable;
2913 return true;
2914 },
2915 else => {
2916 return false;
2917 }
2918 }
2919 }
2920
2796 fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, maybe_ptr: ?&Token, state_after_comma: &const State) !void {2921 fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, maybe_ptr: ?&Token, state_after_comma: &const State) !void {
2797 var token = self.getNextToken();2922 var token = self.getNextToken();
2798 switch (token.id) {2923 switch (token.id) {
...@@ -2884,7 +3009,7 @@ pub const Parser = struct {...@@ -2884,7 +3009,7 @@ pub const Parser = struct {
2884 Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} },3009 Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} },
2885 Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} },3010 Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} },
2886 Token.Id.MinusPercent => ast.NodePrefixOp.PrefixOp { .NegationWrap = void{} },3011 Token.Id.MinusPercent => ast.NodePrefixOp.PrefixOp { .NegationWrap = void{} },
2887 Token.Id.Asterisk => ast.NodePrefixOp.PrefixOp { .Deref = void{} },3012 Token.Id.Asterisk, Token.Id.AsteriskAsterisk => ast.NodePrefixOp.PrefixOp { .Deref = void{} },
2888 Token.Id.Ampersand => ast.NodePrefixOp.PrefixOp {3013 Token.Id.Ampersand => ast.NodePrefixOp.PrefixOp {
2889 .AddrOf = ast.NodePrefixOp.AddrOfInfo {3014 .AddrOf = ast.NodePrefixOp.AddrOfInfo {
2890 .align_expr = null,3015 .align_expr = null,
...@@ -2897,6 +3022,7 @@ pub const Parser = struct {...@@ -2897,6 +3022,7 @@ pub const Parser = struct {
2897 Token.Id.QuestionMark => ast.NodePrefixOp.PrefixOp { .MaybeType = void{} },3022 Token.Id.QuestionMark => ast.NodePrefixOp.PrefixOp { .MaybeType = void{} },
2898 Token.Id.QuestionMarkQuestionMark => ast.NodePrefixOp.PrefixOp { .UnwrapMaybe = void{} },3023 Token.Id.QuestionMarkQuestionMark => ast.NodePrefixOp.PrefixOp { .UnwrapMaybe = void{} },
2899 Token.Id.Keyword_await => ast.NodePrefixOp.PrefixOp { .Await = void{} },3024 Token.Id.Keyword_await => ast.NodePrefixOp.PrefixOp { .Await = void{} },
3025 Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{ } },
2900 else => null,3026 else => null,
2901 };3027 };
2902 }3028 }
...@@ -3051,7 +3177,6 @@ pub const Parser = struct {...@@ -3051,7 +3177,6 @@ pub const Parser = struct {
30513177
3052 const RenderState = union(enum) {3178 const RenderState = union(enum) {
3053 TopLevelDecl: &ast.Node,3179 TopLevelDecl: &ast.Node,
3054 FnProtoRParen: &ast.NodeFnProto,
3055 ParamDecl: &ast.Node,3180 ParamDecl: &ast.Node,
3056 Text: []const u8,3181 Text: []const u8,
3057 Expression: &ast.Node,3182 Expression: &ast.Node,
...@@ -3129,6 +3254,9 @@ pub const Parser = struct {...@@ -3129,6 +3254,9 @@ pub const Parser = struct {
3129 },3254 },
3130 ast.Node.Id.StructField => {3255 ast.Node.Id.StructField => {
3131 const field = @fieldParentPtr(ast.NodeStructField, "base", decl);3256 const field = @fieldParentPtr(ast.NodeStructField, "base", decl);
3257 if (field.visib_token) |visib_token| {
3258 try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
3259 }
3132 try stream.print("{}: ", self.tokenizer.getTokenSlice(field.name_token));3260 try stream.print("{}: ", self.tokenizer.getTokenSlice(field.name_token));
3133 try stack.append(RenderState { .Expression = field.type_expr});3261 try stack.append(RenderState { .Expression = field.type_expr});
3134 },3262 },
...@@ -3190,13 +3318,13 @@ pub const Parser = struct {...@@ -3190,13 +3318,13 @@ pub const Parser = struct {
3190 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(comptime_token) });3318 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(comptime_token) });
3191 }3319 }
31923320
3193 if (var_decl.extern_token) |extern_token| {3321 if (var_decl.extern_export_token) |extern_export_token| {
3194 if (var_decl.lib_name != null) {3322 if (var_decl.lib_name != null) {
3195 try stack.append(RenderState { .Text = " " });3323 try stack.append(RenderState { .Text = " " });
3196 try stack.append(RenderState { .Expression = ??var_decl.lib_name });3324 try stack.append(RenderState { .Expression = ??var_decl.lib_name });
3197 }3325 }
3198 try stack.append(RenderState { .Text = " " });3326 try stack.append(RenderState { .Text = " " });
3199 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });3327 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_token) });
3200 }3328 }
32013329
3202 if (var_decl.visib_token) |visib_token| {3330 if (var_decl.visib_token) |visib_token| {
...@@ -3737,8 +3865,10 @@ pub const Parser = struct {...@@ -3737,8 +3865,10 @@ pub const Parser = struct {
3737 },3865 },
3738 }3866 }
37393867
3740 if (fn_proto.align_expr != null) {3868 if (fn_proto.align_expr) |align_expr| {
3741 @panic("TODO");3869 try stack.append(RenderState { .Text = ") " });
3870 try stack.append(RenderState { .Expression = align_expr});
3871 try stack.append(RenderState { .Text = "align(" });
3742 }3872 }
37433873
3744 try stack.append(RenderState { .Text = ") " });3874 try stack.append(RenderState { .Text = ") " });
...@@ -3774,9 +3904,9 @@ pub const Parser = struct {...@@ -3774,9 +3904,9 @@ pub const Parser = struct {
3774 try stack.append(RenderState { .Text = " " });3904 try stack.append(RenderState { .Text = " " });
3775 try stack.append(RenderState { .Expression = lib_name });3905 try stack.append(RenderState { .Expression = lib_name });
3776 }3906 }
3777 if (fn_proto.extern_token) |extern_token| {3907 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
3778 try stack.append(RenderState { .Text = " " });3908 try stack.append(RenderState { .Text = " " });
3779 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });3909 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_inline_token) });
3780 }3910 }
37813911
3782 if (fn_proto.visib_token) |visib_token| {3912 if (fn_proto.visib_token) |visib_token| {
...@@ -4021,8 +4151,6 @@ pub const Parser = struct {...@@ -4021,8 +4151,6 @@ pub const Parser = struct {
4021 try stream.write("volatile ");4151 try stream.write("volatile ");
4022 }4152 }
40234153
4024 try stream.print("({}", self.tokenizer.getTokenSlice(asm_node.template));
4025
4026 try stack.append(RenderState { .Indent = indent });4154 try stack.append(RenderState { .Indent = indent });
4027 try stack.append(RenderState { .Text = ")" });4155 try stack.append(RenderState { .Text = ")" });
4028 {4156 {
...@@ -4030,7 +4158,7 @@ pub const Parser = struct {...@@ -4030,7 +4158,7 @@ pub const Parser = struct {
4030 var i = cloppers.len;4158 var i = cloppers.len;
4031 while (i != 0) {4159 while (i != 0) {
4032 i -= 1;4160 i -= 1;
4033 try stack.append(RenderState { .Expression = &cloppers[i].base });4161 try stack.append(RenderState { .Expression = cloppers[i] });
40344162
4035 if (i != 0) {4163 if (i != 0) {
4036 try stack.append(RenderState { .Text = ", " });4164 try stack.append(RenderState { .Text = ", " });
...@@ -4099,6 +4227,8 @@ pub const Parser = struct {...@@ -4099,6 +4227,8 @@ pub const Parser = struct {
4099 try stack.append(RenderState.PrintIndent);4227 try stack.append(RenderState.PrintIndent);
4100 try stack.append(RenderState { .Indent = indent + indent_delta});4228 try stack.append(RenderState { .Indent = indent + indent_delta});
4101 try stack.append(RenderState { .Text = "\n" });4229 try stack.append(RenderState { .Text = "\n" });
4230 try stack.append(RenderState { .Expression = asm_node.template });
4231 try stack.append(RenderState { .Text = "(" });
4102 },4232 },
4103 ast.Node.Id.AsmInput => {4233 ast.Node.Id.AsmInput => {
4104 const asm_input = @fieldParentPtr(ast.NodeAsmInput, "base", base);4234 const asm_input = @fieldParentPtr(ast.NodeAsmInput, "base", base);
...@@ -4106,7 +4236,7 @@ pub const Parser = struct {...@@ -4106,7 +4236,7 @@ pub const Parser = struct {
4106 try stack.append(RenderState { .Text = ")"});4236 try stack.append(RenderState { .Text = ")"});
4107 try stack.append(RenderState { .Expression = asm_input.expr});4237 try stack.append(RenderState { .Expression = asm_input.expr});
4108 try stack.append(RenderState { .Text = " ("});4238 try stack.append(RenderState { .Text = " ("});
4109 try stack.append(RenderState { .Expression = &asm_input.constraint.base});4239 try stack.append(RenderState { .Expression = asm_input.constraint });
4110 try stack.append(RenderState { .Text = "] "});4240 try stack.append(RenderState { .Text = "] "});
4111 try stack.append(RenderState { .Expression = &asm_input.symbolic_name.base});4241 try stack.append(RenderState { .Expression = &asm_input.symbolic_name.base});
4112 try stack.append(RenderState { .Text = "["});4242 try stack.append(RenderState { .Text = "["});
...@@ -4125,7 +4255,7 @@ pub const Parser = struct {...@@ -4125,7 +4255,7 @@ pub const Parser = struct {
4125 },4255 },
4126 }4256 }
4127 try stack.append(RenderState { .Text = " ("});4257 try stack.append(RenderState { .Text = " ("});
4128 try stack.append(RenderState { .Expression = &asm_output.constraint.base});4258 try stack.append(RenderState { .Expression = asm_output.constraint });
4129 try stack.append(RenderState { .Text = "] "});4259 try stack.append(RenderState { .Text = "] "});
4130 try stack.append(RenderState { .Expression = &asm_output.symbolic_name.base});4260 try stack.append(RenderState { .Expression = &asm_output.symbolic_name.base});
4131 try stack.append(RenderState { .Text = "["});4261 try stack.append(RenderState { .Text = "["});
...@@ -4140,26 +4270,6 @@ pub const Parser = struct {...@@ -4140,26 +4270,6 @@ pub const Parser = struct {
4140 ast.Node.Id.TestDecl,4270 ast.Node.Id.TestDecl,
4141 ast.Node.Id.ParamDecl => unreachable,4271 ast.Node.Id.ParamDecl => unreachable,
4142 },4272 },
4143 RenderState.FnProtoRParen => |fn_proto| {
4144 try stream.print(")");
4145 if (fn_proto.align_expr != null) {
4146 @panic("TODO");
4147 }
4148 try stream.print(" ");
4149 if (fn_proto.body_node) |body_node| {
4150 try stack.append(RenderState { .Expression = body_node});
4151 try stack.append(RenderState { .Text = " "});
4152 }
4153 switch (fn_proto.return_type) {
4154 ast.NodeFnProto.ReturnType.Explicit => |node| {
4155 try stack.append(RenderState { .Expression = node});
4156 },
4157 ast.NodeFnProto.ReturnType.InferErrorSet => |node| {
4158 try stream.print("!");
4159 try stack.append(RenderState { .Expression = node});
4160 },
4161 }
4162 },
4163 RenderState.Statement => |base| {4273 RenderState.Statement => |base| {
4164 if (base.comment) |comment| {4274 if (base.comment) |comment| {
4165 for (comment.lines.toSliceConst()) |line_token| {4275 for (comment.lines.toSliceConst()) |line_token| {
...@@ -4513,10 +4623,20 @@ test "zig fmt: var type" {...@@ -4513,10 +4623,20 @@ test "zig fmt: var type" {
4513 );4623 );
4514}4624}
45154625
4516test "zig fmt: extern function" {4626test "zig fmt: functions" {
4517 try testCanonical(4627 try testCanonical(
4518 \\extern fn puts(s: &const u8) c_int;4628 \\extern fn puts(s: &const u8) c_int;
4519 \\extern "c" fn puts(s: &const u8) c_int;4629 \\extern "c" fn puts(s: &const u8) c_int;
4630 \\export fn puts(s: &const u8) c_int;
4631 \\inline fn puts(s: &const u8) c_int;
4632 \\pub extern fn puts(s: &const u8) c_int;
4633 \\pub extern "c" fn puts(s: &const u8) c_int;
4634 \\pub export fn puts(s: &const u8) c_int;
4635 \\pub inline fn puts(s: &const u8) c_int;
4636 \\pub extern fn puts(s: &const u8) align(2 + 2) c_int;
4637 \\pub extern "c" fn puts(s: &const u8) align(2 + 2) c_int;
4638 \\pub export fn puts(s: &const u8) align(2 + 2) c_int;
4639 \\pub inline fn puts(s: &const u8) align(2 + 2) c_int;
4520 \\4640 \\
4521 );4641 );
4522}4642}
...@@ -4576,6 +4696,7 @@ test "zig fmt: struct declaration" {...@@ -4576,6 +4696,7 @@ test "zig fmt: struct declaration" {
4576 \\const S = struct {4696 \\const S = struct {
4577 \\ const Self = this;4697 \\ const Self = this;
4578 \\ f1: u8,4698 \\ f1: u8,
4699 \\ pub f3: u8,
4579 \\4700 \\
4580 \\ fn method(self: &Self) Self {4701 \\ fn method(self: &Self) Self {
4581 \\ return *self;4702 \\ return *self;
...@@ -4586,14 +4707,14 @@ test "zig fmt: struct declaration" {...@@ -4586,14 +4707,14 @@ test "zig fmt: struct declaration" {
4586 \\4707 \\
4587 \\const Ps = packed struct {4708 \\const Ps = packed struct {
4588 \\ a: u8,4709 \\ a: u8,
4589 \\ b: u8,4710 \\ pub b: u8,
4590 \\4711 \\
4591 \\ c: u84712 \\ c: u8
4592 \\};4713 \\};
4593 \\4714 \\
4594 \\const Es = extern struct {4715 \\const Es = extern struct {
4595 \\ a: u8,4716 \\ a: u8,
4596 \\ b: u8,4717 \\ pub b: u8,
4597 \\4718 \\
4598 \\ c: u84719 \\ c: u8
4599 \\};4720 \\};
...@@ -4753,6 +4874,7 @@ test "zig fmt: switch" {...@@ -4753,6 +4874,7 @@ test "zig fmt: switch" {
4753 \\ const res = switch (0) {4874 \\ const res = switch (0) {
4754 \\ 0 => 0,4875 \\ 0 => 0,
4755 \\ 1 => 2,4876 \\ 1 => 2,
4877 \\ 1 => a = 4,
4756 \\ else => 44878 \\ else => 4
4757 \\ };4879 \\ };
4758 \\4880 \\
...@@ -4898,6 +5020,7 @@ test "zig fmt: if" {...@@ -4898,6 +5020,7 @@ test "zig fmt: if" {
4898 \\ }5020 \\ }
4899 \\5021 \\
4900 \\ const is_world_broken = if (10 < 0) true else false;5022 \\ const is_world_broken = if (10 < 0) true else false;
5023 \\ const some_number = 1 + if (10 < 0) 2 else 3;
4901 \\5024 \\
4902 \\ const a: ?u8 = 10;5025 \\ const a: ?u8 = 10;
4903 \\ const b: ?u8 = null;5026 \\ const b: ?u8 = null;
...@@ -5011,6 +5134,7 @@ test "zig fmt: inline asm" {...@@ -5011,6 +5134,7 @@ test "zig fmt: inline asm" {
5011test "zig fmt: coroutines" {5134test "zig fmt: coroutines" {
5012 try testCanonical(5135 try testCanonical(
5013 \\async fn simpleAsyncFn() void {5136 \\async fn simpleAsyncFn() void {
5137 \\ const a = async a.b();
5014 \\ x += 1;5138 \\ x += 1;
5015 \\ suspend;5139 \\ suspend;
5016 \\ x += 1;5140 \\ x += 1;
...@@ -5058,3 +5182,13 @@ test "zig fmt: string identifier" {...@@ -5058,3 +5182,13 @@ test "zig fmt: string identifier" {
5058 \\5182 \\
5059 );5183 );
5060}5184}
5185
5186test "zig fmt: error return" {
5187 try testCanonical(
5188 \\fn err() error {
5189 \\ call();
5190 \\ return error.InvalidArgs;
5191 \\}
5192 \\
5193 );
5194}
test/cases/fn.zig+10
...@@ -94,3 +94,13 @@ test "inline function call" {...@@ -94,3 +94,13 @@ test "inline function call" {
94}94}
9595
96fn add(a: i32, b: i32) i32 { return a + b; }96fn add(a: i32, b: i32) i32 { return a + b; }
97
98
99test "number literal as an argument" {
100 numberLiteralArg(3);
101 comptime numberLiteralArg(3);
102}
103
104fn numberLiteralArg(a: var) void {
105 assert(a == 3);
106}
test/compile_errors.zig+1-1
...@@ -1723,7 +1723,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -1723,7 +1723,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
1723 \\}1723 \\}
1724 \\1724 \\
1725 \\export fn entry() usize { return @sizeOf(@typeOf(bar)); }1725 \\export fn entry() usize { return @sizeOf(@typeOf(bar)); }
1726 , ".tmp_source.zig:10:16: error: parameter of type '(integer literal)' requires comptime");1726 , ".tmp_source.zig:10:16: error: compiler bug: integer and float literals in var args function must be casted");
17271727
1728 cases.add("assign too big number to u16",1728 cases.add("assign too big number to u16",
1729 \\export fn foo() void {1729 \\export fn foo() void {