Skip to content

Commit 1baad98

Browse files
committed
feat: Introduce core runtime, standard library, and package manager infrastructure.
1 parent 7b302b9 commit 1baad98

19 files changed

Lines changed: 1054 additions & 116 deletions

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,19 @@ target_link_libraries(ir_gen_test PRIVATE proxpl_lib)
6363

6464
# --- LLVM Gen Test Executable ---
6565
add_executable(llvm_gen_test tools/llvm_gen_test.c)
66+
add_executable(llvm_gen_test tools/llvm_gen_test.c)
6667
target_link_libraries(llvm_gen_test PRIVATE proxpl_lib ${llvm_libs})
6768

69+
# --- PRM Executable ---
70+
add_executable(prm
71+
tools/prm_main.c
72+
src/prm/manifest.c
73+
src/prm/builder.c
74+
)
75+
# PRM doesn't strictly need proxpl_lib unless it uses core types?
76+
# For now, it's standalone, but let's link it if needed later.
77+
# target_link_libraries(prm PRIVATE proxpl_lib)
78+
6879
# --- Optional components ---
6980
option(BUILD_TESTS "Build tests" OFF)
7081
option(BUILD_BENCH "Build benchmarks" OFF)

ECOSYSTEM_DESIGN.md

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
# ProXPL Ecosystem Design Specification
2+
3+
## 1. Executive Summary
4+
5+
This document defines the architecture for the next evolutionary phase of ProXPL. Moving beyond the core compiler and VM, this phase focuses on making the language "batteries-included," operationally robust, and developer-friendly. The design prioritizes **determinism**, **explicit error handling**, and **clean abstractions** over raw feature bloat.
6+
7+
---
8+
9+
## 2. Standard Library Architecture
10+
11+
The ProXPL Standard Library (`std`) serves as the foundation for all applications. It avoids the "kitchen sink" problem by providing high-quality, essential building blocks rather than niche implementations.
12+
13+
### 2.1 Directory Structure & Naming
14+
15+
The library assumes a hierarchical module system rooted at `std`.
16+
17+
```text
18+
lib/
19+
└── std/
20+
├── core/ # Built-in types, basic memory, primitives
21+
│ ├── types.prox # Int, Float, Bool extensions
22+
│ └── mem.prox # Manual memory helpers (unsafe)
23+
├── io/ # Input/Output streams
24+
│ ├── console.prox
25+
│ └── stream.prox
26+
├── fs/ # Filesystem operations
27+
│ ├── path.prox
28+
│ └── file.prox
29+
├── net/ # Networking (Sockets, HTTP client)
30+
├── math/ # Advanced math & Complex numbers
31+
├── time/ # High-precision clocks & Date
32+
├── sys/ # OS interactions (Env, Exit, PID)
33+
├── collection/ # Advanced data structures (Queue, Stack, BST)
34+
└── text/ # String manipulation, Regex, Encodings
35+
```
36+
37+
**Naming Conventions:**
38+
- **Modules**: `snake_case` (e.g., `std.http_client`)
39+
- **Functions/Methods**: `camelCase` (e.g., `readFile`, `toString`)
40+
- **Types/Classes**: `PascalCase` (e.g., `FileStream`, `TcpSocket`)
41+
- **Constants**: `SCREAMING_SNAKE_CASE` (e.g., `MAX_BUFFER_SIZE`)
42+
43+
### 2.2 Import System Semantics
44+
45+
ProXPL uses a path-based import system with support for aliasing.
46+
47+
- **Absolute Imports**: `import std.io;` resolves to `lib/std/io.prox` (or native equivalent).
48+
- **Relative Imports**: `import .utils;` resolves to `./utils.prox` relative to current file.
49+
- **Aliasing**: `import std.collection as coll;`
50+
- **Selective Import**: `from std.math import (sin, cos, PI);`
51+
52+
**Resolution Logic**:
53+
1. Is it a core module (e.g., `std`)? -> Load from internal registry/stdlib path.
54+
2. Is it a local path (starts with `.`)? -> Load relative to current file.
55+
3. Is it a package (e.g., `import requests`)? -> Look in `prox_modules/` or global cache.
56+
57+
### 2.3 Core Modules & APIs
58+
59+
#### `std.core`
60+
Essential runtime utilities. Auto-imported in most contexts.
61+
```prox
62+
// Assertions with clear messages
63+
func assert(condition, message)
64+
65+
// Type checking
66+
func typeOf(value) -> String
67+
68+
// Memory safety (Panic if null dereference happens)
69+
func unwrap(optionalValue) -> Value
70+
```
71+
72+
#### `std.io` & `std.fs`
73+
Explicit separation between stream I/O and Filesystem manipulations.
74+
```prox
75+
// std.fs
76+
module std.fs {
77+
class File {
78+
static func open(path, mode) -> Result<File>
79+
func readAll() -> String
80+
func close()
81+
}
82+
83+
func exists(path) -> Bool
84+
}
85+
86+
// std.io
87+
module std.io {
88+
func print(msg) // Buffered STDOUT
89+
func eprint(msg) // Unbuffered STDERR
90+
func scanln() -> String
91+
}
92+
```
93+
94+
#### `std.sys`
95+
System-level operations.
96+
```prox
97+
module std.sys {
98+
const OS_NAME: String
99+
const ARCH: String
100+
101+
func exit(code)
102+
func env(key) -> Option<String>
103+
func args() -> List<String>
104+
}
105+
```
106+
107+
### 2.4 Native vs Pure Implementation Split
108+
109+
| Module | Implementation | Rationale |
110+
| :--- | :--- | :--- |
111+
| `std.core` | **Intrinsic/Native** | Basic types require VM-level access. |
112+
| `std.math` | **Native (C)** | Performance critical; maps to `<math.h>`. |
113+
| `std.io` | **Native (C)** | Direct syscalls needed. |
114+
| `std.fs` | **Native (C)** | Platform specific syscalls. |
115+
| `std.net` | **Native (C)** | Platform specific sockets. |
116+
| `std.string` | **Mixed** | Basic ops native; formatting/templating pure. |
117+
| `std.collection` | **Pure ProXPL** | Built on top of core arrays/maps. |
118+
| `std.test` | **Pure ProXPL** | Test runner logic doesn't need C. |
119+
120+
### 2.5 Design Principles
121+
1. **Zero Hidden Allocations**: APIs that return new objects should be obvious. Prefer explicitly passing generic buffers for I/O.
122+
2. **Result Types over Exceptions**: Most I/O and System calls should return a `Result<T, E>` or `Option<T>` equivalent to force error handling (mimicking Rust/Go patterns).
123+
3. **Immutable Default**: Strings are immutable. Collections passed by reference but should have clear `clone()` methods.
124+
125+
---
126+
127+
## 3. ProX Resource Manager (PRM)
128+
129+
PRM is the official CLI toolchain for ProXPL, handling dependency management, building, testing, and publishing.
130+
131+
### 3.1 Package Format (`prox.toml`)
132+
Every project is defined by a TOML manifest.
133+
134+
```toml
135+
[package]
136+
name = "my-web-server"
137+
version = "1.0.0"
138+
authors = ["Jane Doe <jane@example.com>"]
139+
edition = "2025"
140+
description = "A fast web server for ProXPL"
141+
license = "MIT"
142+
143+
[dependencies]
144+
std = "0.1.0" # Core stdlib is versioned too!
145+
http_parser = { git = "https://github.com/...", tag = "v1.2" }
146+
json = "2.1.0"
147+
148+
[build]
149+
target = "native" # or "bytecode"
150+
optimize = true
151+
```
152+
153+
### 3.2 Command Suite
154+
155+
| Command | Description |
156+
| :--- | :--- |
157+
| `prm init <name>` | Scaffolds a new project with `prox.toml` and `src/main.prox`. |
158+
| `prm build` | Compiles the project. Supports `--dev` (fast, debug info) and `--release` (opt, stripped). |
159+
| `prm run` | Builds and runs the binary (or interprets in dev mode). |
160+
| `prm test` | Discovers and runs tests in `tests/` or files ending in `_test.prox`. |
161+
| `prm add <pkg>` | Adds a dependency to `prox.toml` and updates lockfile. |
162+
| `prm update` | Updates dependencies within semantic versioning bounds. |
163+
| `prm install` | Downloads dependencies defined in `prox.lock`. |
164+
165+
### 3.3 Dependency Resolution & Cache
166+
- **Lockfile (`prox.lock`)**: Pin exact versions of entire dependency tree. Checked into git.
167+
- **Global Cache**: `~/.prox/cache/registry` stores downloaded packages to avoid re-downloading.
168+
- **Structure**:
169+
- `~/.prox/bin/`: Installed global binaries.
170+
- `~/.prox/registry/`: Source code of packages.
171+
172+
---
173+
174+
## 4. Runtime Services & Tooling
175+
176+
To be production-ready, the runtime needs observability and robust error reporting.
177+
178+
### 4.1 Error System
179+
ProXPL moves away from generic "Runtime Error" to structured errors.
180+
181+
**Proposed Error Structure (C-Side):**
182+
```c
183+
typedef struct {
184+
ErrorType type; // FATAL, LOGIC, IO, FORMAT
185+
const char* message;
186+
const char* file;
187+
int line;
188+
CallFrame* stackTrace; // Captured at error creation
189+
} RuntimeError;
190+
```
191+
**User-Facing Panic:**
192+
When a panic occurs, the VM prints:
193+
1. Error Type & Message.
194+
2. Formatted Stack Trace (File:Line Function).
195+
3. Hint (if available).
196+
197+
### 4.2 Logging & Diagnostics
198+
- **`std.log`**: A structured logging interface.
199+
- Levels: `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`.
200+
- Output: Defaults to stderr, but configurable to file or JSON stream.
201+
- **Trace Hooks**: The VM will expose hooks for function entry/exit, allowing for flamegraph generation and profiling in the future.
202+
203+
### 4.3 Testing Framework (`std.test`)
204+
Built-in support for unit testing without external dependencies.
205+
```prox
206+
import std.test;
207+
208+
test "addition works" {
209+
assert(1 + 1 == 2, "Math is broken");
210+
}
211+
212+
test "failure case" {
213+
// Expect panic
214+
test.should_panic(func() { 1 / 0 });
215+
}
216+
```
217+
**`prm test`** runner will:
218+
1. Recursively find test files.
219+
2. Execute them in a sandbox.
220+
3. Report Pass/Fail statistics and timing.
221+
222+
---
223+
224+
## 5. Ecosystem Roadmap
225+
226+
### Phase 1: Foundation (Weeks 1-4)
227+
*Goal: Minimum usable Standard Library and Build System.*
228+
- [ ] **Stdlib v0.1**: Implement `std.core`, `std.io`, `std.fs`, `std.sys` (Native bindings).
229+
- [ ] **PRM v0.1**: Basic `prox.toml` parsing and `prm build` (local files only).
230+
- [ ] **Docs**: Initial `stdlib` API reference.
231+
232+
### Phase 2: Package Management (Weeks 5-8)
233+
*Goal: Allow sharing code.*
234+
- [ ] **PRM v0.5**: Git dependency support. `prm install` & `prox.lock`.
235+
- [ ] **Stdlib v0.2**: Add `std.net` (basic sockets) and `std.json`.
236+
237+
### Phase 3: Tooling & Stability (Weeks 9-12)
238+
*Goal: Developer Experience.*
239+
- [ ] **Testing**: Implement `std.test` and `prm test` harness.
240+
- [ ] **LSP**: Language Server Protocol basic implementation (Jump to def, simple completion).
241+
- [ ] **Debugger**: Source-map support for LLVM backend debugging.
242+
243+
### Phase 4: Expansion (4 Months+)
244+
*Goal: Enterprise Readiness.*
245+
- [ ] **Registry**: Centralized package registry (web service).
246+
- [ ] **Concurrency**: Go-style coroutines or Actor model in `std.task`.
247+
- [ ] **Sandboxing**: Wasm target or capabilities-based security.
248+
249+
---
250+
251+
## 6. Language Ergonomics (Developer Experience)
252+
253+
- **Formatting**: `prox fmt` is the single source of truth. Style is K&R braces, 4-space indent (or tab, configurable but standard is spaces).
254+
- **Documentation**: Markdown support in doc-comments `///`. `prox doc` generates HTML.
255+
- **Visibility**:
256+
- `pub func` explicitly exports symbols.
257+
- Default visibility is module-private.
258+
- **FFI**: Simple C-interop.
259+
```prox
260+
foreign func MessageBoxA(hwnd, text, caption, type);
261+
```
262+
263+
---
264+
265+
## 7. Trade-offs & Rejected Alternatives
266+
267+
1. **Running `npm` / `pip` for packages**:
268+
- *Rejected*: ProXPL needs deterministic, domain-specific build logic (AOT vs JIT switch). Relying on Python/Node logic introduces bloat and dependency hell.
269+
2. **Classes for everything (Java style)**:
270+
- *Rejected*: `std.core` uses functions acting on data for primitives suitable for SSA optimization. Classes reserved for complex state (Files, Sockets).
271+
3. **Exceptions**:
272+
- *Rejected*: Silent control flow makes systems programming hard. Result/Option types are explicit and force handling.

