Write in Arabic. Run here.

Loading the editor…

This program sums the integers from 1 to 10. On success it prints 55 and returns status 0. Edit the source, then press Run.

Compilation and execution happen in your browser. Source is not sent to a server.

Continue to learning the language

Learn from one program

Consult the contract

Program and process status

One .aspl file contains function definitions and foreign declarations. The required الرئيسية / main takes no parameters and returns i64. Valid statuses are 0..255; any other value traps instead of truncating.

Accepted: top-level functions. Rejected: global bindings, statements outside functions, a missing entry function, or calling it from source.

hello-ar · ASPL 0.1.0

Browser and native

دالة الرئيسية() -> صحيح64 {
    أرجع 0;
}

Expected outcomes and literal output

browser: check success; success / main 0; stdout ""
native: check 0; success / status 0; stdout ""
Download source Open in the editor
aspl check hello.aspl
aspl run hello.aspl
hello-en · ASPL 0.1.0

Browser and native

fn main() -> i64 {
    return 0;
}

Expected outcomes and literal output

browser: check success; success / main 0; stdout ""
native: check 0; success / status 0; stdout ""
Download source Open in the editor
aspl check hello.aspl
aspl run hello.aspl

Reasons and outcomes: missing-entry-function, invalid-entry-signature, entry-call-not-allowed; trap / invalid-process-status

Host applicability: shared

Normative release limitations

Source notation

Source is strict UTF-8 under Unicode 17.0. Identifiers are case-sensitive NFC names, each using one Arabic or Latin script. English keywords are exact aliases and may mix. Executable digits, operators and punctuation use ASCII. Display order does not change source bytes.

Accepted: Arabic and English keywords in one program. Rejected: unconverted non-ASCII digits outside strings and comments, or an identifier mixing scripts. The editor makes invisible controls visible.

Reasons and outcomes: non-ascii-digit, mixed-script-identifier

Host applicability: shared

Read and check the example Normative release limitations

Types and control flow

There are no implicit conversions. i64 is signed and overflow traps. f64 uses IEEE 754 binary64. Strings are immutable literal values; c_ptr is opaque and nullable. unit cannot be stored. Initialized bindings may infer their type. Names cannot shadow; parameters and bindings are immutable unless a local binding opts into mutation. if, while require boolean conditions, and return must match the declared result.

Accepted: assigning a mutable binding and using a comparison as a boolean condition. Rejected: uninitialized bindings, immutable assignment, or implicitly mixing numeric types.

sum-ar · ASPL 0.1.0

Browser and native

دالة الرئيسية() -> صحيح64 {
    متغير المجموع: صحيح64 = 0;
    متغير العدد: صحيح64 = 1;
    طالما (العدد <= 10) {
        المجموع = المجموع + العدد;
        العدد = العدد + 1;
    }
    إذا (المجموع == 55) {
        اطبع("55\n");
        أرجع 0;
    }
    أرجع 1;
}

Expected outcomes and literal output

browser: check success; success / main 0; stdout "55\n"
native: check 0; success / status 0; stdout "55\n"
Download source Open in the editor
aspl check sum-ar.aspl
aspl run sum-ar.aspl
sum-en · ASPL 0.1.0

Browser and native

fn main() -> i64 {
    var المجموع: i64 = 0;
    var العدد: i64 = 1;
    while (العدد <= 10) {
        المجموع = المجموع + العدد;
        العدد = العدد + 1;
    }
    if (المجموع == 55) {
        print("55\n");
        return 0;
    }
    return 1;
}

Expected outcomes and literal output

browser: check success; success / main 0; stdout "55\n"
native: check 0; success / status 0; stdout "55\n"
Download source Open in the editor
aspl check sum-en.aspl
aspl run sum-en.aspl
sum-mixed · ASPL 0.1.0

Browser and native

fn الرئيسية() -> صحيح64 {
    متغير المجموع: صحيح64 = 0;
    متغير العدد: صحيح64 = 1;
    طالما (العدد <= 10) {
        المجموع = المجموع + العدد;
        العدد = العدد + 1;
    }
    إذا (المجموع == 55) {
        print("55\n");
        return 0;
    }
    أرجع 1;
}

Expected outcomes and literal output

browser: check success; success / main 0; stdout "55\n"
native: check 0; success / status 0; stdout "55\n"
Download source Open in the editor
aspl check sum-mixed.aspl
aspl run sum-mixed.aspl

Reasons and outcomes: immutable-assignment, type-mismatch; trap / integer-overflow

Host applicability: shared

Normative release limitations

Functions

Functions have unique top-level names, typed parameters and a typed result. Calls pass values by value. Definition order does not matter and recursion is allowed. Every path in a non-unit function must return a value. The factorial example returns status 120 without output.

Accepted: calling a later definition or recursing. Rejected: overloading, nested functions, wrong call arity, or a missing return path.

functions-ar · ASPL 0.1.0

Browser and native

دالة مضروب(القيمة: صحيح64) -> صحيح64 {
    إذا القيمة <= 1 {
        أرجع 1;
    }
    أرجع القيمة * مضروب(القيمة - 1);
}

دالة الرئيسية() -> صحيح64 {
    أرجع مضروب(5);
}

Expected outcomes and literal output

browser: check success; success / main 120; stdout ""
native: check 0; success / status 120; stdout ""
Download source Open in the editor
aspl check functions-ar.aspl
aspl run functions-ar.aspl
functions-en · ASPL 0.1.0

Browser and native

fn مضروب(القيمة: i64) -> i64 {
    if القيمة <= 1 {
        return 1;
    }
    return القيمة * مضروب(القيمة - 1);
}

fn main() -> i64 {
    return مضروب(5);
}

Expected outcomes and literal output

browser: check success; success / main 120; stdout ""
native: check 0; success / status 120; stdout ""
Download source Open in the editor
aspl check functions-en.aspl
aspl run functions-en.aspl

Reasons and outcomes: argument-count-mismatch, type-mismatch, missing-return

Host applicability: shared

Normative release limitations

Diagnostics and correction

A diagnostic carries a stable reason key, severity, typed arguments, source spans and an optional edit. Language changes wording only. Warnings do not block execution. Direct execution maps findings to source; built programs contain no source map. The first example assigns an immutable binding. The correction replaces دع / let with متغير / var and normally returns status 1.

Accepted: correct the binding and check again. Rejected: interpreting every nonzero status as a source error. Use the outcome class and diagnostic to distinguish failures.

diagnostic-ar · ASPL 0.1.0

Browser and native

دالة الرئيسية() -> صحيح64 {
    دع قيمة = 0;
    قيمة = 1;
    أرجع قيمة;
}

Expected outcomes and literal output

browser: check source-error; source-error / immutable-assignment; stdout ""
native: check 1; source-error / status 1 / immutable-assignment; stdout ""
Download source Open in the editor
aspl check diagnostic-ar.aspl
diagnostic-en · ASPL 0.1.0

Browser and native

fn main() -> i64 {
    let قيمة = 0;
    قيمة = 1;
    return قيمة;
}

Expected outcomes and literal output

browser: check source-error; source-error / immutable-assignment; stdout ""
native: check 1; source-error / status 1 / immutable-assignment; stdout ""
Download source Open in the editor
aspl check diagnostic-en.aspl
corrected-ar · ASPL 0.1.0

Browser and native

دالة الرئيسية() -> صحيح64 {
    متغير قيمة = 0;
    قيمة = 1;
    أرجع قيمة;
}

Expected outcomes and literal output

browser: check success; success / main 1; stdout ""
native: check 0; success / status 1; stdout ""
Download source Open in the editor
aspl check corrected-ar.aspl
aspl run corrected-ar.aspl
corrected-en · ASPL 0.1.0

Browser and native

fn main() -> i64 {
    var قيمة = 0;
    قيمة = 1;
    return قيمة;
}

Expected outcomes and literal output

browser: check success; success / main 1; stdout ""
native: check 0; success / status 1; stdout ""
Download source Open in the editor
aspl check corrected-en.aspl
aspl run corrected-en.aspl

Reasons and outcomes: source-error / immutable-assignment; success / main 1

Host applicability: shared

Normative release limitations

