@@ -191,6 +191,83 @@ pub fn ClosureInterpreter::match_case(
191191 value : RuntimeValue ,
192192 pattern : @syntax.Pattern ,
193193) -> Bool {
194+ fn match_array_pattern_list(
195+ patterns : @list.List [@syntax.ArrayPattern ],
196+ values : Array [RuntimeValue ],
197+ start : Int ,
198+ ) -> Bool {
199+ let mut index = start
200+ for state = patterns {
201+ match state {
202+ @list.More (array_pat, tail=pat_tail) => {
203+ if index >= values.length() {
204+ return false
205+ }
206+ match array_pat {
207+ @syntax.ArrayPattern ::Pattern (pat) =>
208+ if !self.match_case(values[index], pat) {
209+ return false
210+ }
211+ _ => return false
212+ }
213+ index += 1
214+ continue pat_tail
215+ }
216+ @list.Empty => break
217+ }
218+ }
219+ true
220+ }
221+
222+ fn map_pattern_key(key : @syntax.Constant ) -> RuntimeValue? {
223+ match key {
224+ String (str) => Some (String (str))
225+ Int (str) =>
226+ Some (Int (@string.parse_int(str), raw=None )) catch {
227+ _ => None
228+ }
229+ _ => None
230+ }
231+ }
232+
233+ fn json_pattern_key(key : @syntax.Constant ) -> String? {
234+ match key {
235+ String (str) => Some (str)
236+ _ => None
237+ }
238+ }
239+
240+ fn match_json_constructor(
241+ json : Json ,
242+ constr_name : String ,
243+ pattern_args : @list.List [@syntax.ConstrPatArg ]?,
244+ ) -> Bool {
245+ fn match_unary(value : RuntimeValue ) -> Bool {
246+ match pattern_args {
247+ Some (@list.More (arg, tail=@list.Empty )) =>
248+ self.match_case(value, arg.pat)
249+ _ => false
250+ }
251+ }
252+ match (json, constr_name, pattern_args) {
253+ (Null , "Null ", None ) => true
254+ (True , "True ", None ) => true
255+ (False , "False ", None ) => true
256+ (String (str), "String ", _) => match_unary(String (str))
257+ (Number (num, ..), "Number ", _) => match_unary(Double (num))
258+ (Array (arr), "Array ", _) =>
259+ match_unary(Array (arr.map(item => Json (item))))
260+ (Object (obj), "Object ", _) => {
261+ let map : Map [RuntimeValue , RuntimeValue ] = {}
262+ for key, item in obj {
263+ map.set(String (key), Json (item))
264+ }
265+ match_unary(Map (map))
266+ }
267+ _ => false
268+ }
269+ }
270+
194271 match pattern {
195272 // 变量模式匹配(总是匹配,并绑定变量)
196273 Var ({ name, .. }) => {
@@ -275,26 +352,38 @@ pub fn ClosureInterpreter::match_case(
275352 if values.length() != patterns.length() {
276353 return false
277354 }
278- let mut index = 0
279- for state = patterns {
280- match state {
281- @list.More (array_pat, tail=pat_tail) => {
282- match array_pat {
283- @syntax.ArrayPattern ::Pattern (pat) =>
284- if !self.match_case(values[index], pat) {
285- return false
286- }
287- _ => return false // 其他数组模式暂不支持
288- }
289- index = index + 1
290- continue pat_tail
291- }
292- @list.Empty => break
293- }
355+ match_array_pattern_list(patterns, values, 0)
356+ }
357+ @syntax.ArrayPatterns ::Open (left, right, binder) => {
358+ let left_len = left.length()
359+ let right_len = right.length()
360+ if values.length() < left_len + right_len {
361+ return false
362+ }
363+ if !match_array_pattern_list(left, values, 0) {
364+ return false
365+ }
366+ if !match_array_pattern_list(
367+ right,
368+ values,
369+ values.length() - right_len,
370+ ) {
371+ return false
372+ }
373+ let rest_view = values[left_len:values.length() - right_len]
374+ let rest = Array ::new(capacity=rest_view.length())
375+ for item in rest_view {
376+ rest.push(item)
377+ }
378+ match binder {
379+ @syntax.DotDotBinder ::Binder (binder) =>
380+ self.current_pkg.env.set(binder.name, Array (rest))
381+ @syntax.DotDotBinder ::BinderAs (binder) =>
382+ self.current_pkg.env.set(binder.name, Array (rest))
383+ _ => ()
294384 }
295385 true
296386 }
297- _ => false // 其他数组模式暂不支持
298387 }
299388 _ => false
300389 }
@@ -320,6 +409,42 @@ pub fn ClosureInterpreter::match_case(
320409 }
321410 _ => false
322411 }
412+ Map (elems~, ..) =>
413+ match value {
414+ Map (values) => {
415+ for elem in elems {
416+ match map_pattern_key(elem.key) {
417+ Some (key) =>
418+ match values.get(key) {
419+ Some (item) =>
420+ if !self.match_case(item, elem.pat) {
421+ return false
422+ }
423+ None => return false
424+ }
425+ None => return false
426+ }
427+ }
428+ true
429+ }
430+ Json (Object (values)) => {
431+ for elem in elems {
432+ match json_pattern_key(elem.key) {
433+ Some (key) =>
434+ match values.get(key) {
435+ Some (item) =>
436+ if !self.match_case(Json (item), elem.pat) {
437+ return false
438+ }
439+ None => return false
440+ }
441+ None => return false
442+ }
443+ }
444+ true
445+ }
446+ _ => false
447+ }
323448
324449 // Range模式匹配
325450 Range (lhs~, rhs~, kind~, ..) =>
@@ -328,6 +453,8 @@ pub fn ClosureInterpreter::match_case(
328453 // Constructor模式匹配
329454 Constr (constr~, args=pattern_args, ..) =>
330455 match value {
456+ Json (json) =>
457+ match_json_constructor(json, constr.name.name, pattern_args)
331458 Constructor ({ val: { name, fields }, ty }) =>
332459 if name == constr.name.name &&
333460 self.constructor_pattern_matches_type(ty, constr) {
0 commit comments