Files
compiler-explorer/examples/co2/co2_features.co2
hkalbasi 9b47e07d14 Add co2 language (#8842)
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>
2026-07-02 18:26:35 +01:00

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");
}