This page is the contract. One page to work with SB — no need to open src/*.c. Written for humans, structured so AIs can also rely on it.
SB # first line of every file set x to 1. # every statement ends with . define f with a as give back a. end. pls bring maths. # import std/lib say f with 2. # → 2 (also f(2))
Every sentence ends with .. No ;. Keywords are English words:
SB set to give back define with as and plus minus times divided by divided evenly by mod is is not is greater than is less than not or and if then otherwise otherwise if else elif end while count from to loop through break continue try catch raise match with _ say ask pls bring # symbols that also exist: < > <= >= = == != ( ) [ ] , " ${}
is greater than or equal to, is less than or equal to, substr, floor/ceil, ketiwe_delay, ketiwe_key with args. Use symbols <= >=, length, divided evenly by, sleep_ms, ketiwe_key_press (no args).| type | literal | notes |
|---|---|---|
| number | 3 2.5 | float (double) everywhere. int division via divided evenly by |
| string | "hi ${x}" | ${} interpolation. no multiline needed |
| list | list with 1 and 2 and 3 list with (empty) | ordered. length with, item with i and L, L[i], add_to/remove_from |
| map | map("k", 1) | m["k"] / m["k"] = v |
SB set x to 1. if x is 1 then say "yes". end # one-liner then auto-closes at EOL if x is 1 then say "big". otherwise if x is 0 then say "zero". otherwise say "no". # also else / elif end while x is less than 3 then set x to x plus 1. end count i from 0 to 3 then say i. end define add with a and b as give back a plus b. end. define tick with as say "hi". end. # zero-arg needs with
plus also concatenates: "a" plus "b" → "ab"minus times divided by divided evenly by (truncates toward 0) modis is not is greater than is less than + symbols < > <= >= = == !=. Prefix not works: not a is less than b ≡ a >= band or notfoo with 1 and 2 or foo(1, 2). Lists/maps get item with i and L, L[i], m["k"]item with 0 and X plus 1 parses as item with 0 and (X plus 1) → crash. Hoist: set t to item with 0 and X. then t plus 1.This is the #1 source of bugs for AIs.
# globals set HP to list with 100. # single-element list = mutable scalar define heal with n as set x to item with 0 and HP. # read set x to x plus n. set HP[0] to x. # write-through ✓ set HP to x. # ← WRONG: creates function-local, global unchanged end.
set NAME to v inside a define is always function-local.set LIST[i] to v (in-range, write-through via env_get_ptr) or add_to with LIST and v / remove_from with LIST and i (write-through when first arg is an identifier).list with v, read item with 0 and NAME, write NAME[0] = v. Arrays must be pre-sized before indexed writes (out-of-range is silently ignored). Clear by draining with remove_from loop — there is no clear builtin.add_to/remove_from first arg.floor/ceil: use v divided evenly by 1 then adjust for negatives.| group | names |
|---|---|
| math | abs sin cos tan sqrt log only via std/maths; core has divided evenly by trick |
| strings | length with s upper/lower/trim/split/join/contains/replace/find/reverse/to_string/to_number/type_of |
| lists | length with L item with i and L add_to with L and v remove_from with L and i L[i] |
| time | time_ms with sleep_ms with n (not ketiwe_delay) |
| io | say ask |
Keys: there is no substr — use length + concatenation. Font for ketiwe_text is fixed (~8px/char mono, ~13px tall, baseline y).
ketiwe_window with "Title" and 800 and 600. ketiwe_clear with "#1a1a2e". ketiwe_rect with x and y and w and h and "#fff". ketiwe_rect_outline with x and y and w and h and "#fff". ketiwe_circle with cx and cy and r and "#fff". ketiwe_line with x1 and y1 and x2 and y2 and "#fff". ketiwe_text with x and y and "hi". # only x y text, color arg is ignored ketiwe_button with x and y and w and h and label. # returns 1 on click ketiwe_poll with. ketiwe_flip with. ketiwe_key_press with. # no args, one-shot X11 keysym int, cleared on read. 119 w 97 a 115 s 100 d 32 space 49-52 1-4 113 q 65361-65364 arrows. Esc also closes window via ketiwe_poll. ketiwe_mouse_x/y/down with. # held state, updated on poll. No key-held API → design one-shot steps (X autorepeat helps) + mouse fire. time_ms / sleep_ms with # frame pacing; ketiwe_text uses XDrawString baseline
shimgui_window with "App" and 460 and 320. shimgui_label with "Hello". shimgui_entry with "Name...". shimgui_button with "Click". shimgui_run with. say shimgui_entry_text with 0. say shimgui_last_click with.
pls bring NAME. resolves <searchpath>/NAME.sb then <searchpath>/NAME/main.sb then the importing file's own directory (added to search path on load). Convention: one dir per lib with main.sb umbrella. Install via symlink/dir in ~/.shimbabomb/libraries/NAME/.
count (loop), likely others — rename to cols/cnt.try set y to 10 minus "oops". catch e say e. say e_info["line"]. say e_info["trace"]. say err_name with e_info["code"]. end
| cmd | notes |
|---|---|
sb file.sb | run |
sb -i | REPL. sb --parse-only file.sb checks syntax |
sb build file.sb | compile to standalone native binary |
sb pack deb|rpm|exe | installers |
sb fmt / test / doc / lsp | format, test, docs, LSP |
item with 0 and VAR / VAR[0] to v for every cross-function scalar.LIST[i]=v (e.g. 256 zeros for 16×16 map).>= word form — use >= <= or not (a is less than b). Verify with sb --parse-only.item with i and L before math: set t to item with i and L.(length with s) times 6, height 13 (fixed font).then auto-closes at EOL — trailing end belongs to outer block.define f with as (not define f as) for zero args.sb tests/conditions.sb, tests/elseif.sb, examples/fib.sb.Tip: this spec + site/docs/ + std/*.sb are the reference. Everything here is verified against the interpreter — you don't need .c.