-
Notifications
You must be signed in to change notification settings - Fork 2
add the skully program
#70
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
Conversation
* procedure address types are now properly treated as pointers * all IL types are now cached, significantly reducing the amount of produced IL type
Actually generating / translating the body (by merging the fragments) is still missing -- a procedure with a body that does nothing beyond returning is used for now.
* implement various missing string magics * manually implement `mNewString` and `mNewStringOfCap`. Both are importc'ed procedures (of compilerprocs), which skully doesn't support
FFI procedures are not supported by the VM (at the moment). Some FFI procedures have a NimSkull implementation, which is enabled via the `noImported` backend option.
The "any" target is now used, which should prevent a good amount of problematic code (i.e., FFI procedures) to be included in the build.
Neither `patchFile` nor the underlying module overrides system still exist in the NimSkull compiler, and thus a third-party solution is needed. While not pretty, replacing the `TFileInfo` entry for a file works well enough.
Use a simple bump-pointer allocator for providing the OS chunks. Th maximum memory is configured during program start up (in theory; the actual implementation is still missing).
This removes the need to pass around the type and nodes separately.
A base field is now added to all records that have a base type, and `genField` emits the necessary field access chain.
They're layed out in the same way as they're by the NimSkull's `cgen`. `genField` takes care of adding the additional `Field` nodes necessary for navigating the field layout.
`result` was left uninitialized when the type had not been cached already.
The `TFrame` type is marked as imported, which results in it being translated to a `tkImported`, subsequently leading to `genField` failing. Since the type is complete, it can be patched into a non-imported type without issue.
This enables the pure-NimSkull floating point formatting implementation, removing the problematic use of `sprintf`.
The overrides are implemented in a module that's included in the compilation via an implicit import. Upon discovering an importc'ed procedure, the corresponding override is looked up, and on success, the AST of the original procedure is replaced with that of the override. Overrides only need to be provided for actually used (read, part of the live procedure graph) procedures.
This allows projects importing the `os` module to compile. An empty implementation of `getEnv` is provided, so that the `terminal` module compiles.
* numeric type descriptions are leaf nodes now * the memcopy `Copy` operation is named `Blit` now
Immutable parameters that use pass-by-reference aren't detectable as such via just the parameter type, nor do the arguments passed to them use `mnkName` -- the parameters' flags have to be inspected. Beyond improving the efficiency of the generated code, handling the `pfByRef` parameter flag also fixes the improper translation of `lent` parameters (i.e., lent parameters are now properly of pointer type in the IL).
Removing the importc flag is not enough, the type's size also has to be forcefully recomputed afterwards, as the IL currently requires all record types to have a known size.
`getSize` always ignores `openArray` types, setting its size to "unknown", which is a problem for the IL processing, which expects all records to have a valid size. Fortunately, the size of openArray types is trivial to compute.
Closure procedure types were missing the environment parameter (a pointer), resulting in lowering pass failures.
It's a simple API, meant to be wrapped by `os.paramStr` and `os.paramCount`.
The `paramCount`, `paramStr`, `commandLineParams`, and `getExecArgs` procedures are all available to skully-compiled programs now.
The `phy` arguments following a `--` are now passed on to the evaluated program through the host API.
There are some upstream fixes that skully needs.
|
Okay, This wraps up the main part of the work. Implementing some small leftovers and refactoring the code a bit should be all that there's left to do. |
The magic was the last remaining piece missing for ORC support.
Appending the fragments directly to the body of the partial procedure - like the upstream backends do - is quite tricky to do with skully. Therefore, each fragment is wrapped in its own procedure instead. While a lot simpler, it does invalidate the 1-to-1 mapping between MIR and IL procedure IDs, and thus a lookup table is required now.
Control-flow is only guaranteed to reach the statement following a `mnkEndStruct` when it closes an `mnkIf`, not when it closes an `mnkExcept`.
Since compiling skully does take quite a long time, it's not automatically built when doing `koch all`.
|
I've cleaned up the code a little, shuffling some code around and rewording some comments. There's probably a lot more that could be done, but given its standalone nature (i.e.,
|
The module is now named `syntax`.
|
Hm, it looks like some upstream changes uncovered some code generator bug. I suspect that the fix itself is going to be relatively simple and low in impact, so I'll mark the PR as ready-for-review already. @saem: For the review, I think it'll be easiest to review the final diff rather than going commit by commit, as there's was a lot of code churn. I'd recommend the following order of looking over the changes:
There are most likely some latent bugs in there, and if you come across something that looks off to you, please bring it to my attention. Nonetheless, I consider |
The indentation of the index operand translation was wrong, leading to the index operand being part of the `Addr` operation, not the `At`.
|
As expected, the fix was very simple. The moving-around of some code had messed up indentation, resulting in trees not adhering to the |
Summary
Skully (a portmanteau of "Skull" and "Phy") is a backend for NimSkull
that targets the
L25language. It's combined with the NimSkullfrontend into a standalone program that takes a project module as input
and writes the generated
L25code to a specified file.Most NimSkull core language features are supported. The idea with
skully is to get access to large amounts of
L25code resulting fromreal-world code, for the purpose of testing and measuring the lowering
passes and VM.
Details
The implementation is split into two parts:
backend) implementing the MIR toL25translation
skully) combining the NimSkull front- and mid-end withthe Skully code generator
The
L25IL is chosen as the target language because it's the languagemost similar to the MIR.
Except for C interop, the
L25is able to support the same languagefeatures as NimSkull's C backend, and therefore
semis configured asif it were run prior to the C backend. A non-trivial configuration is
used to make compilation possible:
any, disabling mostplatform-specific code
C-reliant code as possible
pure-NimSkull implementations or redirect them to dedicated VM host
procedures
(only
osat the moment, but the facility is generic and canredirect any module)
The VM host procedure specific to Skully are implemented into
phy, sothat the
phyprogram can runskully-produced code.Code Generator
The code generator performs a translation from MIR code to
L25code,attempting to replicate all lowerings NimSkull's C code generator
performs, meaning that the behaviour of the generated code should be
identical.
It's hooked into the compilation process like the native backends are:
via the
backends.processiterator.RTTIv1 generation is complicated and only needed for
deepCopyandthe
typeinfo, therefore it's not implemented by Skully; only theRTTIv2 is, as it's necessary for ORC and
ofsupport.Platform Support
Only the OS procedures necessary for compiling the
phyprogram areimplemented at the moment.
Tests
For making sure Skully works at least somewhat, a CI job is added that
compiles
phytoL25code and then executes saidL25code to buildand run an more complex test from the
exprtests.To-Do
getExecArgs--gc:orcskullywithkochskullycan compile a workingphyprogram