Safe output

The only builtin signature is اطبع / print: (string) -> unit. It writes string bytes in order, including NUL, without an automatic newline or flush. Add \n explicitly. Neither alias can be redefined. The browser safely displays output bytes without interpreting them as page markup.

Accepted: one string, including an empty string. Rejected: a number, multiple arguments, or storing the result.

Writing is synchronous; an empty string does not touch the host. Native output retries interrupted writes and continues short writes. Output accepted before failure remains visible. There is no special SIGPIPE handler; a closed pipe may terminate the process through that signal. If the environment ignores or blocks it and writing returns EPIPE, the result is a host failure with status 8.

output-ar · ASPL 0.1.0

Browser and native

دالة الرئيسية() -> صحيح64 {
    اطبع("مرحبا\n");
    أرجع 0;
}

Expected outcomes and literal output

browser: check success; success / main 0; stdout "مرحبا\n"
native: check 0; success / status 0; stdout "مرحبا\n"
Download source Open in the editor
aspl check output-ar.aspl
aspl run output-ar.aspl
output-en · ASPL 0.1.0

Browser and native

fn main() -> i64 {
    print("مرحبا\n");
    return 0;
}

Expected outcomes and literal output

browser: check success; success / main 0; stdout "مرحبا\n"
native: check 0; success / status 0; stdout "مرحبا\n"
Download source Open in the editor
aspl check output-en.aspl
aspl run output-en.aspl

Reasons and outcomes: type-mismatch, argument-count-mismatch; host-failure / host-operation-failed / write-program-output; limit-stop / output-limit

Host applicability: shared

Normative release limitations

Linux commands and phases

The tool accepts one source file. check validates source, run executes in-process, and build atomically publishes a validated ELF program. Check and build do not open program libraries. Building invokes no C compiler or linker. Built programs run independently of the tool installation.

Accepted: diagnostic options before the command and one source path after it. Rejected: multiple sources, public bytecode output, or program arguments. Use -- before a path starting with a dash.

Reasons and outcomes: 0 success; 1 source-error; 2 usage-error; 3 policy-rejection; 4 load-failure; 5 trap; 6 limit-stop; 7 cancelled; 8 host-failure; 9 internal-failure

Host applicability: native

aspl --diagnostic-language=en check hello.aspl
aspl run hello.aspl
aspl build -o hello hello.aspl
./hello
Read and check the example Normative release limitations

Host and execution limits

The browser runs bytecode locally and applies a ceiling of 10000000 instructions per run. The following loop ends with limit-stop at that ceiling. The table lists both host limits. Units are MiB = 1048576 bytes and KiB = 1024 bytes. Here none means no product ceiling and n/a means not applicable.

Accepted: running the common language in the browser. Rejected: a foreign import even if unused. Do not send the infinite-loop example to native execution.

Fixed resource ceilings
Resource Native Browser
Source bytes16 MiB1 MiB
Lexical items1048576131072
Syntax nodes1048576131072
Syntactic nesting256128
Compiler working memory512 MiB128 MiB
Bytecode bytes64 MiB8 MiB
Functions655364096
Foreign imports40960
Integer constants1048576131072
Float constants1048576131072
String references1048576131072
String bytes16 MiB2 MiB
Bytecode instructions4194304524288
Registers per function655368192
Executed instructionsnone10000000
Runtime frames4096512
Runtime value slots1048576131072
VM-owned execution memory256 MiB64 MiB
Captured outputnone256 KiB
Check wall timenone2 s
Run wall timenone3 s
WebAssembly linear memoryn/a256 MiB
Concurrent worker jobsn/a1

Source includes every byte read, including a leading byte-order mark. Compiler memory includes all live compilation allocations. Execution memory includes frames, slots and C-string loans, excluding immutable program storage, libraries and foreign allocations. A structural ceiling wins over a memory ceiling at the same operation. Allocation failure below the ceiling is host-failure / allocation-failed.

The check clock starts when the loaded worker accepts the job; the run clock starts when it accepts execution after a successful check. Loading counts against neither clock. The first observed ceiling determines the outcome; a deadline terminates the worker with time-limit. The output ceiling rejects the entire crossing write and retains prior output as partial. Native execution has no product instruction, time or output ceiling, subject to the instruction counter's representational maximum.

