Remove =x uses from ISLE, and remove support from the DSL compiler. (#4078)

This is a follow-up on #4074: now that we have the simplified syntax, we
can remove the old, redundant syntax.
This commit is contained in:
Chris Fallin
2022-04-28 11:17:08 -07:00
committed by GitHub
parent 477d394288
commit eceb433b28
8 changed files with 78 additions and 89 deletions

View File

@@ -7,7 +7,7 @@
// - src/isa/aarch64/lower.isle // - src/isa/aarch64/lower.isle
#![allow(dead_code, unreachable_code, unreachable_patterns)] #![allow(dead_code, unreachable_code, unreachable_patterns)]
#![allow(unused_imports, unused_variables, non_snake_case)] #![allow(unused_imports, unused_variables, non_snake_case, unused_mut)]
#![allow(irrefutable_let_patterns)] #![allow(irrefutable_let_patterns)]
use super::*; // Pulls in all external types. use super::*; // Pulls in all external types.
@@ -3105,7 +3105,7 @@ pub fn constructor_imm<C: Context>(ctx: &mut C, arg0: Type, arg1: u64) -> Option
let pattern0_0 = arg0; let pattern0_0 = arg0;
if let Some(pattern1_0) = C::integral_ty(ctx, pattern0_0) { if let Some(pattern1_0) = C::integral_ty(ctx, pattern0_0) {
let pattern2_0 = arg1; let pattern2_0 = arg1;
let closure3 = || { let mut closure3 = || {
let expr0_0: Type = I64; let expr0_0: Type = I64;
return Some(expr0_0); return Some(expr0_0);
}; };
@@ -3332,7 +3332,7 @@ pub fn constructor_alu_rs_imm_logic_commutative<C: Context>(
imm: pattern5_1, imm: pattern5_1,
} => { } => {
if let &Opcode::Iconst = pattern5_0 { if let &Opcode::Iconst = pattern5_0 {
let closure7 = || { let mut closure7 = || {
return Some(pattern1_0); return Some(pattern1_0);
}; };
if let Some(pattern7_0) = closure7() { if let Some(pattern7_0) = closure7() {
@@ -3364,7 +3364,7 @@ pub fn constructor_alu_rs_imm_logic_commutative<C: Context>(
} = &pattern9_0 } = &pattern9_0
{ {
if let &Opcode::Iconst = pattern10_0 { if let &Opcode::Iconst = pattern10_0 {
let closure12 = || { let mut closure12 = || {
return Some(pattern1_0); return Some(pattern1_0);
}; };
if let Some(pattern12_0) = closure12() { if let Some(pattern12_0) = closure12() {
@@ -3403,7 +3403,7 @@ pub fn constructor_alu_rs_imm_logic_commutative<C: Context>(
imm: pattern6_1, imm: pattern6_1,
} => { } => {
if let &Opcode::Iconst = pattern6_0 { if let &Opcode::Iconst = pattern6_0 {
let closure8 = || { let mut closure8 = || {
return Some(pattern1_0); return Some(pattern1_0);
}; };
if let Some(pattern8_0) = closure8() { if let Some(pattern8_0) = closure8() {
@@ -3434,7 +3434,7 @@ pub fn constructor_alu_rs_imm_logic_commutative<C: Context>(
} = &pattern10_0 } = &pattern10_0
{ {
if let &Opcode::Iconst = pattern11_0 { if let &Opcode::Iconst = pattern11_0 {
let closure13 = || { let mut closure13 = || {
return Some(pattern1_0); return Some(pattern1_0);
}; };
if let Some(pattern13_0) = closure13() { if let Some(pattern13_0) = closure13() {
@@ -3490,7 +3490,7 @@ pub fn constructor_alu_rs_imm_logic<C: Context>(
imm: pattern6_1, imm: pattern6_1,
} => { } => {
if let &Opcode::Iconst = pattern6_0 { if let &Opcode::Iconst = pattern6_0 {
let closure8 = || { let mut closure8 = || {
return Some(pattern1_0); return Some(pattern1_0);
}; };
if let Some(pattern8_0) = closure8() { if let Some(pattern8_0) = closure8() {
@@ -3521,7 +3521,7 @@ pub fn constructor_alu_rs_imm_logic<C: Context>(
} = &pattern10_0 } = &pattern10_0
{ {
if let &Opcode::Iconst = pattern11_0 { if let &Opcode::Iconst = pattern11_0 {
let closure13 = || { let mut closure13 = || {
return Some(pattern1_0); return Some(pattern1_0);
}; };
if let Some(pattern13_0) = closure13() { if let Some(pattern13_0) = closure13() {
@@ -4023,7 +4023,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern9_0 } = &pattern9_0
{ {
if let &Opcode::Iconst = pattern10_0 { if let &Opcode::Iconst = pattern10_0 {
let closure12 = || { let mut closure12 = || {
let expr0_0: Type = I32; let expr0_0: Type = I32;
return Some(expr0_0); return Some(expr0_0);
}; };
@@ -4070,7 +4070,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern9_0 } = &pattern9_0
{ {
if let &Opcode::Iconst = pattern10_0 { if let &Opcode::Iconst = pattern10_0 {
let closure12 = || { let mut closure12 = || {
let expr0_0: Type = I32; let expr0_0: Type = I32;
return Some(expr0_0); return Some(expr0_0);
}; };
@@ -4234,7 +4234,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern9_0 } = &pattern9_0
{ {
if let &Opcode::Iconst = pattern10_0 { if let &Opcode::Iconst = pattern10_0 {
let closure12 = || { let mut closure12 = || {
let expr0_0: Type = I64; let expr0_0: Type = I64;
return Some(expr0_0); return Some(expr0_0);
}; };
@@ -4281,7 +4281,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern9_0 } = &pattern9_0
{ {
if let &Opcode::Iconst = pattern10_0 { if let &Opcode::Iconst = pattern10_0 {
let closure12 = || { let mut closure12 = || {
let expr0_0: Type = I64; let expr0_0: Type = I64;
return Some(expr0_0); return Some(expr0_0);
}; };
@@ -5882,7 +5882,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern9_0 } = &pattern9_0
{ {
if let &Opcode::Iconst = pattern10_0 { if let &Opcode::Iconst = pattern10_0 {
let closure12 = || { let mut closure12 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern12_0) = closure12() { if let Some(pattern12_0) = closure12() {
@@ -5924,7 +5924,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern9_0 } = &pattern9_0
{ {
if let &Opcode::Iconst = pattern10_0 { if let &Opcode::Iconst = pattern10_0 {
let closure12 = || { let mut closure12 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern12_0) = closure12() { if let Some(pattern12_0) = closure12() {
@@ -6173,7 +6173,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern14_0 } = &pattern14_0
{ {
if let &Opcode::Iconst = pattern15_0 { if let &Opcode::Iconst = pattern15_0 {
let closure17 = || { let mut closure17 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern17_0) = closure17() { if let Some(pattern17_0) = closure17() {
@@ -6297,7 +6297,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern14_0 } = &pattern14_0
{ {
if let &Opcode::Iconst = pattern15_0 { if let &Opcode::Iconst = pattern15_0 {
let closure17 = || { let mut closure17 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern17_0) = closure17() { if let Some(pattern17_0) = closure17() {
@@ -6430,7 +6430,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern14_0 } = &pattern14_0
{ {
if let &Opcode::Iconst = pattern15_0 { if let &Opcode::Iconst = pattern15_0 {
let closure17 = || { let mut closure17 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern17_0) = closure17() { if let Some(pattern17_0) = closure17() {
@@ -6611,7 +6611,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<InstOutp
} = &pattern13_0 } = &pattern13_0
{ {
if let &Opcode::Iconst = pattern14_0 { if let &Opcode::Iconst = pattern14_0 {
let closure16 = || { let mut closure16 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern16_0) = closure16() { if let Some(pattern16_0) = closure16() {
@@ -7153,7 +7153,7 @@ pub fn constructor_do_shift<C: Context>(
} = &pattern5_0 } = &pattern5_0
{ {
if let &Opcode::Iconst = pattern6_0 { if let &Opcode::Iconst = pattern6_0 {
let closure8 = || { let mut closure8 = || {
return Some(pattern1_0); return Some(pattern1_0);
}; };
if let Some(pattern8_0) = closure8() { if let Some(pattern8_0) = closure8() {

View File

@@ -7,7 +7,7 @@
// - src/isa/s390x/lower.isle // - src/isa/s390x/lower.isle
#![allow(dead_code, unreachable_code, unreachable_patterns)] #![allow(dead_code, unreachable_code, unreachable_patterns)]
#![allow(unused_imports, unused_variables, non_snake_case)] #![allow(unused_imports, unused_variables, non_snake_case, unused_mut)]
#![allow(irrefutable_let_patterns)] #![allow(irrefutable_let_patterns)]
use super::*; // Pulls in all external types. use super::*; // Pulls in all external types.
@@ -1222,7 +1222,7 @@ pub fn constructor_lower_address<C: Context>(
if let Some(()) = C::reloc_distance_near(ctx, pattern6_1) { if let Some(()) = C::reloc_distance_near(ctx, pattern6_1) {
let pattern8_0 = arg2; let pattern8_0 = arg2;
let pattern9_0 = C::i64_from_offset(ctx, pattern8_0); let pattern9_0 = C::i64_from_offset(ctx, pattern8_0);
let closure10 = || { let mut closure10 = || {
return Some(pattern6_2); return Some(pattern6_2);
}; };
if let Some(pattern10_0) = closure10() { if let Some(pattern10_0) = closure10() {
@@ -2885,7 +2885,7 @@ pub fn constructor_push_alu_uimm32shifted<C: Context>(
let pattern2_0 = arg2; let pattern2_0 = arg2;
if let Some(pattern3_0) = C::real_reg(ctx, pattern2_0) { if let Some(pattern3_0) = C::real_reg(ctx, pattern2_0) {
let pattern4_0 = arg3; let pattern4_0 = arg3;
let closure5 = || { let mut closure5 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern5_0) = closure5() { if let Some(pattern5_0) = closure5() {
@@ -2955,7 +2955,7 @@ pub fn constructor_push_rxsbg<C: Context>(
let pattern2_0 = arg2; let pattern2_0 = arg2;
if let Some(pattern3_0) = C::real_reg(ctx, pattern2_0) { if let Some(pattern3_0) = C::real_reg(ctx, pattern2_0) {
let pattern4_0 = arg3; let pattern4_0 = arg3;
let closure5 = || { let mut closure5 = || {
return Some(pattern3_0); return Some(pattern3_0);
}; };
if let Some(pattern5_0) = closure5() { if let Some(pattern5_0) = closure5() {
@@ -13473,7 +13473,7 @@ pub fn constructor_icmpu_val<C: Context>(
{ {
let pattern16_0 = let pattern16_0 =
C::i64_from_offset(ctx, pattern8_3); C::i64_from_offset(ctx, pattern8_3);
let closure17 = || { let mut closure17 = || {
return Some(pattern14_2); return Some(pattern14_2);
}; };
if let Some(pattern17_0) = closure17() { if let Some(pattern17_0) = closure17() {
@@ -13561,7 +13561,7 @@ pub fn constructor_icmpu_val<C: Context>(
{ {
let pattern18_0 = let pattern18_0 =
C::i64_from_offset(ctx, pattern10_3); C::i64_from_offset(ctx, pattern10_3);
let closure19 = || { let mut closure19 = || {
return Some(pattern16_2); return Some(pattern16_2);
}; };
if let Some(pattern19_0) = closure19() { if let Some(pattern19_0) = closure19() {

View File

@@ -1222,7 +1222,7 @@
(decl extend_to_gpr (Value Type ExtendKind) Gpr) (decl extend_to_gpr (Value Type ExtendKind) Gpr)
;; If the value is already of the requested type, no extending is necessary. ;; If the value is already of the requested type, no extending is necessary.
(rule (extend_to_gpr (and val (value_type ty)) =ty _kind) (rule (extend_to_gpr (and val (value_type ty)) ty _kind)
(put_in_gpr val)) (put_in_gpr val))
(rule (extend_to_gpr (and val (value_type from_ty)) (rule (extend_to_gpr (and val (value_type from_ty))

View File

@@ -2111,7 +2111,7 @@
;; Rules for `uextend` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Rules for `uextend` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; T -> T is a no-op. ;; T -> T is a no-op.
(rule (lower (has_type ty (uextend src @ (value_type =ty)))) (rule (lower (has_type ty (uextend src @ (value_type ty))))
src) src)
;; I64 -> I128. ;; I64 -> I128.
@@ -2177,7 +2177,7 @@
(decl generic_sextend (Value Type Type) InstOutput) (decl generic_sextend (Value Type Type) InstOutput)
;; T -> T is a no-op. ;; T -> T is a no-op.
(rule (generic_sextend src ty =ty) (rule (generic_sextend src ty ty)
src) src)
;; Produce upper 64 bits sign-extended from lower 64: shift right by ;; Produce upper 64 bits sign-extended from lower 64: shift right by
@@ -2218,7 +2218,7 @@
;; Rules for `ireduce` / `breduce` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Rules for `ireduce` / `breduce` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; T -> T is always a no-op, even I128 -> I128. ;; T -> T is always a no-op, even I128 -> I128.
(rule (lower (has_type ty (ireduce src @ (value_type =ty)))) (rule (lower (has_type ty (ireduce src @ (value_type ty))))
src) src)
;; T -> I{64,32,16,8}: We can simply pass through the value: values ;; T -> I{64,32,16,8}: We can simply pass through the value: values
@@ -2229,7 +2229,7 @@
;; Likewise for breduce. ;; Likewise for breduce.
(rule (lower (has_type ty (breduce src @ (value_type =ty)))) (rule (lower (has_type ty (breduce src @ (value_type ty))))
src) src)
(rule (lower (has_type (fits_in_64 ty) (breduce src))) (rule (lower (has_type (fits_in_64 ty) (breduce src)))
@@ -2660,126 +2660,126 @@
;; Add mem, reg ;; Add mem, reg
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(iadd (and (iadd (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)) (load flags addr offset))
src2)) src2))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_add_mem ty (to_amode flags addr offset) src2)))) (x64_add_mem ty (to_amode flags addr offset) src2))))
;; Add mem, reg with args swapped ;; Add mem, reg with args swapped
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(iadd src2 (iadd src2
(and (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)))) (load flags addr offset))))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_add_mem ty (to_amode flags addr offset) src2)))) (x64_add_mem ty (to_amode flags addr offset) src2))))
;; Sub mem, reg ;; Sub mem, reg
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(isub (and (isub (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)) (load flags addr offset))
src2)) src2))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_sub_mem ty (to_amode flags addr offset) src2)))) (x64_sub_mem ty (to_amode flags addr offset) src2))))
;; And mem, reg ;; And mem, reg
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(band (and (band (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)) (load flags addr offset))
src2)) src2))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_and_mem ty (to_amode flags addr offset) src2)))) (x64_and_mem ty (to_amode flags addr offset) src2))))
;; And mem, reg with args swapped ;; And mem, reg with args swapped
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(band src2 (band src2
(and (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)))) (load flags addr offset))))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_and_mem ty (to_amode flags addr offset) src2)))) (x64_and_mem ty (to_amode flags addr offset) src2))))
;; Or mem, reg ;; Or mem, reg
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(bor (and (bor (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)) (load flags addr offset))
src2)) src2))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_or_mem ty (to_amode flags addr offset) src2)))) (x64_or_mem ty (to_amode flags addr offset) src2))))
;; Or mem, reg with args swapped ;; Or mem, reg with args swapped
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(bor src2 (bor src2
(and (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)))) (load flags addr offset))))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_or_mem ty (to_amode flags addr offset) src2)))) (x64_or_mem ty (to_amode flags addr offset) src2))))
;; Xor mem, reg ;; Xor mem, reg
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(bxor (and (bxor (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)) (load flags addr offset))
src2)) src2))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_xor_mem ty (to_amode flags addr offset) src2)))) (x64_xor_mem ty (to_amode flags addr offset) src2))))
;; Xor mem, reg with args swapped ;; Xor mem, reg with args swapped
(rule (lower (rule (lower
(store =flags (store flags
(has_type (ty_32_or_64 ty) (has_type (ty_32_or_64 ty)
(bxor src2 (bxor src2
(and (and
(sinkable_load sink) (sinkable_load sink)
(load flags addr offset)))) (load flags addr offset))))
=addr addr
=offset)) offset))
(let ((_ RegMemImm (sink_load sink))) (let ((_ RegMemImm (sink_load sink)))
(side_effect (side_effect
(x64_xor_mem ty (to_amode flags addr offset) src2)))) (x64_xor_mem ty (to_amode flags addr offset) src2))))

View File

@@ -1,4 +1,4 @@
src/clif.isle 443b34b797fc8ace src/clif.isle 443b34b797fc8ace
src/prelude.isle a7915a6b88310eb5 src/prelude.isle a7915a6b88310eb5
src/isa/x64/inst.isle 6dcba190988a695 src/isa/x64/inst.isle a63b8ede292f2e20
src/isa/x64/lower.isle b95161bdf07b9365 src/isa/x64/lower.isle 4c567e9157f84afb

View File

@@ -498,16 +498,16 @@ operators:
`0x80`, `-0x80`) and boolean constants (`#t`, `#f`). `0x80`, `-0x80`) and boolean constants (`#t`, `#f`).
* constants imported from the embedding, of arbitrary type * constants imported from the embedding, of arbitrary type
(`$MyConst`). (`$MyConst`).
* Variable captures (bare identifiers like `x`; an identifier consists * Variable captures and matches (bare identifiers like `x`; an
of alphanumeric characters and underscores, and does not start with identifier consists of alphanumeric characters and underscores, and
a digit). does not start with a digit). The first occurrence of a variable `x`
captures the value; each subsequent occurrence matches on the
already-captured value, rejecting the match if not equal.
* Variable captures with sub-patterns: `x @ PAT`, which captures the * Variable captures with sub-patterns: `x @ PAT`, which captures the
subterm in `x` as above but also matches `PAT` against the subterm in `x` as above but also matches `PAT` against the
subterm. For example, `x @ (A y z)` matches an `A` term and captures subterm. For example, `x @ (A y z)` matches an `A` term and captures
its arguments as `y` and `z`, but also captures the whole term as its arguments as `y` and `z`, but also captures the whole term as
`x`. `x`.
* "Equal-variable" constraints (`=x`): a subterm must match an
already-captured value.
* conjunctions of subpatterns: `(and PAT1 PAT2 ...)` matches all of * conjunctions of subpatterns: `(and PAT1 PAT2 ...)` matches all of
the subpatterns against the term. If any subpattern does not match, the subpatterns against the term. If any subpattern does not match,
then this matcher fails. then this matcher fails.
@@ -680,12 +680,11 @@ The typing rules for patterns in ISLE are:
T2 T2) R)`, has type `R` and provides expected types `T1`, `T2`, and T2 T2) R)`, has type `R` and provides expected types `T1`, `T2`, and
`T3` to its subpatterns. `T3` to its subpatterns.
* A variable capture pattern `x` is compatible with any expected type, * A variable capture pattern `x` is compatible with any expected type
and captures this expected type under the variable identifier `x` in the first time it appears, and captures this expected type under the
the type environment. variable identifier `x` in the type environment. Subsequent
appearances of `x` check that the expected type matches the
* A variable-equality pattern `=x` checks that the expected type is already-captured type.
equal to the already-captured type for `x` in the type environment.
* A conjunction `(and PAT1 PAT2 ...)` checks that each subpattern is * A conjunction `(and PAT1 PAT2 ...)` checks that each subpattern is
compatible with the expected type. compatible with the expected type.
@@ -1397,7 +1396,7 @@ newline). The grammar accepted by the parser is as follows:
<pattern> ::= <int> <pattern> ::= <int>
| <const-ident> | <const-ident>
| "_" | "_"
| "=" <ident> | <ident>
| <ident> "@" <pattern> | <ident> "@" <pattern>
| "(" "and" <pattern>* ")" | "(" "and" <pattern>* ")"
| "(" <ident> <pattern-arg>* ")" | "(" <ident> <pattern-arg>* ")"

View File

@@ -20,7 +20,7 @@
(and (and
a a
(Ext1 x) (Ext1 x)
(Ext2 =x))) (Ext2 x)))
(C #t)) (C #t))
(type Opcode (enum A B C)) (type Opcode (enum A B C))

View File

@@ -411,23 +411,13 @@ impl<'a> Parser<'a> {
Ok(Pattern::Wildcard { pos }) Ok(Pattern::Wildcard { pos })
} else if self.is_sym() { } else if self.is_sym() {
let s = self.symbol()?; let s = self.symbol()?;
if s.starts_with("=") { let var = self.str_to_ident(pos, &s)?;
// Deprecated `=x` syntax. This will go away once we if self.is_at() {
// change all uses to just `x`, which we can do self.at()?;
// because we disambiguate whether a mention of `x` is let subpat = Box::new(self.parse_pattern()?);
// a binding or a matching of the already-bound value. Ok(Pattern::BindPattern { var, subpat, pos })
let s = &s[1..];
let var = self.str_to_ident(pos, s)?;
Ok(Pattern::Var { var, pos })
} else { } else {
let var = self.str_to_ident(pos, &s)?; Ok(Pattern::Var { var, pos })
if self.is_at() {
self.at()?;
let subpat = Box::new(self.parse_pattern()?);
Ok(Pattern::BindPattern { var, subpat, pos })
} else {
Ok(Pattern::Var { var, pos })
}
} }
} else if self.is_lparen() { } else if self.is_lparen() {
self.lparen()?; self.lparen()?;