The hkmc2/shared/src/test/mlscript-compile/apps/parsing/Lexer.mls file currently has this defintion:
fun scan(idx: Int, acc: Stack[TokenType]): Stack[TokenType] =
fun go(idx: Int, tok: TokenType) = if
options.noWhitespace and tok is
Token.Comment then scan(idx, acc)
Token.Space then scan(idx, acc)
else scan(idx, tok :: acc)
if char(idx) is
None then reverse of acc
Some(ch) and ch is...
Char.Whitespace and whitespace(idx) is idx' then
go(idx', Token.space(idx, idx'))
"\"" then go(...string(idx + 1))
Bracket as b then go(idx + 1, Token.symbol(b, idx))
"/" then go(...comment(idx + 1))
Operator as ch then go(...operator(idx + 1, ch))
Char.Digit as ch then go(...number(idx + 1, ch))
IdentifierStart as ch then go(...identifier(idx + 1, ch))
IdentifierQuote as quote
and char(idx + 1) is Some(IdentifierStart as ch)
and identifier(idx + 2, quote + ch) is [idx', token] and
token is Token.Identifier(name, _) then
go(idx', Token.identifier(name, idx))
else go(idx + 1, Token.error(idx, idx + 1))
else
print("Unrecognized character: '" ~ ch ~ "'")
go(idx + 1, Token.error(idx, idx + 1))
scan(0, Nil)
This should clearly be rewritten as a loop by tail-call optimization.
Currently, there are a couple of things preventing that:
- The functions are not lifted by default, and tail-call opt only deals with lifted functions.
Either we should generalize the tail-call optimizer, or we should enable lifting by default, or we should always selectively lift functions that need tail-call optimization.
- The UCS tries to share common branches by introducing labelled block which move some calls to non-tail positions, a known issue that really needs fixing.
It should be possible to share common branches while keeping tail-calls in tail position.
Compounded with that is the strange issue that annotating the scan and go functions above as @tailred does not report any error (defeating the point of the annotation). How come?
The result is that big-enough inputs break it, as can be seen by using slightly larger inputs in hkmc2/shared/src/test/mlscript/apps/parsing/CamlLightTest.mls.
From our discussion in the meeting, we want the tail-rec optimizer to:
The
hkmc2/shared/src/test/mlscript-compile/apps/parsing/Lexer.mlsfile currently has this defintion:This should clearly be rewritten as a loop by tail-call optimization.
Currently, there are a couple of things preventing that:
Either we should generalize the tail-call optimizer, or we should enable lifting by default, or we should always selectively lift functions that need tail-call optimization.
It should be possible to share common branches while keeping tail-calls in tail position.
Compounded with that is the strange issue that annotating the
scanandgofunctions above as@tailreddoes not report any error (defeating the point of the annotation). How come?The result is that big-enough inputs break it, as can be seen by using slightly larger inputs in
hkmc2/shared/src/test/mlscript/apps/parsing/CamlLightTest.mls.From our discussion in the meeting, we want the tail-rec optimizer to: