Closed j-hui closed 2 years ago
wtf why did it fail earlier
i swear i tested this locally
also why was the build cache invalidated
i have questions.
Still no clue why the build is taking so damn long but at least tests are passing now.
I wrote one test, closures.ssl, that is essentially the same as the example I wrote in ssm-runtime. I'll probably write a couple more tests, i.e., I want to get map working. I'm also going to attempt some lambdas and see if @hmontero1205 's closure conversion works as advertised (!!).
Thanks for the review @EmilySillars !
does SSLANG support pattern matching on closures/is pattern matching for closures supported in this PR?
no, that's not possible (in general, one cannot pattern-match on any function type).
I think the way closure tag fields are constructed and the way pattern matching works currently will cause problems for representing fully applied ADTs as closures down the line. This is an issue for the future though.
In your example, the closure will be evaluated (i.e., reduced) to a value of value of type Shape
before being scrutinized. So that should be ok.
This PR adds support for the new closure bindings supported by our runtime library.
A few expected changes:
Standardize the C function call interface (analogous to ABI), such that all step functions have the type:
Regression test harness is adjusted to accommodate this change.
__enter_
and__step_
), toward more standardized mangling behavior.ssm_closure_apply
at every application, and check for yield after each application. Further optimization here to be explored in the future. (Application for data constructors remain the same.)And two changes perhaps warrant some discussion:
(!!) Generate static closure for each global function, so that we don't have to allocate a dynamic closure for each such reference.
I chose to do this because the alternatives are more complicated; dynamically allocating closures for top-level functions requires us to start tracking their lifetimes, which we don't yet have the capability for, while directly inlining call to the enter function begins to encroach upon optimization, which I don't want to tackle yet (and shouldn't do in codegen anyway).
(!!) In the codegen phase, side-effectful expressions (other than function calls) are now forbidden as par operands.
I realized while working on this PR that our old compilation scheme was wrong. Say
e1
,e2
, ande3
are all side-effectful functions; givenpar { e1 () | e2 (e3 ()) }
, one would expect the effects ofe1
to take place beforee2
ande3
. However, the old compilation scheme would first evaluatee3 ()
to produce the argument fore2
, before yielding toe1
ande2
, meaning we would observee3
's effects first.Such parallel effects should be abstracted out in an earlier compiler phase, so that the order of effects obey what we would expect of
par
expressions. So in codegen, I require that all operand expressions of a par expression be pure and "simple".I'm open to suggestions for how to better address two of these issues, especially 1, though my current plan is to just push on ahead and refactor later if we find that either of these choices lead to issues.