Skip to content
Sandesh-inPublic
forked from scarp-lang/scarp

About

A next-generation programming language for software, systems, and intelligent computing.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Scarp

Build Beyond Boundaries.

Scarp is an experimental programming language implemented in Rust. This checkout implements the 0.0.5-alpha.1 source-modules prerelease, extending the 0.0.4-alpha.4 numerical/runtime milestone. It has finite binary64 values, a lexer, parser, name resolver, interpreter and command-line interface. Syntax and library APIs may change.

Use immutable bind and mutable var declarations, checked integers, finite floats, strings, booleans, conditionals, while/repeat loops, and explicit output streams. Typed funcra functions support named/default arguments, recursion, unit returns, purity, contracts, and bounded heap call frames. See the migration guide for older declaration syntax.

// My first Scarp program
print("Hello from Scarp!");
Hello from Scarp!

The documentation hub provides setup, tutorials, command and diagnostic references, Rust embedding, testing, troubleshooting, and compatibility guides. Start there for a reading path matched to your task.

Source modules organize programs with relative .srp imports, explicit aliases and public functions/scalar constants. Follow the import tutorial, then run the three-file example:

cargo run --locked --offline -- run examples/module_demo.srp
cargo run --locked --offline -- check examples/module_demo.srp

The tile and linear-algebra guide covers immutable two-axis values, transpose, matrix-vector/matrix products and tile arithmetic. Shared vector windows keep their visible-slice boundaries through all operations.

bind weights = tile([1.0, 2.0, -1.0, 3.0], 2, 2);
print(matvec(weights, [2.0, 1.0])); // [4.0, 1.0]

Automatic value retirement releases inaccessible scope values while preserving returned values, contracts and output snapshots. Independent runtime budgets bound work, calls, slots, snapshots and cumulative new numerical payload. These do not measure total process memory.

Existing numerical capabilities include compensated vector reductions, scaled norms, softmax, log-space operations, deterministic selection, categorical losses, one-hot targets and explicit loss gradients. See vectors, the numerical tutorial, and error repairs.

The latest published prerelease is 0.0.5-alpha.1, published from afe8b5380c9d6c4774162e51c6c9bc8b90901671 with verified Windows x64, Linux x64 and macOS ARM64 packages. Read the publication and verification record for source, CI, checksums and public-download evidence. The release preparation notes preserve the approved source snapshot; see release engineering for future releases.

The maintainer transferred this repository to scarp-lang/scarp. The migration record documents identity, history, release/download verification and updated clone instructions.

Build and run

Binary archives and checksums are available through GitHub Releases. See the 0.0.5-alpha.1 verification record for platform support, verification, and running an extracted package. The changelog records this version.

To build from source:

Install a stable Rust toolchain with Cargo using the instructions at rustup.rs. On Windows, use the MSVC toolchain and install the C++ build tools if the Rust installer requests them.

git clone https://github.com/scarp-lang/scarp.git
cd scarp
git switch main
cargo build --locked
cargo run -- run examples/hello.srp
cargo run -- run examples/arithmetic.srp
cargo run -- tokens examples/hello.srp
cargo run -- check examples/scopes.srp
cargo run -- --help
cargo run -- --version

The project has no third-party Rust dependencies. After installing Rust, the prototype can be built and tested offline with cargo build --offline and cargo test --offline.

To install the command from this checkout:

cargo install --path . --locked
scarp run examples/hello.srp
scarp tokens examples/hello.srp

Filenames with spaces should be quoted. Use scarp run -- -example.srp for a filename beginning with a dash. Source paths use the platform's native path encoding; source contents must be UTF-8. The .srp suffix is conventional, and the CLI does not reject other filename extensions.

What works now

  • print("text"); statements, executed in source order.
  • Multiple statements, empty strings, and empty or comment-only files.
  • Signed 64-bit integers with +, -, *, /, unary minus, and parentheses.
  • Operator precedence, left-associative binary operators, and checked arithmetic.
  • Immutable integer/string/boolean bindings with bind name = expression; and resolved names.
  • Explicit var bindings, assignment, and checked compound assignment.
  • Lexical block scopes, shadowing, and nearest-binding assignment.
  • Inferred primitive types, checked same-type assignment, and string value snapshots.
  • Boolean comparisons and short-circuit and, or, and not expressions.
  • Scoped if/elif/else statements with explicit boolean conditions.
  • while and counted repeat loops, nearest-loop break/continue.
  • Typed file-level funcra, positional/named/default arguments, forward and mutual recursion, explicit returns, verified purity, and executable contracts.
  • Relative source modules, public/private functions and scalar literal constants, explicit filesystem/in-memory loaders, cycle diagnostics and bounded graphs.
  • Heap call frames and seven deterministic CLI/embedding resource limits shared by run and check; see budgets.
  • Unicode text in strings and comments, Unicode whitespace, and LF or CRLF files.
  • Optional UTF-8 byte order mark at the very start of a file.
  • // comments to the end of the line, and flexible whitespace between tokens.
  • Escapes \\ (backslash), \" (double quote), \n (LF), \t (tab), and \r (CR).
  • run, check, tokens, --help/-h, and --version/-V commands.
  • Syntax errors with a code, filename, line, column, source excerpt, and help.

print appends a newline; write omits it. println remains a supported alias. Both accept zero or more comma-separated values. eprint and ewrite use stderr. See the output guide for exact bytes and embedding APIs. Physical line breaks inside a string are rejected; use \n instead. Identifiers use ASCII letters, digits, and underscores, cannot start with a digit, and are case-sensitive. Statements include declarations, assignments, blocks, if/elif/else decisions, and print calls. Escapes other than the five listed above are rejected.

The entire file is lexed, parsed, resolved, checked for primitive type consistency, and its selected execution path is evaluated before any program output is written. Source and semantic errors therefore produce no program output. Output stream failures propagate as errors; an output failure can occur after earlier statements have been written. A closed output pipe is treated as normal CLI termination.

print(1 + 2 * 3);           // 7
print((1 + 2) * 3);         // 9
print(-7 / 2);              // -3, division truncates toward zero
print(-9223372036854775808); // the minimum signed 64-bit integer

Integer overflow, division by zero, and out-of-range literals are errors in both debug and release builds. Grouping is limited to 64 nested parentheses; long binary chains use a flat syntax tree. Strings can be bound, copied, reassigned with the same type, and printed. Concatenation and mixed string/integer arithmetic are unsupported.

Booleans use true and false. Comparisons support same-type == and !=, and same-type numeric <, <=, >, >=. Readable not, and, and or operators require booleans; and and or short-circuit at runtime while all operands are checked for names and types during compilation. See the boolean design. Conditional statements select the first true if/elif body, or the optional else body. Every condition and body undergoes static checks; arithmetic executes only on the selected path. Start with the decisions tutorial.

check validates syntax, names, mutability, scopes, primitive types, and arithmetic without writing program output. It returns zero and remains silent on success. It evaluates selected loops, declarations, and assignments in fresh local storage, so reachable unused arithmetic failures are still reported. The Rust library's scarp::compile only parses and resolves; it does not evaluate arithmetic. There is no scarp compile CLI command.

tokens checks lexical validity without parsing or executing the file. It prints one token per line, including decoded string text, one-based line/column ranges, and half-open UTF-8 byte ranges. For the hello example, the first token is:

2:1..2:6  identifier(print)  [26..31]

An end-of-file token is always included. Columns count Unicode scalar values; terminal display widths for combining marks and wide characters can differ. Tabs are expanded to four spaces in error excerpts.

error[E0004]: expected ';', found <eof>
 --> example.srp:1:15
  |
1 | print("hello")
  |               ^
 = help: use print("text"); or print(1 + 2);

Exit codes are 0 for success, 1 for source, file, or output errors, and 2 for invalid command-line usage. Diagnostics go to standard error; program output and token listings go to standard output.

Library

The scarp library exposes lexer::lex, parser::parse, compile, evaluator::evaluate, interpreter::execute, and run. parse exposes syntax; compile validates syntax and resolves names into an immutable ResolvedProgram. check and interpreter::validate also evaluate without an output destination. evaluator::evaluate preserves an integer result, while evaluate_value returns an integer/float/string/boolean Value. execute and run validate all arguments before writing and return RunError. The output destination is explicit, making execution usable without redirecting process-wide standard output.

For multiple files, use modules::compile_file or an explicit modules::SourceLoader with modules::compile_with_loader. ModuleProgram owns its source map and offers separate check/execute methods. Source-string APIs keep their existing signatures and never load files implicitly. See module embedding.

let mut output = Vec::new();
scarp::run(r#"print("Hello from Scarp!");"#, &mut output).unwrap();
assert_eq!(output, b"Hello from Scarp!\n");

Development checks

cargo fmt --all -- --check
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
cargo test --locked --release
cargo build --locked
cargo run --locked -- run examples/hello.srp
cargo run --locked -- tokens examples/hello.srp

Tests cover source spans, escapes, Unicode, missing punctuation, invalid files, command-line usage, output failures, arithmetic boundaries, precedence, nesting, long expression chains, and all shipped examples. The complete check sequence, including rustdoc, is available as sh scripts/check.sh --offline or ./scripts/check.ps1 -Offline. See CONTRIBUTING.md for the development and PR workflow.

Prototype limits and planned roadmap

While loops and break/continue support iterative computations with explicit per-call budgets. See loops and limits.

The performance guide provides stage benchmarks and measured execution improvements. C/C++/Rust performance comparisons and native code generation remain future work.

This is a small interpreter. It loads bounded source graphs into memory and reports the first error. Functions are interpreted using heap call frames. It has immutable numerical vectors and tiles and a first source-module system. General-purpose collections, user-defined types, runtime module globals, re-exports, a standard library, a package manager, native code generation and self-hosting require further milestones. It does not execute arbitrary Rust code. The syntax and library API are experimental and may change.

Read the implemented language reference and architecture notes for precise rules. Runnable programs in examples/ are paired with .stdout files and checked by the test suite.

Future work is planned, in this order:

  1. Module tooling, additional conformance and source navigation.
  2. Explicit constant-expression and library organization design.
  3. User-defined types and callable values.
  4. A compiler backend and developer tooling.
  5. Domain-specific libraries.

The remaining capabilities require separate milestones. Integer expressions are implemented as specified in the expression design. Integer, finite float, vector, string, and boolean bindings are implemented in this checkout. Read the variable reference and staged variable design. The preparation notes preserve the original module contract; the publication record confirms the released source and checksums. Tensors and native backends require separate integration decisions.

The function integration in PR #41 integrated typed calls, defaults, contracts, and bounded heap frames into main. Beta.3 published that work with CLI resource controls. Beta.2 binaries do not contain functions. Release notes describe immutable snapshots; branch names can move.

License

Original project code is licensed under the Apache License 2.0.

About

A next-generation programming language for software, systems, and intelligent computing.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages