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
Add Crystal support #2732
Add Crystal support #2732
Conversation
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.
Thanks so much for doing this! Looks good
Some issues that need to be resolved before this:
When running 1.0.0 I get less errors, but errors nonetheless:
It seems to me crystal requires a C compiler in the path, that should be possible with the default Ubuntu 20.04 gcc compiler (though not sure if that's what we want always) - but the main problem lies in the non-standard prerequisite libraries (through the OS package system). So my questions would be:
|
It seems there's this list It also seems to require an LLVM to be installed? And the latest documentation seems to refer to some environment variables for the build command: But I don't know if these are also used in the earlier versions. |
Note that the biggest issue here would probably requiring library installs on the OS level, as we would need to produce new images for our instances. We can probably solve the CC and LLD requirements some other way. cc @mattgodbolt |
LLVM shouldn't be needed just for running Crystal. It definitely needs to be there when building Crystal from Crystal itself (something to consider for nightlies). |
Crystal just requires a linker. It picks up what's configured as
So https://github.com/crystal-lang/crystal/wiki/All-required-libraries is a list of all libraries required for the entire standard library and compiler. If you include the XML module, you need libxml2 for example.
LLVM is linked statically into the compiler binary from the tarball. Unless building the compiler itself, there is no need to have LLVM installed.
They should be available in earlier versions, but probably not all back in 0.29. I'm not sure if there's much point in going so far back, anyways. IMO it would be fine to focus on 1.0, at least for a first iteration. |
The one I mentioned, Perhaps we could build the libraries locally with https://github.com/compiler-explorer/infra/blob/main/update_compilers/install_libraries.sh and symlink to them from Also added an assembly parser that handles Crystal's quoted labels. Filtering everything reduces the number of lines to roughly 13k (the Crystal prelude's own included files are counted as library code). |
Will this work? |
], | ||
|
||
surroundingPairs: [ | ||
{ open: '{', close: '}' }, |
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.
{ open: '{', close: '}' }, | |
{ open: '{', close: '}' }, | |
{ open: '{%', close: '%}' }, |
Not sure I'm reading this correctly, but I think macro block identifiers are missing.
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.
Thank you so much for this!
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.
Forgot to actually send the review
Superweird asm emission, but c'est la vie. The 1 thing I'm worried about is that the square function example is unused and is not emitted until you call the function. |
Any thoughts about the last one? This is different behaviour compared to all the other languages and compilers. Perhaps an option would be to get an input parameter from the command line and give that to the function, so that it's always used? |
Export function would be fun square(num : Int32) : Int32
num * num
end But I don't think that would be very helpful for general use cases. The general approach to include a Crystal method in codegen is adding a call to it. |
Any idea on how to do that without specifying a specific number? I saw you can override the main() function, but doubt that's a recommended thing to do |
Sorry, I actually have no idea how compiler explorer works and what we're aiming for here. If the method is to be called without a baked-in value, the value needs to come from somewhere like a CLI arg, env or There shouldn't be a reason to override |
I didn't mean how to get the value from CE, that's already supported for cmdline args and stdin. My question was about how to write such an example in Crystal that uses it. |
@HertzDevil can you create such an example? (something that uses cmdline input and calls square with it) |
Catching up here, agree with everything @partouf has said. The intention of the default example is to show a little simple assembly, conventionally the "square a number" routine. It's not meant to be a language primer; is there a reason the |
The problem is that the square fun without a call isn't emitting Any assembly, so there would be nothing but overhead showing. So I think this is the way to go. I have tested the rest, so this is good to merge and go live. |
In that case, maybe it would be an option to run the example without stdlib. That would keep the generated assembly to a minimum and more strictly represent the language itself instead of the stdlib. @HertzDevil WDYT? |
I think all Is it possible to pre-populate the compiler args when the default snippet is loaded? |
Ah, I think I missed the point of changing
Not afaik. We've talked about it in various circumstances, but it's just not worth the trouble imo. |
Yes, |
An absolute minimal example for that would be: # compile with --prelude=empty
fun square(num : Int32) : Int32
num &* num
end In this case the ASM output would just be: square:
imull %edi, %edi
movl %edi, %eax
retq
".L'dd40a2442'":
.long 1
.long 9
.long 9
.asciz "dd40a2442"
.zero 2
; ... Does this look fine? |
absolutely, that's fine |
* Add Crystal support * Fix copyright * Add ASM parser for Crystal * Add supportsLibraryCodeFilter * Update crystal-mode.js * use baseName * Force `square` call * Update default snippet Co-authored-by: Patrick Quist <partouf@gmail.com>
Resolves #673. Includes compiler versions from 1.0 down to 0.29.
The Monaco language is written from scratch and supports only basic highlighting; Crystal's syntax is borrowed from Ruby, but there are too many dissimilarities between the two and I'd prefer lack of e.g. indenting rules over incorrect ones. It is subject to future improvements.
Even an empty file produces 190k lines of assembly code, unless
--prelude=empty
is provided (which more or less excludes the entire runtime and all libraries). If this is unacceptable then arrangements would have to be made on the language side.Related: compiler-explorer/infra#533