authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 15:40:16+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 15:40:16+02:00
loga09bb408a20fcfc0575a9298b318803b07517b0a
tree8c230a640a96d08edf2c123a0b15ff5125dbc572
parentaa552633cc0bc66d46f61ea2105f7a4392df37be

std.zig.parser now parses asm expressions

* We cannot render asm expressions yet

2 files changed, 178 insertions(+), 1 deletions(-)

std/zig/ast.zig+41
...@@ -47,6 +47,7 @@ pub const Node = struct {...@@ -47,6 +47,7 @@ pub const Node = struct {
47 NullLiteral,47 NullLiteral,
48 UndefinedLiteral,48 UndefinedLiteral,
49 ThisLiteral,49 ThisLiteral,
50 Asm,
50 Unreachable,51 Unreachable,
51 ErrorType,52 ErrorType,
52 BuiltinCall,53 BuiltinCall,
...@@ -94,6 +95,7 @@ pub const Node = struct {...@@ -94,6 +95,7 @@ pub const Node = struct {
94 Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).iterate(index),95 Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).iterate(index),
95 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).iterate(index),96 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).iterate(index),
96 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).iterate(index),97 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).iterate(index),
98 Id.Asm => @fieldParentPtr(NodeAsm, "base", base).iterate(index),
97 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).iterate(index),99 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).iterate(index),
98 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).iterate(index),100 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).iterate(index),
99 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),101 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
...@@ -143,6 +145,7 @@ pub const Node = struct {...@@ -143,6 +145,7 @@ pub const Node = struct {
143 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).firstToken(),145 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).firstToken(),
144 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).firstToken(),146 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).firstToken(),
145 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).firstToken(),147 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).firstToken(),
148 Id.Asm => @fieldParentPtr(NodeAsm, "base", base).firstToken(),
146 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).firstToken(),149 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).firstToken(),
147 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),150 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
148 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),151 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
...@@ -190,6 +193,7 @@ pub const Node = struct {...@@ -190,6 +193,7 @@ pub const Node = struct {
190 Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).lastToken(),193 Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).lastToken(),
191 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).lastToken(),194 Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).lastToken(),
192 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).lastToken(),195 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).lastToken(),
196 Id.Asm => @fieldParentPtr(NodeAsm, "base", base).lastToken(),
193 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).lastToken(),197 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).lastToken(),
194 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).lastToken(),198 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).lastToken(),
195 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),199 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
...@@ -1512,6 +1516,43 @@ pub const NodeThisLiteral = struct {...@@ -1512,6 +1516,43 @@ pub const NodeThisLiteral = struct {
1512 }1516 }
1513};1517};
15141518
1519pub const NodeAsm = struct {
1520 base: Node,
1521 asm_token: Token,
1522 is_volatile: bool,
1523 template: Token,
1524 //tokens: ArrayList(AsmToken),
1525 outputs: ArrayList(AsmOutput),
1526 inputs: ArrayList(AsmInput),
1527 cloppers: ArrayList(&NodeStringLiteral),
1528 rparen: Token,
1529
1530 const AsmOutput = struct {
1531 symbolic_name: Token,
1532 constraint: Token,
1533 variable_name: ?Token,
1534 return_type: ?&Node,
1535 };
1536
1537 const AsmInput = struct {
1538 symbolic_name: Token,
1539 constraint: Token,
1540 expr: &Node,
1541 };
1542
1543 pub fn iterate(self: &NodeAsm, index: usize) ?&Node {
1544 return null;
1545 }
1546
1547 pub fn firstToken(self: &NodeAsm) Token {
1548 return self.asm_token;
1549 }
1550
1551 pub fn lastToken(self: &NodeAsm) Token {
1552 return self.rparen;
1553 }
1554};
1555
1515pub const NodeUnreachable = struct {1556pub const NodeUnreachable = struct {
1516 base: Node,1557 base: Node,
1517 token: Token,1558 token: Token,
std/zig/parser.zig+137-1
...@@ -164,6 +164,9 @@ pub const Parser = struct {...@@ -164,6 +164,9 @@ pub const Parser = struct {
164 WhileContinueExpr: &?&ast.Node,164 WhileContinueExpr: &?&ast.Node,
165 Statement: &ast.NodeBlock,165 Statement: &ast.NodeBlock,
166 Semicolon: &const &const ast.Node,166 Semicolon: &const &const ast.Node,
167 AsmOutputItems: &ArrayList(ast.NodeAsm.AsmOutput),
168 AsmInputItems: &ArrayList(ast.NodeAsm.AsmInput),
169 AsmClopperItems: &ArrayList(&ast.NodeStringLiteral),
167 ExprListItemOrEnd: ExprListCtx,170 ExprListItemOrEnd: ExprListCtx,
168 ExprListCommaOrEnd: ExprListCtx,171 ExprListCommaOrEnd: ExprListCtx,
169 FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),172 FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),
...@@ -1488,7 +1491,44 @@ pub const Parser = struct {...@@ -1488,7 +1491,44 @@ pub const Parser = struct {
1488 continue;1491 continue;
1489 },1492 },
1490 Token.Id.Keyword_asm => {1493 Token.Id.Keyword_asm => {
1491 @panic("TODO: inline asm");1494 const is_volatile = blk: {
1495 const volatile_token = self.getNextToken();
1496 if (volatile_token.id != Token.Id.Keyword_volatile) {
1497 self.putBackToken(volatile_token);
1498 break :blk false;
1499 }
1500 break :blk true;
1501 };
1502 _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue;
1503 const template = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue;
1504 // TODO parse template
1505
1506 const node = try arena.create(ast.NodeAsm);
1507 *node = ast.NodeAsm {
1508 .base = self.initNode(ast.Node.Id.Asm),
1509 .asm_token = token,
1510 .is_volatile = is_volatile,
1511 .template = template,
1512 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
1513 .outputs = ArrayList(ast.NodeAsm.AsmOutput).init(arena),
1514 .inputs = ArrayList(ast.NodeAsm.AsmInput).init(arena),
1515 .cloppers = ArrayList(&ast.NodeStringLiteral).init(arena),
1516 .rparen = undefined,
1517 };
1518 dest_ptr.store(&node.base);
1519
1520 stack.append(State {
1521 .ExpectTokenSave = ExpectTokenSave {
1522 .id = Token.Id.RParen,
1523 .ptr = &node.rparen,
1524 }
1525 }) catch unreachable;
1526 try stack.append(State { .AsmClopperItems = &node.cloppers });
1527 try stack.append(State { .IfToken = Token.Id.Colon });
1528 try stack.append(State { .AsmInputItems = &node.inputs });
1529 try stack.append(State { .IfToken = Token.Id.Colon });
1530 try stack.append(State { .AsmOutputItems = &node.outputs });
1531 try stack.append(State { .IfToken = Token.Id.Colon });
1492 },1532 },
1493 Token.Id.Keyword_if => {1533 Token.Id.Keyword_if => {
1494 const node = try arena.create(ast.NodeIf);1534 const node = try arena.create(ast.NodeIf);
...@@ -1621,6 +1661,84 @@ pub const Parser = struct {...@@ -1621,6 +1661,84 @@ pub const Parser = struct {
1621 }1661 }
1622 },1662 },
16231663
1664
1665 State.AsmOutputItems => |items| {
1666 const lbracket = self.getNextToken();
1667 if (lbracket.id != Token.Id.LBracket) {
1668 self.putBackToken(lbracket);
1669 continue;
1670 }
1671
1672 stack.append(State { .AsmOutputItems = items }) catch unreachable;
1673 try stack.append(State { .IfToken = Token.Id.Comma });
1674
1675 const symbolic_name = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
1676 _ = (try self.eatToken(&stack, Token.Id.RBracket)) ?? continue;
1677 const constraint = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue;
1678
1679 _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue;
1680 try stack.append(State { .ExpectToken = Token.Id.RParen });
1681
1682 const res = try items.addOne();
1683 *res = ast.NodeAsm.AsmOutput {
1684 .symbolic_name = symbolic_name,
1685 .constraint = constraint,
1686 .variable_name = null,
1687 .return_type = null,
1688 };
1689 const symbol_or_arrow = self.getNextToken();
1690 switch (symbol_or_arrow.id) {
1691 Token.Id.Identifier => res.variable_name = symbol_or_arrow,
1692 Token.Id.Arrow => {
1693 try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &res.return_type } });
1694 },
1695 else => {
1696 try self.parseError(&stack, symbol_or_arrow, "expected '->' or {}, found {}",
1697 @tagName(Token.Id.Identifier),
1698 @tagName(symbol_or_arrow.id));
1699 continue;
1700 },
1701 }
1702 },
1703
1704 State.AsmInputItems => |items| {
1705 const lbracket = self.getNextToken();
1706 if (lbracket.id != Token.Id.LBracket) {
1707 self.putBackToken(lbracket);
1708 continue;
1709 }
1710
1711 stack.append(State { .AsmInputItems = items }) catch unreachable;
1712 try stack.append(State { .IfToken = Token.Id.Comma });
1713
1714 const symbolic_name = (try self.eatToken(&stack, Token.Id.Identifier)) ?? continue;
1715 _ = (try self.eatToken(&stack, Token.Id.RBracket)) ?? continue;
1716 const constraint = (try self.eatToken(&stack, Token.Id.StringLiteral)) ?? continue;
1717
1718 _ = (try self.eatToken(&stack, Token.Id.LParen)) ?? continue;
1719 try stack.append(State { .ExpectToken = Token.Id.RParen });
1720
1721 const res = try items.addOne();
1722 *res = ast.NodeAsm.AsmInput {
1723 .symbolic_name = symbolic_name,
1724 .constraint = constraint,
1725 .expr = undefined,
1726 };
1727 try stack.append(State { .Expression = DestPtr { .Field = &res.expr } });
1728 },
1729
1730 State.AsmClopperItems => |items| {
1731 const string = self.getNextToken();
1732 if (string.id != Token.Id.StringLiteral) {
1733 self.putBackToken(string);
1734 continue;
1735 }
1736
1737 try items.append(try self.createStringLiteral(arena, string));
1738 stack.append(State { .AsmClopperItems = items }) catch unreachable;
1739 try stack.append(State { .IfToken = Token.Id.Comma });
1740 },
1741
1624 State.ExprListItemOrEnd => |list_state| {1742 State.ExprListItemOrEnd => |list_state| {
1625 var token = self.getNextToken();1743 var token = self.getNextToken();
16261744
...@@ -3675,6 +3793,24 @@ pub const Parser = struct {...@@ -3675,6 +3793,24 @@ pub const Parser = struct {
3675 try stack.append(RenderState { .Expression = if_node.condition });3793 try stack.append(RenderState { .Expression = if_node.condition });
3676 try stack.append(RenderState { .Text = "(" });3794 try stack.append(RenderState { .Text = "(" });
3677 },3795 },
3796 ast.Node.Id.Asm => {
3797 const asm_node = @fieldParentPtr(ast.NodeAsm, "base", base);
3798 try stream.print("{} ", self.tokenizer.getTokenSlice(asm_node.asm_token));
3799
3800 if (asm_node.is_volatile) {
3801 try stream.write("volatile ");
3802 }
3803
3804 try stream.print("({}", self.tokenizer.getTokenSlice(asm_node.template));
3805
3806 try stack.append(RenderState { .Text = ")" });
3807 @panic("TODO: Render asm");
3808 //\\ return asm volatile ("syscall"
3809 //\\ : [ret] "={rax}" (-> usize)
3810 //\\ : [number] "{rax}" (number),
3811 //\\ [arg1] "{rdi}" (arg1)
3812 //\\ : "rcx", "r11");
3813 },,
36783814
3679 ast.Node.Id.StructField,3815 ast.Node.Id.StructField,
3680 ast.Node.Id.UnionTag,3816 ast.Node.Id.UnionTag,