Text-file API
ASPL 0.7.0 · Current release
Current 0.7.0 operations, host support, examples, and failure rules.
On this page
Whole-file text API
Both builtins are supported in the browser and by native ASPL 0.7.0 execution. They require no import or unsafe marker. Using unsafe on either is a source error, unsafe-on-safe-call.
| Operation | Signature | Success |
|---|---|---|
اقرأ_ملف_نصي/read_text_file |
(string) -> result<string> |
Entire file as strict UTF-8 |
اكتب_ملف_نصي/write_text_file |
(string, string) -> result<unit> |
Exact replacement completed, no payload |
Reads preserve every content byte, including BOM, CRLF, NUL, and normalization. Empty files return success(""). Invalid UTF-8 returns invalid-utf8. Writes use the string's exact UTF-8 bytes, append no newline, and replace rather than append. Check ok before reading value or error; a successful write has no readable value.
The browser output display labels invisible controls such as BOM and NUL and displays CRLF as a line break. This safe representation does not change file contents. Use file downloads to compare exact bytes.
Per-operation host support
| Operation | Browser | Native |
|---|---|---|
| Read | Named virtual bytes in the current draft; no network or local disk access | Regular filesystem file; relative to process working directory or an absolute path |
| Write | Create or replace a flat virtual name; explicit Download saves bytes to disk | Stage in the destination directory, then atomically replace the final directory entry |
| Paths | Exact case-sensitive UTF-8 name, 1 through 255 bytes | Nonempty string without NUL; normal Linux path resolution |
| Per-file ceiling | 1048576 bytes, 1 MiB | 16777216 bytes, 16 MiB |
Native paths are not relative to the source file. There is no shell expansion of ~, variables, or wildcards, and no implicit parent-directory creation. Reads follow normal filesystem resolution, including symlinks, but reject directories, devices, and pipes as not-regular-file. Successful writes replace the final entry, including a final symlink, rather than following that final symlink. A failed write preserves the previous destination; a later trap does not undo a completed write.
Browser names reject /, backslash, NUL, control characters U+0000 through U+001F and U+007F through U+009F, and . or ... There are no directories. The store allows 64 files and 8388608 total bytes. Each run also has an 8388608-byte write-update transfer budget, counting name bytes, content bytes, and 64 bytes of overhead per write; repeated replacements consume that budget too. Read and write share these host constraints independently of the prose/source language.
Recoverable file errors
| Code | Meaning and applicability |
|---|---|
invalid-path |
Empty/NUL path on either host, or an invalid browser flat name |
not-found |
Missing virtual file, missing native read target or write parent |
permission-denied |
Native filesystem permission failure |
not-regular-file |
Native nonregular read or directory write target |
invalid-utf8 |
Read content is not strict UTF-8 |
file-too-large |
Read or write exceeds the host's per-file ceiling |
virtual-file-limit |
Browser file count, total bytes, or write-update transfer budget exceeded |
io-error |
Other host I/O failure |
unsupported-host |
The embedding host supplies no adapter for this operation; both published hosts supply adapters |
These are recoverable results, not source diagnostics or traps. Resource limits, cancellation, and allocation failure remain separate execution outcomes. A wrong-branch access can still trap. Successful writes before a later failure remain available.
Temporary run files and saved source
Browser virtual files belong to one draft's document-local run data. They survive switching drafts, same-tab reading navigation and Back, locale changes, expansion, and Reset. Reset restores the starting source and clears output/transcripts; it retains files. Refresh, reload, and new tabs lose the files, even when saved draft source returns. Source saving/export does not include run files.
Import files only after opening the intended draft. A whole import batch is validated before changes; replacing same names requires confirmation. Rejected or cancelled imports preserve existing files. Imports, removal, and clear are locked during a run, which uses a stable snapshot. File clear and draft deletion have their own confirmations.
Use the explicit Download button for each imported or successfully written file. Downloads preserve its exact name and bytes, including non-UTF-8 imported bytes. Importing helper.aspl as run data does not make it a native source module or enable browser source imports.
Complete examples and scope
The default read example needs one input line, missing.txt, and no imported file. Its not-found branch prints an error and returns 0. The write example needs no input or asset; it creates or replaces generated.txt with exactly generated\n, then prints Output: saved\n.
Execution: Browser and native · ASPL 0.7.0
- For the declared outcome, missing.txt must be absent. No file asset is required.
- For a successful read, open this new draft first, then import your UTF-8 data file into its Files control before Run; send its flat name.
Input lines: ["missing.txt"]
fn start_main() -> i64 {
print("File: ");
let name = read_line();
let content: result<string> = read_text_file(name);
if (content::ok) {
print(content::value);
} else {
print("error: ");
print(content::error::code);
print("\n");
}
return 0;
}
Expected outcomes
{
"browser": {
"check": "success",
"class": "success",
"output": "File: error: not-found\n",
"processStatus": 0
},
"native": {
"check": 0,
"status": 0,
"output": "File: error: not-found\n"
}
}Execution: Browser and native · ASPL 0.7.0
- No input or asset is required. Run creates or replaces generated.txt with generated followed by LF.
- Browser writes are temporary until explicitly downloaded. Native writes replace the destination in the process working directory.
Input: No input lines are required.
fn start_main() -> i64 {
print("Output: ");
let saved: result<unit> = write_text_file("generated.txt", "generated\n");
if (saved::ok) {
print("saved\n");
} else {
print("error: ");
print(saved::error::code);
print("\n");
}
return 0;
}
Expected outcomes
{
"browser": {
"check": "success",
"class": "success",
"output": "Output: saved\n",
"fileUpdates": [
{
"name": "generated.txt",
"content": "generated\n"
}
],
"processStatus": 0
},
"native": {
"check": 0,
"status": 0,
"output": "Output: saved\n"
}
}Read the practical guide before trying a successful read or saving generated bytes. Complete read and write pages retain the supplied Arabic and English variants. These APIs extend the historical MVP; the archived specification does not define their current host behavior.