authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-12-12 19:26:33-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-12-12 19:26:33-07:00
log0003cc81056b5be394b857b717cf64f08f44c0f5
tree9b7c9de9f129c2c79b4f1efaa8f85630b7530711
parent24c2703dfa64d4a76684c68f6bb029eb50f96aca

self-hosted: implement addr of align parsing


1 files changed, 56 insertions(+), 22 deletions(-)

src-self-hosted/parser.zig+56-22
...@@ -81,6 +81,7 @@ pub const Parser = struct {...@@ -81,6 +81,7 @@ pub const Parser = struct {
81 MultiplyExpression: DestPtr,81 MultiplyExpression: DestPtr,
82 BraceSuffixExpression: DestPtr,82 BraceSuffixExpression: DestPtr,
83 PrefixOpExpression: DestPtr,83 PrefixOpExpression: DestPtr,
84 AddrOfModifiers: &ast.NodeAddrOfExpr,
84 SuffixOpExpression: DestPtr,85 SuffixOpExpression: DestPtr,
85 PrimaryExpression: DestPtr,86 PrimaryExpression: DestPtr,
86 TypeExpr: DestPtr,87 TypeExpr: DestPtr,
...@@ -350,30 +351,51 @@ pub const Parser = struct {...@@ -350,30 +351,51 @@ pub const Parser = struct {
350351
351 State.PrefixOpExpression => |dest_ptr| {352 State.PrefixOpExpression => |dest_ptr| {
352 const first_token = self.getNextToken();353 const first_token = self.getNextToken();
353 if (first_token.id == Token.Id.Ampersand) {354 switch (first_token.id) {
354 const addr_of_expr = %return self.createAttachAddrOfExpr(dest_ptr, first_token);355 Token.Id.Ampersand => {
355 var token = self.getNextToken();356 const addr_of_expr = %return self.createAttachAddrOfExpr(dest_ptr, first_token);
356 if (token.id == Token.Id.Keyword_align) {357 stack.append(State { .AddrOfModifiers = addr_of_expr }) %% unreachable;
357 @panic("TODO align");358 continue;
358 }359 },
359 if (token.id == Token.Id.Keyword_const) {360 else => {
361 self.putBackToken(first_token);
362 stack.append(State { .SuffixOpExpression = dest_ptr }) %% unreachable;
363 continue;
364 },
365 }
366 },
367
368 State.AddrOfModifiers => |addr_of_expr| {
369 var token = self.getNextToken();
370 switch (token.id) {
371 Token.Id.Keyword_align => {
372 stack.append(State { .AddrOfModifiers = addr_of_expr }) %% unreachable;
373 if (addr_of_expr.align_expr != null) return self.parseError(token, "multiple align qualifiers");
374 _ = %return self.eatToken(Token.Id.LParen);
375 %return stack.append(State { .ExpectToken = Token.Id.RParen });
376 %return stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_expr.align_expr} });
377 continue;
378 },
379 Token.Id.Keyword_const => {
380 if (addr_of_expr.const_token != null) return self.parseError(token, "duplicate qualifier: const");
360 addr_of_expr.const_token = token;381 addr_of_expr.const_token = token;
361 token = self.getNextToken();382 stack.append(State { .AddrOfModifiers = addr_of_expr }) %% unreachable;
362 }383 continue;
363 if (token.id == Token.Id.Keyword_volatile) {384 },
385 Token.Id.Keyword_volatile => {
386 if (addr_of_expr.volatile_token != null) return self.parseError(token, "duplicate qualifier: volatile");
364 addr_of_expr.volatile_token = token;387 addr_of_expr.volatile_token = token;
365 token = self.getNextToken();388 stack.append(State { .AddrOfModifiers = addr_of_expr }) %% unreachable;
366 }389 continue;
367 self.putBackToken(token);390 },
368 stack.append(State {391 else => {
369 .PrefixOpExpression = DestPtr { .Field = &addr_of_expr.op_expr},392 self.putBackToken(token);
370 }) %% unreachable;393 stack.append(State {
371 continue;394 .PrefixOpExpression = DestPtr { .Field = &addr_of_expr.op_expr},
395 }) %% unreachable;
396 continue;
397 },
372 }398 }
373
374 self.putBackToken(first_token);
375 stack.append(State { .SuffixOpExpression = dest_ptr }) %% unreachable;
376 continue;
377 },399 },
378400
379 State.SuffixOpExpression => |dest_ptr| {401 State.SuffixOpExpression => |dest_ptr| {
...@@ -997,7 +1019,7 @@ pub const Parser = struct {...@@ -997,7 +1019,7 @@ pub const Parser = struct {
9971019
998 if (addr_of_expr.align_expr) |align_expr| {1020 if (addr_of_expr.align_expr) |align_expr| {
999 %return stream.print("align(");1021 %return stream.print("align(");
1000 %return stack.append(RenderState { .Text = ")"});1022 %return stack.append(RenderState { .Text = ") "});
1001 %return stack.append(RenderState { .Expression = align_expr});1023 %return stack.append(RenderState { .Expression = align_expr});
1002 }1024 }
1003 },1025 },
...@@ -1189,4 +1211,16 @@ test "zig fmt" {...@@ -1189,4 +1211,16 @@ test "zig fmt" {
1189 \\}1211 \\}
1190 \\1212 \\
1191 );1213 );
1214
1215 testCanonical(
1216 \\extern fn f1(s: &align(&u8) u8) -> c_int;
1217 \\
1218 );
1219
1220 testCanonical(
1221 \\extern fn f1(s: &&align(1) &const &volatile u8) -> c_int;
1222 \\extern fn f2(s: &align(1) const &align(1) volatile &const volatile u8) -> c_int;
1223 \\extern fn f3(s: &align(1) const volatile u8) -> c_int;
1224 \\
1225 );
1192}1226}