pattern.js 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. let FinalPattern = format({
  2. is_final: one_of(true),
  3. ignore: Types.Bool,
  4. extract: Types.Any,
  5. target: Types.String,
  6. allow_nil: Types.Bool
  7. })
  8. let Pattern = Uni(FinalPattern, format({
  9. is_final: one_of(false),
  10. extract: Types.Any,
  11. allow_nil: Types.Bool,
  12. items: TypedList.of($(x => is(x, Pattern)))
  13. }))
  14. function match_pattern (scope, is_fixed, pattern, value) {
  15. assert(scope instanceof Scope)
  16. assert(is(is_fixed, Types.Bool))
  17. assert(is(pattern, Pattern))
  18. ensure(is(value, Uni(Nil, Types.GeneralGetter)), 'match_non_getter')
  19. let all_nil = false
  20. if (is(value, Types.Nil)) {
  21. if (pattern.allow_nil) {
  22. all_nil = true
  23. } else {
  24. ensure(false, 'match_nil')
  25. }
  26. }
  27. for (let item of pattern.items) {
  28. if (item.is_final && item.ignore) { continue }
  29. let v = all_nil? Nil: (
  30. call(get_data, [value, item.extract, item.allow_nil])
  31. )
  32. if (item.is_final) {
  33. scope.declare(item.target, v, is_fixed)
  34. } else {
  35. match_pattern(scope, is_fixed, item, v)
  36. }
  37. }
  38. return Void
  39. }