Commit 704374e512
Changed files (11)
doc/docgen.zig
@@ -764,7 +764,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
std.zig.Token.Id.Keyword_pub,
std.zig.Token.Id.Keyword_resume,
std.zig.Token.Id.Keyword_return,
- std.zig.Token.Id.Keyword_section,
+ std.zig.Token.Id.Keyword_linksection,
std.zig.Token.Id.Keyword_stdcallcc,
std.zig.Token.Id.Keyword_struct,
std.zig.Token.Id.Keyword_suspend,
doc/langref.html.in
@@ -7713,36 +7713,35 @@ fn readU32Be() u32 {}
<p>For some discussion on the rationale behind these design decisions, see <a href="https://github.com/ziglang/zig/issues/663">issue #663</a></p>
{#header_close#}
{#header_open|Grammar#}
- <pre><code class="nohighlight">
-Root <- skip ContainerMembers eof
+ <pre><code>Root <- skip ContainerMembers eof
# *** Top level ***
ContainerMembers
- <- TestDecl ContainerMembers
+ <- TestDecl ContainerMembers
/ TopLevelComptime ContainerMembers
/ KEYWORD_pub? TopLevelDecl ContainerMembers
/ KEYWORD_pub? ContainerField COMMA ContainerMembers
/ KEYWORD_pub? ContainerField
/
-TestDecl <- KEYWORD_test STRINGLITERAL Block
+TestDecl <- KEYWORD_test STRINGLITERAL Block
-TopLevelComptime <- KEYWORD_comptime BlockExpr
+TopLevelComptime <- KEYWORD_comptime BlockExpr
TopLevelDecl
- <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
+ <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
/ (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl
/ KEYWORD_use Expr SEMICOLON
-FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Section? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
+FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
-VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? Section? (EQUAL Expr)? SEMICOLON
+VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
-ContainerField <- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
+ContainerField <- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
# *** Block Level ***
Statement
- <- KEYWORD_comptime? VarDecl
+ <- KEYWORD_comptime? VarDecl
/ KEYWORD_comptime BlockExprStatement
/ KEYWORD_suspend (SEMICOLON / BlockExprStatement)
/ KEYWORD_defer BlockExprStatement
@@ -7753,50 +7752,50 @@ Statement
/ AssignExpr SEMICOLON
IfStatement
- <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
+ <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
/ IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
-LabeledStatement <- BlockLabel? (Block / LoopStatement)
+LabeledStatement <- BlockLabel? (Block / LoopStatement)
-LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
+LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
ForStatement
- <- ForPrefix BlockExpr ( KEYWORD_else Statement )?
+ <- ForPrefix BlockExpr ( KEYWORD_else Statement )?
/ ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
WhileStatement
- <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
+ <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
/ WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
BlockExprStatement
- <- BlockExpr
+ <- BlockExpr
/ AssignExpr SEMICOLON
-BlockExpr <- BlockLabel? Block
+BlockExpr <- BlockLabel? Block
# *** Expression Level ***
-AssignExpr <- Expr (AssignOp Expr)?
+AssignExpr <- Expr (AssignOp Expr)?
-Expr <- KEYWORD_try* BoolOrExpr
+Expr <- KEYWORD_try* BoolOrExpr
-BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)*
+BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)*
-BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)*
+BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)*
-CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
+CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
-BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
+BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
-BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)*
+BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)*
-AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)*
+AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)*
-MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)*
+MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)*
-PrefixExpr <- PrefixOp* PrimaryExpr
+PrefixExpr <- PrefixOp* PrimaryExpr
PrimaryExpr
- <- AsmExpr
+ <- AsmExpr
/ IfExpr
/ KEYWORD_break BreakLabel? Expr?
/ KEYWORD_cancel Expr
@@ -7807,35 +7806,35 @@ PrimaryExpr
/ LabeledExpr
/ CurlySuffixExpr
-IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)?
+IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)?
-LabeledExpr <- BlockLabel? (Block / LoopExpr)
+LabeledExpr <- BlockLabel? (Block / LoopExpr)
-Block <- LBRACE Statement* RBRACE
+Block <- LBRACE Statement* RBRACE
-LoopExpr <- KEYWORD_inline? (ForExpr / WhileExpr)
+LoopExpr <- KEYWORD_inline? (ForExpr / WhileExpr)
-ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
+ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
-WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
+WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
-CurlySuffixExpr <- TypeExpr InitList?
+CurlySuffixExpr <- TypeExpr InitList?
InitList
- <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
+ <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
/ LBRACE Expr (COMMA Expr)* COMMA? RBRACE
/ LBRACE RBRACE
-TypeExpr <- PrefixTypeOp* ErrorUnionExpr
+TypeExpr <- PrefixTypeOp* ErrorUnionExpr
-ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
+ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
SuffixExpr
- <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArgumnets
+ <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArgumnets
/ PrimaryTypeExpr (SuffixOp / FnCallArgumnets)*
PrimaryTypeExpr
- <- BUILTININDENTIFIER FnCallArgumnets
+ <- BUILTININDENTIFIER FnCallArgumnets
/ CHAR_LITERAL
/ ContainerDecl
/ ErrorSetDecl
@@ -7858,91 +7857,91 @@ PrimaryTypeExpr
/ STRINGLITERAL
/ SwitchExpr
-ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
+ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
-ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
+ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
-GroupedExpr <- LPAREN Expr RPAREN
+GroupedExpr <- LPAREN Expr RPAREN
-IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
+IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
LabeledTypeExpr
- <- BlockLabel Block
+ <- BlockLabel Block
/ BlockLabel? LoopTypeExpr
-LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
+LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
-ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
+ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
-WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
+WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
-SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
+SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
# *** Assembly ***
-AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
+AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
-AsmOutput <- COLON AsmOutputList AsmInput?
+AsmOutput <- COLON AsmOutputList AsmInput?
-AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
+AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
-AsmInput <- COLON AsmInputList AsmCloppers?
+AsmInput <- COLON AsmInputList AsmCloppers?
-AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
+AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
-AsmCloppers <- COLON StringList
+AsmCloppers <- COLON StringList
# *** Helper grammar ***
-BreakLabel <- COLON IDENTIFIER
+BreakLabel <- COLON IDENTIFIER
-BlockLabel <- IDENTIFIER COLON
+BlockLabel <- IDENTIFIER COLON
-FieldInit <- DOT IDENTIFIER EQUAL Expr
+FieldInit <- DOT IDENTIFIER EQUAL Expr
-WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
+WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
-Section <- KEYWORD_section LPAREN Expr RPAREN
+LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
# Fn specific
FnCC
- <- KEYWORD_nakedcc
+ <- KEYWORD_nakedcc
/ KEYWORD_stdcallcc
/ KEYWORD_extern
/ KEYWORD_async (LARROW TypeExpr RARROW)?
-ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
+ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
ParamType
- <- KEYWORD_var
+ <- KEYWORD_var
/ DOT3
/ TypeExpr
# Control flow prefixes
-IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
+IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
-WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
+WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
-ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
+ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
# Payloads
-Payload <- PIPE IDENTIFIER PIPE
+Payload <- PIPE IDENTIFIER PIPE
-PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
+PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
-PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
+PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
# Switch specific
-SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr
+SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr
SwitchCase
- <- SwitchItem (COMMA SwitchItem)* COMMA?
+ <- SwitchItem (COMMA SwitchItem)* COMMA?
/ KEYWORD_else
-SwitchItem <- Expr (DOT3 Expr)?
+SwitchItem <- Expr (DOT3 Expr)?
# Operators
AssignOp
- <- ASTERISKEQUAL
+ <- ASTERISKEQUAL
/ SLASHEQUAL
/ PERCENTEQUAL
/ PLUSEQUAL
@@ -7958,7 +7957,7 @@ AssignOp
/ EQUAL
CompareOp
- <- EQUALEQUAL
+ <- EQUALEQUAL
/ EXCLAMATIONMARKEQUAL
/ LARROW
/ RARROW
@@ -7966,25 +7965,25 @@ CompareOp
/ RARROWEQUAL
BitwiseOp
- <- AMPERSAND
+ <- AMPERSAND
/ CARET
/ PIPE
/ KEYWORD_orelse
/ KEYWORD_catch Payload?
BitShiftOp
- <- LARROW2
+ <- LARROW2
/ RARROW2
AdditionOp
- <- PLUS
+ <- PLUS
/ MINUS
/ PLUS2
/ PLUSPERCENT
/ MINUSPERCENT
MultiplyOp
- <- PIPE2
+ <- PIPE2
/ ASTERISK
/ SLASH
/ PERCENT
@@ -7992,7 +7991,7 @@ MultiplyOp
/ ASTERISKPERCENT
PrefixOp
- <- EXCLAMATIONMARK
+ <- EXCLAMATIONMARK
/ MINUS
/ TILDE
/ MINUSPERCENT
@@ -8001,77 +8000,77 @@ PrefixOp
/ KEYWORD_await
PrefixTypeOp
- <- QUESTIONMARK
+ <- QUESTIONMARK
/ KEYWORD_promise MINUSRARROW
/ ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)*
/ PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)*
SuffixOp
- <- LBRACKET Expr (DOT2 Expr?)? RBRACKET
+ <- LBRACKET Expr (DOT2 Expr?)? RBRACKET
/ DOT IDENTIFIER
/ DOTASTERISK
/ DOTQUESTIONMARK
-AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)?
+AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)?
-FnCallArgumnets <- LPAREN ExprList RPAREN
+FnCallArgumnets <- LPAREN ExprList RPAREN
# Ptr specific
-ArrayTypeStart <- LBRACKET Expr? RBRACKET
+ArrayTypeStart <- LBRACKET Expr? RBRACKET
PtrTypeStart
- <- ASTERISK
+ <- ASTERISK
/ ASTERISK2
/ LBRACKET ASTERISK RBRACKET
# ContainerDecl specific
-ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
+ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
ContainerDeclType
- <- (KEYWORD_struct / KEYWORD_enum) (LPAREN Expr RPAREN)?
+ <- (KEYWORD_struct / KEYWORD_enum) (LPAREN Expr RPAREN)?
/ KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
# Alignment
-ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
+ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
# Lists
-IdentifierList <- (IDENTIFIER COMMA)* IDENTIFIER?
+IdentifierList <- (IDENTIFIER COMMA)* IDENTIFIER?
-SwitchProngList <- (SwitchProng COMMA)* SwitchProng?
+SwitchProngList <- (SwitchProng COMMA)* SwitchProng?
-AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
+AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
-AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
+AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
-StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
+StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
-ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
+ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
-ExprList <- (Expr COMMA)* Expr?
+ExprList <- (Expr COMMA)* Expr?
# *** Tokens ***
-eof <- !.
-hex <- [0-9a-fA-F]
+eof <- !.
+hex <- [0-9a-fA-F]
char_escape
- <- "\\x" hex hex
+ <- "\\x" hex hex
/ "\\u" hex hex hex hex
/ "\\U" hex hex hex hex hex hex
/ "\\" [nr\\t'"]
char_char
- <- char_escape
+ <- char_escape
/ [^\\'\n]
string_char
- <- char_escape
+ <- char_escape
/ [^\\"\n]
-line_comment <- '//'[^\n]*
-line_string <- ("\\\\" [^\n]* [ \n]*)+
-line_cstring <- ("c\\\\" [^\n]* [ \n]*)+
-skip <- ([ \n] / line_comment)*
+line_comment <- '//'[^\n]*
+line_string <- ("\\\\" [^\n]* [ \n]*)+
+line_cstring <- ("c\\\\" [^\n]* [ \n]*)+
+skip <- ([ \n] / line_comment)*
-CHAR_LITERAL <- "'" char_char "'" skip
+CHAR_LITERAL <- "'" char_char "'" skip
FLOAT
- <- "0b" [01]+ "." [01]+ ([eE] [-+]? [01]+)? skip
+ <- "0b" [01]+ "." [01]+ ([eE] [-+]? [01]+)? skip
/ "0o" [0-7]+ "." [0-7]+ ([eE] [-+]? [0-7]+)? skip
/ "0x" hex+ "." hex+ ([pP] [-+]? hex+)? skip
/ [0-9]+ "." [0-9]+ ([eE] [-+]? [0-9]+)? skip
@@ -8080,128 +8079,128 @@ FLOAT
/ "0x" hex+ "."? [pP] [-+]? hex+ skip
/ [0-9]+ "."? [eE] [-+]? [0-9]+ skip
INTEGER
- <- "0b" [01]+ skip
+ <- "0b" [01]+ skip
/ "0o" [0-7]+ skip
/ "0x" hex+ skip
/ [0-9]+ skip
STRINGLITERAL
- <- "c"? "\"" string_char* "\"" skip
+ <- "c"? "\"" string_char* "\"" skip
/ line_string skip
/ line_cstring skip
IDENTIFIER
- <- !keyword ("c" !["\\] / [A-Zabd-z_]) [A-Za-z0-9_]* skip
+ <- !keyword ("c" !["\\] / [A-Zabd-z_]) [A-Za-z0-9_]* skip
/ "@\"" string_char* "\"" skip
-BUILTININDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
-
-
-AMPERSAND <- '&' ![=] skip
-AMPERSANDEQUAL <- '&=' skip
-ASTERISK <- '*' ![*%=] skip
-ASTERISK2 <- '**' skip
-ASTERISKEQUAL <- '*=' skip
-ASTERISKPERCENT <- '*%' ![=] skip
-ASTERISKPERCENTEQUAL <- '*%=' skip
-CARET <- '^' ![=] skip
-CARETEQUAL <- '^=' skip
-COLON <- ':' skip
-COMMA <- ',' skip
-DOT <- '.' ![*.?] skip
-DOT2 <- '..' ![.] skip
-DOT3 <- '...' skip
-DOTASTERISK <- '.*' skip
-DOTQUESTIONMARK <- '.?' skip
-EQUAL <- '=' ![>=] skip
-EQUALEQUAL <- '==' skip
-EQUALRARROW <- '=>' skip
-EXCLAMATIONMARK <- '!' ![=] skip
-EXCLAMATIONMARKEQUAL <- '!=' skip
-LARROW <- '<' ![<=] skip
-LARROW2 <- '<<' ![=] skip
-LARROW2EQUAL <- '<<=' skip
-LARROWEQUAL <- '<=' skip
-LBRACE <- '{' skip
-LBRACKET <- '[' skip
-LPAREN <- '(' skip
-MINUS <- '-' ![%=>] skip
-MINUSEQUAL <- '-=' skip
-MINUSPERCENT <- '-%' ![=] skip
-MINUSPERCENTEQUAL <- '-%=' skip
-MINUSRARROW <- '->' skip
-PERCENT <- '%' ![=] skip
-PERCENTEQUAL <- '%=' skip
-PIPE <- '|' ![|=] skip
-PIPE2 <- '||' skip
-PIPEEQUAL <- '|=' skip
-PLUS <- '+' ![%+=] skip
-PLUS2 <- '++' skip
-PLUSEQUAL <- '+=' skip
-PLUSPERCENT <- '+%' ![=] skip
-PLUSPERCENTEQUAL <- '+%=' skip
-QUESTIONMARK <- '?' skip
-RARROW <- '>' ![>=] skip
-RARROW2 <- '>>' ![=] skip
-RARROW2EQUAL <- '>>=' skip
-RARROWEQUAL <- '>=' skip
-RBRACE <- '}' skip
-RBRACKET <- ']' skip
-RPAREN <- ')' skip
-SEMICOLON <- ';' skip
-SLASH <- '/' ![=] skip
-SLASHEQUAL <- '/=' skip
-TILDE <- '~' skip
-
-end_of_word <- ![a-zA-Z0-9_] skip
-KEYWORD_align <- 'align' end_of_word
-KEYWORD_and <- 'and' end_of_word
-KEYWORD_anyerror <- 'anyerror' end_of_word
-KEYWORD_asm <- 'asm' end_of_word
-KEYWORD_async <- 'async' end_of_word
-KEYWORD_await <- 'await' end_of_word
-KEYWORD_break <- 'break' end_of_word
-KEYWORD_cancel <- 'cancel' end_of_word
-KEYWORD_catch <- 'catch' end_of_word
-KEYWORD_comptime <- 'comptime' end_of_word
-KEYWORD_const <- 'const' end_of_word
-KEYWORD_continue <- 'continue' end_of_word
-KEYWORD_defer <- 'defer' end_of_word
-KEYWORD_else <- 'else' end_of_word
-KEYWORD_enum <- 'enum' end_of_word
-KEYWORD_errdefer <- 'errdefer' end_of_word
-KEYWORD_error <- 'error' end_of_word
-KEYWORD_export <- 'export' end_of_word
-KEYWORD_extern <- 'extern' end_of_word
-KEYWORD_false <- 'false' end_of_word
-KEYWORD_fn <- 'fn' end_of_word
-KEYWORD_for <- 'for' end_of_word
-KEYWORD_if <- 'if' end_of_word
-KEYWORD_inline <- 'inline' end_of_word
-KEYWORD_nakedcc <- 'nakedcc' end_of_word
-KEYWORD_noalias <- 'noalias' end_of_word
-KEYWORD_null <- 'null' end_of_word
-KEYWORD_or <- 'or' end_of_word
-KEYWORD_orelse <- 'orelse' end_of_word
-KEYWORD_packed <- 'packed' end_of_word
-KEYWORD_promise <- 'promise' end_of_word
-KEYWORD_pub <- 'pub' end_of_word
-KEYWORD_resume <- 'resume' end_of_word
-KEYWORD_return <- 'return' end_of_word
-KEYWORD_section <- 'section' end_of_word
-KEYWORD_stdcallcc <- 'stdcallcc' end_of_word
-KEYWORD_struct <- 'struct' end_of_word
-KEYWORD_suspend <- 'suspend' end_of_word
-KEYWORD_switch <- 'switch' end_of_word
-KEYWORD_test <- 'test' end_of_word
-KEYWORD_true <- 'true' end_of_word
-KEYWORD_try <- 'try' end_of_word
-KEYWORD_undefined <- 'undefined' end_of_word
-KEYWORD_union <- 'union' end_of_word
-KEYWORD_unreachable <- 'unreachable' end_of_word
-KEYWORD_use <- 'use' end_of_word
-KEYWORD_var <- 'var' end_of_word
-KEYWORD_volatile <- 'volatile' end_of_word
-KEYWORD_while <- 'while' end_of_word
-
-keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_anyerror / KEYWORD_asm
+BUILTININDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
+
+
+AMPERSAND <- '&' ![=] skip
+AMPERSANDEQUAL <- '&=' skip
+ASTERISK <- '*' ![*%=] skip
+ASTERISK2 <- '**' skip
+ASTERISKEQUAL <- '*=' skip
+ASTERISKPERCENT <- '*%' ![=] skip
+ASTERISKPERCENTEQUAL <- '*%=' skip
+CARET <- '^' ![=] skip
+CARETEQUAL <- '^=' skip
+COLON <- ':' skip
+COMMA <- ',' skip
+DOT <- '.' ![*.?] skip
+DOT2 <- '..' ![.] skip
+DOT3 <- '...' skip
+DOTASTERISK <- '.*' skip
+DOTQUESTIONMARK <- '.?' skip
+EQUAL <- '=' ![>=] skip
+EQUALEQUAL <- '==' skip
+EQUALRARROW <- '=>' skip
+EXCLAMATIONMARK <- '!' ![=] skip
+EXCLAMATIONMARKEQUAL <- '!=' skip
+LARROW <- '<' ![<=] skip
+LARROW2 <- '<<' ![=] skip
+LARROW2EQUAL <- '<<=' skip
+LARROWEQUAL <- '<=' skip
+LBRACE <- '{' skip
+LBRACKET <- '[' skip
+LPAREN <- '(' skip
+MINUS <- '-' ![%=>] skip
+MINUSEQUAL <- '-=' skip
+MINUSPERCENT <- '-%' ![=] skip
+MINUSPERCENTEQUAL <- '-%=' skip
+MINUSRARROW <- '->' skip
+PERCENT <- '%' ![=] skip
+PERCENTEQUAL <- '%=' skip
+PIPE <- '|' ![|=] skip
+PIPE2 <- '||' skip
+PIPEEQUAL <- '|=' skip
+PLUS <- '+' ![%+=] skip
+PLUS2 <- '++' skip
+PLUSEQUAL <- '+=' skip
+PLUSPERCENT <- '+%' ![=] skip
+PLUSPERCENTEQUAL <- '+%=' skip
+QUESTIONMARK <- '?' skip
+RARROW <- '>' ![>=] skip
+RARROW2 <- '>>' ![=] skip
+RARROW2EQUAL <- '>>=' skip
+RARROWEQUAL <- '>=' skip
+RBRACE <- '}' skip
+RBRACKET <- ']' skip
+RPAREN <- ')' skip
+SEMICOLON <- ';' skip
+SLASH <- '/' ![=] skip
+SLASHEQUAL <- '/=' skip
+TILDE <- '~' skip
+
+end_of_word <- ![a-zA-Z0-9_] skip
+KEYWORD_align <- 'align' end_of_word
+KEYWORD_and <- 'and' end_of_word
+KEYWORD_anyerror <- 'anyerror' end_of_word
+KEYWORD_asm <- 'asm' end_of_word
+KEYWORD_async <- 'async' end_of_word
+KEYWORD_await <- 'await' end_of_word
+KEYWORD_break <- 'break' end_of_word
+KEYWORD_cancel <- 'cancel' end_of_word
+KEYWORD_catch <- 'catch' end_of_word
+KEYWORD_comptime <- 'comptime' end_of_word
+KEYWORD_const <- 'const' end_of_word
+KEYWORD_continue <- 'continue' end_of_word
+KEYWORD_defer <- 'defer' end_of_word
+KEYWORD_else <- 'else' end_of_word
+KEYWORD_enum <- 'enum' end_of_word
+KEYWORD_errdefer <- 'errdefer' end_of_word
+KEYWORD_error <- 'error' end_of_word
+KEYWORD_export <- 'export' end_of_word
+KEYWORD_extern <- 'extern' end_of_word
+KEYWORD_false <- 'false' end_of_word
+KEYWORD_fn <- 'fn' end_of_word
+KEYWORD_for <- 'for' end_of_word
+KEYWORD_if <- 'if' end_of_word
+KEYWORD_inline <- 'inline' end_of_word
+KEYWORD_nakedcc <- 'nakedcc' end_of_word
+KEYWORD_noalias <- 'noalias' end_of_word
+KEYWORD_null <- 'null' end_of_word
+KEYWORD_or <- 'or' end_of_word
+KEYWORD_orelse <- 'orelse' end_of_word
+KEYWORD_packed <- 'packed' end_of_word
+KEYWORD_promise <- 'promise' end_of_word
+KEYWORD_pub <- 'pub' end_of_word
+KEYWORD_resume <- 'resume' end_of_word
+KEYWORD_return <- 'return' end_of_word
+KEYWORD_linksection <- 'linksection' end_of_word
+KEYWORD_stdcallcc <- 'stdcallcc' end_of_word
+KEYWORD_struct <- 'struct' end_of_word
+KEYWORD_suspend <- 'suspend' end_of_word
+KEYWORD_switch <- 'switch' end_of_word
+KEYWORD_test <- 'test' end_of_word
+KEYWORD_true <- 'true' end_of_word
+KEYWORD_try <- 'try' end_of_word
+KEYWORD_undefined <- 'undefined' end_of_word
+KEYWORD_union <- 'union' end_of_word
+KEYWORD_unreachable <- 'unreachable' end_of_word
+KEYWORD_use <- 'use' end_of_word
+KEYWORD_var <- 'var' end_of_word
+KEYWORD_volatile <- 'volatile' end_of_word
+KEYWORD_while <- 'while' end_of_word
+
+keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_anyerror / KEYWORD_asm
/ KEYWORD_async / KEYWORD_await / KEYWORD_break / KEYWORD_cancel
/ KEYWORD_catch / KEYWORD_comptime / KEYWORD_const / KEYWORD_continue
/ KEYWORD_defer / KEYWORD_else / KEYWORD_enum / KEYWORD_errdefer
@@ -8209,12 +8208,11 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_anyerror / KEYWORD_asm
/ KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline
/ KEYWORD_nakedcc / KEYWORD_noalias / KEYWORD_null / KEYWORD_or
/ KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub
- / KEYWORD_resume / KEYWORD_return / KEYWORD_section
+ / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
/ KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend
/ KEYWORD_switch / KEYWORD_test / KEYWORD_true / KEYWORD_try
/ KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable
- / KEYWORD_use / KEYWORD_var / KEYWORD_volatile / KEYWORD_while
-</code></pre>
+ / KEYWORD_use / KEYWORD_var / KEYWORD_volatile / KEYWORD_while</code></pre>
{#header_close#}
{#header_open|Zen#}
<ul>
src/parser.cpp
@@ -2082,7 +2082,7 @@ static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {
// Section <- KEYWORD_section LPAREN Expr RPAREN
static AstNode *ast_parse_section(ParseContext *pc) {
- Token *first = eat_token_if(pc, TokenIdKeywordSection);
+ Token *first = eat_token_if(pc, TokenIdKeywordLinkSection);
if (first == nullptr)
return nullptr;
src/tokenizer.cpp
@@ -140,7 +140,7 @@ static const struct ZigKeyword zig_keywords[] = {
{"pub", TokenIdKeywordPub},
{"resume", TokenIdKeywordResume},
{"return", TokenIdKeywordReturn},
- {"section", TokenIdKeywordSection},
+ {"linksection", TokenIdKeywordLinkSection},
{"stdcallcc", TokenIdKeywordStdcallCC},
{"struct", TokenIdKeywordStruct},
{"suspend", TokenIdKeywordSuspend},
@@ -1583,7 +1583,7 @@ const char * token_name(TokenId id) {
case TokenIdKeywordPromise: return "promise";
case TokenIdKeywordPub: return "pub";
case TokenIdKeywordReturn: return "return";
- case TokenIdKeywordSection: return "section";
+ case TokenIdKeywordLinkSection: return "linksection";
case TokenIdKeywordStdcallCC: return "stdcallcc";
case TokenIdKeywordStruct: return "struct";
case TokenIdKeywordSwitch: return "switch";
src/tokenizer.hpp
@@ -82,7 +82,7 @@ enum TokenId {
TokenIdKeywordPub,
TokenIdKeywordResume,
TokenIdKeywordReturn,
- TokenIdKeywordSection,
+ TokenIdKeywordLinkSection,
TokenIdKeywordStdcallCC,
TokenIdKeywordStruct,
TokenIdKeywordSuspend,
std/zig/ast.zig
@@ -503,6 +503,7 @@ pub const Node = struct {
lib_name: ?*Node,
type_node: ?*Node,
align_node: ?*Node,
+ section_node: ?*Node,
init_node: ?*Node,
semicolon_token: TokenIndex,
@@ -519,6 +520,11 @@ pub const Node = struct {
i -= 1;
}
+ if (self.section_node) |section_node| {
+ if (i < 1) return section_node;
+ i -= 1;
+ }
+
if (self.init_node) |init_node| {
if (i < 1) return init_node;
i -= 1;
@@ -821,6 +827,7 @@ pub const Node = struct {
body_node: ?*Node,
lib_name: ?*Node, // populated if this is an extern declaration
align_expr: ?*Node, // populated if align(A) is present
+ section_expr: ?*Node, // populated if linksection(A) is present
pub const ParamList = SegmentedList(*Node, 2);
@@ -845,6 +852,11 @@ pub const Node = struct {
i -= 1;
}
+ if (self.section_expr) |section_expr| {
+ if (i < 1) return section_expr;
+ i -= 1;
+ }
+
switch (self.return_type) {
// TODO allow this and next prong to share bodies since the types are the same
ReturnType.Explicit => |node| {
std/zig/parse.zig
@@ -291,6 +291,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.body_node = null,
.lib_name = ctx.lib_name,
.align_expr = null,
+ .section_expr = null,
});
try ctx.decls.push(&fn_proto.base);
stack.append(State{ .FnDef = fn_proto }) catch unreachable;
@@ -601,6 +602,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.extern_export_token = ctx.extern_export_token,
.type_node = null,
.align_node = null,
+ .section_node = null,
.init_node = null,
.lib_name = ctx.lib_name,
// initialized later
@@ -622,7 +624,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
State.VarDeclAlign => |var_decl| {
- try stack.append(State{ .VarDeclEq = var_decl });
+ try stack.append(State{ .VarDeclSection = var_decl });
const next_token = nextToken(&tok_it, &tree);
const next_token_index = next_token.index;
@@ -637,6 +639,22 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
prevToken(&tok_it, &tree);
continue;
},
+ State.VarDeclSection => |var_decl| {
+ try stack.append(State{ .VarDeclEq = var_decl });
+
+ const next_token = nextToken(&tok_it, &tree);
+ const next_token_index = next_token.index;
+ const next_token_ptr = next_token.ptr;
+ if (next_token_ptr.id == Token.Id.Keyword_linksection) {
+ try stack.append(State{ .ExpectToken = Token.Id.RParen });
+ try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &var_decl.section_node } });
+ try stack.append(State{ .ExpectToken = Token.Id.LParen });
+ continue;
+ }
+
+ prevToken(&tok_it, &tree);
+ continue;
+ },
State.VarDeclEq => |var_decl| {
const token = nextToken(&tok_it, &tree);
const token_index = token.index;
@@ -719,7 +737,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
State.FnProtoAlign => |fn_proto| {
- stack.append(State{ .FnProtoReturnType = fn_proto }) catch unreachable;
+ stack.append(State{ .FnProtoSection = fn_proto }) catch unreachable;
if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| {
try stack.append(State{ .ExpectToken = Token.Id.RParen });
@@ -728,6 +746,16 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
}
continue;
},
+ State.FnProtoSection => |fn_proto| {
+ stack.append(State{ .FnProtoReturnType = fn_proto }) catch unreachable;
+
+ if (eatToken(&tok_it, &tree, Token.Id.Keyword_linksection)) |align_token| {
+ try stack.append(State{ .ExpectToken = Token.Id.RParen });
+ try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.section_expr } });
+ try stack.append(State{ .ExpectToken = Token.Id.LParen });
+ }
+ continue;
+ },
State.FnProtoReturnType => |fn_proto| {
const token = nextToken(&tok_it, &tree);
const token_index = token.index;
@@ -1524,6 +1552,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.body_node = null,
.lib_name = null,
.align_expr = null,
+ .section_expr = null,
});
ctx.opt_ctx.store(&fn_proto.base);
stack.append(State{ .FnProto = fn_proto }) catch unreachable;
@@ -2579,6 +2608,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.body_node = null,
.lib_name = null,
.align_expr = null,
+ .section_expr = null,
});
opt_ctx.store(&fn_proto.base);
stack.append(State{ .FnProto = fn_proto }) catch unreachable;
@@ -2600,6 +2630,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.body_node = null,
.lib_name = null,
.align_expr = null,
+ .section_expr = null,
});
opt_ctx.store(&fn_proto.base);
stack.append(State{ .FnProto = fn_proto }) catch unreachable;
@@ -2985,12 +3016,14 @@ const State = union(enum) {
VarDecl: VarDeclCtx,
VarDeclAlign: *ast.Node.VarDecl,
+ VarDeclSection: *ast.Node.VarDecl,
VarDeclEq: *ast.Node.VarDecl,
VarDeclSemiColon: *ast.Node.VarDecl,
FnDef: *ast.Node.FnProto,
FnProto: *ast.Node.FnProto,
FnProtoAlign: *ast.Node.FnProto,
+ FnProtoSection: *ast.Node.FnProto,
FnProtoReturnType: *ast.Node.FnProto,
ParamDecl: *ast.Node.FnProto,
std/zig/parser_test.zig
@@ -1,3 +1,10 @@
+test "zig fmt: linksection" {
+ try testCanonical(
+ \\export var aoeu: u64 linksection(".text.derp") = 1234;
+ \\export nakedcc fn _start() linksection(".text.boot") noreturn {}
+ \\
+ );
+}
test "zig fmt: shebang line" {
try testCanonical(
\\#!/usr/bin/env zig
std/zig/render.zig
@@ -1148,6 +1148,17 @@ fn renderExpression(
try renderToken(tree, stream, align_rparen, indent, start_col, Space.Space); // )
}
+ if (fn_proto.section_expr) |section_expr| {
+ const section_rparen = tree.nextToken(section_expr.lastToken());
+ const section_lparen = tree.prevToken(section_expr.firstToken());
+ const section_kw = tree.prevToken(section_lparen);
+
+ try renderToken(tree, stream, section_kw, indent, start_col, Space.None); // section
+ try renderToken(tree, stream, section_lparen, indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, section_expr, Space.None);
+ try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // )
+ }
+
switch (fn_proto.return_type) {
ast.Node.FnProto.ReturnType.Explicit => |node| {
return renderExpression(allocator, stream, tree, indent, start_col, node, space);
@@ -1698,12 +1709,14 @@ fn renderVarDecl(
try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var
const name_space = if (var_decl.type_node == null and (var_decl.align_node != null or
- var_decl.init_node != null)) Space.Space else Space.None;
+ var_decl.section_node != null or var_decl.init_node != null)) Space.Space else Space.None;
try renderToken(tree, stream, var_decl.name_token, indent, start_col, name_space);
if (var_decl.type_node) |type_node| {
try renderToken(tree, stream, tree.nextToken(var_decl.name_token), indent, start_col, Space.Space);
- const s = if (var_decl.align_node != null or var_decl.init_node != null) Space.Space else Space.None;
+ const s = if (var_decl.align_node != null or
+ var_decl.section_node != null or
+ var_decl.init_node != null) Space.Space else Space.None;
try renderExpression(allocator, stream, tree, indent, start_col, type_node, s);
}
@@ -1714,6 +1727,17 @@ fn renderVarDecl(
try renderToken(tree, stream, align_kw, indent, start_col, Space.None); // align
try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
try renderExpression(allocator, stream, tree, indent, start_col, align_node, Space.None);
+ const s = if (var_decl.section_node != null or var_decl.init_node != null) Space.Space else Space.None;
+ try renderToken(tree, stream, rparen, indent, start_col, s); // )
+ }
+
+ if (var_decl.section_node) |section_node| {
+ const lparen = tree.prevToken(section_node.firstToken());
+ const section_kw = tree.prevToken(lparen);
+ const rparen = tree.nextToken(section_node.lastToken());
+ try renderToken(tree, stream, section_kw, indent, start_col, Space.None); // linksection
+ try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
+ try renderExpression(allocator, stream, tree, indent, start_col, section_node, Space.None);
const s = if (var_decl.init_node != null) Space.Space else Space.None;
try renderToken(tree, stream, rparen, indent, start_col, s); // )
}
std/zig/tokenizer.zig
@@ -46,7 +46,7 @@ pub const Token = struct {
Keyword{ .bytes = "pub", .id = Id.Keyword_pub },
Keyword{ .bytes = "resume", .id = Id.Keyword_resume },
Keyword{ .bytes = "return", .id = Id.Keyword_return },
- Keyword{ .bytes = "section", .id = Id.Keyword_section },
+ Keyword{ .bytes = "linksection", .id = Id.Keyword_linksection },
Keyword{ .bytes = "stdcallcc", .id = Id.Keyword_stdcallcc },
Keyword{ .bytes = "struct", .id = Id.Keyword_struct },
Keyword{ .bytes = "suspend", .id = Id.Keyword_suspend },
@@ -175,7 +175,7 @@ pub const Token = struct {
Keyword_pub,
Keyword_resume,
Keyword_return,
- Keyword_section,
+ Keyword_linksection,
Keyword_stdcallcc,
Keyword_struct,
Keyword_suspend,
test/compile_errors.zig
@@ -3867,32 +3867,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"setting a section on an extern variable",
- \\extern var foo: i32 section(".text2");
+ \\extern var foo: i32 linksection(".text2");
\\export fn entry() i32 {
\\ return foo;
\\}
,
- ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'",
+ ".tmp_source.zig:1:33: error: cannot set section of external variable 'foo'",
);
cases.add(
"setting a section on a local variable",
\\export fn entry() i32 {
- \\ var foo: i32 section(".text2") = 1234;
+ \\ var foo: i32 linksection(".text2") = 1234;
\\ return foo;
\\}
,
- ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'",
+ ".tmp_source.zig:2:30: error: cannot set section of local variable 'foo'",
);
cases.add(
"setting a section on an extern fn",
- \\extern fn foo() section(".text2") void;
+ \\extern fn foo() linksection(".text2") void;
\\export fn entry() void {
\\ foo();
\\}
,
- ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'",
+ ".tmp_source.zig:1:29: error: cannot set section of external function 'foo'",
);
cases.add(