For serialized details, read the bytecode contract and runtime value model. Bytecode is private and versioned, not a public compatibility interface.

limit-ar · ASPL 0.1.0

Browser only

دالة الرئيسية() -> صحيح64 {
    طالما صواب {}
    أرجع 0;
}

Expected outcomes and literal output

browser: check success; limit-stop / execution-instruction-limit / ceiling 10000000; stdout ""
Download source Open in the editor
limit-en · ASPL 0.1.0

Browser only

fn main() -> i64 {
    while true {}
    return 0;
}

Expected outcomes and literal output

browser: check success; limit-stop / execution-instruction-limit / ceiling 10000000; stdout ""
Download source Open in the editor

Reasons and outcomes: policy-rejection / foreign-imports-not-supported; limit-stop / execution-instruction-limit

Host applicability: browser

Normative release limitations

Normative limitations

Release 0.1.0 limitations from manifest requirements tagged as limitations. Each identifier links to its owning reference text.

ASPL-SEMANTIC-0403
The ASPL MVP has five storable types; strings are immutable and originate only from literals.
ASPL-SEMANTIC-0404
The ASPL MVP has five storable types; strings are immutable and originate only from literals.
ASPL-SEMANTIC-0405
The ASPL MVP has five storable types; strings are immutable and originate only from literals.
ASPL-SEMANTIC-0406
The ASPL MVP has five storable types; strings are immutable and originate only from literals.
ASPL-SEMANTIC-0407
The ASPL MVP has five storable types; strings are immutable and originate only from literals.
ASPL-SEMANTIC-0189
The ASPL MVP accepts one source file and has no modules, package system, or program arguments.
ASPL-BYTECODE-0531
ASPL bytecode is private and version-matched, not a stable public VM ABI.
ASPL-BYTECODE-0532
ASPL bytecode is private and version-matched, not a stable public VM ABI.
ASPL-BYTECODE-0533
ASPL bytecode is private and version-matched, not a stable public VM ABI.
ASPL-BYTECODE-0534
ASPL bytecode is private and version-matched, not a stable public VM ABI.
ASPL-BYTECODE-0535
ASPL bytecode is private and version-matched, not a stable public VM ABI.
ASPL-CLI-0605
Native execution does not sandbox unsafe foreign code.
ASPL-CLI-0606
Native execution does not sandbox unsafe foreign code.
ASPL-CLI-0607
Native execution does not sandbox unsafe foreign code.
ASPL-CLI-0608
Native execution does not sandbox unsafe foreign code.
ASPL-BROWSER-0347
The browser output builtin creates no foreign import.
ASPL-BROWSER-0348
The browser output builtin adds no filesystem bridge.
ASPL-BROWSER-0349
The browser output builtin adds no network bridge.
ASPL-BROWSER-0350
The browser output builtin adds no server bridge.
ASPL-DIST-0109
The first native target is x86-64 Linux with glibc 2.34 or later.
ASPL-DIST-0144
SHA-256 provides integrity only, without publisher authentication or release signing.
ASPL-PERF-0161
The build and browser performance claims apply only to the specified host, protocol, and pinned browsers.
ASPL-CONFORMANCE-0672
The ASPL MVP makes no production-readiness claim.
ASPL-CONFORMANCE-0673
The ASPL MVP makes no full-C-replacement claim.
ASPL-CONFORMANCE-0674
The ASPL MVP promises no security-support duration.
ASPL-CONFORMANCE-0675
The ASPL MVP makes no stable-public-bytecode claim.

Understand the limits of C

The two adapters and the C-string loan

On x86-64 Linux with glibc, an ASPL native program can load any shared library accepted by the glibc dynamic loader and call a named function when its exact C type matches a supported foreign adapter profile. The MVP supports int(const char *) and double(double). Library availability, pointer validity, and foreign-function behavior remain the program's responsibility.

Accepted: nonempty literal library and symbol names without NUL, with both unsafe markers. Rejected: duplicate library/symbol pairs, mismatched signatures, or a missing marker.

