diff --git a/.gitignore b/.gitignore index cce68ad..cfa1a53 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ tests/object/ **.exe zlang-support/ + +**/.vscode/ diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 59164ed..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "files.associations": { - "*.h": "cpp", - "*.java": "java", - "any": "cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "charconv": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "complex": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "coroutine": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "forward_list": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "format": "cpp", - "fstream": "cpp", - "future": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "queue": "cpp", - "ranges": "cpp", - "semaphore": "cpp", - "span": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stdfloat": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "text_encoding": "cpp", - "thread": "cpp", - "cfenv": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp", - "variant": "cpp", - "ios": "cpp", - "locale": "cpp", - "xfacet": "cpp", - "xhash": "cpp", - "xiosbase": "cpp", - "xlocale": "cpp", - "xlocbuf": "cpp", - "xlocinfo": "cpp", - "xlocmes": "cpp", - "xlocmon": "cpp", - "xlocnum": "cpp", - "xloctime": "cpp", - "xmemory": "cpp", - "xstring": "cpp", - "xtr1common": "cpp", - "xtree": "cpp", - "xutility": "cpp" - }, - "C_Cpp.formatting": "clangFormat", - "C_Cpp.clang_format_style": "{ BasedOnStyle: Google, IndentWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 0, AccessModifierOffset: -4, NamespaceIndentation: All, FixNamespaceComments: false}", - "C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: Google, IndentWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 0, AccessModifierOffset: -4, NamespaceIndentation: All, FixNamespaceComments: false}", - "C_Cpp.clang_format_path": "/usr/bin/clang-format", -} \ No newline at end of file diff --git a/README.md b/README.md index b94b628..d014b71 100644 --- a/README.md +++ b/README.md @@ -23,26 +23,59 @@ A lightweight statically typed programming language that compiles to **x86_64 Li ``` zlang/ ├── include/ +│ ├── common/ +│ │ ├── Colors.hpp +│ │ ├── Errors.hpp +│ │ ├── Logging.hpp +│ │ └── StringUtils.hpp +│ ├── support/ +│ │ ├── CommandLine.hpp +│ │ └── File.hpp +│ ├── ast/ +│ │ └── ASTNode.hpp +│ ├── lexer/ +│ │ └── Lexer.hpp │ ├── parser/ -│ │ ├── ASTNode.hpp │ │ ├── Parser.hpp -│ │ ├── ScopeContext.hpp -│ │ └── Token.hpp -│ ├── codegen/ -│ │ ├── CodegenLinux.hpp -│ │ └── RegisterAllocator.hpp -│ └── typechecker/ -│ └── TypeChecker.hpp +│ │ └── ScopeContext.hpp +│ ├── typechecker/ +│ │ └── TypeChecker.hpp +│ └── codegen/ +│ ├── CodeGen.hpp +│ ├── Canaries.hpp +│ └── RegisterAllocator.hpp ├── src/ +│ ├── common/ +│ │ ├── Logging.cpp +│ │ └── StringUtils.cpp +│ ├── support/ +│ │ ├── CommandLine.cpp +│ │ └── File.cpp +│ ├── ast/ +│ │ └── ASTNode.cpp +│ ├── lexer/ +│ │ └── Lexer.cpp │ ├── parser/ +│ │ ├── ScopeContext.cpp │ │ └── Parser.cpp -│ ├── codegen/ -│ │ └── CodegenLinux.cpp -│ └── typechecker/ -│ └── TypeChecker.cpp +│ ├── typechecker/ +│ │ └── TypeChecker.cpp +│ └── codegen/ +│ ├── CodeGenWindows.cpp +│ ├── CodeGenLinux.cpp +│ ├── CodeGenLLVM.cpp +│ └── RegisterAllocator.cpp +├── tests/ +│ ├── zz/ +│ | ├── [Various test categorized in folders] +├── examples/ +│ ├── [current example we are working on] ├── main.cpp -├── Makefile +├── CMakeLists.txt +├── test_runner.py +├── LICENSE └── README.md + ``` --- @@ -52,9 +85,11 @@ zlang/ ### Prerequisites - Linux (x86_64) -- `gnu` assembler +- `gnu` (linux) +- `ml64.exe` (windows) +- `llc & clang` (LLVM) - `g++` or `clang++` compiler -- `make` or `cmake` (for build automation) +- `cmake` ### Build Instructions @@ -74,43 +109,92 @@ make ## 🔧 Usage +### On Linux when --format is x86_64-linux + +- **Compile** + ```bash -./zpiler +./zpiler --format x86_64-linux -o out.asm ``` -This will: + This will: -1. Parse the input `.zz` file. -2. Typecheck the AST. -3. Generate `out.asm` containing x86_64 assembly. -4. Assemble and link the code to produce an ELF executable. + 1. Parse the input`.zz` file. + 2. Typecheck the AST. + 3. Generate `out.asm` containing x86_64 assembly. + +- **Assemble, Link and Run** ```bash as out.asm -o out.o -ld out.o -o out +gcc out.o -o out ./out ``` ---- +### On Linux when --format is llvm-ir -## 🧠 Example Program (zlang) +- **Compile** -```zlang -let x: integer = 10; -let y: integer; +```bash +./zpiler --format llvm-ir -o out.ll +``` -y = 13; -x = 11; + This will: -let msg: string = "Hello World"; -let pi: double = 3.1415; -let precision: float = 0.0001f; + 1. Parse the input`.zz` file. + 2. Typecheck the AST. + 3. Generate `out.ll` containing LLVM IR. -let a: uint32_t = 123; -let b: float32_t = 12.3f; +- **Assemble, Link and Run** -if (a > b + 10) { - // do something +```bash +llc -filetype=obj -o out.ll +gcc out.o -o out -no-pie +./out +``` + +### On Windows when --format is x86_64-windows + +- **Compile** + +```bash +./zpiler --format x86_64-windows -o out.asm +``` + + This will: + + 1. Parse the input`.zz` file. + 2. Typecheck the AST. + 3. Generate `out.asm` containing x86_64 assembly. + +- **Assemble, Link and Run** + +```bash +ml64 /nologo /c .\out.asm +gcc out.o -o out +./out +``` + +--- + +## 🧠 Example Program (zlang) + +```zlang +extern fn printf(fmt: string, ...) -> int32_t; + +fn factorial(x: uint64_t) -> uint64_t{ + fn multiply(x: uint64_t, y: uint64_t) -> uint64_t{ + return x * y; + } + if(x <= 1){ + return 1; + }else{ + return multiply(x, factorial(x - 1)); + } +} + +fn main() { + printf("Factorial of 10: %d\n", factorial(10)); } ``` @@ -142,4 +226,3 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file **Mihir Patel** Feel free to reach out for contributions, discussions, or collaborations! - diff --git a/examples/functions.zz b/examples/functions.zz index a820007..b8536e3 100644 --- a/examples/functions.zz +++ b/examples/functions.zz @@ -1,17 +1,16 @@ - extern fn printf(fmt: string, ...) -> int32_t; -let a: int64_t = 10; -let f: float = 20.5; -let u: uint8_t = 10; - -fn print_int(x: int64_t) -> none { - printf("%d\n", x); +fn factorial(x: uint64_t) -> uint64_t{ + fn multiply(x: uint64_t, y: uint64_t) -> uint64_t{ + return x * y; + } + if(x <= 1){ + return 1; + }else{ + return multiply(x, factorial(x - 1)); + } } fn main() { - if (a > 100) { - let res: int64_t = a * 2; - print_int(res); - } + printf("Factorial of 10: %d\n", factorial(10)); }