-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
internal: move MIR generation DSL to mirconstr
#793
internal: move MIR generation DSL to mirconstr
#793
Conversation
It's self-contained and doesn't depend on the rest of `mirgen`. The `notOp`, `modify`, `outOp`, and `tupleAccess` operators are not moved -- they're not atoms like the others. For convenience and to keep the set of changes smaller, `mirgen` uses wrapper templates around some of the DSL routines. Apart from some very small documentation fixes, the moved routines are not modified.
They're useful in non-`mirgen` contexts (e.g., `injectdestructors`, which is going to be changed to use `mirconstr`).
It's useful for conditionally excluding chain operands based on some run-time value. For example: ```nim var x = eval: a() if someBool: x = eval: x => b() chain: x => c() ``` can with `cond` be replaced with: ```nim chain: a() => predicate(someBool) => b() => c() ```
They were unused and also didn't fit with the overall design.
Remove the 'gen' prefixes from the chain DSL operands that have them. `genVoid` cannot be renamed to `void`, as that would make the operator not usable in the DSL -- it is instead renamed to `voidOut`.
This shrinks the code quite a bit, and also fixes the problems with nodes staying untyped.
Updated the PR description, under the details section, the second bullet point said that |
Yep, the bullet point was wrong, thank you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DSL definitely makes it more compact, while keeping the tree structure relatively straightforward to follow.
func name*(s: var MirNodeSeq, val: EValue) = | ||
s.add MirNode(kind: mnkName, typ: val.typ) | ||
|
||
func voidOut*(s: var MirNodeSeq, val: EValue) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
func voidOut*(s: var MirNodeSeq, val: EValue) = | |
func voidOut*(s: var MirNodeSeq, val: EValue) = | |
## end the mir input expression as a void-expression |
not sure I have that quite right, this is from what I could gather based on usage. initially I was seeing if I could come up with a better name, settled on a doc string might help. (soft suggestion)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, that sounds correct. I added it plus some additional elaboration.
In general, the 'void' operator/node acts as both a discard
and as a delimiter for expressions ('call' operators that yield nothing also need to be followed by 'void').
Apologies for the long time it took me to respond, I didn't manage to get any work done yesterday. |
no worries. this is a fun project and I don't have any expectations; some days it's not meant to be. |
hand slipped on the trackpad and I clicked the wrong button (close with comment). 🤦🏽 |
/merge |
Merge requested by: @saem Contents after the first section break of the PR description has been removed and preserved below:
|
Summary
Move the routines and types that make up the DSL to the
mirconstr
module and use the DSL in both the
injectdestructors
andmirbridge
module.
Apart from making the MIR code generation in both modules less complex,
manual, and error-prone, this is also significant progress towards the
MIR code coming out of the
injectdestructors
pass having proper typeinformation, which is a requirement for having MIR passes that run after
injectdestructors
.Details
EValue
andChainEnd
types tomirconstr
mirconstr
. ThenotOp
,modify
,outOp
, andtupleAccess
operands stay inmirgen
mirgen
still calls witha
TCtx
instance instead of aMirNodeSeq
As part of moving them, some operand routines that had a 'gen' prefix
are changed to not have it, making the routine names more consistent.
In addition, some cleanup in
mirconstr
is performed, and the DSLextended a bit:
|=>
,=>|
, andprevious
are removed. They were unused and didn'tfit in with the overall design
emit
,symbol
, andopParam
operands are added, all of whichare only useful outside of
mirgen
Another addition is the
predicate
meta operand, which makes itpossible to write chains where an operand is conditionally excluded:
Here,
b()
is only evaluated ifcond
evaluates to 'true'. Using twochains plus an in-between 'if' statement was previously necessary to
achieve the same.
Finally, documentation about the DSL is added, and the
injectdestructors
andmirbridge
modules are changed to use the DSLfor generating MIR code. The logic from the
genInjectedSink
procedurewas previously duplicated into
genSinkFromTemporary
, but this is nowfixed.