include/importer.h

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,33 @@
33
// Author: ProgrammerKR
44
// Created: 2025-12-16
55
// Copyright © 2025. ProXentix India Pvt. Ltd. All rights reserved.
6-
7-
/*
8-
* Module Importer for ProXPL
9-
* Handles "use" keyword and module loading
10-
*
11-
* STUB IMPLEMENTATION - Basic functionality only
12-
* Full implementation would include:
13-
* - Circular dependency detection
14-
* - Module caching
15-
* - Search path resolution
16-
* - Package management integration
17-
*/
6+
// --------------------------------------------------
187

198
#ifndef PROX_IMPORTER_H
209
#define PROX_IMPORTER_H
2110

2211
#include "common.h"
2312
#include "parser.h"
13+
#include "table.h"
2414

15+
// Importer State
2516
typedef struct {
2617
char **searchPaths;
2718
int pathCount;
28-
char **loadedModules;
29-
int loadedCount;
19+
20+
// Cache of loaded modules (Name -> ObjModule*)
21+
Table modules;
3022
} Importer;
3123

32-
// Initialize importer with search paths
24+
// Initialize importer with default search paths
3325
void initImporter(Importer *importer);
3426

35-
// Load a module by name (returns statements)
36-
StmtList *loadModule(Importer *importer, const char *moduleName);
37-
38-
// Resolve module path
39-
char *resolveModulePath(Importer *importer, const char *moduleName);
27+
// Load a module by name (e.g., "std.io" or "utils")
28+
// Returns true if successful, populates *result with the Module object
29+
bool loadModule(Importer *importer, const char *moduleName, void** result);
4030

