cx is a small programming language written in C (my first time!). It contains a scanner, parser, printer and Windows x64 code generator. It only supports Windows x64 and small programs as it uses fixed-size arrays of 100 items for almost everything, for simplicity reasons.
I created this project to learn about compiler theory and low level programming languages.
graph LR
A["Source File"] -- "Reader" --> B["Buffer"]
B -- "Scanner" --> C["Tokens"]
C -- "Parser" --> D["AST"]
D -- "Compiler" --> E["Assembly File"]
E -- NASM --> F["Object File"]
F -- MSVC Link --> H["Portable Executable"]
Before using cx, you will need to:
- Head to the latest release.
- Download the ZIP file corresponding to your operating system. Note that only Windows x64 is supported.
- Unzip the downloaded file.
To use cx, you will need to:
- Compile the program into assembly by running
cx <cx_input_file> <asm_output_file>.
Afterwards, you can optionally assemble the assembly files into portable executable format using NASM and MSVC link, like so:
- Assemble the program by running
nasm -f win64 <asm_output_file> -o <obj_output_file>. - Link necessary libraries by running
link <obj_output_file> /entry:main /subsystem:console /out:<exe_output_file> kernel32.lib msvcrt.lib ucrt.lib legacy_stdio_definitions.lib.
You can use the sample files in the samples/ directory for testing if you wish. fizzbuzz.cx is the most comprehensive sample, utilizing most language features. To write your own samples, refer to the Knowledge Base.
To contribute, you can fork the repository and open a pull request.
program = { declaration }, EOF;
declaration = decl_var | statement;
decl_var = "var", IDENTIFIER, [ "=", expression ], ";";
statement = stmt_expr | stmt_cond | stmt_loop | stmt_print | block;
block = "{", { declaration }, "}";
stmt_expr = expression, ";";
stmt_print = "print", expression, ";";
stmt_cond = "if", "(", expression, ")", statement, [ "else", statement ];
stmt_loop = "while", "(", expression, ")", statement;
expression = equality;
equality = comparison, { ("!=" | "=="), comparison };
comparison = term, { (">" | ">=" | "<" | "<="), term };
term = factor, { ("-" | "+"), factor };
factor = unary, { ("*" | "/" | "%"), unary };
unary = ("!" | "-"), unary | primary;
primary = NUMBER | STRING | "true" | "false" | "nil" | IDENTIFIER | "(", expression, ")";Comments are marked with two slashes (//).
print 1; // Hello!print is the only implementation of IO in cx. It can be used to display the results of operations.
print "Hello World!";Unary operators manipulate a single operand.
| Symbol | Operation |
|---|---|
| ! | Logical negation |
| - | Arithmetic negation |
print !true;
print -1;Arithmetic operators can be used to manipulate values.
| Symbol | Operation |
|---|---|
| + | Addition |
| - | Subtraction |
| * | Multiplication |
| / | Division |
| % | Modulo |
print 1 + 2 - 3 * 4 / 5 % 6;Comparison operators can be used to compare two values and evaluate to booleans.
| Symbol | Operation |
|---|---|
| == | Equal to |
| != | Not equal to |
| > | Greater than |
| >= | Greater than or equal to |
| < | Lesser than |
| <= | Lesser than or equal to |
var x = 1;
var y = 1;
if (x == y) print true;
if (x != y) print true;
if (x > y) print true;
if (x < y) print true;
if (x >= y) print true;
if (x < y) print true;
if (x <= y) print true;Variables can be used for storing the results of operations, allowing for more complex programs. The contents of variables can be changed after initialization via assignment. Variable names can be composed of alphanumeric characters, except for the first letter, which must always be a letter.
var x = 1;
print x;var x = 1;
x = 2;
print x;Blocks can be used to enter a new scope, allowing for variables to be redefined. They are commonly used in conjunction with conditional statements and loop statements as they allow for multiple statements.
var x = 1;
while (x < 10) {
x = x + 1;
print x;
}Conditional statements can be used to execute different blocks of code depending on a condition.
var x = 1;
if (x > 1) x = 2;
print x;var x = 1;
var y = 2;
if (x > y) {
x = 2;
y = 3;
}
print x + y;var x = 1;
if (x > 2) {
x = x - 1;
} else {
print x;
}Loop statements can be used to repeat a given operation until a condition is no longer met.
var x = 1;
while (x < 10) x = x + 1;var x = 1;
while (x < 10) {
x = x + 1;
print x;
}