+core_args :: { [UfExpr RdrName] }
+ : { [] }
+ | core_arg core_args { $1 : $2 }
+
+core_aexpr :: { UfExpr RdrName } -- Atomic expressions
+core_aexpr : qvar_name { UfVar $1 }
+
+ | qdata_name { UfVar $1 }
+ -- This one means that e.g. "True" will parse as
+ -- (UfVar True_Id) rather than (UfCon True_Con []).
+ -- No big deal; it'll be inlined in a jiffy. I tried
+ -- parsing it to (Con con []) directly, but got bitten
+ -- when a real constructor Id showed up in an interface
+ -- file. As usual, a hack bites you in the end.
+ -- If you want to get a UfCon, then use the
+ -- curly-bracket notation (True {}).
+
+ | core_lit { UfCon (UfLitCon $1) [] }
+ | '(' core_expr ')' { $2 }
+ | '(' ')' { UfTuple (mkTupConRdrName 0) [] }
+ | '(' comma_exprs2 ')' { UfTuple (mkTupConRdrName (length $2)) $2 }
+ | '(#' core_expr '#)' { UfTuple (mkUbxTupConRdrName 1) [$2] }
+ | '(#' comma_exprs2 '#)' { UfTuple (mkUbxTupConRdrName (length $2)) $2 }
+
+comma_exprs2 :: { [UfExpr RdrName] } -- Two or more
+comma_exprs2 : core_expr ',' core_expr { [$1,$3] }
+ | core_expr ',' comma_exprs2 { $1 : $3 }
+
+con_or_primop :: { UfCon RdrName }
+con_or_primop : qdata_name { UfDataCon $1 }
+ | qvar_name { UfPrimOp $1 }
+ | '__ccall' ccall_string { let
+ (is_casm, may_gc) = $1
+ in
+ UfCCallOp $2 is_casm may_gc
+ }