Add 3 '*' operators: one prefix, one infix, and one postfix, per #523. (#582)

The presence or absence of whitespace is used to determine which
operator is in use, following the rules described in #520.

Support for prefix * dereference operator follows #523.

Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
Richard Smith
2021-06-21 17:09:34 -07:00
committed by GitHub
co-authored by Geoff Romer
parent d6b47ba10f
commit 89e21113c3
12 changed files with 179 additions and 21 deletions
+32 -5
View File
@@ -123,7 +123,8 @@ void yy::parser::error(
%token TYPE
%token FN
%token FNTY
%token ARROW
%token ARROW "->"
%token FNARROW "-> in return type"
%token VAR
%token EQUAL_EQUAL
%token IF
@@ -142,14 +143,20 @@ void yy::parser::error(
%token CHOICE
%token MATCH
%token CASE
%token DBLARROW
%token DBLARROW "=>"
%token DEFAULT
%token AUTO
%token
EQUAL "="
MINUS "-"
PLUS "+"
STAR "*"
// The lexer determines the arity and fixity of each `*` based on whitespace
// and adjacent tokens. UNARY_STAR indicates that the operator is unary but
// could be either prefix or postfix.
UNARY_STAR "unary *"
PREFIX_STAR "prefix *"
POSTFIX_STAR "postfix *"
BINARY_STAR "binary *"
SLASH "/"
LEFT_PARENTHESIS "("
RIGHT_PARENTHESIS ")"
@@ -163,12 +170,22 @@ void yy::parser::error(
COLON ":"
;
%precedence FNARROW
%precedence "{" "}"
%precedence ":" "," DBLARROW
%left OR AND
%nonassoc EQUAL_EQUAL
%left "+" "-"
%precedence NOT UNARY_MINUS
%left BINARY_STAR
%precedence NOT UNARY_MINUS PREFIX_STAR
// We need to give the `UNARY_STAR` token a precedence, rather than overriding
// the precedence of the `expression UNARY_STAR` rule below, because bison
// compares the precedence of the final token (for a shift) to the precedence
// of the other rule (for a reduce) when attempting to resolve a shift-reduce
// conflict. See https://stackoverflow.com/a/26188429/1041090. When UNARY_STAR
// is the final token of a rule, it must be a postfix usage, so we give it the
// same precedence as POSTFIX_STAR.
%precedence POSTFIX_STAR UNARY_STAR
%left "." ARROW
%precedence "(" ")" "[" "]"
@@ -214,6 +231,8 @@ expression:
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
| expression "-" expression
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
| expression BINARY_STAR expression
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::Mul, $1, $3); }
| expression AND expression
{ $$ = Carbon::Expression::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
| expression OR expression
@@ -222,8 +241,16 @@ expression:
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
| "-" expression %prec UNARY_MINUS
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
| PREFIX_STAR expression
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, $2); }
| UNARY_STAR expression %prec PREFIX_STAR
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Deref, $2); }
| expression tuple
{ $$ = Carbon::Expression::MakeCall(yylineno, $1, $2); }
| expression POSTFIX_STAR
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, $1); }
| expression UNARY_STAR
{ $$ = Carbon::Expression::MakeUnOp(yylineno, Carbon::Operator::Ptr, $1); }
| FNTY tuple return_type
{ $$ = Carbon::Expression::MakeFunType(yylineno, $2, $3); }
;
@@ -324,7 +351,7 @@ statement_list:
return_type:
// Empty
{ $$ = Carbon::Expression::MakeUnit(yylineno); }
| ARROW expression
| ARROW expression %prec FNARROW
{ $$ = $2; }
;
function_definition: