Skip to content

Latest commit

 

History

History
412 lines (312 loc) · 11 KB

File metadata and controls

412 lines (312 loc) · 11 KB

RedEX Language Reference

RedEX is a reference-driven programming-language design. Human-readable names make source approachable; permanent numeric references give declarations a stable identity that survives a rename.

Current implementation boundary: RedEXCompile provides the file type, tokenizer, snippets, formatting, outline/reference map, diagnostics, starter project, CLI, and a literal/io.print preview runner. Sections describing broader runtime behavior define the language direction and editor syntax; they do not claim the preview runner already compiles every example.

1. Files and project structure

File Purpose
*.RedEX RedEX source module
*.RedEXP Declarative RedEXCompile plugin manifest
*.rexdb RedEX database storage
*.rexv Reference/version history
REX.sig Project signature and identity
.redexcompile/project.json IDE-only linked-tool configuration

A small project can look like:

MyProject/
├─ REX.sig
├─ src/
│  └─ Main.RedEX
└─ data/
   └─ Accounts.rexdb

2. Permanent references

@module $"Main"[100] {
    let {displayName}[20]: string = "Ada";

    public fn {greet}[50]() -> void {
        io.print(f"Hello {displayName}");
    }
}
  • Main, displayName, and greet are readable names.
  • [100], [20], and [50] are stable numeric references.
  • A rename changes the name, not the permanent identity.
  • A reference must be unique within its declaration scope. The editor reports duplicate declaration references as RX-REF-002.

Reference-shaped syntax recognized by the editor includes:

