@@ -677,6 +677,40 @@ class Parser:
677677
678678 return result
679679
680+ def parse_special_function_like_expression(self) -> AstExpression:
681+ expr = AstExpression{location = self.tokens.location}
682+
683+ assert self.tokens.kind == TokenKind.Keyword
684+ match (self.tokens++).short_string with strcmp:
685+ case "sizeof":
686+ expr.kind = AstExpressionKind.SizeOf
687+ error = "value after sizeof must be in parentheses, e.g. sizeof(foo)"
688+ case "array_count":
689+ expr.kind = AstExpressionKind.ArrayCount
690+ error = "value after array_count must be in parentheses, e.g. array_count(foo)"
691+ case "enum_count":
692+ expr.kind = AstExpressionKind.EnumCount
693+ error = "enum type after enum_count must be in parentheses, e.g. enum_count(Foo)"
694+ case "embed_file":
695+ expr.kind = AstExpressionKind.EmbedFile
696+ error = "file name after embed_file must be in parentheses, e.g. embed_file(\"foo.txt\")"
697+ case _:
698+ assert False
699+
700+ if not self.tokens.is_operator("("):
701+ fail(self.tokens.location, error)
702+ self.tokens++
703+
704+ if expr.kind == AstExpressionKind.EnumCount:
705+ expr.enumcount.enum_type_ast = self.parse_type()
706+ else:
707+ expr.operands = malloc(sizeof(expr.operands[0]))
708+ assert expr.operands != NULL
709+ *expr.operands = self.parse_expression()
710+
711+ self.eat_operator(")", True, "a ')'")
712+ return expr
713+
680714 def parse_elementary_expression(self) -> AstExpression:
681715 expr = AstExpression{location = self.tokens.location}
682716
@@ -730,20 +764,13 @@ class Parser:
730764 elif self.tokens.is_operator("["):
731765 expr.kind = AstExpressionKind.Array
732766 expr.array = self.parse_array()
733- elif self.tokens.is_keyword("sizeof"):
734- expr.kind = AstExpressionKind.SizeOf
735- self.eat_keyword("sizeof", False, NULL)
736- if not self.tokens.is_operator("("):
737- fail(self.tokens.location, "value after sizeof must be in parentheses, e.g. sizeof(thing)")
738- self.tokens++
739- expr.operands = malloc(sizeof(expr.operands[0]))
740- assert expr.operands != NULL
741- *expr.operands = self.parse_expression()
742- self.eat_operator(")", True, "a ')'")
743- elif self.tokens.is_keyword("enum_count"):
744- expr.kind = AstExpressionKind.EnumCount
745- self.tokens++
746- expr.enumcount.enum_type_ast = self.parse_type()
767+ elif (
768+ self.tokens.is_keyword("sizeof")
769+ or self.tokens.is_keyword("array_count")
770+ or self.tokens.is_keyword("embed_file")
771+ or self.tokens.is_keyword("enum_count")
772+ ):
773+ expr = self.parse_special_function_like_expression()
747774 else:
748775 # Special error message for e.g. int(x)
749776 msg: byte[300]
@@ -845,8 +872,6 @@ class Parser:
845872 or self.tokens.is_operator("&")
846873 or self.tokens.is_operator("*")
847874 or self.tokens.is_operator("~")
848- or self.tokens.is_keyword("embed_file")
849- or self.tokens.is_keyword("array_count")
850875 ):
851876 self.tokens++
852877 prefix_end = self.tokens
@@ -883,10 +908,6 @@ class Parser:
883908 kind = AstExpressionKind.AddressOf
884909 elif token.is_operator("~"):
885910 kind = AstExpressionKind.BitNot
886- elif token.is_keyword("embed_file"):
887- kind = AstExpressionKind.EmbedFile
888- elif token.is_keyword("array_count"):
889- kind = AstExpressionKind.ArrayCount
890911 else:
891912 assert False
892913
0 commit comments