| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
into its header and records (names uncompressed in their wire form, the owner's and those in NS, CNAME, PTR, MX, SOA and SRV data; each compression pointer pointing before the last, so they end), the message written back by the view wire (the owners compressed: the message is state, its bytes a view of it); no new form: names compared a byte at a time (bytes have no ==), the compression written out in the view (a view calls no block fn); 115 lines against Python's 72
|
| |
|
|
| |
inflated to its bytes, codes read a bit at a time from their canonical counts (as zlib's puff.c), stored, fixed and dynamic blocks, a stream that is none failing its event; no new form: the code tables passed in a record (a fn takes no list), the output a list of one item (a bytes value is no state), a block's tables built in a fn (a let's list lives in the handler's own block); 132 lines against Python's 81
|
| |
|
|
| |
no bytes by key, message by key, name[key] or .replace(first .. last, value), the opcodes DOC, DOC_SIZE and REPLACE (those after them moved up), the header 38 bytes; examples/editor.aup and bounded-editor.aup gone (examples/documents.aup does their work in a keyed list), and with them the parity with the earlier editor (documents_model checks the new one); diagnostics on documents rewritten for plain messages or gone (304); a module's records counted at their v7 place; a field changed by '=' said so where a call was written
|
| |
|
|
| |
default's bytes), x.body.bytes its length (LEN), a text going there only as bytes(t); no list keyed by bytes or by a list; examples/documents.aup: keyed byte documents as a keyed list of records, each edit checked against the revision it was made on; documents_model: random shows and edits (stale revisions, past the end, any bytes, up to 5,000 at once) against a model, in memory and on a store restarting six times (half of the runs in bursts), four seeds alike (1,280 steps); four diagnostics
|
| |
|
|
| |
characters (Pure 027's stage 2c): a fn with a block (statements, return a, b; return alone gives nothing) or one a cycle of calls goes through runs as Pure's function (CALL), once for each kinds of arguments it is called with, in code of its own after the handlers' and views'; its parameters held by name as it begins, its let's lists, held values and registers each call's own (Pure's); -> types where it calls itself before a return says what it gives, a return's values wanted as those types; f(x) as a statement where it gives nothing, let a, b = f(x) and a, b = f(x) (lets and states) where it gives several; a view, a count, sum, max or min calls none; records' and variants' values: R { ... }, V.case(x), V.case and calls giving one onto the stack field by field, held by a name (name.field lets), passed and given back, matched (a case's value named, read only), appended (a call's value held first), an item and a record under an item's field passed as values (a function has its own lists), a list a value holds walked through a register, a list in a local (Pure's local type 4), R { ... } written where a let, an assignment, a return or an argument takes a value; never-run lines after a return or a break refused, no jump past an else whose then stops, the last arm of a match that names every case taken without asking; for ch in t: a text's characters as code points (a let's, a parameter's, a state's, a record's field, a message's text field), char(n); examples/json_tree.aup by recursive descent and a depth-first walk; 13 diagnostics, 2 accepted forms, a functions test against Python (40 random trees built and summed recursively, deepest and leaves as two values, 60 random texts' characters, a call without end failing as memory with nothing changed); the 2b compiler's modules for 49 sources byte for byte the same (json_tree.aup's match aside); three diagnostics' wording follows records being values
|
| |
|
|
| |
2b): a field may hold a record or a variant (flattened into paths: at.x; a variant's case a field of its own, its value at name.case) or a list of anything (list of Json, a variant holding itself through a list); variant V { case, case(type) } and V.case(value) where items are made; match item { case(name) => ... _ => ... } over an item of a variant or a variant in a field (the binding a field, a list read through a register, or fields under it; missing cases refused); x.items.append(...), xs.last.items.append, xs[i].items.append; for, folds, count, first, last and [i] over a list in a field; xs[i] an item of an unkeyed list; number(t) of a text; examples/json_tree.aup; 16 diagnostics, an accepted program, a nested values test
|
| |
|
|
| |
decide alone (Pure 027's stage 2a): {v:08x}, {p:.2f} (Python's mini-language, [0][width][.digits][d x X b o f]), a + b of texts or of bytes, b[a .. c] of bytes and of texts (a cut inside a character failing as encoding), byte(n), let s = bytes or text (16 of each a handler, s = s + e appending in place), while c { } as a count to 2^53 that breaks when c is false, && and || computing their right side only where it decides (an AND or OR still where it cannot fail: comparisons, states and fields, a walked item's fields, a number plus a small literal, what the left side computed; every module of the apps and benchmarks byte for byte the same but json's); examples/json.aup, examples/sha256.aup in formats and joined bytes; 14 diagnostics, one accepted form, 144 random formats against Python's format() and an app cutting at commas
|
| |
|
|
| |
& | ^ ~ << >> on i64s by Python's precedence (a shift's count a number or an i64), b[i] the byte at a position of bytes (a field's, an argument's, a parameter's, bytes(t)), list of i64 (number, bool, text) as records of one field whose items read as their values, a let's list begun with [elements], xs[i] read and written by position (not_found past the end), bytes(xs), and a, b = x, y and let a, b = x, y given at once; examples/sha256.aup; 12 diagnostics, one accepted form, 192 random bit expressions against Python's integers and an app of bytes and lists
|
| | |
|
| |
|
|
| |
(Pure 018)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A condition was any number, non-zero being true: done was a number field,
a view showed 1 for true, and done + 1 was no type error. Now bool is its
own type (Pure 016, module format v6):
- true and false; comparisons, text comparisons, has and ! && || give a
bool. Bools are equal or not; they are no numbers and have no order.
- if, conditional expressions, require, where (folds, walks, filtered
tables) take a bool. Given a number, the diagnostic says how to make
one: "if takes a bool, not a number: compare it, as in n != 0".
- Bool states (state on = false), record fields (done = false), message,
output and argument fields (ok: bool), lets, views and columns.
Interpolation writes true or false. A list is not keyed by a bool.
- The examples' flags are bools (charge's holding, toggle's visible,
tasks' done).
Checks: 20 bool diagnostics, a form using bools everywhere, an app whose
every output shows true and false (states, items, views, columns, text)
and whose replacement turns a number into a bool and back. Models hold
bools and compare them strictly: Python's True == 1 no longer hides a 1
where a true belongs. Generated programs are typed, numbers and bools.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
state xs: list of R by field keeps its items in that field's order, each
key once: xs.add(R { ... }) places an item (a taken key fails the event
with exists), xs[key] finds one by halving (its field, or its index),
xs.has(key) asks, xs.remove(key) removes. append and insert are refused
on a keyed list, add on another, and a key field is never assigned.
Texts compare with == != < <= > >= by their bytes.
Checked against a Python model over 3,600 random steps with a text-keyed
and a number-keyed list; 13 diagnostics; examples/tally.aup.
|
| |
|
|
|
|
|
|
| |
`state from: mark in note` is a cursor that stays before text inserted
at its position; `cursor in` goes after it, as a caret does. Everything
a cursor takes, a mark takes too. The notes example's mark is now one,
and its reference model agrees: typing at the mark leaves it in place.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
fn name(params) = value declares one expression, inlined where it is
called: arguments are computed once onto the stack and the body reads them
with PICK, so a fn costs no runtime call and keeps Pure's bound on work.
Parameters take any kind of value; recursion is a compile error.
use name reads name.aup beside the source or from AUP_PATH. A library
declares only fns and uses, sees only its parameters, and is called as
name.fn(...). Diagnostics now carry the file they are in, and the
compiler takes a loader so that sources come from the host.
examples/words.aup is such a library; examples/tasks.aup uses it and still
matches its reference model.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
if c { a } else { b }, with else-if chains, is an expression anywhere a
value goes. Only the chosen branch runs, every branch gives the same type,
and nesting that would pass Pure's limit of 8 value-carrying joins is a
compile error.
view name = each row in list { column = value ... } declares a table with
a row per item; columns read their row as an index of the list. An index
now reads and writes its item's fields directly (at.title, at.done = 1),
so 'position' cannot name a record field.
examples/tasks.aup gains conditional views and a board table and still
matches its reference model; a new check confirms the unchosen branch is
never computed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
A record declares named number and text fields with defaults. A list of a
record is runtime-owned state, and an index of a list always names one of
its items: it follows its item across inserts and removes and stops at the
ends. Items are read and changed by field (tasks[at].title), appended or
inserted as record values whose missing fields take defaults, and removed
by index. Using an index of another list is a compile error.
examples/tasks.aup matches a Python reference model over 4,800 random steps,
including events that fail on an empty list. Replacing it with a module
whose record gained and reordered fields keeps every item.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
aup now emits Pure module v3 and adds text states with string initializers,
cursors bound to a text, text inputs, string literals with escapes and
{interpolation} of numbers and text, cursor distances in chars and lines,
.start/.end, insert/remove, name.line(cursor), .chars/.lines/.bytes on text,
.chars/.line on cursors, and text(bytes)/bytes(text). Replies and replace
accept text as its UTF-8 bytes. Views are numbers or text. Up to 32 inputs.
examples/notes.aup is a small editor. make check replays random typing
(ASCII, Korean, emoji, combining marks, NUL, newlines), moves and deletions
against a Python reference model: 4,800 snapshots of text, cursor, mark and
views match. It also checks escapes and number text, 16 new diagnostics, a
document loaded into text and saved back, and all earlier parity; the
compiler and the Pure executor each pass under ASan/UBSan.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
aup now emits Pure module v2 and adds keyed byte collections
(state documents: bytes by key), message inputs by key with u32 and a
trailing bytes field, on-message handlers, field access, name[key] reads
and .bytes sizes, replace(a .. b, value), reply and require, all checked
for number/bytes types with file:line:column diagnostics.
The document editor and its size-bounded variant are rewritten in aup.
make check runs them through pure-edit-module against pure-edit running the
original editor.pure programs: 1,280 random show/edit/apply operations,
including conflicts, limits, missing documents, budgets and invalid keys,
produce byte-identical stdout, stderr and exit codes, and each CLI reads the
other's store identically. v0a parity with the workbench engine, 33
diagnostics and generated/damaged programs still pass, also with a
sanitizer-built compiler.
|
|
|
aup check/build parse states, key inputs, views and handlers (with if/else
and else-if), resolve names, generate forward-only stack code and encode a
Pure module v1 deterministically. Diagnostics carry file:line:column.
make check loads every module with Pure's verifier, checks determinism, 20
diagnostics and accepted forms, replacement by name, 600 generated programs
and damaged sources (every emitted module verifies), and replays random event
scripts against the workbench Zig engine: 16,667 snapshots across counter,
toggle, charge, else-if and fault programs matched, including 921 failed
events. The sanitizer-built compiler passes the same checks.
|