mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2026-07-22 02:56:57 -04:00
This PR adds [CO2](https://github.com/hkalbasi/co2) which is a language backward compatible with C, with some Rust interop features that compiles to Rust's MIR. I added two compiler `co2rustc` and `co2cc`, and a tool `co2miri` which is Miri for CO2. I added `co2cc` under C compilers, to make it possible to view diff of assembly for a C code compiled with CO2 and clang or gcc. `co2cc` is a CO2 frontend which accepts gcc-like flags, and can (or at least should) compile almost every ISO compatible C23 code. `co2rustc` accepts Rust like flags, and added under a new `CO2` language. Tested locally and it seems to work. I need some help in setting up artifacts (which, if I understand correctly, needs to happen in `infra` or `compiler-workflows`). I make an artifact `co2-multicall` in my CI, which needs to get symlinked in `co2cc`, `co2rustc` and `co2miri`, and it needs to run a simple project with miri to create the miri sysroot. If you show me a similar project, I will do the job. Disclaimer: Written partially by LLM. --------- Co-authored-by: Matt Godbolt <matt@godbolt.org>
65 lines
1.6 KiB
Plaintext
65 lines
1.6 KiB
Plaintext
use std::vec::Vec;
|
|
use std::f64::consts::PI;
|
|
|
|
// You can include any system installed header.
|
|
// You can manage include directories using build.rs.
|
|
#include <stdio.h>
|
|
|
|
// C-style function with C ABI
|
|
int add(int a, int b) {
|
|
return a + b;
|
|
}
|
|
|
|
// Rust-style function with Rust ABI
|
|
fn rust_multiply(a: i32, b: i32) -> i32 {
|
|
// The body still uses the C like syntax. E.g. using `a * b` without return is invalid.
|
|
return a * b;
|
|
}
|
|
|
|
fn main() {
|
|
// C-style function call
|
|
int sum = add(3, 4);
|
|
|
|
// Calling C external functions does not need `unsafe` block.
|
|
// In fact, there is no unsafe block at all.
|
|
printf("Sum is %d\n", sum);
|
|
|
|
// Rust-style function call (Rust ABI)
|
|
i32 product = rust_multiply(5, 6);
|
|
printf("Product is %d\n", product);
|
|
|
|
// Using generic Rust types
|
|
Vec::<i32> v = Vec::<i32>::new();
|
|
v.push(10);
|
|
v.push(20);
|
|
|
|
// Access Rust method results
|
|
i32 last = v.pop().unwrap();
|
|
printf("Last is %d\n", last);
|
|
|
|
// Use Rust constants
|
|
double pi = PI;
|
|
printf("PI is %.8f\n", pi);
|
|
|
|
v.push(20);
|
|
v.push(3);
|
|
v.push(15);
|
|
|
|
// Raw pointers get automatically casted to references.
|
|
// There is a borrow checker which can see through the raw pointers
|
|
// and warn you when things are obviously wrong, but the programmer
|
|
// is solely responsible for avoiding UB.
|
|
Vec::<i32> *v_ptr = &v;
|
|
|
|
v_ptr.push(1000); // A customized auto dereference mechanism is available.
|
|
Vec::<i32>::push(&v, 60);
|
|
v.push(16);
|
|
|
|
// C style for loop
|
|
i32 *v_data_ptr = v.as_ptr();
|
|
for (int i = 0; i < v.len(); i += 1) {
|
|
printf("%d ", v_data_ptr[i]);
|
|
}
|
|
printf("\n");
|
|
}
|