41-
// Check if module is already loaded
42-
bool isModuleLoaded(Importer *importer, const char *path);
31+
// Add a directory to the module search path
32+
void addSearchPath(Importer *importer, const char *path);
4333

4434
// Free importer resources
4535
void freeImporter(Importer *importer);

include/object.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@
2525
#define IS_NATIVE(value) isObjType(value, OBJ_NATIVE)
2626
#define AS_NATIVE(value) (((ObjNative *)AS_OBJ(value))->function)
2727

28+
// Macros for Modules
29+
#define IS_MODULE(value) isObjType(value, OBJ_MODULE)
30+
#define AS_MODULE(value) ((ObjModule *)AS_OBJ(value))
31+
2832
typedef enum {
2933
OBJ_STRING,
3034
OBJ_FUNCTION,
3135
OBJ_NATIVE,
36+
OBJ_MODULE,
3237
} ObjType;
3338

3439
struct Obj {
@@ -59,10 +64,17 @@ struct ObjNative {
5964
NativeFn function;
6065
};
6166

67+
struct ObjModule {
68+
Obj obj;
69+
ObjString *name;
70+
Table exports; // Symbols exported by this module
71+
};
72+
6273
ObjString *takeString(char *chars, int length);
6374
ObjString *copyString(const char *chars, int length);
6475
ObjFunction *newFunction();
6576
ObjNative *newNative(NativeFn function);
77+
ObjModule *newModule(ObjString *name);
6678
void printObject(Value value);
6779

6880
static inline bool isObjType(Value value, ObjType type) {

include/vm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "common.h"
1111
#include "value.h"
1212
#include "table.h"
13+
#include "importer.h"
1314

1415
#define FRAMES_MAX 64
1516
#define STACK_MAX (FRAMES_MAX * 256)
@@ -40,6 +41,7 @@ struct VM {
4041
size_t nextGC;
4142

4243
const char* source;
44+
Importer importer;
4345
};
4446

4547
typedef enum {

0 commit comments

Comments
 (0)