|
| 1 | +# Noviq Project Structure |
| 2 | + |
| 3 | +This document describes the organization of the Noviq interpreter codebase. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Noviq is an interpreted programming language written in Rust. The project is organized as a library (`lib.rs`) with a minimal binary entry point (`main.rs`). |
| 8 | + |
| 9 | +## Directory Structure |
| 10 | + |
| 11 | +``` |
| 12 | +Noviq/ |
| 13 | +├── src/ |
| 14 | +│ ├── main.rs # Binary entry point |
| 15 | +│ ├── lib.rs # Library root |
| 16 | +│ ├── utils/ # Utilities |
| 17 | +│ │ ├── mod.rs # Utils module exports |
| 18 | +│ │ ├── version.rs # Version management |
| 19 | +│ │ └── tests.rs # Integration tests |
| 20 | +│ ├── frontend/ # Lexer and Parser |
| 21 | +│ │ ├── mod.rs # Frontend module exports |
| 22 | +│ │ ├── token.rs # Token definitions |
| 23 | +│ │ ├── ast.rs # AST definitions |
| 24 | +│ │ ├── lexer/ # Tokenization |
| 25 | +│ │ │ ├── mod.rs # Lexer main logic |
| 26 | +│ │ │ └── reader.rs # Character reading utilities |
| 27 | +│ │ └── parser/ # AST generation |
| 28 | +│ │ ├── mod.rs # Parser main logic |
| 29 | +│ │ ├── expr.rs # Expression parsing |
| 30 | +│ │ └── stmt.rs # Statement parsing |
| 31 | +│ └── runtime/ # Interpreter and execution |
| 32 | +│ ├── mod.rs # Runtime module exports |
| 33 | +│ ├── value.rs # Runtime value types |
| 34 | +│ ├── builtins/ # Built-in functions |
| 35 | +│ │ ├── mod.rs # Builtin router |
| 36 | +│ │ └── log.rs # log() function |
| 37 | +│ └── interpreter/ # Execution engine |
| 38 | +│ ├── mod.rs # Interpreter main logic |
| 39 | +│ ├── expr.rs # Expression evaluation |
| 40 | +│ └── stmt.rs # Statement execution |
| 41 | +├── examples/ # Example Noviq programs |
| 42 | +│ ├── README.md |
| 43 | +│ ├── hello.nvq |
| 44 | +│ └── test.nvq |
| 45 | +├── Cargo.toml |
| 46 | +├── README.md |
| 47 | +├── STRUCTURE.md |
| 48 | +└── build.sh/bat/ps1 |
| 49 | +``` |
| 50 | + |
| 51 | +## Module Organization |
| 52 | + |
| 53 | +### `main.rs` |
| 54 | +The binary entry point. Kept minimal - only initializes and calls into the library. |
| 55 | +Handles command-line arguments: |
| 56 | +- No args: Shows version info and usage |
| 57 | +- `--help` / `-h`: Shows help message |
| 58 | +- `--version` / `-v`: Shows version |
| 59 | +- `<file.nvq>`: Reads and executes a Noviq file |
| 60 | + |
| 61 | +### `lib.rs` |
| 62 | +The library root that: |
| 63 | +- Declares all modules |
| 64 | +- Re-exports public API |
| 65 | +- Provides documentation for the crate |
| 66 | + |
| 67 | +### `utils/` |
| 68 | +Utility modules: |
| 69 | +- `version.rs` - Version string generation (nebula-X.Y.Z or pulsar builds) |
| 70 | +- `tests.rs` - Integration tests |
| 71 | + |
| 72 | +### `frontend/` |
| 73 | +Tokenization and parsing: |
| 74 | +- `token.rs` - Token type definitions |
| 75 | +- `ast.rs` - AST node definitions (Expr, Stmt) |
| 76 | +- `lexer/` - Tokenizer implementation |
| 77 | + - `mod.rs` - Main lexer logic |
| 78 | + - `reader.rs` - Character reading and string/identifier extraction |
| 79 | +- `parser/` - Parser implementation |
| 80 | + - `mod.rs` - Main parser logic |
| 81 | + - `expr.rs` - Expression parsing |
| 82 | + - `stmt.rs` - Statement parsing |
| 83 | + |
| 84 | +### `runtime/` |
| 85 | +Execution and built-in functions: |
| 86 | +- `value.rs` - Runtime value types |
| 87 | +- `builtins/` - Built-in function implementations |
| 88 | + - `mod.rs` - Builtin function router |
| 89 | + - `log.rs` - The `log()` function |
| 90 | +- `interpreter/` - Execution engine |
| 91 | + - `mod.rs` - Main interpreter logic |
| 92 | + - `expr.rs` - Expression evaluator |
| 93 | + - `stmt.rs` - Statement executor |
| 94 | + |
| 95 | +### `tests.rs` |
| 96 | +Integration tests that verify: |
| 97 | +- Example files exist and are readable |
| 98 | +- File syntax is correct |
| 99 | +- Core functionality works as expected |
| 100 | + |
| 101 | +### `examples/` |
| 102 | +Example Noviq programs (`.nvq` extension): |
| 103 | +- `hello.nvq` - Basic hello world with log statements |
| 104 | +- `test.nvq` - Simple log test |
| 105 | +- Each example demonstrates language features |
| 106 | + |
| 107 | +## Current Features |
| 108 | + |
| 109 | +The interpreter currently supports: |
| 110 | +- **Comments**: Lines starting with `#` |
| 111 | +- **String literals**: Double-quoted strings with escape sequences |
| 112 | +- **Function calls**: `log("message")` - prints to stdout |
| 113 | + |
| 114 | +## Module Organization |
| 115 | + |
| 116 | +### Frontend (Parsing) |
| 117 | +``` |
| 118 | +frontend/ |
| 119 | +├── token.rs - Token enum (Identifier, String, LeftParen, etc.) |
| 120 | +├── ast.rs - AST nodes (Expr, Stmt) |
| 121 | +├── lexer/ |
| 122 | +│ ├── mod.rs - Main tokenization logic |
| 123 | +│ └── reader.rs - Character-level reading (skip whitespace, read strings, etc.) |
| 124 | +└── parser/ |
| 125 | + ├── mod.rs - Main parsing logic |
| 126 | + ├── expr.rs - Expression parser |
| 127 | + └── stmt.rs - Statement parser |
| 128 | +``` |
| 129 | + |
| 130 | +### Runtime (Execution) |
| 131 | +``` |
| 132 | +runtime/ |
| 133 | +├── value.rs - Value enum (String, Null) |
| 134 | +├── builtins/ |
| 135 | +│ ├── mod.rs - Routes builtin calls by name |
| 136 | +│ └── log.rs - log() implementation |
| 137 | +└── interpreter/ |
| 138 | + ├── mod.rs - Main interpreter |
| 139 | + ├── expr.rs - Expression evaluator |
| 140 | + └── stmt.rs - Statement executor |
| 141 | +``` |
| 142 | + |
| 143 | +### Utils |
| 144 | +``` |
| 145 | +utils/ |
| 146 | +├── version.rs - Version string generation |
| 147 | +└── tests.rs - Integration tests |
| 148 | +``` |
| 149 | + |
| 150 | +## Building |
| 151 | + |
| 152 | +```bash |
| 153 | +# Debug build (includes pulsar timestamp) |
| 154 | +cargo build |
| 155 | + |
| 156 | +# Release build |
| 157 | +cargo build --release |
| 158 | + |
| 159 | +# Snapshot build (optimized but with pulsar timestamp) |
| 160 | +SNAPSHOT=1 cargo build --profile=snapshot |
| 161 | +``` |
| 162 | + |
| 163 | +## Testing |
| 164 | + |
| 165 | +```bash |
| 166 | +# Run all tests |
| 167 | +cargo test |
| 168 | + |
| 169 | +# Run a specific test |
| 170 | +cargo test test_example_files_exist |
| 171 | + |
| 172 | +# Run tests with output |
| 173 | +cargo test -- --nocapture |
| 174 | +``` |
| 175 | + |
| 176 | +## Running Examples |
| 177 | + |
| 178 | +```bash |
| 179 | +# Run with cargo |
| 180 | +cargo run -- examples/hello.nvq |
| 181 | + |
| 182 | +# Or run the binary directly |
| 183 | +./target/debug/noviq examples/hello.nvq |
| 184 | + |
| 185 | +# Show help |
| 186 | +./target/debug/noviq --help |
| 187 | + |
| 188 | +# Show version |
| 189 | +./target/debug/noviq --version |
| 190 | +``` |
| 191 | + |
| 192 | +## Design Principles |
| 193 | + |
| 194 | +1. **Separation of Concerns**: Each module has a single, well-defined purpose |
| 195 | +2. **Library-First**: Core functionality in `lib.rs`, binary is just a thin wrapper |
| 196 | +3. **Testability**: Each module includes its own tests |
| 197 | +4. **Documentation**: All public items are documented |
| 198 | +5. **Extensibility**: Easy to add new modules without modifying existing code |
| 199 | + |
| 200 | +## Adding New Features |
| 201 | + |
| 202 | +To add a new feature: |
| 203 | + |
| 204 | +1. Create a new module file in the appropriate directory |
| 205 | +2. Add module declaration to `lib.rs` or the parent module |
| 206 | +3. Implement the feature with tests |
| 207 | +4. Update documentation |
| 208 | +5. Re-export public items if needed |
| 209 | + |
| 210 | +Example: |
| 211 | +```rust |
| 212 | +// src/builtins/math.rs |
| 213 | +pub fn add(a: i64, b: i64) -> i64 { a + b } |
| 214 | + |
| 215 | +// src/builtins/mod.rs |
| 216 | +pub mod math; |
| 217 | +pub use math::add; |
| 218 | +``` |
0 commit comments