aboutsummaryrefslogtreecommitdiff
path: root/src/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.y')
-rw-r--r--src/parser.y38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/parser.y b/src/parser.y
index dd177d0..751aaa1 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -227,9 +227,31 @@ type
| APPLY "[" opt_types "]" {
$$ = tgen_construct($[APPLY], $[opt_types], src_loc(@$));
}
- | "(" opt_types ")" { $$ = tgen_callable($2, src_loc(@$)); }
- | "&" type { $$ = tgen_ref($2, src_loc(@$)); }
- | "*" type { $$ = tgen_ptr($2, src_loc(@$)); }
+ | "(" opt_types ")" { $$ = tgen_closure($2, src_loc(@$)); }
+ | "&&" type {
+ if ($2->k == TYPE_CLOSURE) {
+ $$ = $2; $$->k = TYPE_PURE_CLOSURE;
+ } else {
+ $$ = tgen_ref($2, src_loc(@$));
+ }
+
+ /* heh */
+ $$ = tgen_ref($$, src_loc(@$));
+ }
+ | "&" type {
+ if ($2->k == TYPE_CLOSURE) {
+ $$ = $2; $$->k = TYPE_PURE_CLOSURE;
+ } else {
+ $$ = tgen_ref($2, src_loc(@$));
+ }
+ }
+ | "*" type {
+ if ($2->k == TYPE_CLOSURE) {
+ $$ = $2; $$->k = TYPE_FUNC_PTR;
+ } else {
+ $$ = tgen_ptr($2, src_loc(@$));
+ }
+ }
rev_types
: rev_types "," type { $$ = $3; $$->n = $1; }
@@ -259,6 +281,8 @@ expr
| INT { $$ = gen_const_int($1, src_loc(@$)); }
| ID { $$ = gen_id($1, src_loc(@$)); }
| "(" expr ")" { $$ = $2; }
+ | expr "&" { $$ = gen_ref($1, src_loc(@$)); }
+ | expr "*" { $$ = gen_deref($1, src_loc(@$)); }
| construct
| binop
| unop
@@ -276,6 +300,10 @@ opt_exprs
closure
: "=>" opt_vars body { $$ = gen_closure($[opt_vars], $[body], src_loc(@$)); }
+ | "&" "=>" opt_vars body {
+ $$ = gen_closure($[opt_vars], $[body], src_loc(@$));
+ ast_set_flags($$, AST_FLAG_NOMOVES);
+ }
rev_closures
: rev_closures closure { $$ = $2; $2->n = $1; }
@@ -283,6 +311,10 @@ rev_closures
trailing_closure
: "=>" opt_vars ";" { $$ = gen_closure($[opt_vars], NULL, src_loc(@$));}
+ | "&" "=>" opt_vars ";" {
+ $$ = gen_closure($[opt_vars], NULL, src_loc(@$));
+ ast_set_flags($$, AST_FLAG_NOMOVES);
+ }
opt_trailing_closure
: trailing_closure