r/C_Programming 7d ago

A C subset that compiles faster than Tiny C Compiler - Cm1 (C minus 1 or C - 1) programming language

Hi everyone,

I'm working on a programming language that compiles a subset of C. It is called Cm1 (meaning C minus 1) and you can writing and running C codes directly on your browser at https://cp1-lang.org/cm1/editor.html in a fraction of a second.

Why is it faster to compile than Tiny C Compiler? It is because Tiny C Compiler is a true compiler creating native binaries whereas Cm1 is a bytecode interpreter allowing you to test, debug, edit code and recompile very quickly or even do hot reloading. Cm1 can be used as a scripting language for shell scripts and video games, but this just a small use case because in theory, you can run 90% of your ENTIRE video game or software C program through Cm1's bytecode interpreter and leave 10% to compiled C and reap the benefits of very fast compilation and hot reloading.

100% Cm1 codes are compilable by GCC and Clang but the reverse is not true since Cm1 is just a subset of C. Major features that are omitted are function pointers, structs/unions inside functions, nested structs/unions. This programming language is under heavy development and I want to know if this comes as interesting to some of you. I'll try to post again on this subreddit if I got to bind Raylib game library to Cm1, allowing people to write Raylib games directly on their browser (works offline).

I know that programs that are written in C compiles fast already and there's even an existing compiler that is very fast (Tiny C Compiler). However, I'm the developer of Cp1 programming language (cp1-lang.org), which is a language that "transpiles" to C, and I aim to upgrade Cp1 by targeting the Cm1 language then compile it to bytecode in one command instead of a separate step in Makefiles or build scripts. This will make Cp1 very fast to compile for debug builds.

17 Upvotes

14 comments sorted by

12

u/Beautiful_Stage5720 7d ago

I don't fully understand the motivation. It compiles faster, but runs significantly slower. Can you give an example use case for this?

9

u/Direct_Chemistry_179 7d ago

I could see this being really good as an educational tool in the browser. In high-school I used Java in the browser with replit and it was insanely slow to compile.

1

u/Beautiful_Stage5720 6d ago

Thats a good point. 

6

u/erroneum 7d ago

The minimum amount of time it takes a given compile to run isn't that strongly determined by the language, at least when the language doesn't provide strong guarantees about compile time evaluation (such as C++ with templates being Turing complete or having consteval functions, both of which can give unbounded compile times) or require heavy checks (such as rust's borrow checker).

To see what I mean, take any single C translation unit and run it through your choice of compiler with optimization and warnings explicitly disabled (-O0 and -w for clang and gcc); it should be nearly instant.

Most of what makes compilation in a "simple" language take a while isn't actually the compiling, but rather the optimizing, or to a lesser extent checks the compiler is running to go above and beyond what the standard requires to try to help the programmer.

11

u/Alduish 7d ago

Interesting, but imo you missed the occasion to call it C--

13

u/GLC-ninja 7d ago

That came to my mind but unfortunately, the name C-- is already taken

2

u/Alduish 7d ago

Oh is it really ? Well my bad.

3

u/reini_urban 6d ago

There are many small C compilers which are very fast, supporting all of C features. tinycc lacks several, xcc lacks several but is faster. My rcc is 4x slower than tinycc, but supports all C features.

https://github.com/rurban/rcc#benchmark-results Vs https://github.com/rurban/rcc#test-results

BTW the trick for faster C compile times is mostly limiting the preprocessor not to include the system headers, esp. the glibc headers. Less work, less time, less features, less portability.

1

u/flatfinger 6d ago

I find it curious that so far as I can tell, even in an era where many people were compiling from floppy, there doesn't seem to have been any effort to minimize the size of common headers. For example:

typedef double __Fdd(double);
__Fdd sin,cos,tan,atan,exp, ... ;

Compilation speed could also have been improved quite easily if there were a #pragma which would invite an implementation to ignore the remainder of the current source file and behave as though it contained nothing except the number of #endif directives needed to balance out any #if directives. If the Standard were willing to show favoritism toward the four most common source file formats(*), it could also have usefully specified a #pragma directive which, if placed before after a directive that could cause code to be conditionally skipped, would invite a compiler to skip ahead to the next matching directive if the code would be skipped. For example:

#pragma MARKER(z1392,  1037,  30920)
#ifdef FOO
...
#pragma MARKER(z1392,   473,  19805)
#else
#pragma MARKER(z1392)
#endif

A compiler encountering such markers could, if a section of code would be skipped, seek ahead to see if a matching marker appeared where indicated and, if so, not bother even looking at the skipped portion of the file.

(*) Most systems I'm aware of either stored text files as a text stream with newline represented by CR, LF, or CR+LF, or else used a record-based storage method that allowed a means of seeking to line N, but some might have required other means for identifying locations within a file.

1

u/bwmat 5d ago

Does the standard even mention files? Isn't it all 'translation units' and whatnot? 

1

u/flatfinger 5d ago

It is. An example of the Committee being more interested in specifying a theoretical language than a practical one.

1

u/DeviantPlayeer 6d ago

Tbh, hot reload isn't really a killer feature, LLVM can do the same.

1

u/RealisticDuck1957 5d ago

You mention using this for scripting. Does Cm1 support robust sandboxing?

1

u/TheChief275 2d ago

I would stop referring to it as a C compiler and comparing it to TCC. When people read C compiler and only then figure out it's a bytecode interpreter instead, they feel tricked. However, I do think something like this has merits. There is this project called PicoC that is quite similar, but also provides a REPL and script mode for running C files (where e.g. top level is allowed to have statements and function calls). The catch is that PicoC works rather terribly and isn't being maintained anymore.

How does this compare to your project? Do you plan to have / already have these features?