Language experimental

Stellar C

A small C-like language that compiles straight to STELLAR bytecode. Write a program, compile it, and run it here on the real V0061.35 firmware — or download the .lst for an Elf2K. The compiler is the real one, written in Python, running in your browser.

Experimental
Stellar C is a prototype and the language is still growing. Everything here compiles and runs in this simulator; the compiled Snake has run on a real Elf2K. New to it? Read the Stellar C guide - the language step by step, with a Try it link on every example.
On your own computer
Download Stellar C (stellar-c.zip, about 60 KB) — the same compiler this page runs, with every example, the guide and its examples, and a README. It needs only Python 3.8 or newer. Unzip it, then python3 scc.py myprog.sc writes myprog.lst, ready to send to an Elf2K or to open on the Simulator.

loading the compiler…

Source

Compiled

Compile to see the STELLAR bytecode here, each opcode next to the source line it came from.

Run it

clock
not loaded

Serial terminal

Click the terminal and type to send keys to the running program; on a phone or tablet, tap it for the keyboard, with the arrow keys, Esc and Enter in the row underneath. The input box pre-loads keystrokes before it starts.

Front panel

The language

STELLAR has sixteen fast registers and no stack frames, so Stellar C works like PL/M or Atari Action!: every variable has one fixed home, most of them in registers, and there is no recursion (the compiler refuses it). Two functions that are never active at the same time share registers. Everything is unsigned.

WriteMeans
const W = 80;a compile-time constant
u16 score, best;16-bit unsigned variables — registers where possible
u8 lvl;one byte of memory
u8 grid[1680];a byte array (set to zero at every start if the program writes it)
u8 rev[] = { 0, 2, 1 };
u8 msg[] = "hello";
initialised arrays; a string is one, with a 0 on the end
u16 f(u16 a, u16 b) { … }functions with parameters, locals and a return value; void main() is where it starts
if else while for break continue returnas in C
= += -= *= /= %= &= |= ^= ++ --assignment
+ - * / % & | ^ << >>arithmetic (shifts by a constant); a[i], &a[i], calls
== != < <= > >= && || !conditions
putc(c) print("text") printu(n)a character, a string or array, a number in decimal
getc() keyready()wait for a key; is a key waiting?
rand() delay(k) halt()a random number, a pause, stop the program
fill(&a[i], v, n) copy(&dst, &src, n)fill or copy a run of bytes
out(e) outmem(&a[i]) outport(p)a byte to the output port — the front panel's hex display on port 4 (choose 1, 4-7)
q(e)the Q lamp: q(0) off, q(1) on, q(2) one blink, q(3) two
scanin() getin() inport(p)read the input port now; or wait for the INPUT button (EF4), then read it
ef() ef(n) efsource(n) efsource(n, 1)all four EF lines as a mask (bit 0 = EF1 ... bit 3 = EF4); 1 if line n is on, else 0; the EF line getin() and waitef() wait on, 1-4 (a second argument of 1: inverted, active low)
waitef() waitef(n)wait for that EF line to go on, then off — or for EF line n (1-4), whatever efsource() says. Other VMs keep running meanwhile

Inline STELLAR: asm { }

One STELLAR command per line — the mnemonic, then its operand bytes in hex, as the opcode reference lays them out. {x} is the register variable x lives in, #e two bytes (a constant or &array), %e one byte, @name an address (a label, a function, or @break @continue @return), and name: a label. Each command's length is checked. The asm may use RD, RE and RF, and must leave RC alone.

asm {
poll:
    SERST              // a key waiting?
    IFFALSEI @done
    SERIN
    INCX 0{k}          // {k} = the register k lives in
    GAL @poll
done:
}

Native 1802: native { }

Raw 1802 machine code, assembled by the compiler and run in place by $F1 RUNMC — for the inner loop that must be fast. {x} is the address of variable x's VM register (high byte first), &a an array's address, hi(e) and lo(e) its two bytes. The block returns by itself at the end (or BR exit). Free registers are R7 R8 R9 RB RD RE RF; the compiler refuses writes to the others. Set X with SEX before any STR, and remember the other VMs wait while native code runs.

The compiler's Python source is served with this page, in sc/, and as one download, stellar-c.zip. Look up any opcode in the reference; load other programs on the Simulator.