summary refs log tree commit diff
path: root/bin/order.y
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-05-18 19:15:12 -0400
committerJune McEnroe <june@causal.agency>2019-05-18 19:15:12 -0400
commitda89e0df3c659c5ede5692299404603994429db6 (patch)
tree5ae736fa63e11d63684065324246928dc5907f01 /bin/order.y
parentSupport simple assignment in order (diff)
downloadsrc-da89e0df3c659c5ede5692299404603994429db6.tar.gz
src-da89e0df3c659c5ede5692299404603994429db6.zip
Add compound assignment operators to order
Diffstat (limited to '')
-rw-r--r--bin/order.y45
1 files changed, 35 insertions, 10 deletions
diff --git a/bin/order.y b/bin/order.y
index 8700ded4..e6377771 100644
--- a/bin/order.y
+++ b/bin/order.y
@@ -44,10 +44,8 @@ static int yylex(void);
 
 %}
 
-%token Var
-
 %left ','
-%right '='
+%right '=' MulAss DivAss ModAss AddAss SubAss ShlAss ShrAss AndAss XorAss OrAss
 %right '?' ':'
 %left Or
 %left And
@@ -60,7 +58,9 @@ static int yylex(void);
 %left '+' '-'
 %left '*' '/' '%'
 %right '!' '~' Inc Dec Sizeof
-%left '[' ']' Arr '.'
+%left '(' ')' '[' ']' Arr '.'
+
+%token Var
 
 %%
 
@@ -103,10 +103,24 @@ expr:
 	| expr And expr { $$ = fmt("(%s && %s)", $1, $3); }
 	| expr Or expr { $$ = fmt("(%s || %s)", $1, $3); }
 	| expr '?' expr ':' expr { $$ = fmt("(%s ? %s : %s)", $1, $3, $5); }
-	| expr '=' expr { $$ = fmt("(%s = %s)", $1, $3); }
+	| expr ass expr %prec '=' { $$ = fmt("(%s %s %s)", $1, $2, $3); }
 	| expr ',' expr { $$ = fmt("(%s, %s)", $1, $3); }
 	;
 
+ass:
+	'=' { $$ = "="; }
+	| MulAss { $$ = "*="; }
+	| DivAss { $$ = "/="; }
+	| ModAss { $$ = "%="; }
+	| AddAss { $$ = "+="; }
+	| SubAss { $$ = "-="; }
+	| ShlAss { $$ = "<<="; }
+	| ShrAss { $$ = ">>="; }
+	| AndAss { $$ = "&="; }
+	| XorAss { $$ = "^="; }
+	| OrAss { $$ = "|="; }
+	;
+
 %%
 
 #define T(a, b) ((int)(a) << 8 | (int)(b))
@@ -129,7 +143,7 @@ static int yylex(void) {
 		return Var;
 	}
 
-	int tok = 0;
+	int tok;
 	switch (T(input[0], input[1])) {
 		break; case T('-', '>'): tok = Arr;
 		break; case T('+', '+'): tok = Inc;
@@ -142,13 +156,24 @@ static int yylex(void) {
 		break; case T('!', '='): tok = Ne;
 		break; case T('&', '&'): tok = And;
 		break; case T('|', '|'): tok = Or;
+		break; case T('*', '='): tok = MulAss;
+		break; case T('/', '='): tok = DivAss;
+		break; case T('%', '='): tok = ModAss;
+		break; case T('+', '='): tok = AddAss;
+		break; case T('-', '='): tok = SubAss;
+		break; case T('&', '='): tok = AndAss;
+		break; case T('^', '='): tok = XorAss;
+		break; case T('|', '='): tok = OrAss;
+		break; default: return *input++;
 	}
-	if (tok) {
-		input += 2;
-		return tok;
+	input += 2;
+
+	switch (T(tok, input[0])) {
+		case T(Shl, '='): input++; return ShlAss;
+		case T(Shr, '='): input++; return ShrAss;
 	}
 
-	return *input++;
+	return tok;
 }
 
 int main(int argc, char *argv[]) {