Adapter سي_صحيح__مؤشر_محرف_ثابت / c_int__const_char_ptr maps (string) -> i64 to int (*)(const char *). Before entering C, it rejects a string containing NUL, copies the bytes and appends the terminator. The loan ends when the function returns. C may read only during the call and may neither modify nor retain the pointer. The int result converts by value; negative values remain ordinary data.

Adapter سي_مزدوج__مزدوج / c_double__double maps (f64) -> f64 to double (*)(double). It passes binary64 values, canonicalizes returned NaN and restores the floating-point environment. Neither adapter inspects errno, exception flags or library error conventions.

The commands check and build validate declarations without opening libraries. Execution prepares every import before the entry function, ordered by library bytes, symbol bytes, then adapter ID. Each name opens once with RTLD_NOW | RTLD_LOCAL, followed by lookup using dlsym and dlerror. Names pass unchanged under the glibc loader rules. The first failure prevents entry and closes opened handles in reverse order.

For puts, download the source, check it, then run on the native host. The library function adds the newline. Check a negative result yourself and do not use its unspecified positive value as the process status. Loan allocation failure is a host failure; foreign crashes or retention of the pointer are outside the trap guarantees.

puts-ar · ASPL 0.1.0

Native only

Native only. The browser rejects this import with policy-rejection / foreign-imports-not-supported before execution, even if unused.

غير_آمن خارجي اطبع_سطر(رسالة: نص) -> صحيح64
    = سي_صحيح__مؤشر_محرف_ثابت("libc.so.6", "puts");

دالة الرئيسية() -> صحيح64 {
    دع النتيجة = غير_آمن اطبع_سطر("مرحبا");
    إذا النتيجة < 0 { أرجع 1; }
    أرجع 0;
}

Expected outcomes and literal output

browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout ""
native: check 0; success / status 0; stdout "مرحبا\n"
Download source Check browser rejection
aspl check puts-ar.aspl
aspl run puts-ar.aspl
puts-en · ASPL 0.1.0

Native only

Native only. The browser rejects this import with policy-rejection / foreign-imports-not-supported before execution, even if unused.

unsafe foreign اطبع_سطر(رسالة: string) -> i64
    = c_int__const_char_ptr("libc.so.6", "puts");

fn main() -> i64 {
    let النتيجة = unsafe اطبع_سطر("مرحبا");
    if النتيجة < 0 { return 1; }
    return 0;
}

Expected outcomes and literal output

browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout ""
native: check 0; success / status 0; stdout "مرحبا\n"
Download source Check browser rejection
aspl check puts-en.aspl
aspl run puts-en.aspl
double-ar · ASPL 0.1.0

Native only

Native only. The browser rejects this import with policy-rejection / foreign-imports-not-supported before execution, even if unused.

غير_آمن خارجي جذر(قيمة: عائم64) -> عائم64
    = سي_مزدوج__مزدوج("libm.so.6", "sqrt");

دالة الرئيسية() -> صحيح64 {
    دع النتيجة = غير_آمن جذر(4.0);
    إذا النتيجة == 2.0 { أرجع 0; }
    أرجع 1;
}

Expected outcomes and literal output

browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout ""
native: check 0; success / status 0; stdout ""
Download source Check browser rejection
aspl check double-ar.aspl
aspl run double-ar.aspl
double-en · ASPL 0.1.0

Native only

Native only. The browser rejects this import with policy-rejection / foreign-imports-not-supported before execution, even if unused.

unsafe foreign جذر(قيمة: f64) -> f64
    = c_double__double("libm.so.6", "sqrt");

fn main() -> i64 {
    let النتيجة = unsafe جذر(4.0);
    if النتيجة == 2.0 { return 0; }
    return 1;
}

Expected outcomes and literal output

browser: check policy-rejection; policy-rejection / foreign-imports-not-supported; stdout ""
native: check 0; success / status 0; stdout ""
Download source Check browser rejection
aspl check double-en.aspl
aspl run double-en.aspl

