alan icon indicating copy to clipboard operation
alan copied to clipboard

Conditionals

Open cdmistman opened this issue 3 years ago • 0 comments

This one will be the most fun :) /s

Work on implementing the 2-opcode conditional design originally implemented in #430. The biggest difference between the 2 should be the name of the condfn opcode, since that opcode name is already taken by the current front-end compiler's conditionals implementation, and we need to maintain backwards compatibility at least until the lnn compiler replaces the current front-end compiler.

Status

  • This is currently blocked on #535

Design

Ideally, the desugaring would happen while constructing the AST. This requires closures for each of the branches that can be executed, as well as a way of signalling from class Expr to class Stmt (and from there to class Fn) that it needs the rest of the statements in the syntactic function.

#430 has most of the design for the new way conditionals will work. Effectively, it would desugar Alan code that looks like this:

let x = 4;
if somethingIsTrue() {
  x = 5;
} else if somethingElseIsTrue() {
  x = 6;
} else {
  x = 7;
}
return x;

into Alan code that looks like this:

let x = 4;
let condTable = condtable(); // note: condtable is an opcode that returns the opaque type CondTable<T>
// note: condfn is an opcode with the signature `fn(CondTable<T>, boolean, fn(): Maybe<T>): void`
condfn(condTable, somethingIsTrue(), fn() {
  x = 5;
  return none();
});
condfn(condTable, somethingElseIsTrue(), fn() {
  x = 6;
  return none();
});
condfn(condTable, true, fn() {
  x = 7;
  return none();
});
// note: evalcond is an opcode with the signature `fn(CondTable<T>, fn(): Maybe<T>): Maybe<T>`
return evalcond(condTable, fn() = some(x)).getOrExit();

The desugaring will have to take care when inlining nested conditionals though, to ensure that only one getOrExit call is inserted.

cdmistman avatar May 20 '21 15:05 cdmistman