authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 18:58:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 18:58:28-07:00
log2bb2e61ee288a02e184e5b8422859a4afcbb4813
treef7b77f8ce8837d9909250b9dec3326d963976d6d
parentff028525e5421ee93182bbf19102d34d434286f3

parser: allow missing fn name and missing param names

now these problems are caught in analyzer this is for purpose of function type, see #14

4 files changed, 138 insertions(+), 97 deletions(-)

doc/langref.md+90-74
...@@ -3,153 +3,153 @@...@@ -3,153 +3,153 @@
3## Grammar3## Grammar
44
5```5```
6Root : many(TopLevelDecl) "EOF"6Root = many(TopLevelDecl) "EOF"
77
8TopLevelDecl : many(Directive) option(VisibleMod) (FnDef | ExternDecl | RootExportDecl | Import | ContainerDecl | GlobalVarDecl | ErrorValueDecl | CImportDecl)8TopLevelDecl = many(Directive) option(VisibleMod) (FnDef | ExternDecl | RootExportDecl | Import | ContainerDecl | GlobalVarDecl | ErrorValueDecl | CImportDecl)
99
10CImportDecl : "c_import" Block10CImportDecl = "c_import" Block
1111
12ErrorValueDecl : "error" "Symbol" ";"12ErrorValueDecl = "error" "Symbol" ";"
1313
14GlobalVarDecl : VariableDeclaration ";"14GlobalVarDecl = VariableDeclaration ";"
1515
16VariableDeclaration : ("var" | "const") "Symbol" option(":" PrefixOpExpression) "=" Expression16VariableDeclaration = ("var" | "const") "Symbol" option(":" PrefixOpExpression) "=" Expression
1717
18ContainerDecl : ("struct" | "enum") "Symbol" "{" many(StructMember) "}"18ContainerDecl = ("struct" | "enum") "Symbol" "{" many(StructMember) "}"
1919
20StructMember: many(Directive) option(VisibleMod) (StructField | FnDef)20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef)
2121
22StructField : "Symbol" option(":" Expression) ",")22StructField = "Symbol" option(":" Expression) ",")
2323
24Import : "import" "String" ";"24Import = "import" "String" ";"
2525
26RootExportDecl : "export" "Symbol" "String" ";"26RootExportDecl = "export" "Symbol" "String" ";"
2727
28ExternDecl : "extern" FnProto ";"28ExternDecl = "extern" FnProto ";"
2929
30FnProto : "fn" "Symbol" ParamDeclList option("->" PrefixOpExpression)30FnProto = "fn" option("Symbol") ParamDeclList option("->" PrefixOpExpression)
3131
32Directive : "#" "Symbol" "(" "String" ")"32Directive = "#" "Symbol" "(" "String" ")"
3333
34VisibleMod : "pub" | "export"34VisibleMod = "pub" | "export"
3535
36FnDef : FnProto Block36FnDef = FnProto Block
3737
38ParamDeclList : "(" list(ParamDecl, ",") ")"38ParamDeclList = "(" list(ParamDecl, ",") ")"
3939
40ParamDecl : option("noalias") "Symbol" ":" PrefixOpExpression | "..."40ParamDecl = option("noalias") option("Symbol" ":") PrefixOpExpression | "..."
4141
42Block : "{" list(option(Statement), ";") "}"42Block = "{" list(option(Statement), ";") "}"
4343
44Statement : Label | VariableDeclaration ";" | NonBlockExpression ";" | BlockExpression44Statement = Label | VariableDeclaration ";" | NonBlockExpression ";" | BlockExpression
4545
46Label: "Symbol" ":"46Label = "Symbol" ":"
4747
48Expression : BlockExpression | NonBlockExpression48Expression = BlockExpression | NonBlockExpression
4949
50NonBlockExpression : ReturnExpression | AssignmentExpression50NonBlockExpression = ReturnExpression | AssignmentExpression
5151
52AsmExpression : "asm" option("volatile") "(" "String" option(AsmOutput) ")"52AsmExpression = "asm" option("volatile") "(" "String" option(AsmOutput) ")"
5353
54AsmOutput : ":" list(AsmOutputItem, ",") option(AsmInput)54AsmOutput = ":" list(AsmOutputItem, ",") option(AsmInput)
5555
56AsmInput : ":" list(AsmInputItem, ",") option(AsmClobbers)56AsmInput = ":" list(AsmInputItem, ",") option(AsmClobbers)
5757
58AsmOutputItem : "[" "Symbol" "]" "String" "(" ("Symbol" | "->" PrefixOpExpression) ")"58AsmOutputItem = "[" "Symbol" "]" "String" "(" ("Symbol" | "->" PrefixOpExpression) ")"
5959
60AsmInputItem : "[" "Symbol" "]" "String" "(" Expression ")"60AsmInputItem = "[" "Symbol" "]" "String" "(" Expression ")"
6161
62AsmClobbers: ":" list("String", ",")62AsmClobbers= ":" list("String", ",")
6363
64UnwrapExpression : BoolOrExpression (UnwrapMaybe | UnwrapError) | BoolOrExpression64UnwrapExpression = BoolOrExpression (UnwrapMaybe | UnwrapError) | BoolOrExpression
6565
66UnwrapMaybe : "??" BoolOrExpression66UnwrapMaybe = "??" BoolOrExpression
6767
68UnwrapError : "%%" option("|" "Symbol" "|") BoolOrExpression68UnwrapError = "%%" option("|" "Symbol" "|") BoolOrExpression
6969
70AssignmentExpression : UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression70AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression
7171
72AssignmentOperator : "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "&&=" | "||="72AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "&&=" | "||="
7373
74BlockExpression : IfExpression | Block | WhileExpression | ForExpression | SwitchExpression74BlockExpression = IfExpression | Block | WhileExpression | ForExpression | SwitchExpression
7575
76SwitchExpression : "switch" "(" Expression ")" "{" many(SwitchProng) "}"76SwitchExpression = "switch" "(" Expression ")" "{" many(SwitchProng) "}"
7777
78SwitchProng : (list(SwitchItem, ",") | "else") option(":" "(" "Symbol" ")") "=>" Expression ","78SwitchProng = (list(SwitchItem, ",") | "else") option(":" "(" "Symbol" ")") "=>" Expression ","
7979
80SwitchItem : Expression | (Expression "..." Expression)80SwitchItem = Expression | (Expression "..." Expression)
8181
82WhileExpression : "while" "(" Expression ")" Expression82WhileExpression = "while" "(" Expression ")" Expression
8383
84ForExpression : "for" "(" "Symbol" "," Expression option("," "Symbol") ")" Expression84ForExpression = "for" "(" "Symbol" "," Expression option("," "Symbol") ")" Expression
8585
86BoolOrExpression : BoolAndExpression "||" BoolOrExpression | BoolAndExpression86BoolOrExpression = BoolAndExpression "||" BoolOrExpression | BoolAndExpression
8787
88ReturnExpression : option("%" | "?") "return" option(Expression)88ReturnExpression = option("%" | "?") "return" option(Expression)
8989
90IfExpression : IfVarExpression | IfBoolExpression90IfExpression = IfVarExpression | IfBoolExpression
9191
92IfBoolExpression : "if" "(" Expression ")" Expression option(Else)92IfBoolExpression = "if" "(" Expression ")" Expression option(Else)
9393
94IfVarExpression : "if" "(" ("const" | "var") "Symbol" option(":" PrefixOpExpression) "?=" Expression ")" Expression Option(Else)94IfVarExpression = "if" "(" ("const" | "var") "Symbol" option(":" PrefixOpExpression) "?=" Expression ")" Expression Option(Else)
9595
96Else : "else" Expression96Else = "else" Expression
9797
98BoolAndExpression : ComparisonExpression "&&" BoolAndExpression | ComparisonExpression98BoolAndExpression = ComparisonExpression "&&" BoolAndExpression | ComparisonExpression
9999
100ComparisonExpression : BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression100ComparisonExpression = BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression
101101
102ComparisonOperator : "==" | "!=" | "<" | ">" | "<=" | ">="102ComparisonOperator = "==" | "!=" | "<" | ">" | "<=" | ">="
103103
104BinaryOrExpression : BinaryXorExpression "|" BinaryOrExpression | BinaryXorExpression104BinaryOrExpression = BinaryXorExpression "|" BinaryOrExpression | BinaryXorExpression
105105
106BinaryXorExpression : BinaryAndExpression "^" BinaryXorExpression | BinaryAndExpression106BinaryXorExpression = BinaryAndExpression "^" BinaryXorExpression | BinaryAndExpression
107107
108BinaryAndExpression : BitShiftExpression "&" BinaryAndExpression | BitShiftExpression108BinaryAndExpression = BitShiftExpression "&" BinaryAndExpression | BitShiftExpression
109109
110BitShiftExpression : AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression110BitShiftExpression = AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
111111
112BitShiftOperator : "<<" | ">>"112BitShiftOperator = "<<" | ">>"
113113
114AdditionExpression : MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression114AdditionExpression = MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
115115
116AdditionOperator : "+" | "-" | "++"116AdditionOperator = "+" | "-" | "++"
117117
118MultiplyExpression : CurlySuffixExpression MultiplyOperator MultiplyExpression | CurlySuffixExpression118MultiplyExpression = CurlySuffixExpression MultiplyOperator MultiplyExpression | CurlySuffixExpression
119119
120CurlySuffixExpression : PrefixOpExpression option(ContainerInitExpression)120CurlySuffixExpression = PrefixOpExpression option(ContainerInitExpression)
121121
122MultiplyOperator : "*" | "/" | "%"122MultiplyOperator = "*" | "/" | "%"
123123
124PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression124PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression
125125
126SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)126SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
127127
128FieldAccessExpression : "." "Symbol"128FieldAccessExpression = "." "Symbol"
129129
130FnCallExpression : "(" list(Expression, ",") ")"130FnCallExpression = "(" list(Expression, ",") ")"
131131
132ArrayAccessExpression : "[" Expression "]"132ArrayAccessExpression = "[" Expression "]"
133133
134SliceExpression : "[" Expression "..." option(Expression) "]" option("const")134SliceExpression = "[" Expression "..." option(Expression) "]" option("const")
135135
136ContainerInitExpression : "{" ContainerInitBody "}"136ContainerInitExpression = "{" ContainerInitBody "}"
137137
138ContainerInitBody : list(StructLiteralField, ",") | list(Expression, ",")138ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
139139
140StructLiteralField : "." "Symbol" "=" Expression140StructLiteralField = "." "Symbol" "=" Expression
141141
142PrefixOp : "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" | "%%"142PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" | "%%"
143143
144PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol")144PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
145145
146ArrayType : "[" option(Expression) "]" option("const") PrefixOpExpression146ArrayType = "[" option(Expression) "]" option("const") PrefixOpExpression
147147
148GotoExpression: "goto" "Symbol"148GotoExpression = "goto" "Symbol"
149149
150GroupedExpression : "(" Expression ")"150GroupedExpression = "(" Expression ")"
151151
152KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error"152KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error"
153```153```
154154
155## Operator Precedence155## Operator Precedence
...@@ -204,9 +204,11 @@ c_ulonglong unsigned long long for ABI compatibility with C...@@ -204,9 +204,11 @@ c_ulonglong unsigned long long for ABI compatibility with C
204```204```
205205
206### Boolean Type206### Boolean Type
207
207The boolean type has the name `bool` and represents either true or false.208The boolean type has the name `bool` and represents either true or false.
208209
209### Function Type210### Function Type
211
210TODO212TODO
211213
212### Fixed-Size Array Type214### Fixed-Size Array Type
...@@ -222,6 +224,7 @@ A slice can be obtained with the slicing syntax: `array[start...end]`...@@ -222,6 +224,7 @@ A slice can be obtained with the slicing syntax: `array[start...end]`
222Example: `"aoeu"[0...2]` has type `[]u8`.224Example: `"aoeu"[0...2]` has type `[]u8`.
223225
224### Struct Type226### Struct Type
227
225TODO228TODO
226229
227### Enum Type230### Enum Type
...@@ -296,34 +299,44 @@ Hex floating point TODO TODO...@@ -296,34 +299,44 @@ Hex floating point TODO TODO
296```299```
297300
298### Identifiers301### Identifiers
302
299TODO303TODO
300304
301### Declarations305### Declarations
306
302Declarations have type `void`.307Declarations have type `void`.
303308
304#### Function Declarations309#### Function Declarations
310
305TODO311TODO
306312
307#### Variable Declarations313#### Variable Declarations
314
308TODO315TODO
309316
310#### Struct Declarations317#### Struct Declarations
318
311TODO319TODO
312320
313#### Enum Declarations321#### Enum Declarations
322
314TODO323TODO
315324
316325
317## Built-in Functions326## Built-in Functions
327
318Built-in functions are prefixed with `@`.328Built-in functions are prefixed with `@`.
319329
320### Typeof330### Typeof
331
321TODO332TODO
322333
323### Sizeof334### Sizeof
335
324TODO336TODO
325337
326### Overflow Arithmetic338### Overflow Arithmetic
339
327Overflow arithmetic functions have defined behavior on overflow or underflow. TODO what is that behaviour?340Overflow arithmetic functions have defined behavior on overflow or underflow. TODO what is that behaviour?
328341
329The functions take an integer (TODO float?) type, two variables of the specified type, and a pointer to a variable of the specified type where the result is stored. The functions return a boolean value: true of overflow/underflow occurred, false otherwise.342The functions take an integer (TODO float?) type, two variables of the specified type, and a pointer to a variable of the specified type where the result is stored. The functions return a boolean value: true of overflow/underflow occurred, false otherwise.
...@@ -336,10 +349,13 @@ bool mul_with_overflow(type, a: type, b: type, x: &type) *x = a * b...@@ -336,10 +349,13 @@ bool mul_with_overflow(type, a: type, b: type, x: &type) *x = a * b
336```349```
337350
338### Memory Operations351### Memory Operations
352
339TODO memset and memcpy353TODO memset and memcpy
340354
341### Value Count355### Value Count
356
342TODO357TODO
343358
344### Max and Min Value359### Max and Min Value
360
345TODO361TODO
src/analyze.cpp+20-1
...@@ -457,6 +457,10 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t...@@ -457,6 +457,10 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
457 assert(node->type == NodeTypeFnProto);457 assert(node->type == NodeTypeFnProto);
458 AstNodeFnProto *fn_proto = &node->data.fn_proto;458 AstNodeFnProto *fn_proto = &node->data.fn_proto;
459459
460 if (fn_proto->skip) {
461 return;
462 }
463
460 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);464 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
461 fn_table_entry->type_entry = fn_type;465 fn_table_entry->type_entry = fn_type;
462 fn_type->data.fn.calling_convention = fn_table_entry->internal_linkage ? LLVMFastCallConv : LLVMCCallConv;466 fn_type->data.fn.calling_convention = fn_table_entry->internal_linkage ? LLVMFastCallConv : LLVMCCallConv;
...@@ -932,6 +936,9 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -932,6 +936,9 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
932static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,936static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
933 AstNode *proto_node)937 AstNode *proto_node)
934{938{
939 if (proto_node->data.fn_proto.skip) {
940 return;
941 }
935 AstNode *fn_def_node = proto_node->data.fn_proto.fn_def_node;942 AstNode *fn_def_node = proto_node->data.fn_proto.fn_def_node;
936 AstNode *struct_node = proto_node->data.fn_proto.struct_node;943 AstNode *struct_node = proto_node->data.fn_proto.struct_node;
937 bool is_extern = proto_node->data.fn_proto.is_extern;944 bool is_extern = proto_node->data.fn_proto.is_extern;
...@@ -4307,6 +4314,10 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo...@@ -4307,6 +4314,10 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
4307 buf_sprintf("byvalue struct parameters not yet supported on exported functions"));4314 buf_sprintf("byvalue struct parameters not yet supported on exported functions"));
4308 }4315 }
43094316
4317 if (buf_len(&param_decl->name) == 0) {
4318 add_node_error(g, param_decl_node, buf_sprintf("missing parameter name"));
4319 }
4320
4310 VariableTableEntry *var = add_local_var(g, param_decl_node, context, &param_decl->name, type, true);4321 VariableTableEntry *var = add_local_var(g, param_decl_node, context, &param_decl->name, type, true);
4311 var->src_arg_index = i;4322 var->src_arg_index = i;
4312 param_decl_node->data.param_decl.variable = var;4323 param_decl_node->data.param_decl.variable = var;
...@@ -4682,6 +4693,15 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -4682,6 +4693,15 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
4682 }4693 }
4683 case NodeTypeFnProto:4694 case NodeTypeFnProto:
4684 {4695 {
4696 // if the name is missing, we immediately announce an error
4697 Buf *name = &node->data.fn_proto.name;
4698 if (buf_len(name) == 0) {
4699 node->data.fn_proto.skip = true;
4700 add_node_error(g, node, buf_sprintf("missing function name"));
4701 break;
4702 }
4703
4704
4685 // determine which other top level declarations this function prototype depends on.4705 // determine which other top level declarations this function prototype depends on.
4686 TopLevelDecl *decl_node = &node->data.fn_proto.top_level_decl;4706 TopLevelDecl *decl_node = &node->data.fn_proto.top_level_decl;
4687 decl_node->deps.init(1);4707 decl_node->deps.init(1);
...@@ -4692,7 +4712,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -4692,7 +4712,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
4692 }4712 }
4693 collect_expr_decl_deps(g, import, node->data.fn_proto.return_type, decl_node);4713 collect_expr_decl_deps(g, import, node->data.fn_proto.return_type, decl_node);
46944714
4695 Buf *name = &node->data.fn_proto.name;
4696 decl_node->name = name;4715 decl_node->name = name;
4697 decl_node->import = import;4716 decl_node->import = import;
4698 if (decl_node->deps.size() > 0) {4717 if (decl_node->deps.size() > 0) {
src/parser.cpp+21-22
...@@ -569,35 +569,33 @@ static void ast_parse_directives(ParseContext *pc, int *token_index,...@@ -569,35 +569,33 @@ static void ast_parse_directives(ParseContext *pc, int *token_index,
569}569}
570570
571/*571/*
572ParamDecl : option("noalias") "Symbol" ":" PrefixOpExpression | "..."572ParamDecl = option("noalias") option("Symbol" ":") PrefixOpExpression | "..."
573*/573*/
574static AstNode *ast_parse_param_decl(ParseContext *pc, int *token_index) {574static AstNode *ast_parse_param_decl(ParseContext *pc, int *token_index) {
575 Token *first_token = &pc->tokens->at(*token_index);575 Token *token = &pc->tokens->at(*token_index);
576576
577 if (first_token->id == TokenIdEllipsis) {577 if (token->id == TokenIdEllipsis) {
578 *token_index += 1;578 *token_index += 1;
579 return nullptr;579 return nullptr;
580 }580 }
581581
582 AstNode *node = ast_create_node(pc, NodeTypeParamDecl, first_token);582 AstNode *node = ast_create_node(pc, NodeTypeParamDecl, token);
583 Token *name_token;
584583
585 if (first_token->id == TokenIdKeywordNoAlias) {584 if (token->id == TokenIdKeywordNoAlias) {
586 node->data.param_decl.is_noalias = true;585 node->data.param_decl.is_noalias = true;
587 *token_index += 1;586 *token_index += 1;
588 name_token = ast_eat_token(pc, token_index, TokenIdSymbol);587 token = &pc->tokens->at(*token_index);
589 } else if (first_token->id == TokenIdSymbol) {
590 name_token = first_token;
591 *token_index += 1;
592 } else {
593 ast_invalid_token_error(pc, first_token);
594 }588 }
595589
596 ast_buf_from_token(pc, name_token, &node->data.param_decl.name);590 buf_resize(&node->data.param_decl.name, 0);
597591
598 Token *colon = &pc->tokens->at(*token_index);592 if (token->id == TokenIdSymbol) {
599 *token_index += 1;593 Token *next_token = &pc->tokens->at(*token_index + 1);
600 ast_expect_token(pc, colon, TokenIdColon);594 if (next_token->id == TokenIdColon) {
595 ast_buf_from_token(pc, token, &node->data.param_decl.name);
596 *token_index += 2;
597 }
598 }
601599
602 node->data.param_decl.type = ast_parse_prefix_op_expr(pc, token_index, true);600 node->data.param_decl.type = ast_parse_prefix_op_expr(pc, token_index, true);
603601
...@@ -2179,7 +2177,7 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato...@@ -2179,7 +2177,7 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
2179}2177}
21802178
2181/*2179/*
2182FnProto : "fn" "Symbol" ParamDeclList option("->" PrefixOpExpression)2180FnProto : "fn" option("Symbol") ParamDeclList option("->" PrefixOpExpression)
2183*/2181*/
2184static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory,2182static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory,
2185 ZigList<AstNode*> *directives, VisibMod visib_mod)2183 ZigList<AstNode*> *directives, VisibMod visib_mod)
...@@ -2200,11 +2198,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand...@@ -2200,11 +2198,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand
2200 node->data.fn_proto.directives = directives;2198 node->data.fn_proto.directives = directives;
22012199
2202 Token *fn_name = &pc->tokens->at(*token_index);2200 Token *fn_name = &pc->tokens->at(*token_index);
2203 *token_index += 1;2201 if (fn_name->id == TokenIdSymbol) {
2204 ast_expect_token(pc, fn_name, TokenIdSymbol);2202 *token_index += 1;
22052203 ast_buf_from_token(pc, fn_name, &node->data.fn_proto.name);
2206 ast_buf_from_token(pc, fn_name, &node->data.fn_proto.name);2204 } else {
22072205 buf_resize(&node->data.fn_proto.name, 0);
2206 }
22082207
2209 ast_parse_param_decl_list(pc, token_index, &node->data.fn_proto.params, &node->data.fn_proto.is_var_args);2208 ast_parse_param_decl_list(pc, token_index, &node->data.fn_proto.params, &node->data.fn_proto.is_var_args);
22102209
test/run_tests.cpp+7
...@@ -1859,6 +1859,13 @@ fn f(foo: Foo, index: i32) {...@@ -1859,6 +1859,13 @@ fn f(foo: Foo, index: i32) {
1859 const result = members[index]();1859 const result = members[index]();
1860}1860}
1861 )SOURCE", 1, ".tmp_source.zig:21:34: error: expected 1 arguments, got 0");1861 )SOURCE", 1, ".tmp_source.zig:21:34: error: expected 1 arguments, got 0");
1862
1863 add_compile_fail_case("missing function name and param name", R"SOURCE(
1864fn () {}
1865fn f(i32) {}
1866 )SOURCE", 2,
1867 ".tmp_source.zig:2:1: error: missing function name",
1868 ".tmp_source.zig:3:6: error: missing parameter name");
1862}1869}
18631870
1864//////////////////////////////////////////////////////////////////////////////1871//////////////////////////////////////////////////////////////////////////////