std.zig.parser parses all prefix operators

This commit is contained in:
Jimmi Holst Christensen 2018-03-30 21:45:42 +02:00
parent 1dfa927a67
commit 24071c6803
3 changed files with 73 additions and 10 deletions

View File

@ -432,9 +432,15 @@ pub const NodePrefixOp = struct {
rhs: &Node,
const PrefixOp = union(enum) {
AddrOf: AddrOfInfo,
BitNot,
BoolNot,
Deref,
Negation,
NegationWrap,
Return,
Try,
AddrOf: AddrOfInfo,
UnwrapMaybe,
};
const AddrOfInfo = struct {
align_expr: ?&Node,
@ -448,14 +454,20 @@ pub const NodePrefixOp = struct {
var i = index;
switch (self.op) {
PrefixOp.Return,
PrefixOp.Try => {},
PrefixOp.AddrOf => |addr_of_info| {
if (addr_of_info.align_expr) |align_expr| {
if (i < 1) return align_expr;
i -= 1;
}
},
PrefixOp.BitNot,
PrefixOp.BoolNot,
PrefixOp.Deref,
PrefixOp.Negation,
PrefixOp.NegationWrap,
PrefixOp.Return,
PrefixOp.Try,
PrefixOp.UnwrapMaybe => {},
}
if (i < 1) return self.rhs;

View File

@ -336,6 +336,42 @@ pub const Parser = struct {
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.Minus => {
try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
ast.NodePrefixOp.PrefixOp.Negation) });
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.MinusPercent => {
try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
ast.NodePrefixOp.PrefixOp.NegationWrap) });
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.Tilde => {
try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
ast.NodePrefixOp.PrefixOp.BitNot) });
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.QuestionMarkQuestionMark => {
try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
ast.NodePrefixOp.PrefixOp.UnwrapMaybe) });
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.Bang => {
try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
ast.NodePrefixOp.PrefixOp.BoolNot) });
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.Asterisk => {
try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
ast.NodePrefixOp.PrefixOp.Deref) });
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.Ampersand => {
const prefix_op = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{
.AddrOf = ast.NodePrefixOp.AddrOfInfo {
@ -1323,12 +1359,6 @@ pub const Parser = struct {
const prefix_op_node = @fieldParentPtr(ast.NodePrefixOp, "base", base);
try stack.append(RenderState { .Expression = prefix_op_node.rhs });
switch (prefix_op_node.op) {
ast.NodePrefixOp.PrefixOp.Return => {
try stream.write("return ");
},
ast.NodePrefixOp.PrefixOp.Try => {
try stream.write("try ");
},
ast.NodePrefixOp.PrefixOp.AddrOf => |addr_of_info| {
try stream.write("&");
if (addr_of_info.volatile_token != null) {
@ -1343,6 +1373,14 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = align_expr});
}
},
ast.NodePrefixOp.PrefixOp.BitNot => try stream.write("~"),
ast.NodePrefixOp.PrefixOp.BoolNot => try stream.write("!"),
ast.NodePrefixOp.PrefixOp.Deref => try stream.write("*"),
ast.NodePrefixOp.PrefixOp.Negation => try stream.write("-"),
ast.NodePrefixOp.PrefixOp.NegationWrap => try stream.write("-%"),
ast.NodePrefixOp.PrefixOp.Return => try stream.write("return "),
ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "),
ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),
}
},
ast.Node.Id.IntegerLiteral => {
@ -1627,7 +1665,7 @@ test "zig fmt" {
);
try testCanonical(
\\test "operators" {
\\test "infix operators" {
\\ var i = undefined;
\\ i = 2;
\\ i *= 2;
@ -1676,6 +1714,13 @@ test "zig fmt" {
\\
);
try testCanonical(
\\test "prefix operators" {
\\ --%~??!*&0;
\\}
\\
);
try testCanonical(
\\test "test calls" {
\\ a();

View File

@ -125,6 +125,7 @@ pub const Token = struct {
AngleBracketRightEqual,
AngleBracketAngleBracketRight,
AngleBracketAngleBracketRightEqual,
Tilde,
IntegerLiteral,
FloatLiteral,
LineComment,
@ -361,6 +362,11 @@ pub const Tokenizer = struct {
self.index += 1;
break;
},
'~' => {
result.id = Token.Id.Tilde;
self.index += 1;
break;
},
'.' => {
state = State.Period;
},