rename section keyword to linksection

add zig fmt support for this syntax

closes #1152
This commit is contained in:
Andrew Kelley 2018-11-17 01:38:35 -05:00
parent 3862962881
commit 704374e512
No known key found for this signature in database
GPG Key ID: 4E7CD66038A4D47C
11 changed files with 310 additions and 236 deletions

View File

@ -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,

View File

@ -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 &lt;- skip ContainerMembers eof
# *** Top level ***
ContainerMembers
<- TestDecl ContainerMembers
&lt;- TestDecl ContainerMembers
/ TopLevelComptime ContainerMembers
/ KEYWORD_pub? TopLevelDecl ContainerMembers
/ KEYWORD_pub? ContainerField COMMA ContainerMembers
/ KEYWORD_pub? ContainerField
/
TestDecl <- KEYWORD_test STRINGLITERAL Block
TestDecl &lt;- KEYWORD_test STRINGLITERAL Block
TopLevelComptime <- KEYWORD_comptime BlockExpr
TopLevelComptime &lt;- KEYWORD_comptime BlockExpr
TopLevelDecl
<- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
&lt;- (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 &lt;- 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 &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
ContainerField <- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
ContainerField &lt;- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
# *** Block Level ***
Statement
<- KEYWORD_comptime? VarDecl
&lt;- 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 )?
&lt;- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
/ IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
LabeledStatement <- BlockLabel? (Block / LoopStatement)
LabeledStatement &lt;- BlockLabel? (Block / LoopStatement)
LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
LoopStatement &lt;- KEYWORD_inline? (ForStatement / WhileStatement)
ForStatement
<- ForPrefix BlockExpr ( KEYWORD_else Statement )?
&lt;- ForPrefix BlockExpr ( KEYWORD_else Statement )?
/ ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
WhileStatement
<- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
&lt;- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
/ WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
BlockExprStatement
<- BlockExpr
&lt;- BlockExpr
/ AssignExpr SEMICOLON
BlockExpr <- BlockLabel? Block
BlockExpr &lt;- BlockLabel? Block
# *** Expression Level ***
AssignExpr <- Expr (AssignOp Expr)?
AssignExpr &lt;- Expr (AssignOp Expr)?
Expr <- KEYWORD_try* BoolOrExpr
Expr &lt;- KEYWORD_try* BoolOrExpr
BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)*
BoolOrExpr &lt;- BoolAndExpr (KEYWORD_or BoolAndExpr)*
BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)*
BoolAndExpr &lt;- CompareExpr (KEYWORD_and CompareExpr)*
CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
CompareExpr &lt;- BitwiseExpr (CompareOp BitwiseExpr)?
BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
BitwiseExpr &lt;- BitShiftExpr (BitwiseOp BitShiftExpr)*
BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)*
BitShiftExpr &lt;- AdditionExpr (BitShiftOp AdditionExpr)*
AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)*
AdditionExpr &lt;- MultiplyExpr (AdditionOp MultiplyExpr)*
MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)*
MultiplyExpr &lt;- PrefixExpr (MultiplyOp PrefixExpr)*
PrefixExpr <- PrefixOp* PrimaryExpr
PrefixExpr &lt;- PrefixOp* PrimaryExpr
PrimaryExpr
<- AsmExpr
&lt;- AsmExpr
/ IfExpr
/ KEYWORD_break BreakLabel? Expr?
/ KEYWORD_cancel Expr
@ -7807,35 +7806,35 @@ PrimaryExpr
/ LabeledExpr
/ CurlySuffixExpr
IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)?
IfExpr &lt;- IfPrefix Expr (KEYWORD_else Payload? Expr)?
LabeledExpr <- BlockLabel? (Block / LoopExpr)
LabeledExpr &lt;- BlockLabel? (Block / LoopExpr)
Block <- LBRACE Statement* RBRACE
Block &lt;- LBRACE Statement* RBRACE
LoopExpr <- KEYWORD_inline? (ForExpr / WhileExpr)
LoopExpr &lt;- KEYWORD_inline? (ForExpr / WhileExpr)
ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
ForExpr &lt;- ForPrefix Expr (KEYWORD_else Expr)?
WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
WhileExpr &lt;- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
CurlySuffixExpr <- TypeExpr InitList?
CurlySuffixExpr &lt;- TypeExpr InitList?
InitList
<- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
&lt;- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
/ LBRACE Expr (COMMA Expr)* COMMA? RBRACE
/ LBRACE RBRACE
TypeExpr <- PrefixTypeOp* ErrorUnionExpr
TypeExpr &lt;- PrefixTypeOp* ErrorUnionExpr
ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
ErrorUnionExpr &lt;- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
SuffixExpr
<- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArgumnets
&lt;- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArgumnets
/ PrimaryTypeExpr (SuffixOp / FnCallArgumnets)*
PrimaryTypeExpr
<- BUILTININDENTIFIER FnCallArgumnets
&lt;- BUILTININDENTIFIER FnCallArgumnets
/ CHAR_LITERAL
/ ContainerDecl
/ ErrorSetDecl
@ -7858,91 +7857,91 @@ PrimaryTypeExpr
/ STRINGLITERAL
/ SwitchExpr
ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
ContainerDecl &lt;- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
ErrorSetDecl &lt;- KEYWORD_error LBRACE IdentifierList RBRACE
GroupedExpr <- LPAREN Expr RPAREN
GroupedExpr &lt;- LPAREN Expr RPAREN
IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
IfTypeExpr &lt;- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
LabeledTypeExpr
<- BlockLabel Block
&lt;- BlockLabel Block
/ BlockLabel? LoopTypeExpr
LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
LoopTypeExpr &lt;- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
ForTypeExpr &lt;- ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
WhileTypeExpr &lt;- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
SwitchExpr &lt;- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
# *** Assembly ***
AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
AsmExpr &lt;- KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
AsmOutput <- COLON AsmOutputList AsmInput?
AsmOutput &lt;- COLON AsmOutputList AsmInput?
AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
AsmOutputItem &lt;- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
AsmInput <- COLON AsmInputList AsmCloppers?
AsmInput &lt;- COLON AsmInputList AsmCloppers?
AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
AsmInputItem &lt;- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
AsmCloppers <- COLON StringList
AsmCloppers &lt;- COLON StringList
# *** Helper grammar ***
BreakLabel <- COLON IDENTIFIER
BreakLabel &lt;- COLON IDENTIFIER
BlockLabel <- IDENTIFIER COLON
BlockLabel &lt;- IDENTIFIER COLON
FieldInit <- DOT IDENTIFIER EQUAL Expr
FieldInit &lt;- DOT IDENTIFIER EQUAL Expr
WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
WhileContinueExpr &lt;- COLON LPAREN AssignExpr RPAREN
Section <- KEYWORD_section LPAREN Expr RPAREN
LinkSection &lt;- KEYWORD_linksection LPAREN Expr RPAREN
# Fn specific
FnCC
<- KEYWORD_nakedcc
&lt;- KEYWORD_nakedcc
/ KEYWORD_stdcallcc
/ KEYWORD_extern
/ KEYWORD_async (LARROW TypeExpr RARROW)?
ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
ParamDecl &lt;- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
ParamType
<- KEYWORD_var
&lt;- KEYWORD_var
/ DOT3
/ TypeExpr
# Control flow prefixes
IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
IfPrefix &lt;- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
WhilePrefix &lt;- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
ForPrefix &lt;- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
# Payloads
Payload <- PIPE IDENTIFIER PIPE
Payload &lt;- PIPE IDENTIFIER PIPE
PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
PtrPayload &lt;- PIPE ASTERISK? IDENTIFIER PIPE
PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
PtrIndexPayload &lt;- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
# Switch specific
SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr
SwitchProng &lt;- SwitchCase EQUALRARROW PtrPayload? AssignExpr
SwitchCase
<- SwitchItem (COMMA SwitchItem)* COMMA?
&lt;- SwitchItem (COMMA SwitchItem)* COMMA?
/ KEYWORD_else
SwitchItem <- Expr (DOT3 Expr)?
SwitchItem &lt;- Expr (DOT3 Expr)?
# Operators
AssignOp
<- ASTERISKEQUAL
&lt;- ASTERISKEQUAL
/ SLASHEQUAL
/ PERCENTEQUAL
/ PLUSEQUAL
@ -7958,7 +7957,7 @@ AssignOp
/ EQUAL
CompareOp
<- EQUALEQUAL
&lt;- EQUALEQUAL
/ EXCLAMATIONMARKEQUAL
/ LARROW
/ RARROW
@ -7966,25 +7965,25 @@ CompareOp
/ RARROWEQUAL
BitwiseOp
<- AMPERSAND
&lt;- AMPERSAND
/ CARET
/ PIPE
/ KEYWORD_orelse
/ KEYWORD_catch Payload?
BitShiftOp
<- LARROW2
&lt;- LARROW2
/ RARROW2
AdditionOp
<- PLUS
&lt;- PLUS
/ MINUS
/ PLUS2
/ PLUSPERCENT
/ MINUSPERCENT
MultiplyOp
<- PIPE2
&lt;- PIPE2
/ ASTERISK
/ SLASH
/ PERCENT
@ -7992,7 +7991,7 @@ MultiplyOp
/ ASTERISKPERCENT
PrefixOp
<- EXCLAMATIONMARK
&lt;- EXCLAMATIONMARK
/ MINUS
/ TILDE
/ MINUSPERCENT
@ -8001,77 +8000,77 @@ PrefixOp
/ KEYWORD_await
PrefixTypeOp
<- QUESTIONMARK
&lt;- 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
&lt;- LBRACKET Expr (DOT2 Expr?)? RBRACKET
/ DOT IDENTIFIER
/ DOTASTERISK
/ DOTQUESTIONMARK
AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)?
AsyncPrefix &lt;- KEYWORD_async (LARROW PrefixExpr RARROW)?
FnCallArgumnets <- LPAREN ExprList RPAREN
FnCallArgumnets &lt;- LPAREN ExprList RPAREN
# Ptr specific
ArrayTypeStart <- LBRACKET Expr? RBRACKET
ArrayTypeStart &lt;- LBRACKET Expr? RBRACKET
PtrTypeStart
<- ASTERISK
&lt;- ASTERISK
/ ASTERISK2
/ LBRACKET ASTERISK RBRACKET
# ContainerDecl specific
ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
ContainerDeclAuto &lt;- ContainerDeclType LBRACE ContainerMembers RBRACE
ContainerDeclType
<- (KEYWORD_struct / KEYWORD_enum) (LPAREN Expr RPAREN)?
&lt;- (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 &lt;- KEYWORD_align LPAREN Expr RPAREN
# Lists
IdentifierList <- (IDENTIFIER COMMA)* IDENTIFIER?
IdentifierList &lt;- (IDENTIFIER COMMA)* IDENTIFIER?
SwitchProngList <- (SwitchProng COMMA)* SwitchProng?
SwitchProngList &lt;- (SwitchProng COMMA)* SwitchProng?
AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
AsmOutputList &lt;- (AsmOutputItem COMMA)* AsmOutputItem?
AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
AsmInputList &lt;- (AsmInputItem COMMA)* AsmInputItem?
StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
StringList &lt;- (STRINGLITERAL COMMA)* STRINGLITERAL?
ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
ParamDeclList &lt;- (ParamDecl COMMA)* ParamDecl?
ExprList <- (Expr COMMA)* Expr?
ExprList &lt;- (Expr COMMA)* Expr?
# *** Tokens ***
eof <- !.
hex <- [0-9a-fA-F]
eof &lt;- !.
hex &lt;- [0-9a-fA-F]
char_escape
<- "\\x" hex hex
&lt;- "\\x" hex hex
/ "\\u" hex hex hex hex
/ "\\U" hex hex hex hex hex hex
/ "\\" [nr\\t'"]
char_char
<- char_escape
&lt;- char_escape
/ [^\\'\n]
string_char
<- char_escape
&lt;- char_escape
/ [^\\"\n]
line_comment <- '//'[^\n]*
line_string <- ("\\\\" [^\n]* [ \n]*)+
line_cstring <- ("c\\\\" [^\n]* [ \n]*)+
skip <- ([ \n] / line_comment)*
line_comment &lt;- '//'[^\n]*
line_string &lt;- ("\\\\" [^\n]* [ \n]*)+
line_cstring &lt;- ("c\\\\" [^\n]* [ \n]*)+
skip &lt;- ([ \n] / line_comment)*
CHAR_LITERAL <- "'" char_char "'" skip
CHAR_LITERAL &lt;- "'" char_char "'" skip
FLOAT
<- "0b" [01]+ "." [01]+ ([eE] [-+]? [01]+)? skip
&lt;- "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
&lt;- "0b" [01]+ skip
/ "0o" [0-7]+ skip
/ "0x" hex+ skip
/ [0-9]+ skip
STRINGLITERAL
<- "c"? "\"" string_char* "\"" skip
&lt;- "c"? "\"" string_char* "\"" skip
/ line_string skip
/ line_cstring skip
IDENTIFIER
<- !keyword ("c" !["\\] / [A-Zabd-z_]) [A-Za-z0-9_]* skip
&lt;- !keyword ("c" !["\\] / [A-Zabd-z_]) [A-Za-z0-9_]* skip
/ "@\"" string_char* "\"" skip
BUILTININDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
BUILTININDENTIFIER &lt;- "@"[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
AMPERSAND &lt;- '&' ![=] skip
AMPERSANDEQUAL &lt;- '&=' skip
ASTERISK &lt;- '*' ![*%=] skip
ASTERISK2 &lt;- '**' skip
ASTERISKEQUAL &lt;- '*=' skip
ASTERISKPERCENT &lt;- '*%' ![=] skip
ASTERISKPERCENTEQUAL &lt;- '*%=' skip
CARET &lt;- '^' ![=] skip
CARETEQUAL &lt;- '^=' skip
COLON &lt;- ':' skip
COMMA &lt;- ',' skip
DOT &lt;- '.' ![*.?] skip
DOT2 &lt;- '..' ![.] skip
DOT3 &lt;- '...' skip
DOTASTERISK &lt;- '.*' skip
DOTQUESTIONMARK &lt;- '.?' skip
EQUAL &lt;- '=' ![>=] skip
EQUALEQUAL &lt;- '==' skip
EQUALRARROW &lt;- '=>' skip
EXCLAMATIONMARK &lt;- '!' ![=] skip
EXCLAMATIONMARKEQUAL &lt;- '!=' skip
LARROW &lt;- '&lt;' ![&lt;=] skip
LARROW2 &lt;- '&lt;&lt;' ![=] skip
LARROW2EQUAL &lt;- '&lt;&lt;=' skip
LARROWEQUAL &lt;- '&lt;=' skip
LBRACE &lt;- '{' skip
LBRACKET &lt;- '[' skip
LPAREN &lt;- '(' skip
MINUS &lt;- '-' ![%=>] skip
MINUSEQUAL &lt;- '-=' skip
MINUSPERCENT &lt;- '-%' ![=] skip
MINUSPERCENTEQUAL &lt;- '-%=' skip
MINUSRARROW &lt;- '->' skip
PERCENT &lt;- '%' ![=] skip
PERCENTEQUAL &lt;- '%=' skip
PIPE &lt;- '|' ![|=] skip
PIPE2 &lt;- '||' skip
PIPEEQUAL &lt;- '|=' skip
PLUS &lt;- '+' ![%+=] skip
PLUS2 &lt;- '++' skip
PLUSEQUAL &lt;- '+=' skip
PLUSPERCENT &lt;- '+%' ![=] skip
PLUSPERCENTEQUAL &lt;- '+%=' skip
QUESTIONMARK &lt;- '?' skip
RARROW &lt;- '>' ![>=] skip
RARROW2 &lt;- '>>' ![=] skip
RARROW2EQUAL &lt;- '>>=' skip
RARROWEQUAL &lt;- '>=' skip
RBRACE &lt;- '}' skip
RBRACKET &lt;- ']' skip
RPAREN &lt;- ')' skip
SEMICOLON &lt;- ';' skip
SLASH &lt;- '/' ![=] skip
SLASHEQUAL &lt;- '/=' skip
TILDE &lt;- '~' 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
end_of_word &lt;- ![a-zA-Z0-9_] skip
KEYWORD_align &lt;- 'align' end_of_word
KEYWORD_and &lt;- 'and' end_of_word
KEYWORD_anyerror &lt;- 'anyerror' end_of_word
KEYWORD_asm &lt;- 'asm' end_of_word
KEYWORD_async &lt;- 'async' end_of_word
KEYWORD_await &lt;- 'await' end_of_word
KEYWORD_break &lt;- 'break' end_of_word
KEYWORD_cancel &lt;- 'cancel' end_of_word
KEYWORD_catch &lt;- 'catch' end_of_word
KEYWORD_comptime &lt;- 'comptime' end_of_word
KEYWORD_const &lt;- 'const' end_of_word
KEYWORD_continue &lt;- 'continue' end_of_word
KEYWORD_defer &lt;- 'defer' end_of_word
KEYWORD_else &lt;- 'else' end_of_word
KEYWORD_enum &lt;- 'enum' end_of_word
KEYWORD_errdefer &lt;- 'errdefer' end_of_word
KEYWORD_error &lt;- 'error' end_of_word
KEYWORD_export &lt;- 'export' end_of_word
KEYWORD_extern &lt;- 'extern' end_of_word
KEYWORD_false &lt;- 'false' end_of_word
KEYWORD_fn &lt;- 'fn' end_of_word
KEYWORD_for &lt;- 'for' end_of_word
KEYWORD_if &lt;- 'if' end_of_word
KEYWORD_inline &lt;- 'inline' end_of_word
KEYWORD_nakedcc &lt;- 'nakedcc' end_of_word
KEYWORD_noalias &lt;- 'noalias' end_of_word
KEYWORD_null &lt;- 'null' end_of_word
KEYWORD_or &lt;- 'or' end_of_word
KEYWORD_orelse &lt;- 'orelse' end_of_word
KEYWORD_packed &lt;- 'packed' end_of_word
KEYWORD_promise &lt;- 'promise' end_of_word
KEYWORD_pub &lt;- 'pub' end_of_word
KEYWORD_resume &lt;- 'resume' end_of_word
KEYWORD_return &lt;- 'return' end_of_word
KEYWORD_linksection &lt;- 'linksection' end_of_word
KEYWORD_stdcallcc &lt;- 'stdcallcc' end_of_word
KEYWORD_struct &lt;- 'struct' end_of_word
KEYWORD_suspend &lt;- 'suspend' end_of_word
KEYWORD_switch &lt;- 'switch' end_of_word
KEYWORD_test &lt;- 'test' end_of_word
KEYWORD_true &lt;- 'true' end_of_word
KEYWORD_try &lt;- 'try' end_of_word
KEYWORD_undefined &lt;- 'undefined' end_of_word
KEYWORD_union &lt;- 'union' end_of_word
KEYWORD_unreachable &lt;- 'unreachable' end_of_word
KEYWORD_use &lt;- 'use' end_of_word
KEYWORD_var &lt;- 'var' end_of_word
KEYWORD_volatile &lt;- 'volatile' end_of_word
KEYWORD_while &lt;- 'while' end_of_word
keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_anyerror / KEYWORD_asm
keyword &lt;- 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>

View File

@ -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;

View File

@ -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";

View File

@ -82,7 +82,7 @@ enum TokenId {
TokenIdKeywordPub,
TokenIdKeywordResume,
TokenIdKeywordReturn,
TokenIdKeywordSection,
TokenIdKeywordLinkSection,
TokenIdKeywordStdcallCC,
TokenIdKeywordStruct,
TokenIdKeywordSuspend,

View File

@ -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| {

View File

@ -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,

View File

@ -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

View File

@ -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); // )
}

View File

@ -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,

View File

@ -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(