27 comments

[ 3.7 ms ] story [ 75.3 ms ] thread
A prominent project where I have encountered this is GHC, the Haskell compiler. The route there goes: Haskell --> Core --> STG --> C--

(It then goes to one of: - Machine code generation - into C for feeding to gcc - into LLVM's intermediate representation. )

Would converting C-- to C/LLVM IR be redundant?
It's true that they are mostly on the same level but it's way easier to compile C-- to LLVM IR or C than to write three separate STG->(Imperative code) stages.
For those who are not Haskell experts, Core is a small lambda-calculus with case (pattern matching), let and coercions, see [1] for details. STG stands for Spineless-Tagless G-machine and is a refinement of the older G-machine. The G-machine (short for Graph-Reduction Machine) is for the lazy (call-by-need) evaluation of functional programs in supercombinator form [4]. Instead of interpreting supercombinators as rewrite rules, they were compiled into sequential code with special instructions for graph manipulation. See [2].

For a general overview of GHC's architecture, see [3].

[1] A. Tolmach, T. Chevalier and the GHC Team, An External Representation for the GHC Core Language (For GHC 6.10). https://downloads.haskell.org/~ghc/6.12.2/docs/core.pdf

[2] S. Peyton Jones, Implementing lazy functional languages on stock hardware: the Spineless Tagless G-machine. https://www.microsoft.com/en-us/research/wp-content/uploads/...

[3] S. Marlow, S. Peyton-Jones, The Glasgow Haskell Compiler. https://www.aosabook.org/en/ghc.html

[4] https://wiki.haskell.org/Super_combinator

The other project named C-- http://c--sphinx.narod.ru/indexe.htm
At least that one actually defines a decrement operator.
I used this in the mid- to late-90's on my 80386 (which was very much out of date at the time, but was all I had). I was very new to computing at the time, and the only other languages that I had under my belt were QuickBASIC and 80386 assembler, so I can't comment on if it were a "good" language or not. After less than a year, I ended up abandoning it, preferring to use QuickBASIC for high level, and machine language for low, not feeling like I needed the intermediate C--.
IIRC EiffelStudio compiled Eiffel to C-- as an intermediary stage, but I haven't used it since university and struggle to find information about that online.
Slightly off topic: did you do any projects using Eiffel, and if yes, what were the benefits / unique features?
There’s an alternative timeline where c— was better marketed / promulgated as a backend tool kit for optimizing compilers and everyone use c— instead.

That’s not to say llvm isn’t great, but some of the design choices it has make it a lot of work to do funky stuff ! And c— is a bit easier to write low level rts snippets in.

I do think the ghc c— flavor is super nice to write in these days.

Sometime in the 90's I downloaded a programming language called "C--" that was basically assembly with some loop control structures and functions. I'm assuming this completely unrelated.

Edit: ah, looks like dragonbonheur found and linked it already in this thread!

Does compiling to C-- have any benefits compared to compiling equivalent C code (maybe a subset of C)? My guess would be modern C compilers, powered by decades of R&D and programming, would be able to optimize just as well and possibly better.

EDIT: One advantage that comes to my mind is that compiling to C-- will give slightly more power to deal with stack. E.g. implementing exceptions, continuations etc would be simpler. This is possible in C using inline assembly.

>My guess would be modern C compilers, powered by decades of R&D and programming, would be able to optimize just as well and possibly better.

GHC often produces more efficient code than the LLVM backend.

Another thing it helps with is garbage collection. If you compile down to C it also requires stack trickery.
One benefit that is repeatedly mentioned in the papers is the ability to do tail-call optimization, which is more or less impossible with compile-to-c interpretations, and mandatory for functional languages.
Is GHC the only project that uses this?
Are there any projects other than GHC which still use C--? I had heard that it was unfortunately kind of dead these days.
This looks like a precursor of LLVM IR.
Interesting! I've been writing a lot of C/C++ for over a decade, but had never heard of C-- before.

So, I went to the website[1] linked in the PDF to learn more, but sadly it appears the domain has been taken over and now just displays a small collection of badly written articles about Windows.

[1] http://cminusminus.org

Generalizing Overloading for C++2000: Bjarne Stroustrup, AT&T Labs, Florham Park, NJ, USA.

Abstract: This paper outlines the proposal for generalizing the overloading rules for Standard C++ that is expected to become part of the next revision of the standard. The focus is on general ideas rather than technical details (which can be found in AT&T Labs Technical Report no. 42, April 1,1998).

http://www.stroustrup.com/whitespace98.pdf

I would love to use it for my compiler backend…if I could find any maintained standalone implementations of it.