morganstanley / hobbes

A language and an embedded JIT compiler
http://hobbes.readthedocs.io/
Apache License 2.0
1.16k stars 105 forks source link

add language option "IgnoreUnreachableMatches" #408

Closed mo-xiaoming closed 3 years ago

mo-xiaoming commented 3 years ago

User might need to add ad-hoc change to disable some matching rows, the original behavior of hobbes considers unreachable rows as an error, for example, if we have a tt.hob

foo x y = match x y with
  | 0 0 -> "zero/zero"
  | _ _ -> "wildcard"
  | 1 _ -> "unreachable"
  | _ 1 -> "unreachable"

add2 x = x + 2

bar x y = match x y with
  | 1 1 -> "one/one"
  | _ _ -> "wildcard"
  | _ 7 -> "unreachable"
  | 7 _ -> "unreachable"

Both foo and bar have 3 rows of unreachable patterns, the current behavior is

$ ./hi -s tt.hob
tt.hob:1,11-5,23: Unreachable rows in match expression:
  1 .t19610 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]
  .t19611 1 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]

1 foo x y = match x y with
2   | 0 0 -> "zero/zero"
3   | _ _ -> "wildcard"
4   | 1 _ -> "unreachable"
5   | _ 1 -> "unreachable"
6
7 add2 x = x + 2
8
9 bar x y = match x y with
> :l tt.hob
tt.hob:1,11-5,23: Unreachable rows in match expression:
  1 .t19610 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]
  .t19611 1 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]

1 foo x y = match x y with
2   | 0 0 -> "zero/zero"
3   | _ _ -> "wildcard"
4   | 1 _ -> "unreachable"
5   | _ 1 -> "unreachable"
6
7 add2 x = x + 2
8
9 bar x y = match x y with

They both stops execution and exit with error code

With newly added IgnoreUnreachableMatches language option, we can achieve something like

$ ./hi -s -o IgnoreUnreachableMatches tt.hob
warning: tt.hob:tt.hob:1,11-5,23    Unreachable rows in match expression:
  1 .t19610 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]
  .t19611 1 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]

warning: tt.hob:tt.hob:9,11-13,23    Unreachable rows in match expression:
  .t19620 7 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]
  7 .t19621 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]

> add2(3)
5
> foo(0, 0)
"zero/zero"
> bar(9, 10)
"wildcard"
> bar(7, 10)
"wildcard"
> :o IgnoreUnreachableMatches
> :l tt.hob
warning: tt.hob:tt.hob:1,11-5,23    Unreachable rows in match expression:
  1 .t19620 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]
  .t19621 1 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]

warning: tt.hob:tt.hob:9,11-13,23    Unreachable rows in match expression:
  .t19630 7 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]
  7 .t19631 -> ['u', 'n', 'r', 'e', 'a', 'c', 'h', 'a', 'b', 'l', 'e']::[char]

loaded module 'tt.hob'
> add2(3)
5

The default behavior of this option is a noop. In hi, we can easily define a custom function and make it print related info as warnings

void defPrintUnreachableMatches(const hobbes::cc::UnreachableMatches& m) {
  std::cout << "warning: " << m.la.filename() << ':' << m.la.lineDesc() << "    " << m.lines << std::endl;
}

void some_func() {
  this->ctx.ignoreUnreachableMatches(true);
  this->ctx.setGatherUnreachableMatchesFn(defPrintUnreachableMatches);
}

this->ctx in this code is a pointer to hobbes::cc

smunix commented 3 years ago

@mo-xiaoming - take a look at this link to sign your commits