P1SCode — Modules, imports, and the std story¶
This page is the contract-oriented story for how modules work today and how virtual (“std-like”) namespaces are reserved for the future. It complements the tutorial tone of P1SCode Language Guide and the stack view in P1SCode — Architecture (language & SDK).
1. Two kinds of imports¶
1.1 File imports (project modules)¶
import "lib/bump";
import "utils/helpers";
Resolution (same rules in p1sc.py and p1sc_syntax::import_resolve):
Paths are relative to the directory of the file that contains the import.
Try
join(base_dir, target)as a path, then the same path with.p1sappended.Cycles: revisiting an already-loaded path during merge yields an empty chunk for that edge (no infinite recursion).
After merge, the import "…" line is not present in the merged compilation unit; dependency text is prepended, then the importer’s non-import lines.
1.2 Virtual imports (no file on disk)¶
An import target is virtual if it starts with any of:
Prefix |
Role today |
|---|---|
|
Used in practice for |
|
Virtual merge (strip import line). Subpath |
|
Reserved for platform/SDK surface ( |
Implementation: _is_virtual_import in p1sc.py and is_virtual_import in SDK/p1sdk/p1sc_syntax/src/import_resolve.rs — keep them in sync when adding a prefix.
2. Why import "os/sys" but sys.print in code?¶
The string inside quotes is only the module path key for the import machinery and documentation. The transpiler recognizes sys, math, str, fs, crypto, ui, and (after import "std/io") io as top-level spellings in source (see P1SCode Language Guide §9).
So today:
import "os/sys"is the conventional way to say “I use the syscall-facingsyssurface.”There is no separate file that defines
sys; it is provided by codegen and boilerplate.
import "std/io" also introduces the io top-level (same convention as sys after import "os/sys") — see §3.
3. std/io — standard I/O module¶
This section defines std/io and the io.* surface. Virtual import behavior is unchanged (§3.1). The transpiler (p1sc.py transpile()) implements every io.* member in §3.3 (including io.read_line on stdin / fd 0).
3.1 Import¶
import "std/io";
Merge: line is removed (virtual import); like
os/sys, there is nostd/io.p1son disk.Intent: programs that
import "std/io"may callio.…APIs below without pulling inos/sysexplicitly for those calls.
3.2 Scope: what “I/O” means here¶
Stream / concept |
P1Start notes |
|---|---|
Standard output |
Process fd 1; line-oriented |
Standard input |
Process fd 0; |
Standard error |
Often fd 2; may start as alias of stdout for simple programs unless split is required. |
Filesystem |
Paths under the VFS; binary vs text is a real distinction (today: |
3.3 API surface (io.*)¶
Names and signatures are proposed; tweak only with a fixture + this doc update. Codegen status is noted per row.
Member |
Role |
Notes |
|---|---|---|
|
Print a line (string or debug-format) |
Implemented — mirrors |
|
Print to stderr (if distinct) |
Implemented — mirrors |
|
Read one line from stdin |
Implemented — |
|
Read entire file as text |
Implemented — same lowering as |
|
Read entire file as text |
Implemented — same lowering as |
|
Write text file |
Implemented — same lowering as |
|
Read file as raw bytes |
Implemented — same lowering as |
|
Write raw bytes |
Implemented — same lowering as |
|
Sleep |
Implemented — same lowering as |
|
Exec helper |
Implemented — same lowering as |
Non-goals for an initial std/io drop:
Buffered
stdiowith flush modes (can staysys-level later).Async I/O (language has no
asynccontract).
3.4 Relationship to sys and fs¶
Today (works in transpiler) |
Role |
|---|---|
|
Syscall-forward helpers; |
|
Binary vs text file emphasis. |
After std/io, io.read_file / io.write_file (and siblings) share codegen with sys/fs so behavior does not diverge without an RFC-style doc change.
3.5 Mapping: io.*, sys.*, and fs.*¶
You want (portable intent) |
Prefer |
|---|---|
Print line |
|
Print to stderr |
|
Read whole file as string |
|
Read raw bytes |
|
Write text file |
|
Write bytes |
|
Sleep / execute |
|
Read one line from stdin |
|
3.6 Implementation checklist (std/io)¶
When you extend io.* in p1sc.py:
[x] Add
io.token patterns mirroringsys./fs.(§3.3).[x] Add fixtures
std_io_print.p1s,std_io_read_line.p1s,std_io_print_err.p1s,std_io_sleep.p1s(import "std/io").[x] Update P1SCode — Language reference (concise) builtins table.
[x] Native
p1sc_syntax: merge + parse tests coverimport "std/io"(seeimport_resolve::virtual_import_std_io_stripped,fixture_std_io_*inlib.rs);p1sc.elfremains parse/check-only until a Rust transpiler exists — no ABI change forcheckwhen syntax is unchanged.[x] Document fd 0 /
io.read_lineinnewdocs/syscalls-reference.md(readrow).
4. Host-only: import_root / stdin¶
For unsaved buffers, Python supports --stdin-source, --stdin-path, and --stdin-import-root. The root frame of merge uses import_root as base_dir for resolving file imports; nested imports still use dirname(resolved path).
Native p1sc.elf exposes --import-root for the same root-frame semantics.
5. What “a P1SCode standard library” means (roadmap)¶
Not contract today:
A single
stdtree of.p1sshipped on the ramdisk that the compiler loads like Rust’sstd.
Current pattern:
Virtual prefixes declare intent and strip duplicate-import clutter after merge.
Builtin behavior is largely transpiler specials mapping to
cstd(and friends).Project code shares logic via file imports under
lib/(template pattern).
Recommended evolution:
Document each virtual submodule as it gets transpiler + (optional) parser support.
Add fixtures for every new
std/...orp1/...import path before claiming stability.Consider
SDK/lib/p1scode_std/(or similar) as real.p1sonly when the driver can load both virtual and file-based std without ambiguity—until then, prefer virtual + codegen for thin layers.
6. Checklist when adding a module story¶
[ ] Update
import_resolvevirtual set if new prefix.[ ] Update
p1sc.py_is_virtual_importto match.[ ] Teach transpiler (and language guide / reference) any new
xyz.surface.[ ] Add fixture
.p1s+cases.jsonorerror_cases.jsonas appropriate.[ ] Extend P1SCode — Language reference (concise) builtins table if user-facing.
See also¶
P1SCode — Architecture (language & SDK) — where merge lives in the stack
P1SCode Language Guide — hands-on imports and builtins
P1SCode — Language reference (concise) — compact builtins / syntax tables
P1SCode Toolchain Workflow — CLI flags and diagnostics