Form Meaning
{Name}[20] Named declaration with permanent reference
${764[46]} Stable data reference
&{20[50]} Stable function/reference address
{$"Store"}[764]{ Database-style referenced block
{$$"Store"}[764]{ Project/global database-style referenced block

3. Modules, imports, and entry points

@module $"Main"[100] {
    use "redex/io";
    use "redex/fs" as fs;

    @entry
    public async fn {Main}[99]() -> void {
        io.print("Hello from RedEX");
    }
}
  • A normal .RedEX source file should declare one @module.
  • An executable module may contain one @entry function.
  • use imports a module; as supplies a local alias.
  • Visibility keywords are public, project, private, and the design also reserves internal for project-scoped APIs.

The editor reports a missing module declaration as RX-MODULE-001, more than one main module as RX-MODULE-002, and duplicate entry annotations as RX-CALL-001.

4. Comments

RedEX uses visually distinctive comment fences:

<-> This is an inline/fenced comment <->

>-<
This is a multiline comment block.
>-<

The tokenizer ignores brackets inside recognized comments. An unclosed multiline comment is RX-SYNTAX-005.

5. Values, mutability, constants, and literal casing

let {count}[20]: int = 0;
let mut {status}[21]: string = "ready";
const {MAX_RETRIES}[22]: int = 3;
let {enabled}[23]: bool = true;
let {ratio}[24]: float = 0.75;
let {nothing}[25]: null = null;

RedEX literals are lowercase: true, false, and null. Forms such as True, False, NULL, Null, NUL, and nullptr are deliberately diagnosed as RX-SYNTAX-001.

Numeric forms include decimal, floating point, hexadecimal (0xFF), and binary (0b1010).

6. Core types

The editor recognizes these core type words:

string char bool byte int float number null void any
table map set option result task channel bytes

Examples:

let {name}[30]: string = "RedEX";
let {letter}[31]: char = 'R';
let {payload}[32]: bytes = bytes.from("data");
let {anything}[33]: any = 42;

7. Collections, tuples, and ranges

let {scores}[40]: table<int> = [10, 20, 30];
let {uniqueIds}[41]: set<int> = set(1, 2, 3);
let {profile}[42]: map<string, string> = { "name": "Ada" };
let {pair}[43] = ("port", 4217);
let {exclusivePages}[44] = 1..10;
let {inclusivePages}[45] = 1..=10;

Generic type arguments use angle brackets. Collection behavior belongs to the production runtime; Monaco currently supplies syntax/bracket editing and the RedEX formatter preserves the structure.

8. Strings and interpolation

let {plain}[46]: string = "Hello";
let {raw}[47]: string = r"C:\project\file";
let {message}[48]: string = f"Hello {name}";
  • Normal strings use "…".
  • r"…" is highlighted as a raw string.
  • f"…" is highlighted as an interpolated string.
  • The preview runner evaluates simple named interpolation in io.print(f"…").

9. Functions and generics

public fn {add}[50](left: int, right: int) -> int {
    return left + right;
}

public fn {identity}[51]<T>(value: T) -> T {
    return value;
}

private fn {logInternal}[52](message: string) -> void {
    io.print(message);
}

Functions use fn, a referenced name, parameters, ->, and a return type. void means no returned value. Generic parameters follow the declaration name.

10. Conditions and pattern matching

if score >= 90 {
    io.print("A");
} else if score >= 80 {
    io.print("B");
} else {
    io.print("C");
}

let label = match status {
    200 => "ok",
    404 => "missing",
    _ => "other",
};

The tokenizer recognizes equality, comparison, boolean, arithmetic, assignment, null-coalescing, range, and arrow operators.

11. Loops

for item in items {
    io.print(f"{item}");
}

while connected {
    network.poll();
}

loop {
    if finished { break; }
    if shouldSkip { continue; }
}

12. Records, enums, traits, and implementations

public record {User}[60] {
    public {id}[61]: int,
    public {name}[62]: string,
}

public enum {Role}[63] {
    {Admin}[64],
    {Member}[65],
}

public trait {Display}[66] {
    fn {display}[67](self) -> string;
}

impl Display for User {
    fn {display}[68](self) -> string {
        return self.name;
    }
}

Records, enums, and traits appear in the Reference Outline with their stable references.

13. Options, results, and error propagation

fn {findUser}[70](id: int) -> option<User> {
    return none;
}

fn {parsePort}[71](text: string) -> result<int, string> {
    return int.parse(text);
}

let port = parsePort("4217")?;

option<T> represents a possibly absent value. some and none represent its states. result<T,E> represents success or recoverable failure; ok, fail, and ? are reserved for result flow.

14. Exceptions and cleanup

try {
    await service.connect();
} catch error {
    io.print(f"Connection failed: {error}");
} finally {
    service.close();
}

The design reserves try, catch, finally, and throw. Prefer typed result<T,E> for expected recoverable failures.

15. Async work, tasks, spawning, and channels

public async fn {loadUser}[72](id: int) -> task<User> {
    return await api.users.get(id);
}

let worker = spawn processQueue();
let events: channel<string> = channel.create();

async, await, spawn, task, and channel are reserved and highlighted. The full scheduler/channel runtime is beyond the current preview runner.

16. File and HTTP direction

let text = await fs.readText("README.md");
await fs.writeText("output.txt", text);

let response = await http.get("https://example.com/data.json");
let payload = await response.json();

These calls describe standard-library direction. They require the future production RedEX runtime; Help Write and the editor should not claim they executed in the preview.

17. Databases, mounts, transactions, and watches

mount db $"Accounts"[764]
from "data/Accounts.rexdb"
as accounts;

transaction [764] {
    accounts.Users.insert(user);
}

watch ${764[46]} as oldValue, newValue {
    io.print(f"Changed from {oldValue} to {newValue}");
}
  • mount, db, from, and as identify database storage.
  • transaction defines an atomic data operation.
  • watch observes a stable data reference.
  • ${764[46]} addresses referenced data rather than a changeable name.

18. Query direction

let activeUsers = select all from accounts.Users
    where enabled == true
    order name ascending
    first 10;

let total = select count from accounts.Users;

The language reserves select, where, order, ascending, descending, first, count, all, and with for query work.

19. Tests

@test
fn {addsNumbers}[90]() -> void {
    assert.equal(add(2, 3), 5);
}

@test is an annotation-style entry for the planned test runner. The current editor highlights annotations; production test execution remains a compiler/runtime milestone.

20. Formatting and diagnostics

RedEXCompile’s formatter:

  • normalizes line endings;
  • uses four-space indentation;
  • adjusts indentation around bracketed blocks;
  • reduces runs of blank lines;
  • preserves comment blocks; and
  • leaves stable numeric references unchanged.

Current diagnostic codes:

Code Meaning
RX-SYNTAX-001 Non-RedEX uppercase/null literal
RX-REF-002 Duplicate declaration reference
RX-MODULE-001 Suggested module declaration missing
RX-MODULE-002 More than one main module
RX-CALL-001 More than one entry point
RX-SYNTAX-003 Unexpected closing bracket
RX-SYNTAX-004 Unclosed opening bracket
RX-SYNTAX-005 Unclosed multiline comment

Errors display as red squiggles, Problems entries, and red glyphs beside line numbers.

21. CLI

redex new MyProject
redex check MyProject
redex format MyProject
redex run MyProject
redex build MyProject

The preview runner evaluates simple let/const literal declarations, interpolated strings, and io.print. Unsupported expressions are labeled rather than falsely reported as executed.

22. .RedEXP plugin language

.RedEXP is a separate declarative JSON format:

{
  "redexp": 1,
  "name": "My Plugin",
  "version": "0.1.0",
  "description": "Adds RedEX snippets.",
  "contributes": {
    "snippets": [
      {
        "language": "redex",
        "prefix": "hello",
        "description": "Insert a hello message",
        "body": "io.print(\"Hello\");"
      }
    ],
    "theme": { "accent": "#ed2d43" }
  }
}

Executable code, main, and scripts fields are rejected. Plugin metadata must match the public registry entry before a remote install succeeds.

23. Editor support vs. compiler support

Capability Current
File recognition and red-X icon Yes
Syntax highlighting Yes
Snippets and name completion Yes
Brackets/autoclosing Yes
Formatter Yes
Reference outline Yes
Core structural diagnostics Yes
Literal/io.print preview Yes
Complete type checker Not yet
Production compiler/runtime Not yet
Full database engine Not yet
Debug adapter and breakpoints Not yet

This distinction is intentional: RedEXCompile should expose what works today without presenting future language design as an already-complete compiler.