Reasons and outcomes: unknown-foreign-adapter, foreign-signature-mismatch, invalid-foreign-library-name, invalid-foreign-symbol-name, duplicate-foreign-target, unsafe-required-on-foreign-declaration, unsafe-required-on-foreign-call; load-failure / foreign-library-open-failed, foreign-symbol-lookup-failed; trap / foreign-string-contains-nul; host-failure / allocation-failed; policy-rejection / foreign-imports-not-supported

Host applicability: native

Normative release limitations

Move to Linux

Check the host first

The target is baseline Linux x86-64 with glibc 2.34 or later. Results must be Linux, x86_64 and glibc 2.34 or later. Failure to identify GNU libc does not establish compatibility. See the normative host limitations.

uname -s
uname -m
getconf GNU_LIBC_VERSION
Normative release limitations

Archive and verification

The 0.1.0 project release is published. Download aspl-0.1.0-x86_64-linux-gnu.tar.xz; it is 126468 bytes with SHA-256 e022c777a6e3b61f721fdd02b0adb16a5a0dec25724b9daa545f476793d8fe61. The evidence bundle records both the passing checks and the release owner's accepted evidence omissions. This publication therefore does not claim complete official ASPL MVP conformance.

The download directory contains the archive, SHA256SUMS and the licenses. The matching directory inside the archive contains only aspl, LICENSE-MIT, LICENSE-APACHE and THIRD-PARTY-NOTICES. Licensing is a choice of MIT OR Apache-2.0.

Download the archive and checksum into the same directory. The checksum file has one line with 64 lowercase hex digits, two spaces, the filename and a newline. Verification must report aspl-0.1.0-x86_64-linux-gnu.tar.xz: OK before extraction. The checksum checks integrity and does not prove publisher identity.

This archive includes Unicode notices because the tool incorporates derived Unicode tables. Read the complete texts: MIT, Apache-2.0, and third-party notices.

Use a fresh download directory for each version. Inspect the listing before extraction; it must match the directory, files and modes described here. Stop if any command fails or the listing or version differs, and do not continue to the install commands.

sha256sum --check SHA256SUMS &&
tar -tvJf aspl-0.1.0-x86_64-linux-gnu.tar.xz

tar -xJf aspl-0.1.0-x86_64-linux-gnu.tar.xz &&
./aspl-0.1.0-x86_64-linux-gnu/aspl --version
Normative release limitations

Install the tool and verify PATH

The extracted tool must print aspl 0.1.0. Directory and tool modes are 0755; licenses use 0644. The archive has no links, absolute paths or parent traversal. Choose one installation location. The default path is user-owned and needs no administrator access.

The command command -v aspl must resolve to $HOME/.local/bin/aspl. Otherwise use export PATH="$HOME/.local/bin:$PATH" in the current shell. To persist it, manually add that line to ~/.bashrc for Bash or ~/.zshrc for Zsh. For Fish, use fish_add_path "$HOME/.local/bin". Open a new shell and check the path and version again.

For administrator-managed installation, after the same verification, replace the two install commands with sudo install -m 0755 aspl-0.1.0-x86_64-linux-gnu/aspl /usr/local/bin/aspl. Check the resolved path so an older copy does not mask the chosen executable.

test "$(./aspl-0.1.0-x86_64-linux-gnu/aspl --version)" = "aspl 0.1.0" &&
install -d "$HOME/.local/bin" &&
install -m 0755 aspl-0.1.0-x86_64-linux-gnu/aspl "$HOME/.local/bin/aspl"
command -v aspl
aspl --version
Normative release limitations

Upgrade, rollback and uninstall

To upgrade, repeat the host check, download, verification, extraction and extracted-version check for the new release, then replace the tool with the same install command. To roll back, follow those steps with a chosen archived version and its checksum. Published versions are immutable. There is no automatic backup; retain archives for offline rollback. Only the newest release receives fixes before 1.0.

Uninstall removes only the selected executable, leaving shell configuration, source, built programs and archives. Remove only the path you selected.

After removal, run command -v aspl to detect another installed copy on your path.

rm -- "$HOME/.local/bin/aspl"

For the administrator-managed location only: sudo rm -- /usr/local/bin/aspl

Normative release limitations
Return to the editor