A contemporary high-level front-end for NASM (Windows x64 focused) that accepts a C-like/assembly hybrid language and generates NASM assembly code. Write high-level constructs like loops, and conditionals while maintaining the power of assembly.
- High-level constructs:
if/elif/else,for,while,print - Built-in standard library: I/O, strings, math, arrays, memory operations
- Seamless inline assembly passthrough
- Windows x64 NASM output (adaptable to other platforms)
- Automatic register allocation for parameters and temporaries
- Python 3.8+
- NASM - for assembling produced
.asmfiles into object files - Linker toolchain (optional, for producing executables):
- Windows: MSVC, MinGW-w64, or similar
- macOS/Linux:
clangorgcc - macOS cross-compile to Windows:
mingw-w64(via Homebrew)
# Compile to assembly only
python3 main.py examples/hello.asm -o out_compiled.asm
# Compile, build, and run
python3 main.py examples/hello.asm --build --runYou can install CASM system-wide using the provided installer script inshall.sh (optional). The installer will place a small wrapper/entrypoint in a system PATH directory (for example /usr/local/bin) so you can run the compiler from anywhere using the casm command.
Basic usage:
# make the installer executable
chmod +x inshall.sh
# run the installer (may require sudo to write to /usr/local/bin)
sudo ./inshall.sh
# afterwards you can run casm globally
casm examples/hello.asm --build --runWhat the installer does (typical behavior):
- Copies an executable wrapper or entrypoint script to
/usr/local/bin/casm(or another destination you pass to the script). - Makes the wrapper executable and ensures the
build/directory exists under the project when run from a repository clone. - Optionally updates permissions and prints instructions for uninstallation.
If you prefer a manual install instead of using the script, you can create a symlink yourself:
# from the project root
sudo ln -s "$(pwd)/main.py" /usr/local/bin/casm
sudo chmod +x /usr/local/bin/casmNotes:
- The installer is optional and provided as a convenience. Review the
inshall.shscript before running it and adjust the destination if you do not want to write to/usr/local/bin. - On systems where
/usr/local/binis not in the PATH for non-login shells, you may need to add it or choose a different location.
Files are plain text assembly-like source files. The compiler recognizes:
- High-level statements - Recognized keywords that generate assembly
- NASM passthrough - Lines not starting with high-level keywords are emitted as raw NASM
Standard NASM sections are forwarded to the generated output:
section .data ; Initialized data (labels, strings)
section .bss ; Uninitialized storage (resb/resq/etc.)
section .text ; Assembly code and high-level constructs; Print without newline
call print "Hello"
; Print with newline
call println "Hello, World!"
; Print register value
call println rax
; Print blank newline
call printlnif rax == 0
call println "zero"
elif rax == 1
call println "one"
else
call println "other"
endifSupported operators: ==, !=, <, >, <=, >=
Inclusive range loops:
for rcx = 1, 5
call println rcx
endforThe loop variable is assigned a register internally to survive function calls.
while rbx > 0
; loop body
dec rbx
endwhilebreak ; Exit the loop immediately
continue ; Skip to next iteration- The language expects you to use registers for storage (
rax,rbx,rcx, etc.) - High-level constructs automatically manage value movement between registers and temporaries
- No explicit variable declaration needed - registers are your variables
Any line not recognized as a high-level keyword is passed through verbatim:
section .text
mov rax, 5 ; Raw NASM instruction
add rax, rbx ; Another raw instruction
; Mix with high-level constructs
call println raxThe compiler automatically injects only the standard library routines you actually use. No bloat.
| Function | Description |
|---|---|
print |
Print string/value without newline |
println |
Print string/value with newline |
scan |
Read string input |
scanint |
Read integer input |
| Function | Description |
|---|---|
strlen |
Get string length |
strcpy |
Copy string |
strcmp |
Compare strings |
strcat |
Concatenate strings |
| Function | Description |
|---|---|
abs |
Absolute value |
min |
Minimum of two values |
max |
Maximum of two values |
pow |
Power/exponentiation |
| Function | Description |
|---|---|
arraysum |
Sum array elements |
arrayfill |
Fill array with value |
arraycopy |
Copy array |
| Function | Description |
|---|---|
memset |
Set memory region |
memcpy |
Copy memory region |
| Function | Description |
|---|---|
rand |
Generate random number |
sleep |
Sleep/delay execution |
func greet(name)
call print "Hello, "
call println name
return
endfunc
call greet("world")for rcx = 1, 3
call println rcx
endforOutput:
1
2
3
section .text
mov rax, 5 ; Raw NASM instruction
add rax, 10 ; Another raw instruction
call println rax ; High-level constructmov rax, 42
if rax > 40
call println "Greater than 40"
elif rax > 20
call println "Greater than 20"
else
call println "20 or less"
endif- Platform focus: Primarily designed for Windows x64 NASM output
- Windows API dependencies: Some stdlib functions assume Windows APIs (
WriteConsoleA, etc.) - Register allocation: Simple register allocator may have conflicts with heavy variable usage
- String literals: Automatically emitted into
.datasection with generated labels
To target Linux/macOS, modify the standard library in libs/stdio.py to use appropriate syscalls or libc functions instead of Windows API calls.
.
├── src/
│ ├── lexer.py # Tokenization
│ ├── token.py # Token type definitions
│ └── codegen.py # Code generation
├── utils/
│ └── syntax.py # Compiler & syntax checker
├── libs/
│ └── stdio.py # Standard library
├── examples/ # Example programs
└── main.py # Entry point
- Define tokens: Add token types in
src/token.py - Update lexer: Modify tokenization logic in
src/lexer.py - Update syntax checker: Add validation in
utils/syntax.py - Implement codegen: Add generation logic in
src/codegen.py
Add new functions to libs/stdio.py following the existing pattern. The compiler will automatically inject them when used.
Problem: nasm: command not found
Solution: Install NASM for your platform:
- Windows: Download from nasm.us
- macOS:
brew install nasm - Linux:
sudo apt-get install nasmorsudo yum install nasm
Problem: Linker errors during build
Solution: Ensure you have a working C compiler/linker:
- Windows: Install Visual Studio Build Tools or MinGW-w64
- macOS/Linux: Install Xcode Command Line Tools or GCC
Problem: Compilation succeeds but executable doesn't run
Solution: Verify your target platform matches your execution environment (Windows x64)
Contributions are welcome! Areas for improvement:
- Lexer enhancements: Better error messages, more token types
- Parser robustness: Edge case handling, error recovery
- Code generation: Improved register allocation, optimization passes
- Cross-platform support: Linux/macOS stdlib implementations
- Documentation: More examples, tutorials
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
This project is a small experimental compiler front-end. See LICENSE file for details.
- Issues: Open an issue on the project repository
- Pull Requests: Contributions welcome
- Questions: Use the discussion board or issues