diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-06 01:53:05 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-06 02:01:28 -0500 |
| commit | 9726149c73919f68d00053bc226b4c0b1ef68a62 (patch) | |
| tree | e8a89da1b7ff811817504f97a0d1093e2cb9fde9 | |
| parent | [cup] Flesh out some more boilerplate based on C implementation (diff) | |
| download | cup-9726149c73919f68d00053bc226b4c0b1ef68a62.tar.xz cup-9726149c73919f68d00053bc226b4c0b1ef68a62.zip | |
Add some information to the README
| -rw-r--r-- | README.md | 121 |
1 files changed, 118 insertions, 3 deletions
@@ -1,6 +1,121 @@ # CUP: C(ompiler) U(nder) P(rogress) -A badly named, in-progress programming language just to learn how these things work. -Wait, doesn't everyone write a compiler when they're bored? +A badly named, in-progress programming language just to learn how these things work. Wait, doesn't everyone write a compiler when they're bored? -Why am I writing this in C? Good question. +Currently, the language is comparable to C, with some syntax changes inspired by Rust (that also make it a little easier to parse). The compiler outputs assembly code in `nasm` format, so you will need [nasm](https://www.nasm.us/) and a linker of your choise to compile it. The included Makefile and scripts use `ld`. + +Only linux and macOS (only on x86_64) are supported. + +## Building + +Build the compiler `build/cupcc` using: +```bash +make +``` +Compile a test program to nasm using: +```bash +build/cupcc /path/to/test.cup -o test.nasm +``` +Assemble and link the assembly to a binary: +```bash +make test.out # converts XXX.nasm to XXX.out +``` + +Or, you can do all the above in one go, and run the exeutable with the `run.sh` script, which by default creates the `build/output.out` executable: +```bash +./run.sh /path/to/test.cup +``` +--- + +## Code Samples + +### Hello World + +Some common functions you'll want are located in `std/common.cup` +```rust +import "std/common.cup"; + +fn main(arc: int, argv: char**): int { + putsln("Hello, world!"); + return 0; +} +``` + +### Variables + +Variables are strongly typed. You can either declare them with a type, or they can be inferred if there is an initial assignment. + +```rust +fn main() { + let x: int = 5; // Explicity define the type + let y = 6; // Infer the type + let z = x + y; // Add them, and infer the type +} +``` + +### Pointers and arrays +```rust +fn main() { + let x: int[10]; // An array of 10 ints (initializers not supported) + let y: int* = x; // Automatically decays to a pointer when passed or assigned + let z = y; // type(z) == int* also works + + let a = x[0]; // Access the first element (`a` is an int) + let b = *(x+1); // Access the second element (can use pointer arithmetic) +} +``` + +### File I/O + +For now, the file I/O API is essentially the same as in C. You'll find a buffered file in `std/file.cup`, but you can also just use the raw system calls to work with file descriptors. + +A simple implementation of `cat` is: +```rust +import "std/file.cup"; + +fn main(argc: int, argv: char**) { + for (let i = 1; i < argc; ++i) { + let f = fopen(argv[i], 'r'); + defer fclose(f); // Close the file at the end of the block (in each iteration) + + let buf: char[1024]; + let n = fread(f, buf, 1024); // use file-specific functions + while (n > 0) { + write(0, buf, n); // Use raw system calls + n = fread(f, buf, 1024); + } + // file closed here because of defer + } +} +``` + +### Structs / Unions / Enums + +```rust +// For now, enums just generate constant values with sequential numbers. +// They aren't a "type" on their own. +enum Type { + TypeInt, + TypeFloat, + TypeChar, +} + +struct Variable { + typ: int; // Can't use `Type` here, because it's not a type + value: union { // Anonymous nested structures are allowed. + as_int: int; + as_char: char; + as_ptr: Variable*; // Can recursively define types. + }; +}; + +fn main() { + let x: Variable; // No struct initializers yet + x.typ = TypeInt; + x.value.as_int = 5; +} +``` + +--- + +Want some more examples? Check out the [examples](examples/) directory, or the [compiler](compiler/) directory, which contains an in-progress rewrite of the compiler in CUP!
\ No newline at end of file |