| ... | @@ -5479,18 +5479,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5479,18 +5479,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5479 | .LParen => { | 5479 | .LParen => { |
| 5480 | const inner_node = try parseCExpr(c, it, source, source_loc, scope); | 5480 | const inner_node = try parseCExpr(c, it, source, source_loc, scope); |
| 5481 | | 5481 | |
| 5482 | if (it.next().?.id != .RParen) { | 5482 | const next_id = it.next().?.id; |
| | 5483 | if (next_id != .RParen) { |
| 5483 | const first_tok = it.list.at(0); | 5484 | const first_tok = it.list.at(0); |
| 5484 | try failDecl( | 5485 | try failDecl( |
| 5485 | c, | 5486 | c, |
| 5486 | source_loc, | 5487 | source_loc, |
| 5487 | source[first_tok.start..first_tok.end], | 5488 | source[first_tok.start..first_tok.end], |
| 5488 | "unable to translate C expr: expected ')'' here", | 5489 | "unable to translate C expr: expected ')'' instead got: {}", |
| 5489 | .{}, | 5490 | .{@tagName(next_id)}, |
| 5490 | ); | 5491 | ); |
| 5491 | return error.ParseError; | 5492 | return error.ParseError; |
| 5492 | } | 5493 | } |
| 5493 | var saw_l_paren = false; | 5494 | var saw_l_paren = false; |
| | 5495 | var saw_integer_literal = false; |
| 5494 | switch (it.peek().?.id) { | 5496 | switch (it.peek().?.id) { |
| 5495 | // (type)(to_cast) | 5497 | // (type)(to_cast) |
| 5496 | .LParen => { | 5498 | .LParen => { |
| ... | @@ -5499,6 +5501,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5499,6 +5501,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5499 | }, | 5501 | }, |
| 5500 | // (type)identifier | 5502 | // (type)identifier |
| 5501 | .Identifier => {}, | 5503 | .Identifier => {}, |
| | 5504 | // (type)integer |
| | 5505 | .IntegerLiteral => { |
| | 5506 | saw_integer_literal = true; |
| | 5507 | }, |
| 5502 | else => return inner_node, | 5508 | else => return inner_node, |
| 5503 | } | 5509 | } |
| 5504 | | 5510 | |
| ... | @@ -5519,12 +5525,21 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5519,12 +5525,21 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5519 | return error.ParseError; | 5525 | return error.ParseError; |
| 5520 | } | 5526 | } |
| 5521 | | 5527 | |
| 5522 | //if (@typeInfo(@TypeOf(x)) == .Pointer) | 5528 | if (saw_integer_literal) { |
| 5523 | // @ptrCast(dest, x) | 5529 | // @intToPtr(dest, x) |
| 5524 | //else if (@typeInfo(@TypeOf(x)) == .Int and @typeInfo(dest) == .Pointer) | 5530 | const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr"); |
| | 5531 | try int_to_ptr.params.push(inner_node); |
| | 5532 | try int_to_ptr.params.push(node_to_cast); |
| | 5533 | int_to_ptr.rparen_token = try appendToken(c, .RParen, ")"); |
| | 5534 | return &int_to_ptr.base; |
| | 5535 | } |
| | 5536 | |
| | 5537 | //( if (@typeInfo(@TypeOf(x)) == .Pointer) |
| | 5538 | // @ptrCast(dest, @alignCast(@alignOf(dest.Child), x)) |
| | 5539 | //else if (@typeInfo(@TypeOf(x)) == .Integer and @typeInfo(dest) == .Pointer)) |
| 5525 | // @intToPtr(dest, x) | 5540 | // @intToPtr(dest, x) |
| 5526 | //else | 5541 | //else |
| 5527 | // @as(dest, x) | 5542 | // @as(dest, x) ) |
| 5528 | | 5543 | |
| 5529 | const lparen = try appendToken(c, .LParen, "("); | 5544 | const lparen = try appendToken(c, .LParen, "("); |
| 5530 | | 5545 | |
| ... | @@ -5546,9 +5561,30 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5546,9 +5561,30 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5546 | if_1.condition = &cmp_1.base; | 5561 | if_1.condition = &cmp_1.base; |
| 5547 | _ = try appendToken(c, .RParen, ")"); | 5562 | _ = try appendToken(c, .RParen, ")"); |
| 5548 | | 5563 | |
| | 5564 | const period_tok = try appendToken(c, .Period, "."); |
| | 5565 | const child_ident = try transCreateNodeIdentifier(c, "Child"); |
| | 5566 | const inner_node_child = try c.a().create(ast.Node.InfixOp); |
| | 5567 | inner_node_child.* = .{ |
| | 5568 | .op_token = period_tok, |
| | 5569 | .lhs = inner_node, |
| | 5570 | .op = .Period, |
| | 5571 | .rhs = child_ident, |
| | 5572 | }; |
| | 5573 | |
| | 5574 | const align_of = try transCreateNodeBuiltinFnCall(c, "@alignOf"); |
| | 5575 | try align_of.params.push(&inner_node_child.base); |
| | 5576 | align_of.rparen_token = try appendToken(c, .RParen, ")"); |
| | 5577 | // hack to get zig fmt to render a comma in builtin calls |
| | 5578 | _ = try appendToken(c, .Comma, ","); |
| | 5579 | |
| | 5580 | const align_cast = try transCreateNodeBuiltinFnCall(c, "@alignCast"); |
| | 5581 | try align_cast.params.push(&align_of.base); |
| | 5582 | try align_cast.params.push(node_to_cast); |
| | 5583 | align_cast.rparen_token = try appendToken(c, .RParen, ")"); |
| | 5584 | |
| 5549 | const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast"); | 5585 | const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast"); |
| 5550 | try ptr_cast.params.push(inner_node); | 5586 | try ptr_cast.params.push(inner_node); |
| 5551 | try ptr_cast.params.push(node_to_cast); | 5587 | try ptr_cast.params.push(&align_cast.base); |
| 5552 | ptr_cast.rparen_token = try appendToken(c, .RParen, ")"); | 5588 | ptr_cast.rparen_token = try appendToken(c, .RParen, ")"); |
| 5553 | if_1.body = &ptr_cast.base; | 5589 | if_1.body = &ptr_cast.base; |
| 5554 | | 5590 | |
| ... | @@ -5729,19 +5765,24 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5729,19 +5765,24 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5729 | // hack to get zig fmt to render a comma in builtin calls | 5765 | // hack to get zig fmt to render a comma in builtin calls |
| 5730 | _ = try appendToken(c, .Comma, ","); | 5766 | _ = try appendToken(c, .Comma, ","); |
| 5731 | | 5767 | |
| 5732 | const ptr_kind = blk: { | 5768 | // * token |
| 5733 | // * token | 5769 | _ = it.prev(); |
| 5734 | _ = it.prev(); | 5770 | // last token of `node` |
| 5735 | // last token of `node` | 5771 | const prev_id = it.prev().?.id; |
| 5736 | const prev_id = it.prev().?.id; | 5772 | _ = it.next(); |
| 5737 | _ = it.next(); | 5773 | _ = it.next(); |
| 5738 | _ = it.next(); | | |
| 5739 | break :blk if (prev_id == .Keyword_void) .Asterisk else Token.Id.Identifier; | | |
| 5740 | }; | | |
| 5741 | | 5774 | |
| 5742 | const ptr = try transCreateNodePtrType(c, false, false, ptr_kind); | 5775 | if (prev_id == .Keyword_void) { |
| 5743 | ptr.rhs = node; | 5776 | const ptr = try transCreateNodePtrType(c, false, false, .Asterisk); |
| 5744 | return &ptr.base; | 5777 | ptr.rhs = node; |
| | 5778 | const optional_node = try transCreateNodePrefixOp(c, .OptionalType, .QuestionMark, "?"); |
| | 5779 | optional_node.rhs = &ptr.base; |
| | 5780 | return &optional_node.base; |
| | 5781 | } else { |
| | 5782 | const ptr = try transCreateNodePtrType(c, false, false, Token.Id.Identifier); |
| | 5783 | ptr.rhs = node; |
| | 5784 | return &ptr.base; |
| | 5785 | } |
| 5745 | } else { | 5786 | } else { |
| 5746 | // expr * expr | 5787 | // expr * expr |
| 5747 | op_token = try appendToken(c, .Asterisk, "*"); | 5788 | op_token = try appendToken(c, .Asterisk, "*"); |