P1SCode Language Guide¶
This is a practical, guide-style introduction to writing P1SCode (.p1s): what you can type today, how it maps to a generated Rust app, and where the real limits are. It complements P1SCode Toolchain Workflow (commands and CI), P1SCode Status And Scope (supported vs preview), P1SCode — Language reference (concise) (compact syntax/builtins tables), P1SCode — Modules, imports, and the std story (imports / virtual std story), and P1SCode — Architecture (language & SDK) (how the SDK stack fits together).
Note
P1SCode is still transpiler-driven: most “language” behavior is whatever SDK/p1sdk/p1sc.py emits, checked by fixtures (SDK/p1sdk/fixtures/) and the shared parser crate SDK/p1sdk/p1sc_syntax. If this guide disagrees with a fixture or the transpiler, treat the code as truth and open a doc fix.
1. What you are writing¶
Files use the extension
.p1s.Entry is usually a
func main() -> int { ... }(see below formainand return codes).The host tool
p1sc.pyreads your sources, mergesimport "…"graphs, tokenizes, transpiles to Rust, and feeds Cargo using thep1scode-apptemplate pattern.On device,
/bin/p1sc.elfcan lex+parse (after the same import merge rules) for a fast syntax check; it does not compile your program by itself.
2. Your first program¶
Save as hello.p1s:
import "os/sys";
func main() -> int {
sys.print("hello, P1SCode");
return 0;
}
import "os/sys"— virtual module: the transpiler wiressys.printand friends for you (noos/sysfile on disk).func main() -> int— main becomes a Rustpub extern "C" fn mainwith a numeric process exit code (return 0→ success).
From the repo root, validate without building:
python SDK/p1sdk/p1sc.py check hello.p1s --project-root .
For a full template (local library + build.ps1), use SDK/template/p1scode-app/ — that is the best “real project” starting point.
3. How a small project is structured¶
Typical layout (matches the official template):
my-app/
main.p1s # entry; imports other modules
lib/
helpers.p1s # sibling module
import "lib/helpers"— resolves next to the current file’s directory: looks forhelpersorhelpers.p1s.import "os/sys",import "std/…",import "p1/…"— virtual prefixes: not real paths; they tell the toolchain you want the built-in / SDK-facing surface (see §9).
After merging, file-import lines disappear from the compilation unit (same as p1sc.py and p1sc.elf).
4. Functions¶
func add(a: int, b: int) -> int {
return a + b;
}
func main() -> int {
var x = add(1, 2);
return x;
}
Name then
(parameter list).Optional
: typeon parameters and optional-> return_type(ofteninttoday).`main is special-cased in the transpiler (see §2).
5. Variables and assignment¶
var x = 0;
let y = 10; // same as var for transpile output (both become `let mut` in Rust)
x = x + 1;
Optional type on declarations (common in signatures; in bodies the transpiler often infers from usage):
var n: int = 5;
Type names you will see in examples and signatures:
In |
Emitted Rust (typical) |
|---|---|
|
|
|
|
|
|
There is no separate user manual for the type system yet: treat types as hints for the transpiler and the generated boilerplate, not a full checked language spec.
6. Literals and operators¶
Literals (as modeled in the shared AST):
Integers:
42, hex0xFF.Floats:
3.14(decimal point form).Strings:
"text"with escapes like\",\n,\t,\\,\0(lexer-level; transpiler may re-escape for Rust).Booleans:
true,false.null.
Operators (typical uses):
Arithmetic:
+,-,*,/,%Comparison:
==,!=,<,>,<=,>=Logical:
&&,||,!Unary
-on numbers
Keywords reserved by the profile (used as names only if you want confusing errors) include:
func, var, let, const, if, else, while, for, loop, return, break, continue, struct, enum, import, true, false, null, and, or, not
— see SDK/p1sdk/p1scode_profile.json.
7. Control flow¶
If / else:
if x < 3 {
sys.print("small");
} else {
sys.print("ok");
}
While:
while x < 10 {
x = x + 1;
}
Loop (infinite):
loop {
if done { break; }
}
For — parsed in p1sc_syntax; prefer matching a fixture or keeping loops simple until you need it.
Return / break / continue — use as in C-like languages; main should return an int exit code.
8. Imports: files vs virtual¶
Form |
Meaning |
|---|---|
|
Project file |
|
Virtual — |
|
Virtual namespace (reserved pattern) |
|
Virtual namespace (reserved pattern) |
Syntax must match: import "path" with optional ;. Malformed lines are diagnostics P1SC-EIMP003 on the host; missing files P1SC-EIMP001.
std/io (virtual import; import "std/io")¶
Use this when you want io.* without import "os/sys". The import line is removed after merge (like os/sys).
Call |
Role |
|---|---|
|
Print line to stdout (fd 1) or stderr (fd 2); same shaping as |
|
Read one line from stdin (fd 0); see P1SCode — Modules, imports, and the std story §3. |
|
Read file as |
|
Write text via syscall 202; same as |
|
Binary file I/O; same as |
|
Same as |
9. Built-in surfaces the transpiler knows¶
These are not a frozen standard library contract — they are what p1sc.py recognizes today. Names mirror Rust cstd / helpers where possible.
sys (requires import "os/sys" in entry-oriented samples)¶
Call |
Role |
|---|---|
|
Print line (string literal fast path, or debug-format) |
|
Read file as string (UTF-8-ish chunk loop) |
|
Write bytes via syscall 202 |
|
Sleep ms |
|
Exec helper |
math¶
Call |
Role |
|---|---|
|
Random |
str¶
Call |
Role |
|---|---|
|
String concatenation |
fs (binary vs text variants)¶
Call |
Role |
|---|---|
|
Read raw |
|
Read |
|
Write (expects byte-oriented |
crypto (maps to cstd::crypto)¶
Call |
Role |
|---|---|
|
Random bytes |
|
SHA-256 |
|
HMAC |
|
Hex encode |
ui (windowing sample surface)¶
Call |
Role |
|---|---|
|
Open window |
|
Poll events |
|
Event query |
Window / framebuffer helpers (on a value you stored from create_window): .get_framebuffer(), .set_pixel(x, y, color), .draw() — see transpiler for exact arity.
10. Arrays, maps, and “extra” syntax¶
The transpilier has special cases for array / map-like literals in Rust (e.g. [ → alloc::vec![ in some contexts, { may become map-like construction). If you need this, copy a working pattern from SDK/p1sdk/fixtures/ or from a known sample — this is the least documented corner of the surface.
11. How to learn safely¶
Run check often:
python SDK/p1sdk/p1sc.py check your.p1s --project-root .Read fixtures under
SDK/p1sdk/fixtures/— each.p1sis a pinned behavior example.Run the fixture harness:
python SDK/p1sdk/run_fixtures.pyPrefer the template
SDK/template/p1scode-app/for structure (imports,build.ps1, package output paths).
12. What this guide is not¶
Not a formal grammar (use
p1sc_syntaxparser + lexer for that).Not a promise of stable ABI or stable std — see P1SCode Status And Scope.
Not a replacement for Rust or Cargo docs for the generated
apps/p1scode_appcrate.
When you add a user-visible language feature, add a fixture and a short subsection here so the next person finds it.
See also¶
P1SCode Toolchain Workflow — flags, JSON diagnostics,
p1sc.elf,dump_tokensnewdocs/p1scode-m1.md— M1 platform contract and ramdisk pathsSDK/template/p1scode-app/README.md— copy-paste quick start