### Run JIT Compilation Example with Nightly Rust Source: https://createlang.rs/01_calculator/basic_llvm Navigate to the LLVM example sub-crate and execute the JIT compilation using Cargo. This command requires a nightly Rust toolchain to be installed. ```bash rustup run nightly cargo run ``` -------------------------------- ### Fuzzing Setup with cargo-fuzz Source: https://createlang.rs/testing Provides instructions for setting up and running fuzz tests using `cargo-fuzz`. It covers installing the tool, initializing a fuzzing project, and running fuzz targets. Fuzzing is crucial for discovering crashes, infinite loops, stack overflows, and memory issues by feeding unexpected inputs to the parser. ```bash cargo install cargo-fuzz cargo fuzz init cargo fuzz run parse_fuzz ``` -------------------------------- ### Run Secondlang Examples: Basics Source: https://createlang.rs/03_secondlang/jit_fibonacci Executes the 'basics.sl' example, which demonstrates fundamental Secondlang features like typed variables, functions, and control flow. ```shell rustup run nightly cargo run -- examples/basics.sl ``` -------------------------------- ### Run Secondlang Example: Type Inference Source: https://createlang.rs/03_secondlang/jit_fibonacci Executes the 'inference.sl' example, showcasing Secondlang's ability to automatically infer variable types based on their usage and context. ```secondlang def complex_calc(x: int) -> int { a = x + 1 # int (inferred from x + literal) b = a * a # int (inferred from int * int) c = b - x # int (inferred from int - int) flag = c > 100 # bool (inferred from comparison) if (flag) { return c } else { return b } } complex_calc(10) ``` ```shell rustup run nightly cargo run -- examples/inference.sl ``` -------------------------------- ### Unification Rule Examples Source: https://createlang.rs/03_secondlang/inference Illustrates the outcomes of applying the unification rules with concrete examples, showing successful unifications (e.g., `Int` with `Int`, `Unknown` with `Int`) and failures (e.g., `Int` with `Bool`). ```markdown Unify| Result| Why ---|---|--- `Int.unify(Int)`| `Ok(Int)`| Same types match `Bool.unify(Bool)`| `Ok(Bool)`| Same types match `Unknown.unify(Int)`| `Ok(Int)`| Unknown takes on the concrete type `Int.unify(Unknown)`| `Ok(Int)`| Unknown takes on the concrete type `Int.unify(Bool)`| `Err`| Incompatible types cannot unify The `Unknown` case is the heart of type inference. When we unify `Unknown` with a concrete type, we _learn_ what the unknown type should be. ``` -------------------------------- ### Install LLVM on macOS Source: https://createlang.rs/intro Command to install LLVM on macOS using Homebrew, a prerequisite for JIT compilation with Secondlang and Thirdlang. ```bash __ # Install LLVM (macOS) brew install llvm ``` -------------------------------- ### Rust Inference Example Execution Source: https://createlang.rs/03_secondlang/inference Command to run the type inference example for Secondlang using a nightly Rust toolchain. ```bash rustup run nightly cargo run -- examples/inference.sl ``` -------------------------------- ### Batch Run All Secondlang Examples Source: https://createlang.rs/03_secondlang/jit_fibonacci A shell script to iterate through all '.sl' files in the 'examples/' directory and execute each one using the Secondlang compiler. ```shell for file in examples/*.sl; do echo "Running $file..." rustup run nightly cargo run -- "$file" done ``` -------------------------------- ### Run Secondlang Examples Source: https://createlang.rs/03_secondlang/intro Commands to compile and run example programs (like Fibonacci) using the Secondlang compiler with the Rust nightly toolchain. Options to show LLVM IR or perform type checking only are also demonstrated. ```bash cd secondlang # Run Fibonacci rustup run nightly cargo run -- examples/fibonacci.sl # Show LLVM IR rustup run nightly cargo run -- --ir examples/fibonacci.sl # Type check only rustup run nightly cargo run -- --check examples/fibonacci.sl ``` -------------------------------- ### Running Thirdlang Examples and Tests Source: https://createlang.rs/04_thirdlang/intro Provides commands to compile and run Thirdlang example programs like 'Point' and 'Counter', as well as execute all integration tests. These commands utilize the nightly Rust toolchain and the `thirdlang` binary. ```bash cd thirdlang # Run Point example rustup run nightly cargo run --bin thirdlang -- examples/point.tl # Run Counter example rustup run nightly cargo run --bin thirdlang -- examples/counter.tl # Run all tests rustup run nightly cargo test ``` -------------------------------- ### Example: Function Definitions and Calls in Custom Language Source: https://createlang.rs/02_firstlang/syntax Shows examples of defining and calling functions in the custom language. It includes a simple function `greet` that returns a constant, and an `add` function that takes two parameters and returns their sum. Function calls demonstrate passing arguments. ```plaintext def greet() { return 42 } def add(a, b) { return a + b } add(3, 4) # = 7 ``` -------------------------------- ### Run Example Programs with Cargo Source: https://createlang.rs/02_firstlang/repl Executes example programs written in the custom language using the Cargo build tool. This is useful for demonstrating language features and testing functionality. ```shell cargo run -- examples/fibonacci.fl ``` ```shell cargo run -- examples/factorial.fl ``` ```shell cargo run -- examples/basics.fl ``` ```shell for file in examples/*.fl; do echo "Running $file..." cargo run -- "$file" done ``` -------------------------------- ### Install Rust Nightly Source: https://createlang.rs/03_secondlang/intro Command to install the Rust nightly toolchain, which is required for Secondlang due to its dependency on the inkwell crate. ```bash rustup toolchain install nightly ``` -------------------------------- ### GitHub Actions CI for Rust Tests Source: https://createlang.rs/testing Shows a GitHub Actions workflow configuration (`ci.yml`) to automatically run tests and examples on every commit. It includes steps for executing `cargo test --all` and running example programs using `cargo run`. ```yaml # .github/workflows/ci.yml - name: Run tests run: cargo test --all - name: Run examples run: | cargo run -- examples/fibonacci.sl cargo run -- examples/factorial.sl ``` -------------------------------- ### Setting up Rust Nightly and Checking LLVM Version Source: https://createlang.rs/04_thirdlang/intro Instructions for installing the nightly Rust toolchain and verifying the LLVM version, which are prerequisites for building and running the Thirdlang project. This ensures compatibility with the required LLVM features. ```bash # Install nightly Rust rustup toolchain install nightly # Check LLVM version llvm-config --version ``` -------------------------------- ### Install GCC JIT Development Library Source: https://createlang.rs/01_calculator/exercise This command installs the necessary development files for libgccjit on Ubuntu/Debian systems. libgccjit is a foreign function interface for the GCC compiler's Just-In-Time compilation engine. ```bash # Ubuntu/Debian sudo apt install libgccjit-10-dev ``` -------------------------------- ### Command Line Flags for Optimization Source: https://createlang.rs/03_secondlang/optimizations These command-line examples show how to run the CreateLang compiler with and without optimizations enabled. The `-O` flag is used to activate optimization passes. ```bash # Without optimization rustup run nightly cargo run -- --ir examples/fibonacci.sl # With optimization rustup run nightly cargo run -- --ir -O examples/fibonacci.sl ``` -------------------------------- ### Execute Multiple Thirdlang Examples (Shell) Source: https://createlang.rs/04_thirdlang/running Runs several Thirdlang example programs, including 'point.tl', 'counter.tl', 'destructor.tl', and 'linked_node.tl'. It iterates through all '.tl' files in the 'examples/' directory and executes them quietly. ```shell for file in examples/*.tl; do echo "=== $file ===" rustup run nightly cargo run --bin thirdlang -q -- "$file" done ``` -------------------------------- ### Install GCC for GCC JIT on macOS Source: https://createlang.rs/01_calculator/exercise This command installs GCC on macOS using the Homebrew package manager. GCC is a prerequisite for using the gccjit.rs Rust wrapper, which leverages libgccjit for JIT compilation. ```bash # macOS brew install gcc ``` -------------------------------- ### Run Thirdlang Program: Point Example (Shell) Source: https://createlang.rs/04_thirdlang/running Executes a Thirdlang program that defines and uses a 'Point' class. This command navigates to the 'thirdlang' directory and uses 'rustup' to run the 'thirdlang' binary with the 'examples/point.tl' file. ```shell cd thirdlang rustup run nightly cargo run --bin thirdlang -- examples/point.tl ``` -------------------------------- ### Example: Variable Assignment in Custom Language Source: https://createlang.rs/02_firstlang/syntax Illustrates variable assignment and usage within the custom programming language. The examples show how to assign a value to a variable and then use that variable in subsequent expressions. ```plaintext x = 10 y = x + 5 # = 15 ``` -------------------------------- ### Variable and Arithmetic Operations Example Source: https://createlang.rs/02_firstlang/variables Provides a comprehensive example of variable declaration, arithmetic operations, and reassignment within a custom language. It includes a mental trace of the environment's state. ```plaintext # Variables and arithmetic a = 5 b = 3 sum = a + b # 8 diff = a - b # 2 prod = a * b # 15 # Reassignment x = 1 x = x + 1 x = x * 2 x # 4 ``` -------------------------------- ### Run Thirdlang Program: Counter Example (Shell) Source: https://createlang.rs/04_thirdlang/running Executes a Thirdlang program that defines and uses a 'Counter' class. This command compiles and runs the 'examples/counter.tl' file using the 'thirdlang' binary. ```shell rustup run nightly cargo run --bin thirdlang -- examples/counter.tl ``` -------------------------------- ### LLVM IR Examples for Optimization Passes Source: https://createlang.rs/04_thirdlang/optimization These examples illustrate the effect of common LLVM optimization passes on Intermediate Representation (IR). They show 'before' and 'after' snippets demonstrating how passes like `mem2reg`, `dce` (Dead Code Elimination), and `instcombine` simplify the code. ```llvm ; mem2reg example %x = alloca i64 store i64 42, ptr %x %val = load i64, ptr %x ``` ```llvm ; After mem2reg %val = 42 ``` ```llvm ; dce example %unused = add i64 %a, %b ; result never used %result = mul i64 %c, %d ret i64 %result ``` ```llvm ; After dce %result = mul i64 %c, %d ret i64 %result ``` -------------------------------- ### Run Thirdlang Program: Destructor Example (Shell) Source: https://createlang.rs/04_thirdlang/running Executes a Thirdlang program demonstrating object destruction. This command runs the 'examples/destructor.tl' file using the 'thirdlang' binary, testing the functionality of the '__del__' method. ```shell rustup run nightly cargo run --bin thirdlang -- examples/destructor.tl ``` -------------------------------- ### Starting Firstlang REPL (Shell) Source: https://createlang.rs/02_firstlang/intro Command to launch the Firstlang Read-Eval-Print Loop (REPL) using Cargo. The REPL allows interactive execution of Firstlang code snippets and definition of functions. ```shell cargo run # Firstlang REPL v0.1.0 # >>> 1 + 2 # 3 # >>> def double(x) { return x * 2 } # >>> double(21) # 42 ``` -------------------------------- ### Function Type Checking Example in Python Source: https://createlang.rs/03_secondlang/inference Illustrates the type checking process for a function in Python. It shows how parameters are added to the environment, and how types of local variables are inferred and checked against expressions and the return type. ```python def compute(a: int, b: int) -> int { temp = a + b # What type is temp? doubled = temp * 2 # What type is doubled? return doubled + 1 } ``` -------------------------------- ### Call Methods using Dot Notation in Firstlang Source: https://createlang.rs/04_thirdlang/methods Demonstrates the syntax for calling methods on an object using dot notation in Firstlang. Examples include calling 'increment', 'add' with an argument, and 'get' to retrieve a value from the object's state. ```firstlang c = new Counter() c.increment() # Call increment on c c.add(5) # Call add with argument 5 x = c.get() # Get returns an int ``` -------------------------------- ### Rust VM Compilation and Execution Example Source: https://createlang.rs/01_calculator/vm Demonstrates the process of compiling source code into bytecode, executing it with a VM, and retrieving the result. It assumes the existence of an Interpreter struct with a from_source method and a VM struct with run and pop_last methods. ```Rust let byte_code = Interpreter::from_source(source); println!("byte code: {:?}", byte_code); let mut vm = VM::new(byte_code); vm.run(); println!("{}", vm.pop_last()); ``` -------------------------------- ### Example: While Loop in Custom Language Source: https://createlang.rs/02_firstlang/syntax Illustrates the usage of a `while` loop for iterative execution in the custom language. The example shows a loop that increments a variable `x` until it reaches a certain condition. ```plaintext x = 0 while (x < 5) { x = x + 1 } x # = 5 ``` -------------------------------- ### Rust REPL: LLVM IR with JIT Compilation Source: https://createlang.rs/01_calculator/repl This example shows the output of the Rust REPL when using the JIT backend with LLVM. It includes the user input, the compilation process, the generated LLVM Intermediate Representation (IR), and the final computed result. Notice how LLVM performs constant folding, optimizing `1 + 2` directly to `3` within the generated IR. ```text Calculator prompt. Expressions are line evaluated. >> 1 + 2 Compiling the source: 1 + 2 [BinaryExpr { op: Plus, lhs: Int(1), rhs: Int(2) }] Generated LLVM IR: define i32 @jit() { entry: ret i32 3 } 3 ``` -------------------------------- ### Recursive Fibonacci Example (Firstlang) Source: https://createlang.rs/02_firstlang/intro A recursive implementation of the Fibonacci sequence in Firstlang. This example demonstrates function definition, recursion, conditional logic, and return statements within the language. ```plaintext def fib(n) { if (n < 2) { return n } else { return fib(n - 1) + fib(n - 2) } } fib(10) # Returns 55 ``` -------------------------------- ### Example: Recursive Function in Custom Language Source: https://createlang.rs/02_firstlang/syntax Provides an example of a recursive function, `factorial`, implemented in the custom language. The function calculates the factorial of a number using recursion and conditional logic. ```plaintext def factorial(n) { if (n <= 1) { return 1 } else { return n * factorial(n - 1) } } factorial(5) # = 120 ``` -------------------------------- ### Running Firstlang Code from File Source: https://createlang.rs/02_firstlang/fibonacci Demonstrates how to compile and run a Firstlang program saved in a file using Cargo. This shows the practical application of the created programming language. ```shell cargo run -- examples/fibonacci.fl 55 ``` -------------------------------- ### Define and Run Factorial in Secondlang Source: https://createlang.rs/03_secondlang/jit_fibonacci Illustrates defining a recursive factorial function in Secondlang and running it. Includes the Secondlang code and the command to execute it, along with the expected output. ```secondlang def factorial(n: int) -> int { if (n <= 1) { return 1 } else { return n * factorial(n - 1) } } factorial(10) ``` ```shell rustup run nightly cargo run -- examples/factorial.sl ``` -------------------------------- ### Command-line Interface for Thirdlang Compiler Source: https://createlang.rs/04_thirdlang/optimization This section provides examples of how to use the `thirdlang` command-line tool to compile and run programs, with options for optimization and IR output. It demonstrates running without optimization, with standard optimization levels, custom pass pipelines, and printing IR. ```bash # Run without optimization thirdlang examples/point.tl # Run with optimization thirdlang -O examples/point.tl # Run with custom passes thirdlang --passes "mem2reg,dce" examples/point.tl # Print unoptimized IR thirdlang --ir examples/point.tl # Print optimized IR thirdlang --ir -O examples/point.tl # Use LLVM's O2 pipeline thirdlang --passes "default" examples/point.tl ``` -------------------------------- ### Running REPL with Different Backends Source: https://createlang.rs/01_calculator/repl These commands demonstrate how to compile and run the Rust REPL using different feature flags, enabling the interpreter, bytecode VM, or JIT compiler. This allows for comparison of how the same code is handled by each backend. ```bash # Interpreter (stable Rust) # Walks the AST and computes directly carbox run --bin repl --features interpreter # Bytecode VM (stable Rust) # Compiles to bytecode, then interprets that carbox run --bin repl --features vm # JIT (requires nightly Rust + LLVM) # Compiles to native machine code rustup run nightly carbox run --bin repl --features jit ``` -------------------------------- ### Destructor (`__del__`) Example in Thirdlang Source: https://createlang.rs/04_thirdlang/memory Provides an example of a destructor (`__del__`) in Thirdlang, which is automatically called when an object is deleted. This allows for cleanup operations before memory is freed, such as closing file handles or releasing resources. ```Thirdlang class Resource { id: int def __init__(self, id: int) { self.id = id } def __del__(self) { # Cleanup code here # (In a real language, might close files, release handles, etc.) } } r = new Resource(42) delete r # Calls __del__, then free() ``` -------------------------------- ### Simple Expression Bytecode Generation (Rust) Source: https://createlang.rs/01_calculator/repl Illustrates the bytecode generation process for a basic addition expression. It shows the AST representation, the compilation steps for each opcode, and the final bytecode with constants. This example highlights the `OpConstant` and `OpAdd` instructions. ```rust >> 1 + 2 Compiling the source: 1 + 2 [BinaryExpr { op: Plus, lhs: Int(1), rhs: Int(2) }] compiling node BinaryExpr { op: Plus, lhs: Int(1), rhs: Int(2) } added instructions [1, 0, 0] from opcode OpConstant(0) added instructions [1, 0, 0, 1, 0, 1] from opcode OpConstant(1) added instructions [1, 0, 0, 1, 0, 1, 3] from opcode OpAdd added instructions [1, 0, 0, 1, 0, 1, 3, 2] from opcode OpPop byte code: Bytecode { instructions: [1, 0, 0, 1, 0, 1, 3, 2], constants: [Int(1), Int(2)] } 3 ``` -------------------------------- ### Clone Project Repository with Git Source: https://createlang.rs/intro Instructions to clone the project repository from GitHub using the git clone command. This is the first step to obtain the project files and source code. ```bash __ git clone https://github.com/ehsanmok/create-your-own-lang-with-rust cd create-your-own-lang-with-rust ``` -------------------------------- ### Example: Arithmetic Expression Evaluation in Custom Language Source: https://createlang.rs/02_firstlang/syntax Demonstrates basic arithmetic expression evaluation, including operator precedence and the use of parentheses for overriding default precedence. The examples cover addition, multiplication, and unary minus operations. ```plaintext 1 + 2 * 3 # = 7 (multiplication first) (1 + 2) * 3 # = 9 (parentheses override) -5 + 3 # = -2 (unary minus) ``` -------------------------------- ### Mutual Recursion Example in Python Source: https://createlang.rs/03_secondlang/inference Demonstrates mutual recursion between `isEven` and `isOdd` functions in Python. This example highlights the need for the first pass in type checking to collect all function signatures before processing their bodies, enabling the resolution of inter-function dependencies. ```python def isEven(n: int) -> bool { if (n == 0) { return true } else { return isOdd(n - 1) } } def isOdd(n: int) -> bool { if (n == 0) { return false } else { return isEven(n - 1) } } ``` -------------------------------- ### Code Formatting Command Source: https://createlang.rs/whats_next Demonstrates a command-line tool for automatically formatting code consistently, analogous to tools like `rustfmt` or `prettier` for other languages. ```Shell __ ./myfmt program.tl # Like rustfmt or prettier ``` -------------------------------- ### Generate LLVM IR for Secondlang Program Source: https://createlang.rs/03_secondlang/jit_fibonacci Shows how to compile a Secondlang program and output its LLVM Intermediate Representation (IR). Useful for understanding the compilation process and optimizations. ```shell rustup run nightly cargo run -- --ir examples/fibonacci.sl ``` -------------------------------- ### Add Automatic Getter/Setter Generation in Custom Language Source: https://createlang.rs/04_thirdlang/exercises Implement automatic generation of getter and setter methods for class fields. Syntax like `{ get; set; }` or `{ get; }` should be parsed to create corresponding methods, transparently handling property access. ```python class Point { x: int { get; set; } y: int { get; } # read-only } p = new Point(1, 2) p.x = 10 # Uses setter print(p.x) # Uses getter ``` -------------------------------- ### Static Typing Example in Secondlang Source: https://createlang.rs/03_secondlang/why_types Illustrates a statically typed language (Secondlang) where type mismatches are caught at compile time. This example shows the same 'add' function, but with type annotations, preventing a runtime error by flagging the incorrect type usage during compilation. ```plaintext def add(a: int, b: int) -> int { return a + b } add(1, true) # Error at COMPILE time: expected int, got bool ``` -------------------------------- ### Type Inference Examples for Variable Assignment Source: https://createlang.rs/03_secondlang/inference Demonstrates the step-by-step type inference process for arithmetic and boolean expressions in CreateLang. It shows how the compiler checks operands, applies typing rules, and infers the types of intermediate results and final variable assignments. ```plaintext For `y = x * 2 + 10`: 1. Check `x * 2`: * Look up `x` in environment → `Int` * `2` is an `Int` literal * `*` with `Int * Int` → produces `Int` * Set type: `(x * 2).ty = Int` 2. Check `(x * 2) + 10`: * Left side `(x * 2)` has type `Int` (from step above) * Right side `10` is an `Int` literal * `+` with `Int + Int` → produces `Int` * Set type: `((x * 2) + 10).ty = Int` 3. Infer the variable type: * Value has type `Int` * `y` has type `Int` * Add to environment: `{ x: Int, y: Int }` For `is_big = y > 50`: 1. Check `y > 50`: * Look up `y` in environment → `Int` * `50` is an `Int` literal * `>` with `Int > Int` → produces `Bool` (comparisons return boolean) * Set type: `(y > 50).ty = Bool` 2. Infer the variable type: * Value has type `Bool` * `is_big` has type `Bool` * Add to environment: `{ x: Int, y: Int, is_big: Bool }` ``` -------------------------------- ### While Loop Example: Sum of 1 to 10 in Firstlang Source: https://createlang.rs/02_firstlang/control_flow A Firstlang example demonstrating the 'while' loop to calculate the sum of numbers from 1 to 10. It initializes 'sum' to 0 and 'i' to 1, then iteratively adds 'i' to 'sum' and increments 'i' until 'i' is no longer less than or equal to 10. ```Firstlang sum = 0 i = 1 while (i <= 10) { sum = sum + i i = i + 1 } sum # 55 ``` -------------------------------- ### Secondlang Project File Structure Comparison Source: https://createlang.rs/04_thirdlang/intro Illustrates the simpler file structure of Secondlang, highlighting the differences and reduced complexity compared to Thirdlang, particularly in its type system and code generation modules. ```tree secondlang/ ├── src/ │ ├── types.rs # Simpler: no ClassInfo │ ├── typeck.rs # Simpler: no class type checking │ └── codegen.rs # Simpler: no malloc/free ``` -------------------------------- ### Example of Unrelated Variables vs. Class-Based Data Organization Source: https://createlang.rs/04_thirdlang/intro This example contrasts a procedural approach using separate variables for related data (like point coordinates) with an object-oriented approach using a 'Point' class. The class-based approach groups data and behavior, improving organization and readability. ```rust # Unrelated variables floating around point_x = 10 point_y = 20 point2_x = 30 point2_y = 40 def distance(x1, y1, x2, y2) -> int { dx = x2 - x1 dy = y2 - y1 return dx * dx + dy * dy } distance(point_x, point_y, point2_x, point2_y) ``` ```rust class Point { x: int y: int def __init__(self, x: int, y: int) { self.x = x self.y = y } def distance_squared(self, other: Point) -> int { dx = other.x - self.x dy = other.y - self.y return dx * dx + dy * dy } } p1 = new Point(10, 20) p2 = new Point(30, 40) p1.distance_squared(p2) ``` -------------------------------- ### Interactive Programming with REPL Source: https://createlang.rs/whats_next Illustrates interactive programming using a Read-Eval-Print Loop (REPL). Users can execute commands, define functions, and see immediate results, similar to environments in Python or JavaScript. ```CreateLang __ > x = 10 > x + 5 15 > def double(n) { return n * 2 } > double(x) 20 ``` -------------------------------- ### Firstlang Fibonacci Function (Untyped) Source: https://createlang.rs/03_secondlang/intro An example of the recursive Fibonacci function written in Firstlang, which is dynamically typed. ```unspecified def fib(n) { if (n < 2) { return n } else { return fib(n - 1) + fib(n - 2) } } fib(10) ``` -------------------------------- ### Define and Run Recursive Fibonacci in Secondlang Source: https://createlang.rs/03_secondlang/jit_fibonacci Demonstrates defining a recursive Fibonacci function in Secondlang and executing it using the JIT compiler. Shows the input Secondlang code and the command to run it. ```secondlang def fib(n: int) -> int { if (n < 2) { return n } else { return fib(n - 1) + fib(n - 2) } } fib(10) ``` ```shell cd secondlang rustup run nightly cargo run -- examples/fibonacci.sl ```