diff options
| author | 2026-10-12 08:46:23 +0330 | |
|---|---|---|
| committer | 2026-10-12 08:46:23 +0330 | |
| commit | ecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch) | |
| tree | 70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /docs/history/10-zc/code | |
a
Diffstat (limited to 'docs/history/10-zc/code')
46 files changed, 5589 insertions, 0 deletions
diff --git a/docs/history/10-zc/code/README.md b/docs/history/10-zc/code/README.md new file mode 100644 index 0000000..c9576c3 --- /dev/null +++ b/docs/history/10-zc/code/README.md @@ -0,0 +1,300 @@ +# tinyvm zygote: notes and transcript + +a tiny stack cpu that started as a c89 code golf entry and ended up as a self-hosting runtime. a small native core runs vm code (jit-compiled to arm64, or interpreted anywhere else), and the genome it boots is a compiler for zc, a c-like language that keeps the forth habits: the compiler lives in vm memory next to your program, your program can call into it, patch its tables, add syntax to it and compile new code while it runs. heap objects carry an ownership tag (u, m or d) that a static analyzer inside the compiler checks, with deterministic frees at scope ends and a mark-sweep collector underneath for everything else. + +this folder only has the latest code. earlier stages are described in the transcript below, but their code isn't included, except the asm-only genome from stage 7, which sits in `legacy/`. + +## files + +`core.c` is the native core and the only native code at runtime: the arm64 jit, its stubs and invalidation logic, and a portable interpreter used on every other host. `src/rt.zc` is the runtime (i/o, software division, the heap and the collector) and `src/compiler.zc` is the compiler, both written in zc. together they are the genome. `zc0.c` is stage 0 of the bootstrap, a compiler in c for the subset of zc that `compiler.zc` is written in. `tools/build.zc` is a small zc program that makes the resident compiler compile its own source into a fresh image, and `mkgenome.c` turns that image into `genome.h`, which is generated and checked in. `examples/` has hello, factorial, echo, self-patching code, a list that owns its elements, and a repl. `tests/` has feature tests, plus `tests/errors/` with programs the analyzer has to reject (each starts with the error it expects) and `tests/runerr.sh` to run them. `test.sh` does the whole bootstrap and runs everything on both the interpreter and the jit. `legacy/` has the old asm genome. + +## build + +``` +cc -O2 core.c io_linux.c -o zy # io_linux.c provides Q, G and J +./zy <examples/hello.zc +``` + +on arm64 that builds the jit, anywhere else the interpreter (`-DZYINTERP` forces the interpreter on arm64 too). `J` is a `char` by default, so compile with `-DJTYPE=int` if yours is an int. the source ends at eof or at a backtick, and anything after the backtick stays unread for the program itself. + +regenerating the genome after changing `src/`: + +``` +cc zc0.c -o zc0 && cc mkgenome.c -o mkgenome +cat src/rt.zc src/compiler.zc | ./zc0 >genome.h # stage 0, from c +cc -O2 core.c io_linux.c -o zy +(cat tools/build.zc; printf '`'; cat src/rt.zc src/compiler.zc) | ./zy | ./mkgenome >g.h +mv g.h genome.h && cc -O2 core.c io_linux.c -o zy # now built by itself +``` + +run the last two lines once more and `genome.h` should come out byte for byte the same. `test.sh` checks that. + +## zc, the language + +it reads like c and behaves like b: there are no types, every value is a 32 bit word, and a heap object is an array of words. memory is word addressed, so `p + 1` is the next word and strings are one char per word with a 0 at the end. + +``` +const N = 10; +var table[N], count; // globals: scalars and arrays, constant initializers or "strings" +fn fib(n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +fn main() { + for (var i = 0; i < N; i++) table[i] = fib(i); + var sq = { var t = table[5]; t * t }; // a block is an expression too, its last line is its value + var x = asm { 2 3 + }; // raw vm code, leaves one value + putn(sq + x); putc(10); + return 0; +} +``` + +statements are `var`, `if`/`else`, `while`, `for`, `break`, `continue`, `return`, `{ }` blocks, `asm { }` and expressions. operators are c's, with c's precedence: `* / % + - << >> < > <= >= == != & ^ | && ||`, unary `- ! ~ * &`, `++`/`--` both ways, `=` and the compound assignments, indexing `a[i]` (which is `*(a + i)`), and calls. a call through a value works (`f(x)` when `f` holds an address). comparisons and `&& ||` give 0 or 1. `/`, `%` and `<<` call into the runtime, since the cpu has no divider and only a right shift. character literals, `0x` hex and the usual escapes are there. there's no `?:`, no `switch` and no struct syntax. + +a function is called by name once it's declared, so mutual recursion works without prototypes, except that a function with tagged parameters has to be declared before a checked call to it (`fn f(d p);` is a prototype). `main` runs after the whole program compiled. every function returns one word, 0 if it falls off the end. + +builtins come from the runtime: `putc`, `getc`, `eof`, `puts`, `putn`, `halt`, `strlen`, `streq`, `wcopy`, `wfill`, `new`, `free`, `gc`, `isobj`, `osize`, `live_objects`. + +## memory model: u, m and d + +`new(n)` gives back a fresh object of n words. bind it to a local and the local owns it, tagged **m**. tags live on local variables and parameters, the analyzer follows them through the code, and the compiler inserts `free` calls where owned objects die. + +**m** means the object belongs to this block and has to be used in it. you can lend it to callees as often as you like (to parameters declared `m`), and when the block ends it's freed. an m object that's never used anywhere in its block is an error. + +**d** means the object is going down. `x as d` recasts it, and the first time it's handed to a lower scope its life here is over: passing it to a parameter declared `d`, or touching it inside an inner block, which then owns it as m and frees it when that block ends. using it afterwards is an error, and so is ending the block with a d object that never left. + +**u** means the object is going up. `x as u` recasts it, and from then on it has to leave this block for the one above, where it arrives as m. it leaves through `return` (the function has to be declared `-> u`), as the value of a block expression, or by assignment to a variable of the enclosing block. letting it fall out of scope, or throwing away a u result, is an error. + +recasting only goes away from m: m can become u or d (and u and d can swap), but nothing goes back to m in the same scope. a `d` parameter arrives as m. an `m` parameter is a borrow: the callee can read and write it, but it can't free it, return it, recast it or store it anywhere. + +``` +fn box(v) -> u { var b = new(1); b[0] = v; return b as u; } +fn push(m list, d item) { list[list[0] + 1] = item as d; list[0]++; return 0; } +fn main() { + var l = new(9); + var b = box(5); // u from box becomes m here + push(l, b as d); // l is lent, b is given away + return 0; // l is freed here, and b with it, since l owns it +} +``` + +containers own what you store in them. `p[i] = c` needs `c` to carry the same tag as `p` (or be a fresh object), and from then on `c` follows `p`: if `p` is recast, so is `c`, if `p` is given away, `c` goes with it, and when `p` is freed its children are freed too. a child can't be recast or given away on its own. storing into an object you only borrowed is giving the child away, so it needs `as d`. the runtime records the owner in the child's header, so freeing a container frees exactly the objects it owns. + +globals, plain pointers and arrays aren't tracked. storing an owned object there needs `as d`, and the mark-sweep collector takes it over. a fresh object can go straight in. + +branches have to agree: at the end of an `if` every variable has to be in the same state on both paths (a path that returns or breaks doesn't count), and a loop body has to leave every outer variable the way it found it, so a d object can't be given away inside a loop that might run twice. + +### the analyzer + +it runs inside the compiler on every function, including code compiled at runtime by `eval` and friends, and stops at the first violation with a line number and the variable's name. `tests/errors/` has one small program for each rule. three ways to turn it off: `unchecked fn f() { }` for one function, `unchecked { }` for a block, and a top-level `unchecked;` for the rest of the unit (a parse word can also set `check_on = 0`). unchecked code doesn't track anything, so whatever it allocates belongs to the collector, and checked variables can't be touched from inside an unchecked block. what it doesn't see: a value that isn't a bare variable name (`p + 0`, `p[0]` read back out) is a plain word, so pointer arithmetic and reading pointers out of containers make untracked aliases. that's the escape hatch, and also the hole. + +## the heap and the collector + +the heap is 0x40000..0xA0000. every block is a power of two words with a 5 word header (size, class, flags, a check word, owner) and comes from a free list per size class or a bump pointer, so `new` and `free` are a few instructions in the common case. checked code frees deterministically and never needs the collector. the collector is mark-sweep, non-moving and conservative: roots are the program area, the genome's globals, the compiler's input stack, the live frame stack and the data stack region, and a word counts as a pointer only if its object header checks out. it runs when you call `gc()` (which returns how many objects it freed) or when `new` runs out of room. objects never move, so raw addresses stay valid, which keeps the forth habits working. + +## code as data + +the compiler is in memory with your program and every name in it is callable. the pieces: + +`asm { }` emits raw vm words: numbers push, `-5` pushes a negative, `#n` emits a raw word, one-char tokens from the mnemonic table are opcodes, `:name` defines a label local to the block, and other names push the address of a variable or function. + +`quote { ... }` is a token list as a fresh object: `[n, kind, value, kind, value, ...]`, where names, strings and operators are interned pointers (`intern("while")` gets one). `tokens(s)` makes one from a string, `qdup(q)` copies one. + +`eval(q)` compiles a token list as a function body and runs it, `compile(q)` returns its address instead, `load(q)` compiles top-level declarations, and `evals(s)` does `eval` on a string. + +parse words: `immediate fn name() { }` runs at compile time whenever `name` shows up as a statement, inside an expression or at the top level. it starts with the current token on its own name and works the compiler directly: `next()`, `tk`/`tv` (current token kind and value), `expect`, `accept`, `expr()`, `stmt()`, `substmt()`, `emit`, `lit`, `op`, `hole`/`setlit` for jumps, `here`. `grab()` reads a `{ }` group into a token list and `feed(q)` pushes a list back into the input, which is all a macro needs. parse words can call `eval` mid-compile; the compiler saves its state and emits the new function in place with a jump around it. the built-in keywords are entries in the same table, so a parse word called `while` replaces `while`. + +tables: `add_binop("**", 11, "ipow c")` adds or replaces a binary operator with a precedence and its code (written like asm, names resolve when it's used), `add_unop` does the same for prefix operators, and the lexer learns new spellings from them. `mnem` is the asm mnemonic table, `q@!$_~cjzr,?.+-*&|^><`, and can be rewritten like before. + +``` +fn ipow(a, b) { var r = 1; while (b > 0) { r *= a; b--; } return r; } +immediate fn pow_op() { next(); add_binop("**", 11, "ipow c"); return 0; } +pow_op // runs now, at compile time +immediate fn repeat() { // repeat 3 { body } + var n, body, i = 0; + next(); n = tv; next(); + body = grab(); + while (i < n) { feed(qdup(body)); i++; } + free(body as d); + return 0; +} +fn main() { repeat 2 { putn(2 ** 10); putc(10); } return 0; } +``` + +## the bootstrap + +`zc0.c` compiles the subset `compiler.zc` uses (no analyzer, quote, parse words or block expressions) into a first genome. that genome compiles `compiler.zc` again, running on the vm, which is where the real compiler and the analyzer first see their own source, and `compiler.zc` passes its own lifetime checks. the result compiles itself into identical words, and that's the `genome.h` that ships. an image build (`build_image(org, dst)`) compiles with only the image's own names visible, writes code for one address into another, and appends a symbol table so the booted genome knows its own names. + +## the instruction set + +unchanged since stage 3. every word is 32 bits. an odd word is a literal that pushes `w>>1` (31 bits, sign extended). an even word is an opcode, `w/2`. there's a data stack and a return stack, both stored inside memory. + +``` +0 q halt 5 ~ swap 10 , in (Q) 15 * mul 20 < less +1 @ load 6 c call 11 ? empty (J) 16 & and +2 ! store 7 j jump 12 . out (G) 17 | or +3 $ pick 8 z jz 13 + add 18 ^ xor +4 _ drop 9 r ret 14 - sub 19 > shr +``` + +stack effects: `!` is `(v addr --)`, `$` is `(n -- copy of the nth item)` so `0 $` is dup, `z` is `(cond addr --)` and jumps when cond is 0, and `c` and `j` take their target from the stack. there's no div or mod, because a divider can't finish in one cycle in hardware. division is done in software. + +## memory map and abi + +memory grew from 64k words to 1m (1048576) words, since a self-hosted compiler and a heap don't fit in 64k. nothing in the instruction set changed. + +``` +0x00000.. the program: code, with globals between functions +0x40000..0x9FFFF heap +0xA0000 frame pointer word +0xA0100..0xBDFFF compiler data: interned names, symbol table, locals, tables +0xC0000.. genome: 0xC0000 entry, 0xC0005 symbol table address, 0xC0006 image end +0xE0000..0xEFFFF frame stack, grows down from 0xF0000 +0xF0000.. return stack, grows up +0xF8000.. mark stack +0xFC000..0xFFFF0 data stack, grows down +``` + +calls push the arguments left to right and the callee's prologue pops them into its frame. locals live in the frame at `*0xA0000 + slot`. every function leaves exactly one word on the data stack. + +## how the core works + +registers: x19 holds the memory base, x20 the data stack pointer, x21 the return stack pointer, x22 the translation table and x23 the state block (memory, s, r, table, coverage map, Q, G, &J, store hook). + +compilation is lazy. the first time control reaches an address, that block is translated from live memory. a block ends at call, jump, ret or halt. a `z` doesn't end it: the not-taken side keeps compiling, which makes superblocks. a literal followed by `c`, `j` or `z` is fused into a constant target. every exit goes through a 5-instruction dispatch stub that bounds-checks the target, loads `tab[t]` and branches to it directly when it's already compiled. otherwise it returns to c, which compiles the block and re-enters. + +self-modification is handled with a byte map of which words some live translation covers. a store checks that byte inline: an uncovered target, the usual case, gets a plain store. a covered target calls the hook, which drops every translation containing that word and makes the jit code return to c at the next instruction, so even patches to the very next word take effect. writing back the same value is a no-op. if the 16 mb code buffer fills, everything is flushed. + +platform: arm64 for the jit. the darwin path uses `MAP_JIT`, `pthread_jit_write_protect_np` and `sys_icache_invalidate`. linux uses rwx mmap and `__builtin___clear_cache`. only the linux arm64 path has actually been run, under qemu. the darwin path follows apple's documented recipe but hasn't been tested. under the hardened runtime it also needs the allow-jit entitlement. every other host gets the interpreter, which has the same semantics: shift counts wrap at 32, stores outside memory are ignored, loads outside memory read 0, and jumping outside memory halts. + +## test results + +`test.sh` passes all 27 checks on x86-64 linux (interpreter) and on linux arm64 under qemu (jit): the fixpoint, an up-to-date `genome.h`, every example and feature test on both paths with identical output, all 24 programs in `tests/errors/` rejected with the expected message on both, and the jit's self-compile matching too. the genome is 37505 words. the compiler compiles itself in about 0.15 s on the interpreter and 0.45 s on the jit under qemu. + +## open ends + +- branch and loop states have to match exactly. a loop that gives something away and then always breaks is rejected, even though it's fine. +- untracked aliases (pointer arithmetic, pointers read out of containers) aren't checked, and can dangle once the owner is freed. +- the collector is conservative, so a stale word on the stack can keep an object alive a little longer. it scans the whole data stack region because the vm can't read its own stack pointer. +- `?:`, `switch` and structs are missing. a parse word could add any of them. +- free lists never coalesce, so a heap full of one size class can't be reused for another until those objects die. +- translations are only reclaimed by a full flush, and the hook rescans the block list on every store to a covered word. + +--- + +## transcript + +each of my messages is quoted exactly, followed by a summary of the reply. + +### 1 + +> codegolf a tiny cpu vm in C89. the goal is to achieve the lowest character count possible. include an assembler as well (scored separately) and a hello world program (not scored, but elegance and simplicity is a bonus) +> it must be capable of re-entrant code and a realistically workable instruction set. + +**summary:** a two-stack forth-style machine. the vm was 384 bytes: one ternary chain inside `while(o=m[p++])`, the top two stack items cached in `a` and `b`, the program loaded with `read(open(...))` so it needs no headers, and both stacks inside the 65536-word memory. it had 22 opcodes including div and mod, a two-word literal, and jump/call targets popped from the stack. the assembler was 348 bytes and two-pass, using `strcspn` instead of `strchr` so the implicit int return stays safe on 64-bit. hello world was a pointer loop over a string with a zero terminator. re-entrancy was shown with a recursive factorial plus a recursive decimal printer. + +### 2 + +> your cpu should also be realistically close to hardware (translating it to logical circuitry hardware should be fairly easy) and sport an acceptably fast execution (if hypothetically ported to hardware, not in software) +> +> assume i/o is handled by two external functions, `char Q()` (getchar) and `void G(char)` (putchar) and a state variable J (boolean, shows if input is empty). +> +> don't be afraid to use macros. + +**summary:** no reply was sent to this message at the time. it was answered together with message 3. + +### 3 + +> pro tip: if you define a macro as `!o--`, you can save 2 characters per if condition +> oh and btw, newlines are free + +**summary:** used the tip as `#define X !--o?`, with pre-decrement because opcode 0 (halt) is already handled by the loop, and with the `?` folded into the macro and free newlines used as separators. the hardware-oriented redesign: bit 0 of each word is a literal flag, so literals take one cycle like the j1 cpu. div and mod were dropped because they can't finish in one cycle and were replaced by an arithmetic shift right, giving 8 alu ops that decode from 3 bits. every instruction does a fixed amount of work with at most one data memory access, and call and jump share a datapath (`r-=o`). i/o now goes through `Q`, `G` and a `?` op that reads `J`. the result was the vm at 339 bytes and the assembler at 346. the final golfed code: + +```c +#define X !--o? +int m[1<<16],p,s=65e3,r=6e4,o,a,b;main(c,v)char**v;{read(open(v[1],0),m,s);while(o=m[p++])a=m[s],b=m[s+1],o&1?m[--s]=o>>1:(o/=2,X +m[s]=m[a]:X +m[a]=b,s+=2:X +m[s]=m[s-~a]:X +s++:X +m[s]=b,m[s+1]=a:(o-=2)<1?m[r]=p,r-=o,p=a,s++:X +p=b?p:a,s+=2:X +p=m[--r]:X +m[--s]=Q():X +m[--s]=J:X +G(a),s++:(m[++s]=X +b+a:X +b-a:X +b*a:X +b&a:X +b|a:X +b^a:X +b>>a:b<a));} +``` + +```c +char t[9999][99],*o="q@!$_~cjzr,?.+-*&|^><",*q;A[9999],k,i,j,n,P;E(y){n++;write(P,&y,4);}V(char*s){for(j=k;j--&&(*t[j]-58||strcmp(t[j]+1,s)););return~j?A[j]:atoi(s);}main(){while(~scanf("%s",t[k]))k++;for(;P<2;P++)for(n=i=0;i<k;i++)if(*(q=t[i])==34)while(*++q)E(*q);else*q==58?A[i]=n:!q[1]&&o[j=strcspn(o,q)]?E(j*2):*q==35?E(V(q+1)):E(V(q)*2+1);} +``` + +### 4 + +> now let's move in stages. write a compiler that takes this assembler's code and converts it into darwin arm + +**summary:** an ungolfed c89 compiler from vm assembly to darwin arm64 assembly. every word got its own label, the image was emitted as an addressable data array, x19/x20/x21 held the memory base and the two stack pointers, and computed jumps went through a table of offsets. a literal followed by a jump became a direct branch. `Q` and `G` went through `sxtb`, since char is signed on apple arm64, and `J` was read with `ldrb`. it was verified by assembling with llvm-mc for darwin, then rewriting to linux with sed and running under qemu, where it matched the vm byte for byte. this version couldn't handle self-modifying code. + +### 5 + +> can you write the assembler in assembly and pair the code with the assembly and the assembler so that it can re-wire itself at runtime? or maybe include an interp for self-modification, otherwise fns are exec'd native + +**summary:** both. `aslib.s` is the assembler written in vm assembly as a library (`a.src`, `a.dst`, `a.org`, `a.lab`, then `a.run c`), and with `asmain.s` it's a 568-word standalone assembler. it's byte-identical to the c assembler and reaches a fixpoint when assembling itself. this is also where the `:;comment` trick came from. the compiler became a hybrid. the image is split into basic blocks, each block counts how many of its words differ from the original image, and stores into code go through a slow path that updates the counters. clean blocks run native, while dirty blocks and anything past the image run in an interpreter compiled into the same binary, which hands control back to native code whenever it lands in a clean block. `cc -t` printed `[` and `]` at each switch. the demo rewired a function at runtime to point at freshly assembled code and then restored it. + +### 6 + +> which one do you like more? and which is more performant? +> keep that one, then port to using llvm ir so that it can be platform independent + +**summary:** no reply was sent at the time. the llvm port was dropped when message 7 changed direction. the question was answered at the start of the reply to message 7: the hybrid was the favorite because it kept the vm's semantics exact. the plain compiler was slightly faster on code that never rewrites itself, but it silently ran stale code once anything did. the zygote beats both. + +### 7 + +> can you make it a zygote approach? +> a minimal core loads first, reads and compiles the program (either wholly or partially, for speed) and replaces it with itself. so it's like a jvm but self-contained and on the same level as itself, where the assembler can itself be modified in-memory to assemble different code. for this we need to ditch llvm + +**summary:** the current design, described above. the native core only does jit and glue. it loads the genome (boot loader + assembler, both vm code) at 48000. the boot loader reads source until eof or a backtick, assembles it at 0 and jumps there. compilation is lazy per block, straight from live memory, with superblocks through `z`, fused constant targets, and dispatch chained through a table. invalidation uses the coverage byte map plus a store hook, so self-modified code gets retranslated instead of interpreted. the resident assembler sits at fixed addresses, and `repl.s` rewrites its mnemonic table so `p` means out, then assembles and runs input chunks in a loop, overwriting the same address each time. verified under qemu on linux arm64, including the self-hosted assembler running on the zygote. about 4x faster than the golfed interpreter. + +### 8 + +> damn dawg you made an entire baremetal os? +> +> let's move to cowork. pack everything up alongside a transcript of every message i've sent and your own notes on what you've implemented in an md file, with the code, so i can move it. + +**summary:** not quite an os. it's a userland runtime. it still runs on darwin or linux, uses their mmap for executable memory, and gets i/o from the host through `Q`, `G` and `J`. there's no scheduler, no drivers and no hardware access, so a closer description is a tiny self-hosting jit, in the spirit of a jvm. the first packing attempt bundled every stage's code with a full test script. + +### 9 + +> nono we don't need all the code, just the recent ones. my msgs and your summaries are more important and all should be there + +**summary:** this package. only the zygote stack plus its examples and tests are included, and earlier stages appear only as summaries. the golfed reference vm and assembler are inlined under message 3, because they define the instruction set. + +### 10 + +> we're gonna make this thing cooler. make the syntax C-like whilst still keeping the forth capabilities like super-homiconicity and the likes, add explicit and automatic gc (use a fast approach) and memory management that looks like this: +> every heap object has a classifier u m d, up middle down. up means the object will die at the scope above (becomes m when returned to the parent scope, and it must be returned and cannot be discarded). m means it must be used here and can be passed down (but once it's recasted as u or d it can't be casted back to m in this scope). d means the variable is passed down, and its lifetime ends after it's given for the first time to a scope lower than the current one. +> ask me questions to clarify this approach, then add it to the code and also add a simple static analyzer which checks these lifetimes + +my answers to the clarifying questions, exactly: + +> scope: every { } block +> +> lending an m object to a callee: borrow, no escape (Recommended) +> +> storing a heap object inside another object or a global: container gets ownership. putting a value inside a container requires its umd to match the parent, and from then on, the umd for that is also inherited from the parent (as in if a parent m is casted to d, so is the child heap object) +> +> gc: free lists + mark-sweep (Recommended) +> +> where the compiler lives: resident in vm code. bootstrap it step by step, by writing a c-like in core.c and then rewriting the compiler inside the c-like. also bring back llvm if you think it'll make your job easier +> +> homoiconic features: parse words, quoted code blocks, inline stack code, patchable compiler tables +> +> how an inner block hands a u object up: expression and assign, both +> +> when the analyzer runs: inside the compiler but can be turned off if the code requests it + +**summary:** the genome is now zc, a typeless c-like language, described above. stage 0 is `zc0.c` (kept as its own file next to core.c rather than inside it, so the runtime still has one native file), and the resident compiler is `src/compiler.zc` plus `src/rt.zc`, which reached a byte-identical fixpoint compiling itself. llvm wasn't brought back, since the target is the vm itself. memory went to 1m words, and core.c gained an interpreter for non-arm64 hosts. calls i made without asking: tags go on signatures (`fn f(m a, d b) -> u`) and recasts are `x as u` / `x as d`; a d object touched inside an inner block moves into that block; storing into a borrowed object, a global or untracked memory needs `as d`; handing a u up by assignment only reaches the directly enclosing block; unchecked code gives its objects to the collector. the old asm genome moved to `legacy/`. diff --git a/docs/history/10-zc/code/core.c b/docs/history/10-zc/code/core.c new file mode 100644 index 0000000..ed148c6 --- /dev/null +++ b/docs/history/10-zc/code/core.c @@ -0,0 +1,332 @@ +/* zygote core: puts the genome (the zc compiler and its runtime, both vm code) + into memory and runs it. on arm64, every block of vm code is translated to + arm64 the first time it is reached, straight from live memory. stores that + land on translated words throw those translations away, so code that + rewrites itself, including the resident compiler, just gets retranslated + on the next visit. on other hosts (or with -DZYINTERP) a plain interpreter + with the same semantics runs instead. ZYTRACE=1 logs translations on stderr. */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined(__aarch64__) && !defined(ZYINTERP) +#define ZYJIT 1 +#include <sys/mman.h> +#ifdef __APPLE__ +#include <pthread.h> +#include <libkern/OSCacheControl.h> +#endif +#endif +#include "genome.h" + +#ifndef JTYPE +#define JTYPE char +#endif +char Q(void); +void G(char); +extern JTYPE J; + +#define MW (1 << 20) /* memory, in words */ +#define DS0 (MW - 16) /* data stack grows down from here */ +#define RS0 0xF0000 /* return stack grows up from here */ +#define CODEW (4 << 20) /* 16 MB of code, in instruction words */ +#define MAXB 65536 +#define BLKW 1024 /* longest block, in vm words */ + +static int m[MW]; +static int trace; +#ifdef ZYJIT +static unsigned char cov[MW]; /* 1 if a live translation covers the word */ +static void *tab[MW]; /* vm address -> translation */ +static struct { int a, b; } bl[MAXB]; /* live translations cover [a,b); a < 0 is dead */ +static int nbl; +static unsigned *code, *cp, *x_enter, *x_exit, *x_disp, *x_first; +static long S[9]; /* m, s, r, tab, cov, Q, G, &J, store hook; read by the stubs */ + +enum { W0 = 0, W1 = 1, X9 = 9, X10, X11, M = 19, SP = 20, RP = 21, TAB = 22, ST = 23 }; + +static void E(unsigned x) { *cp++ = x; } +static void li(int d, int v) +{ + unsigned u = (unsigned)v; + E(0x52800000 | (u & 0xffff) << 5 | d); + if (u >> 16) E(0x72a00000 | (u >> 16) << 5 | d); +} +static void ldr_post(int t, int n, int i) { E(0xb8400400 | (i & 0x1ff) << 12 | n << 5 | t); } +static void ldr_pre(int t, int n, int i) { E(0xb8400c00 | (i & 0x1ff) << 12 | n << 5 | t); } +static void str_pre(int t, int n, int i) { E(0xb8000c00 | (i & 0x1ff) << 12 | n << 5 | t); } +static void str_post(int t, int n, int i) { E(0xb8000400 | (i & 0x1ff) << 12 | n << 5 | t); } +static void ldr_u(int t, int n, int o) { E(0xb9400000 | (o / 4) << 10 | n << 5 | t); } +static void str_u(int t, int n, int o) { E(0xb9000000 | (o / 4) << 10 | n << 5 | t); } +static void ldrx_u(int t, int n, int o) { E(0xf9400000 | (o / 8) << 10 | n << 5 | t); } +static void ldr_rr(int t, int n, int r, int ext) { E(0xb8600800 | r << 16 | ext << 13 | 1 << 12 | n << 5 | t); } +static void str_rr(int t, int n, int r, int ext) { E(0xb8200800 | r << 16 | ext << 13 | 1 << 12 | n << 5 | t); } +static void ldp_post(int t, int u, int n, int i) { E(0x28c00000 | ((i / 4) & 0x7f) << 15 | u << 10 | n << 5 | t); } +static void op3(unsigned op, int d, int n, int r) { E(op | r << 16 | n << 5 | d); } +static void addx_ext(int d, int n, int r, int ext) { E(0x8b200000 | r << 16 | ext << 13 | 2 << 10 | n << 5 | d); } +static void movw(int d, int r) { E(0x2a0003e0 | r << 16 | d); } +static void blr(int n) { E(0xd63f0000 | n << 5); } +static void b_to(unsigned *t) { long o = t - cp; E(0x14000000 | (o & 0x3ffffff)); } +static void cb_fix(unsigned *at, unsigned *to) { *at |= ((to - at) & 0x7ffff) << 5; } +#define SXTW 6 +#define UXTW 2 + +static void build_stubs(void) +{ + cp = code; + x_enter = cp; /* int enter(long *S, void *code) */ + E(0xa9bc7bfd); /* stp x29, x30, [sp, #-64]! */ + E(0x910003fd); /* mov x29, sp */ + E(0xa90153f3); /* stp x19, x20, [sp, #16] */ + E(0xa9025bf5); /* stp x21, x22, [sp, #32] */ + E(0xf9001bf7); /* str x23, [sp, #48] */ + E(0xaa0003f7); /* mov x23, x0 */ + ldrx_u(M, ST, 0); + ldr_u(X9, ST, 8); addx_ext(SP, M, X9, UXTW); + ldr_u(X9, ST, 16); addx_ext(RP, M, X9, UXTW); + ldrx_u(TAB, ST, 24); + E(0xd61f0020); /* br x1 */ + x_exit = cp; /* w0 = next vm address */ + op3(0xcb000000, X9, SP, M); E(0xd342fd29); str_u(X9, ST, 8); /* s = (x20 - x19) >> 2 */ + op3(0xcb000000, X9, RP, M); E(0xd342fd29); str_u(X9, ST, 16); + E(0xa94153f3); /* ldp x19, x20, [sp, #16] */ + E(0xa9425bf5); /* ldp x21, x22, [sp, #32] */ + E(0xf9401bf7); /* ldr x23, [sp, #48] */ + E(0xa8c47bfd); /* ldp x29, x30, [sp], #64 */ + E(0xd65f03c0); /* ret */ + x_disp = cp; /* w0 = target: chain through tab[] or fall back to c */ + E(0x7144001f); /* cmp w0, #MW */ + E(0x54000002 | ((x_exit - cp) & 0x7ffff) << 5); /* b.hs exit */ + E(0xf8605ac9); /* ldr x9, [x22, w0, uxtw #3] */ + E(0xb4000009 | ((x_exit - cp) & 0x7ffff) << 5); /* cbz x9, exit */ + E(0xd61f0120); /* br x9 */ + x_first = cp; +} + +static void flush(void) +{ + memset(tab, 0, sizeof tab); + memset(cov, 0, sizeof cov); + nbl = 0; + cp = x_first; + if (trace) fprintf(stderr, "jit: flushed\n"); +} + +static void jitwrite(int on) +{ +#ifdef __APPLE__ + pthread_jit_write_protect_np(!on); +#else + (void)on; +#endif +} + +static void syncicache(unsigned *a, unsigned *b) +{ +#ifdef __APPLE__ + sys_icache_invalidate(a, (char *)b - (char *)a); +#else + __builtin___clear_cache((char *)a, (char *)b); +#endif +} + +/* store hook for words that are covered by a translation */ +static int hook(int a, int v) +{ + int j, x, hit = 0; + if (m[a] == v) return 0; + m[a] = v; + for (j = 0; j < nbl; j++) + if (bl[j].a >= 0 && bl[j].a <= a && a < bl[j].b) { + tab[bl[j].a] = 0; + for (x = bl[j].a; x < bl[j].b; x++) cov[x] = 0; + if (trace) fprintf(stderr, "jit: dropped %d..%d\n", bl[j].a, bl[j].b - 1); + bl[j].a = -1; + hit = 1; + } + for (j = 0; j < nbl; j++) + if (bl[j].a >= 0) for (x = bl[j].a; x < bl[j].b; x++) cov[x] = 1; + return hit; +} + +static void op(int i, int k) /* everything except control flow */ +{ + unsigned *a, *b, *c, *z; + switch (k) { + case 1: ldr_u(X9, SP, 0); ldr_rr(X9, M, X9, SXTW); str_u(X9, SP, 0); return; + case 2: /* store: inline unless the target word is translated */ + ldp_post(X9, X10, SP, 8); + E(0x7144013f); /* cmp w9, #MW */ + a = cp; E(0x54000002); /* b.hs done */ + ldrx_u(X11, ST, 32); + E(0x3869496b); /* ldrb w11, [x11, w9, uxtw] */ + b = cp; E(0x3500000b); /* cbnz w11, slow */ + str_rr(X10, M, X9, UXTW); + c = cp; E(0x14000000); /* b done */ + cb_fix(b, cp); /* slow: hook(a, v) */ + movw(W0, X9); movw(W1, X10); ldrx_u(X11, ST, 64); blr(X11); + z = cp; E(0x34000000); /* cbz w0, done */ + li(W0, i + 1); b_to(x_exit); /* a translation died: resume at i+1 in c */ + cb_fix(a, cp); cb_fix(z, cp); + *c |= (cp - c) & 0x3ffffff; + return; + case 3: ldr_u(X9, SP, 0); E(0x9100128a); ldr_rr(X9, X10, X9, SXTW); str_u(X9, SP, 0); return; /* add x10, x20, #4 */ + case 4: E(0x91001294); return; /* add x20, x20, #4 */ + case 5: E(0x29402a89); E(0x2900268a); return; /* ldp w9, w10, [x20]; stp w10, w9, [x20] */ + case 10: ldrx_u(X11, ST, 40); blr(X11); E(0x13001c09); str_pre(X9, SP, -4); return; /* sxtb w9, w0 */ + case 11: + ldrx_u(X9, ST, 56); + if (sizeof J == 1) E(0x39400129); else ldr_u(X9, X9, 0); /* ldrb w9, [x9] */ + str_pre(X9, SP, -4); + return; + case 12: ldr_post(W0, SP, 4); E(0x13001c00); ldrx_u(X11, ST, 48); blr(X11); return; /* sxtb w0, w0 */ + } + ldr_post(X9, SP, 4); + ldr_u(X10, SP, 0); + switch (k) { + case 13: op3(0x0b000000, X10, X10, X9); break; + case 14: op3(0x4b000000, X10, X10, X9); break; + case 15: op3(0x1b007c00, X10, X10, X9); break; + case 16: op3(0x0a000000, X10, X10, X9); break; + case 17: op3(0x2a000000, X10, X10, X9); break; + case 18: op3(0x4a000000, X10, X10, X9); break; + case 19: op3(0x1ac02800, X10, X10, X9); break; + default: E(0x6b09015f); E(0x1a9fa7ea); /* cmp w10, w9; cset w10, lt */ + } + str_u(X10, SP, 0); +} + +static void *translate(int p) +{ + unsigned *start; + int i = p, n = 0, w, k, t; + if (cp - code > CODEW - 65536 || nbl >= MAXB) flush(); + start = cp; + for (;;) { + if (i >= MW) { E(0x12800000); b_to(x_exit); break; } /* movn w0, #0: halt */ + if (n++ >= BLKW) { li(W0, i); b_to(x_disp); break; } + w = m[i]; + cov[i] = 1; + if (w & 1 && i + 1 < MW && !(m[i + 1] & 1) && (k = m[i + 1] / 2) >= 6 && k <= 8) { + t = (w - 1) / 2; /* literal + call/jmp/jz with a known target */ + cov[i + 1] = 1; + if (k == 8) { + unsigned *a; + ldr_post(X10, SP, 4); + a = cp; E(0x3500000a); /* cbnz w10, fallthrough */ + li(W0, t); b_to(x_disp); + cb_fix(a, cp); + i += 2; + continue; + } + li(X10, i + 2); + if (k == 6) str_post(X10, RP, 4); else str_u(X10, RP, 0); + li(W0, t); b_to(x_disp); + i += 2; + break; + } + if (w & 1) { li(X9, (w - 1) / 2); str_pre(X9, SP, -4); i++; continue; } + k = w / 2; + if (k == 0) { E(0x12800000); b_to(x_exit); i++; break; } + if (k < 0 || k == 6 || k == 7) { + ldr_post(W0, SP, 4); + li(X10, i + 1); + if (k == 6) str_post(X10, RP, 4); else str_u(X10, RP, 0); + if (k < 0) { li(X11, 7 - k); addx_ext(RP, RP, X11, SXTW); } + b_to(x_disp); + i++; + break; + } + if (k == 8) { /* jz: taken leaves, not taken keeps going */ + ldp_post(X9, X10, SP, 8); + E(0x3500006a); /* cbnz w10, +3 */ + movw(W0, X9); + b_to(x_disp); + i++; + continue; + } + if (k == 9) { ldr_pre(W0, RP, -4); b_to(x_disp); i++; break; } + op(i, k); + i++; + } + bl[nbl].a = p; + bl[nbl++].b = i; + tab[p] = start; + syncicache(start, cp); + if (trace) fprintf(stderr, "jit: %d..%d -> %ld bytes\n", p, i - 1, (long)((char *)cp - (char *)start)); + return start; +} + +#else +/* portable path for hosts without the arm64 jit: a plain interpreter with + the same semantics (shift counts wrap at 32, stores outside memory are + ignored, loads outside memory read 0, leaving memory halts). */ +#define LD(x) ((unsigned)(x) < MW ? m[x] : 0) +static void run(int p) +{ + int s = DS0, r = RS0, w, a, b; + unsigned long long steps = 0; + while ((unsigned)p < MW) { + w = m[p++]; + steps++; + if (w & 1) { m[--s] = w >> 1; continue; } + a = m[s]; b = m[s + 1]; + switch (w / 2) { + case 1: m[s] = LD(a); break; + case 2: if ((unsigned)a < MW) m[a] = b; s += 2; break; + case 3: m[s] = LD(s + 1 + a); break; + case 4: s++; break; + case 5: m[s] = b; m[s + 1] = a; break; + case 6: m[r++] = p; p = a; s++; break; + case 7: p = a; s++; break; + case 8: if (!b) p = a; s += 2; break; + case 9: p = m[--r]; break; + case 10: m[--s] = (signed char)Q(); break; + case 11: m[--s] = J; break; + case 12: G((char)a); s++; break; + case 13: m[++s] = b + a; break; + case 14: m[++s] = (int)((unsigned)b - (unsigned)a); break; + case 15: m[++s] = (int)((unsigned)b * (unsigned)a); break; + case 16: m[++s] = b & a; break; + case 17: m[++s] = b | a; break; + case 18: m[++s] = b ^ a; break; + case 19: m[++s] = b >> (a & 31); break; + case 20: m[++s] = b < a; break; + default: p = MW; break; /* halt, and the reserved negative opcodes */ + } + } + if (trace) fprintf(stderr, "interp: %llu steps\n", steps); +} +#endif + +int main(void) +{ + trace = getenv("ZYTRACE") != 0; + memcpy(m + GORG, genome, sizeof genome); +#ifdef ZYJIT + { + int p = GORG; + union { unsigned *u; int (*f)(long *, void *); } enter; +#ifdef __APPLE__ + code = mmap(0, CODEW * 4, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON | MAP_JIT, -1, 0); +#else + code = mmap(0, CODEW * 4, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +#endif + if (code == MAP_FAILED) { perror("mmap"); return 1; } + jitwrite(1); + build_stubs(); + jitwrite(0); + syncicache(code, cp); + S[0] = (long)m; S[1] = DS0; S[2] = RS0; S[3] = (long)tab; S[4] = (long)cov; + S[5] = (long)Q; S[6] = (long)G; S[7] = (long)&J; S[8] = (long)hook; + enter.u = x_enter; + while ((unsigned)p < MW) { + void *c = tab[p]; + if (!c) { jitwrite(1); c = translate(p); jitwrite(0); } + p = enter.f(S, c); + } + } +#else + run(GORG); +#endif + return 0; +} diff --git a/docs/history/10-zc/code/examples/echo.zc b/docs/history/10-zc/code/examples/echo.zc new file mode 100644 index 0000000..01f28b0 --- /dev/null +++ b/docs/history/10-zc/code/examples/echo.zc @@ -0,0 +1,2 @@ +// everything after the backtick is left unread, for the program itself +fn main() { while (!eof()) putc(getc()); return 0; } diff --git a/docs/history/10-zc/code/examples/fact.zc b/docs/history/10-zc/code/examples/fact.zc new file mode 100644 index 0000000..2a218b2 --- /dev/null +++ b/docs/history/10-zc/code/examples/fact.zc @@ -0,0 +1,4 @@ +fn fact(n) { if (n < 2) return 1; return n * fact(n - 1); } +// prints in binary, like the old asm example +fn bin(n) { if (n > 1) bin(n >> 1); putc('0' + (n & 1)); return 0; } +fn main() { bin(fact(10)); putc(10); putn(fact(10)); putc(10); return 0; } diff --git a/docs/history/10-zc/code/examples/hello.zc b/docs/history/10-zc/code/examples/hello.zc new file mode 100644 index 0000000..f36a810 --- /dev/null +++ b/docs/history/10-zc/code/examples/hello.zc @@ -0,0 +1 @@ +fn main() { puts("hello, world!\n"); return 0; } diff --git a/docs/history/10-zc/code/examples/lists.zc b/docs/history/10-zc/code/examples/lists.zc new file mode 100644 index 0000000..7392752 --- /dev/null +++ b/docs/history/10-zc/code/examples/lists.zc @@ -0,0 +1,35 @@ +// ownership in practice: a list owns its boxes. nothing here calls free; +// everything is released at the end of the block that owns it. +fn box(v) -> u { var b = new(1); b[0] = v; return b as u; } +fn mklist(cap) -> u { var l = new(cap + 1); l[0] = 0; return l as u; } +// item arrives as m (it was given down), and goes on as d into the borrowed list +fn push(m l, d item) { l[l[0] + 1] = item as d; l[0] = l[0] + 1; return 0; } +fn show(m l) +{ + var i = 1; + putc('['); + while (i <= l[0]) { if (i > 1) putc(' '); putn(l[i][0]); i++; } + putc(']'); + return 0; +} +fn squares(n) -> u +{ + var l = mklist(n), i = 0; + while (i < n) { + var b = box(i * i); + push(l, b as d); + i++; + } + return l as u; +} +fn main() +{ + var before = live_objects(); + { + var l = squares(6); + show(l); putc(10); + puts("live: "); putn(live_objects() - before); putc(10); + } + puts("after the block: "); putn(live_objects() - before); putc(10); + return 0; +} diff --git a/docs/history/10-zc/code/examples/repl.zc b/docs/history/10-zc/code/examples/repl.zc new file mode 100644 index 0000000..49a8c7b --- /dev/null +++ b/docs/history/10-zc/code/examples/repl.zc @@ -0,0 +1,27 @@ +// a repl on the resident compiler: each backtick-separated chunk of input is +// compiled as a function body and run. definitions (fn ...) can be loaded too: +// a chunk that starts with "fn" goes through load instead of eval. +var buf[4000]; +fn readchunk() +{ + var n = 0, c; + while (!eof()) { + c = getc(); + if (c == 96) break; + if (n < 3999) { buf[n] = c; n++; } + } + buf[n] = 0; + return n; +} +fn main() +{ + var q, i; + while (!eof()) { + readchunk(); + q = tokens(buf); + if (q[0] && q[1] == T_ID && q[2] == intern("fn")) load(q); + else eval(q); + free(q as d); + } + return 0; +} diff --git a/docs/history/10-zc/code/examples/selfpatch.zc b/docs/history/10-zc/code/examples/selfpatch.zc new file mode 100644 index 0000000..35a4843 --- /dev/null +++ b/docs/history/10-zc/code/examples/selfpatch.zc @@ -0,0 +1,17 @@ +// code is data: find the literal 'A' inside f's compiled words and rewrite it. +// on the jit the store lands on translated code, which gets dropped and +// retranslated on the next call. +fn f() { putc('A'); return 0; } +fn litw(v) { return v + v + 1; } // how the vm encodes a literal push +fn main() +{ + var p = f; + f(); + while (*p != litw('A')) p++; + *p = litw('B'); + f(); + *p = litw('C'); + f(); + putc(10); + return 0; +} diff --git a/docs/history/10-zc/code/genome.h b/docs/history/10-zc/code/genome.h new file mode 100644 index 0000000..0075426 --- /dev/null +++ b/docs/history/10-zc/code/genome.h @@ -0,0 +1,2349 @@ +#define GORG 786432 +static const int genome[] = { +1966081,1310721,4,1640539,14,820495,823937,1310721,2,3,28,1310721,4,1310721,2,4, +1310721,2,2,24,1,1572913,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,1,28,1310721,4,20,1572947,14,1,1310721,2,1,26,1310721,4,18, +1310721,2,1,28,1310721,4,22,1572981,14,1,1310721,2,1,26,1310721,4, +18,1310721,2,1,28,1310721,4,0,1,1573017,14,1,1310721,2,1,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1,1310721,2,3, +26,4,1310721,2,2,1310721,2,3,26,2,26,2,1573149,16,1310721,2, +2,1310721,2,3,26,2,26,2,1572879,12,8,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1573061,14,1,1573157, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,29,28,1310721,4,1310721, +2,4,1,1310721,2,27,26,4,1310721,2,2,1,40,1573249,16,91, +1572879,12,8,1310721,2,1,1310721,2,2,28,10,3,6,10,4,8, +1310721,2,2,1,40,1573303,16,1573289,14,50,49,52,55,52,56,51, +54,52,56,0,1573267,1573031,12,8,1,1573521,14,3,1573445,16,1310721,2, +3,26,1310721,2,27,26,1,6,2,1,6,3,26,5,6,4, +10,8,26,97,1310721,2,2,21,1575169,12,26,10,3,6,10,4, +8,1310721,2,1310721,2,2,21,1574815,12,10,3,6,10,4,8,1310721, +2,2,1,6,1,10,28,34,63,38,3,26,1573441,16,1573445,14, +1573303,14,1310721,2,27,26,2,1573513,16,1310721,2,3,26,1310721,2,27, +26,1,6,2,-1,26,1,6,5,6,4,10,8,26,2,1572879, +12,8,1573445,14,1,1573521,14,1,1310721,2,29,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,4,1,1310721,2,3,26,4,1310721,2, +2,1310721,2,3,26,2,26,2,1573627,16,1310721,2,3,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1573565,14,1310721,2,3, +26,2,1573643,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28, +1310721,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2,5,26,4, +1310721,2,2,1310721,2,5,26,2,26,2,1573813,16,1310721,2,2,1310721, +2,5,26,2,26,2,1310721,2,3,26,2,1310721,2,5,26,2, +26,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1573815,14,1,1573857,16,1310721,2,5, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1573697,14, +1310721,2,2,1310721,2,5,26,2,26,2,1310721,2,3,26,2,1310721, +2,5,26,2,26,2,28,1,6,1,10,28,34,63,38,3, +26,1573929,14,1,1310721,2,7,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721, +2,7,26,4,1310721,2,7,26,2,1310721,2,5,26,2,40,1574111, +16,1310721,2,2,1310721,2,7,26,2,26,1310721,2,3,26,2,1310721, +2,7,26,2,26,2,10,3,6,10,4,8,1310721,2,7,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1573993,14,1, +1574119,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4, +1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2, +7,26,4,1310721,2,7,26,2,1310721,2,5,26,2,40,1574287,16, +1310721,2,2,1310721,2,7,26,2,26,1310721,2,3,26,2,10,3, +6,10,4,8,1310721,2,7,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1574183,14,1,1574295,14,1,1310721,2,9,26,1310721, +4,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1310721,2,11,28,1310721,4,1310721,2,3,26,4,1310721,2, +4,1,1310721,2,5,26,4,1,1310721,2,7,26,4,61,1310721,2, +9,26,4,1310721,2,2,1310721,2,3,26,2,40,1574487,16,1574373,1310721, +2,2,10,3,6,10,4,8,1,1574801,14,1310721,2,9,26,2, +1,40,3,36,1574761,16,1310721,2,7,26,1310721,2,7,26,2,1310721, +2,7,26,2,26,1310721,2,2,1310721,2,9,26,2,38,3,32, +26,10,3,6,10,4,8,1310721,2,5,26,1310721,2,5,26,2, +1310721,2,5,26,2,26,10,3,6,10,4,8,1310721,2,7,26, +2,1310721,2,3,26,2,40,3,36,1574723,16,1310721,2,7,26,1310721, +2,7,26,2,1310721,2,3,26,2,28,10,3,6,10,4,8, +1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1310721,2,9,26,1,6,2,1,6,-1,26,5,6,4,10, +8,8,1574487,14,1574373,1310721,2,7,26,2,10,3,6,10,4,8, +1310721,2,5,26,2,1574801,14,1,1310721,2,11,26,1310721,4,18,1310721, +2,9,28,1310721,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2, +5,26,4,1310721,2,3,26,2,1,28,1,6,1,10,28,34, +63,38,3,26,1574919,16,1574373,1310721,2,2,10,3,6,10,4,8, +1,1575155,14,1310721,2,2,1,40,1574981,16,1310721,2,1,1310721,2,2, +28,10,3,6,10,4,8,1310721,2,5,26,3,10,3,6,10, +4,8,1310721,2,3,26,2,1,40,1575067,16,1310721,2,3,26,1, +1310721,2,3,26,2,28,10,3,6,10,4,8,1310721,2,5,26, +1310721,2,5,26,2,3,36,10,3,6,10,4,8,1310721,2,7, +26,1310721,2,2,1310721,2,3,26,2,1574375,12,10,3,6,10,4, +8,1310721,2,5,26,2,1575139,16,1,1310721,2,7,26,2,28,1575155, +14,1310721,2,7,26,2,1575155,14,1,1310721,2,9,26,1310721,4,18, +1310721,2,7,28,1310721,4,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,1,40,1310721,2,5,26,4,1310721,2,2,1310721,2,3,26,2, +1574815,12,8,1310721,2,5,26,2,1575265,16,1,1574373,2,28,1575275,14, +1574373,2,1575275,14,1,1310721,2,7,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1574309,1310721,2, +3,26,2,63,32,26,2,30,1575351,14,1,1310721,2,5,26,1310721, +4,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,1310721,2,3,28,1310721,4,3,1310721,2,4, +1574309,1,26,3,10,3,6,10,4,8,1310721,2,2,65,40,1575581, +16,1574309,1310721,2,2,26,1574309,1310721,2,2,3,28,26,2,1574309,1310721, +2,2,3,28,26,2,26,10,3,6,10,4,8,1310721,2,1, +6,2,1,6,3,26,5,6,4,10,8,8,1575477,14,1575365,524289, +10,3,6,10,4,8,1575367,1,65,1574133,12,8,1,1575617,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4, +1310721,2,2,524289,11,26,40,3,36,1575709,16,1310721,2,2,1575365,2, +40,1,6,1,10,28,34,63,38,1,10,28,1575711,14,1,1575791, +16,1310721,2,2,5,1,10,28,26,2,1310721,2,2,1459366445,36,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1575793,14,1,1575845,16,1310721,2,2,7,1,10, +28,26,2,3,32,1,6,1,10,28,34,63,38,1,10,28, +1575847,14,1,1575853,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1, +28,1310721,4,1575931,14,122,99,58,32,111,117,116,32,111,102,32, +104,101,97,112,32,109,101,109,111,114,121,10,0,1575883,1573031,12, +8,1572995,12,8,1,1575953,14,1,1310721,2,1,26,1310721,4,18,1310721, +2,13,28,1310721,4,1310721,2,4,1310721,2,2,11,26,1310721,2,3, +26,4,7,1310721,2,5,26,4,17,1310721,2,7,26,4,1,1310721, +2,9,26,4,1310721,2,2,1,40,1576077,16,1310721,2,3,26,11, +10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,3,26,2, +40,1576183,16,1310721,2,7,26,1310721,2,7,26,2,1310721,2,7,26, +2,26,10,3,6,10,4,8,1310721,2,5,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1576077,14,1575367,1310721,2,5,26, +2,26,2,1576285,16,1310721,2,9,26,1575367,1310721,2,5,26,2,26, +2,10,3,6,10,4,8,1575367,1310721,2,5,26,2,26,1310721,2, +9,26,2,11,26,2,10,3,6,10,4,8,1576583,14,1575365,2, +1310721,2,7,26,2,26,1310721,10,40,3,36,1576373,16,1310721,2,9, +26,1575365,2,10,3,6,10,4,8,1575365,1575365,2,1310721,2,7,26, +2,26,10,3,6,10,4,8,1576583,14,1575435,2,1576387,16,1578127,12, +8,1575367,1310721,2,5,26,2,26,2,1576489,16,1310721,2,9,26,1575367, +1310721,2,5,26,2,26,2,10,3,6,10,4,8,1575367,1310721,2, +5,26,2,26,1310721,2,9,26,2,11,26,2,10,3,6,10, +4,8,1576583,14,1575365,2,1310721,2,7,26,2,26,1310721,10,40,3, +36,1576577,16,1310721,2,9,26,1575365,2,10,3,6,10,4,8,1575365, +1575365,2,1310721,2,7,26,2,26,10,3,6,10,4,8,1576583,14, +1575867,12,8,1310721,2,11,26,1310721,2,9,26,2,11,26,10,3, +6,10,4,8,1310721,2,9,26,2,1,26,1310721,2,7,26,2, +10,3,6,10,4,8,1310721,2,9,26,2,3,26,1310721,2,5, +26,2,10,3,6,10,4,8,1310721,2,9,26,2,5,26,3, +10,3,6,10,4,8,1310721,2,9,26,2,7,26,1310721,2,11, +26,2,1459366445,36,10,3,6,10,4,8,1310721,2,9,26,2,9, +26,1,10,3,6,10,4,8,1310721,2,11,26,2,1,1310721,2, +7,26,2,11,28,1574133,12,8,1310721,2,11,26,2,1576833,14,1, +1310721,2,13,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4, +1310721,2,2,1575631,12,1,6,1,10,28,34,63,38,3,26,1576905, +16,1,1576933,14,1310721,2,2,11,1,10,28,26,2,11,28,1576933, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721, +2,4,1310721,2,2,11,28,1310721,2,3,26,4,1310721,2,3,26, +2,1,26,2,11,28,1310721,2,5,26,4,1,1310721,2,7,26, +4,1310721,2,3,26,2,5,26,1,10,3,6,10,4,8,1310721, +2,7,26,2,1310721,2,5,26,2,40,1577275,16,1310721,2,9,26, +1310721,2,2,1310721,2,7,26,2,26,2,10,3,6,10,4,8, +1310721,2,9,26,2,1575631,12,1577215,16,1310721,2,9,26,2,3,1, +10,28,26,2,1310721,2,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1577217,14,1, +1577237,16,1310721,2,9,26,2,1576947,12,8,1310721,2,7,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1577055,14,1310721,2,3, +26,2,9,26,1,10,3,6,10,4,8,1310721,2,3,26,2, +11,26,1575367,1310721,2,3,26,2,3,26,2,26,2,10,3,6, +10,4,8,1575367,1310721,2,3,26,2,3,26,2,26,1310721,2,3, +26,2,10,3,6,10,4,8,1,1577401,14,1,1310721,2,11,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,1575631, +12,1577459,16,1310721,2,2,1576947,12,8,1,1577467,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3,26,4,1310721, +2,4,1310721,2,2,1575631,12,1577561,16,1310721,2,2,3,1,10,28, +26,1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,2,1577573, +14,1,1310721,2,5,26,1310721,4,18,0,0,0,0,1310721,2,3, +28,1310721,4,1310721,2,4,1310721,2,2,1575631,12,1,6,1,10,28, +34,63,38,3,26,1577653,16,3,1577697,14,1310721,2,2,7,1,10, +28,26,2,5,32,1,6,1,10,28,34,63,38,1,10,28, +1577707,16,1,1577851,14,1310721,2,2,7,1,10,28,26,1310721,2,2, +7,1,10,28,26,2,5,34,10,3,6,10,4,8,1577587,2, +32769,40,1577827,16,2031617,1577587,2,26,1310721,2,2,10,3,6,10,4, +8,1577587,1,6,2,1,6,3,26,5,6,4,10,8,8,1577843, +14,1577589,3,10,3,6,10,4,8,1,1577851,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3,26,4,1310721, +2,4,1310721,2,2,1310721,2,3,26,2,40,1577963,16,1310721,2,2, +2,1577595,12,8,1310721,2,1,6,2,1,6,3,26,5,6,4, +10,8,8,1577893,14,1,1577971,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1577587,2,1578105,16,1577587,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1310721,2,2031617,1577587,2,26,2,10, +3,6,10,4,8,1310721,2,2,1310721,2,2,1310721,2,2,11,1, +10,28,26,2,26,11,28,1577865,12,8,1577997,14,1,1578113,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721,4,1,1310721,2, +5,26,4,1577587,1,10,3,6,10,4,8,1577589,1,10,3,6, +10,4,8,1637825,12,8,1577985,12,8,1577589,2,1578379,16,1577589,1,10, +3,6,10,4,8,1310721,2,524289,10,3,6,10,4,8,1310721,2, +2,1575365,2,40,1578375,16,1310721,2,2,5,26,2,7,28,1,6, +1,10,28,34,63,38,3,26,1578329,16,1310721,2,2,11,26,1310721, +2,2,1310721,2,2,1,26,2,26,1577865,12,8,1310721,2,1310721,2, +2,1310721,2,2,1,26,2,26,10,3,6,10,4,8,1577985,12, +8,1578237,14,1578195,14,1310721,2,524289,10,3,6,10,4,8,1310721,2, +2,1575365,2,40,1578747,16,1310721,2,3,26,1310721,2,2,1,26,2, +10,3,6,10,4,8,1310721,2,2,5,26,2,3,28,1,6, +1,10,28,34,63,38,3,26,1578645,16,1310721,2,2,5,26,1, +10,3,6,10,4,8,1310721,2,2,9,26,1,10,3,6,10, +4,8,1310721,2,2,11,26,1575367,1310721,2,2,3,26,2,26,2, +10,3,6,10,4,8,1575367,1310721,2,2,3,26,2,26,1310721,2, +2,10,3,6,10,4,8,1310721,2,5,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1578709,14,1310721,2,2,5,26,2, +7,28,1,6,1,10,28,34,63,38,3,26,1578709,16,1310721,2, +2,5,26,3,10,3,6,10,4,8,1310721,2,1310721,2,2,1310721, +2,3,26,2,26,10,3,6,10,4,8,1578397,14,1575431,1,6, +2,1,6,3,26,5,6,4,10,8,8,1575433,1575433,2,1310721,2, +5,26,2,26,10,3,6,10,4,8,1310721,2,5,26,2,1578821, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,5,28,1310721,4,524289, +1310721,2,4,1,1310721,2,3,26,4,1310721,2,2,1575365,2,40,1578977, +16,1310721,2,2,5,26,2,3,32,1578937,16,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1310721,2,1310721,2, +2,1310721,2,2,1,26,2,26,10,3,6,10,4,8,1578867,14, +1310721,2,3,26,2,1578993,14,1,1310721,2,5,26,1310721,4,18,0, +0,0,0,0,0,0,0,0,0,0,789515,113,64,33,36,95, +126,99,106,122,114,44,63,46,43,45,42,38,124,94,62,60, +0,1,0,0,0,0,1,0,0,0,0,-1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1310721,2,3,28,1310721,4,1310721,2,4,1581455,14,122,99,58, +32,108,105,110,101,32,0,1581435,1573031,12,8,1579083,2,1573171,12,8, +1581483,14,58,32,0,1581477,1573031,12,8,1310721,2,2,1573031,12,8,21, +1572879,12,8,1572995,12,8,1,1581525,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,3,26,4,1310721,2,4,1581591, +14,122,99,58,32,108,105,110,101,32,0,1581571,1573031,12,8,1579083, +2,1573171,12,8,1581619,14,58,32,0,1581613,1573031,12,8,1310721,2,2, +1573031,12,8,1581649,14,58,32,0,1581643,1573031,12,8,1310721,2,3,26, +2,1573031,12,8,21,1572879,12,8,1572995,12,8,1,1581695,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1581313, +2,1581765,16,1581317,2,1,6,1,10,28,34,63,38,1,10,28, +1581767,14,1,1581783,16,1310721,2,2,1581413,12,8,1,1581791,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3,26, +4,1310721,2,4,1581313,2,1581871,16,1581317,2,1,6,1,10,28,34, +63,38,1,10,28,1581873,14,1,1581905,16,1466881,1310721,2,2,26,2, +1310721,2,3,26,2,1581539,12,8,1,1581913,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1,1310721,2,3, +26,4,1310721,2,2,2,1582047,16,1310721,2,3,26,1310721,2,3,26, +2,63,30,1310721,2,2,2,26,10,3,6,10,4,8,1310721,2, +1,6,2,1,6,3,26,5,6,4,10,8,8,1581957,14,1310721, +2,3,26,2,16385,3,28,32,1582071,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,4,1310721,2,2,1581927,12, +1310721,2,3,26,4,3,1582287,16,1310721,2,5,26,1311233,1310721,2,3, +26,2,26,2,10,3,6,10,4,8,1310721,2,5,26,2,1, +6,1,10,28,34,63,38,3,26,1582203,16,1582287,14,1310721,2,5, +26,2,1310721,2,2,1573657,12,1582241,16,1310721,2,5,26,2,1582567,14, +1310721,2,3,26,1310721,2,3,26,2,3,26,16385,3,28,32,10, +3,6,10,4,8,1582123,14,1310721,2,7,26,1310721,2,2,1573535,12, +10,3,6,10,4,8,1579007,2,1310721,2,7,26,2,26,5,26, +1409025,40,3,36,1582395,16,1582387,14,115,116,114,105,110,103,32,112, +111,111,108,32,102,117,108,108,0,1582353,1581413,12,8,1579007,2,1, +26,1,10,3,6,10,4,8,1310721,2,5,26,1579007,2,3,26, +10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,2,1310721,2, +7,26,2,3,26,1573943,12,8,1579007,1579007,2,1310721,2,7,26,2, +26,5,26,10,3,6,10,4,8,1311233,1310721,2,3,26,2,26, +1310721,2,5,26,2,10,3,6,10,4,8,1310721,2,5,26,2, +1582567,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4, +1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1579009,2,1310721, +2,7,26,4,1579009,2,8193,40,3,36,1582697,16,1582689,14,115,121, +109,98,111,108,32,116,97,98,108,101,32,102,117,108,108,0, +1582653,1581413,12,8,1579009,1,6,2,1,6,3,26,5,6,4,10, +8,8,1409537,1310721,2,7,26,2,26,1310721,2,2,10,3,6,10, +4,8,1417729,1310721,2,7,26,2,26,1310721,2,3,26,2,10,3, +6,10,4,8,1425921,1310721,2,7,26,2,26,1310721,2,5,26,2, +10,3,6,10,4,8,1434113,1310721,2,7,26,2,26,1,10,3, +6,10,4,8,1442305,1310721,2,7,26,2,26,3,10,3,6,10, +4,8,1450497,1310721,2,7,26,2,26,1,10,3,6,10,4,8, +1458689,1310721,2,7,26,2,26,1310721,2,2,3,1,10,28,26,2, +10,3,6,10,4,8,1310721,2,2,3,1,10,28,26,1310721,2, +7,26,2,3,26,10,3,6,10,4,8,1310721,2,7,26,2, +1583015,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,4,1310721,2,2,3,1,10,28,26,2,3,28,1310721,2, +3,26,4,1310721,2,3,26,2,1,40,3,36,1583255,16,1310721,2, +3,26,2,1579013,2,40,3,36,1583131,16,3,1583193,14,1417729,1310721,2, +3,26,2,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1583211,16,1310721,2, +3,26,2,1583269,14,1310721,2,3,26,1458689,1310721,2,3,26,2,26, +2,3,28,10,3,6,10,4,8,1583079,14,3,1,10,28,1583269, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,4,1579009,2,1310721,2,2,10,40,1583393,16,1579009,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1409537,1579009,2,26,2,3,1, +10,28,26,1458689,1579009,2,26,2,10,3,6,10,4,8,1583301,14, +1,1583401,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,4,1310721,2,2,1582085,12,1583029,12,1583453,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,3,26,4, +1310721,2,4,1579017,2,1310721,2,5,26,4,1310721,2,5,26,2,1583557, +16,1579017,1491457,1310721,2,5,26,2,26,2,10,3,6,10,4,8, +1583699,14,1579015,1,6,2,1,6,3,26,5,6,4,10,8,8, +1310721,2,5,26,1579015,2,10,3,6,10,4,8,1310721,2,5,26, +2,16385,40,3,36,1583699,16,1583691,14,116,111,111,32,109,97,110, +121,32,102,111,114,119,97,114,100,32,114,101,102,101,114,101, +110,99,101,115,0,1583635,1581413,12,8,1475073,1310721,2,5,26,2,26, +1310721,2,2,10,3,6,10,4,8,1491457,1310721,2,5,26,2,26, +1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,5,26,2, +1583783,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,3,26,4,1310721,2,4,1310721,2,2,1583971,16,1475073,1310721,2, +2,26,2,1310721,2,3,26,2,1584275,12,8,1310721,2,5,26,1491457, +1310721,2,2,26,2,10,3,6,10,4,8,1491457,1310721,2,2,26, +1579017,2,10,3,6,10,4,8,1579017,1310721,2,2,10,3,6,10, +4,8,1310721,2,1310721,2,5,26,2,10,3,6,10,4,8,1583825, +14,1,1583979,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1581297,2,1581301,2,40,3,36,1584073,16,1584065,14, +112,114,111,103,114,97,109,32,116,111,111,32,98,105,103,0, +1584033,1581413,12,8,1581297,2,1581299,2,26,1310721,2,2,10,3,6,10, +4,8,1581297,1,6,2,1,6,3,26,5,6,4,10,8,8, +1,1584137,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,4,1310721,2,2,1310721,2,2,26,3,26,1583993,12,8, +1,1584201,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,4,1310721,2,2,1310721,2,2,26,1583993,12,8,1,1584261, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,1581299,2,26,1310721,2,3, +26,2,1310721,2,3,26,2,26,3,26,10,3,6,10,4,8, +1,1584361,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,4,1310721,2,2,1584151,12,8,15,1584215,12,8,1,1584421, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1581297, +2,1310721,2,4,2097153,3,28,1584151,12,8,1310721,2,2,1584481,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4, +1310721,2,2,3,1,1582581,12,1310721,2,3,26,4,1442305,1310721,2,3, +26,2,26,1,10,3,6,10,4,8,1310721,2,3,26,2,1584581, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,4,1442305,1310721,2,2,26,2,3,32,1584657,16,1425921,1310721,2,2, +26,2,1584151,12,8,1,1584719,14,1450497,1310721,2,2,26,1581297,2,1450497, +1310721,2,2,26,2,1583467,12,10,3,6,10,4,8,2097153,3,28, +1584151,12,8,1,1584719,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,4,1310721,2,2,1583029,12,1310721,2,3,26, +4,1310721,2,3,26,2,1,40,1584819,16,1310721,2,3,26,1310721,2, +2,1584495,12,10,3,6,10,4,8,1310721,2,3,26,2,1584595,12, +8,13,1584215,12,8,1,1584851,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,4,1310721,1584151,12,8,3,1584215,12, +8,1310721,2,2,1584929,16,1310721,2,2,1584151,12,8,27,1584215,12,8, +1,1584937,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,4,1584435,12,1310721,2,3,26,4,15,1584215,12,8,1310721, +2,5,26,1581297,2,10,3,6,10,4,8,1310721,2,2,2,1585075, +16,1310721,2,2,2,1583993,12,8,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1585015,14,1,1583993,12,8,1310721,2,3, +26,2,1581297,2,1584275,12,8,1310721,2,5,26,2,1584151,12,8,1, +1585127,14,1,1310721,2,7,26,1310721,4,18,1310721,2,1,28,1310721,4, +1579089,2,1,28,1,6,1,10,28,34,63,38,3,26,1585355,16, +1579093,2,1585199,16,3,1585225,14,1572961,12,1,6,1,10,28,34,63, +38,1,10,28,1585257,16,1579087,3,1,10,28,10,3,6,10,4, +8,1,1585505,14,1579087,1572927,12,10,3,6,10,4,8,1579087,2,193, +28,1,6,1,10,28,34,63,38,3,26,1585351,16,1579093,3,10, +3,6,10,4,8,1579087,3,1,10,28,10,3,6,10,4,8, +1,1585505,14,1585437,14,1579087,1579091,2,2,10,3,6,10,4,8,1579087, +2,1585415,16,1579091,1,6,2,1,6,3,26,5,6,4,10,8, +8,1585437,14,1579087,3,1,10,28,10,3,6,10,4,8,1579087,2, +21,28,1,6,1,10,28,34,63,38,3,26,1585497,16,1579085,1, +6,2,1,6,3,26,5,6,4,10,8,8,1,1585505,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,7, +26,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1579095, +1,6,2,1,6,3,26,5,6,4,10,8,8,1579095,2,65, +40,3,36,1585675,16,1585667,14,115,111,117,114,99,101,115,32,110, +101,115,116,101,100,32,116,111,111,32,100,101,101,112,108,121, +0,1585615,1581413,12,8,1310721,2,9,26,1540609,1579095,2,25,30,26,10, +3,6,10,4,8,1310721,2,9,26,2,1,26,1310721,2,2,10, +3,6,10,4,8,1310721,2,9,26,2,3,26,1310721,2,3,26, +2,10,3,6,10,4,8,1310721,2,9,26,2,5,26,1,10, +3,6,10,4,8,1310721,2,9,26,2,7,26,1,10,3,6, +10,4,8,1310721,2,9,26,2,9,26,1310721,2,5,26,2,10, +3,6,10,4,8,1310721,2,9,26,2,23,26,1310721,2,7,26, +2,10,3,6,10,4,8,1310721,2,9,26,2,11,26,1579077,2, +10,3,6,10,4,8,1310721,2,9,26,2,13,26,1579079,2,10, +3,6,10,4,8,1310721,2,9,26,2,15,26,1579081,2,10,3, +6,10,4,8,1310721,2,9,26,2,17,26,1579087,2,10,3,6, +10,4,8,1310721,2,9,26,2,19,26,1579089,2,10,3,6,10, +4,8,1310721,2,9,26,2,21,26,1579091,2,10,3,6,10,4, +8,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3,26, +1586159,16,1310721,2,9,26,2,7,26,1310721,2,3,26,2,1,26, +2,10,3,6,10,4,8,1310721,2,2,1,28,1,6,1,10, +28,34,63,38,3,26,1586231,16,1579089,1,10,3,6,10,4,8, +1579093,1,10,3,6,10,4,8,1585141,12,8,1310721,2,2,5,28, +1,6,1,10,28,34,63,38,3,26,1586311,16,1579089,5,10,3, +6,10,4,8,1579091,1310721,2,3,26,2,10,3,6,10,4,8, +1585141,12,8,1,1586319,14,1,1310721,2,11,26,1310721,4,18,1310721,2, +3,28,1310721,4,1540609,1579095,2,25,30,26,1310721,2,4,1579077,1310721,2, +2,11,26,2,10,3,6,10,4,8,1579079,1310721,2,2,13,26, +2,10,3,6,10,4,8,1579081,1310721,2,2,15,26,2,10,3, +6,10,4,8,1579087,1310721,2,2,17,26,2,10,3,6,10,4, +8,1579089,1310721,2,2,19,26,2,10,3,6,10,4,8,1579091,1310721, +2,2,21,26,2,10,3,6,10,4,8,1579095,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1310721,2,2,23,26,2,1586581, +16,1310721,2,2,3,26,2,1577415,12,8,1,1586589,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1586665,14, +43,45,42,47,37,61,60,62,33,38,124,94,126,63,58,46, +64,35,36,0,1586625,1310721,2,3,26,4,1310721,2,3,26,2,2, +1586781,16,1310721,2,3,26,2,2,1310721,2,2,28,1,6,1,10, +28,34,63,38,3,26,1586743,16,3,1586789,14,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1586677,14,1,1586789, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721, +2,3,26,4,1310721,2,4,1,1310721,2,5,26,4,1310721,2,5, +26,2,1579025,2,40,1587245,16,1310721,2,7,26,1547777,1310721,2,5,26, +2,26,2,10,3,6,10,4,8,1310721,2,9,26,1,10,3, +6,10,4,8,1310721,2,9,26,2,1310721,2,2,40,1587031,16,1310721, +2,7,26,2,1310721,2,9,26,2,26,2,1579097,1310721,2,9,26, +2,26,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1587033,14,1,1587075,16,1310721,2, +9,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1586921, +14,1310721,2,9,26,2,1310721,2,2,28,1,6,1,10,28,34, +63,38,3,26,1587195,16,1310721,2,7,26,2,1310721,2,2,26,2, +1310721,2,3,26,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1587197,14,1,1587207,16, +3,1587253,14,1310721,2,5,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1586843,14,1,1587253,14,1,1310721,2,11,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,97,40,3, +36,1587345,16,1310721,2,2,115,10,40,3,36,1,6,1,10,28, +34,63,38,1,10,28,1587347,14,1,1587353,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,195, +40,3,36,1587445,16,1310721,2,2,245,10,40,3,36,1,6,1, +10,28,34,63,38,1,10,28,1587447,14,1,1587457,16,3,1587541,14, +1310721,2,2,131,40,3,36,1587517,16,1310721,2,2,181,10,40,3, +36,1,6,1,10,28,34,63,38,1,10,28,1587519,14,1,1, +6,1,10,28,34,63,38,1,10,28,1587551,16,3,1587603,14,1310721, +2,2,191,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1587609,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,1587267, +12,1587669,16,1310721,2,2,97,28,1587851,14,1310721,2,2,195,40,3, +36,1587729,16,1310721,2,2,205,10,40,3,36,1,6,1,10,28, +34,63,38,1,10,28,1587731,14,1,1587753,16,1310721,2,2,195,28, +21,26,1587851,14,1310721,2,2,131,40,3,36,1587813,16,1310721,2,2, +141,10,40,3,36,1,6,1,10,28,34,63,38,1,10,28, +1587815,14,1,1587837,16,1310721,2,2,131,28,21,26,1587851,14,3,1, +10,28,1587851,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1579087,2,1310721,2,4,1585141,12,8,1310721,2,2,185,28,1, +6,1,10,28,34,63,38,1,10,28,1587939,16,1310721,2,2,1588177, +14,1310721,2,1579087,2,10,3,6,10,4,8,1585141,12,8,1310721,2, +2,221,28,1,6,1,10,28,34,63,38,3,26,1588005,16,21, +1588177,14,1310721,2,2,233,28,1,6,1,10,28,34,63,38,3, +26,1588045,16,19,1588177,14,1310721,2,2,229,28,1,6,1,10,28, +34,63,38,3,26,1588085,16,27,1588177,14,1310721,2,2,97,28,1, +6,1,10,28,34,63,38,3,26,1588125,16,1,1588177,14,1310721,2, +2,203,28,1,6,1,10,28,34,63,38,3,26,1588165,16,55, +1588177,14,1310721,2,2,1588177,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,4,1579087,2,1,40,3,36,1588259,16, +1579087,2,1586603,12,1,6,1,10,28,34,63,38,1,10,28,1588261, +14,1,1588305,16,1310721,2,2,1579087,2,1586803,12,1,6,1,10,28, +34,63,38,1,10,28,1588307,14,1,1588377,16,1579097,1310721,2,2,26, +1579087,2,10,3,6,10,4,8,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1585141,12,8,1588209,14,1579097,1310721,2,2, +26,1,10,3,6,10,4,8,1579077,9,10,3,6,10,4,8, +1579079,1579097,1582085,12,10,3,6,10,4,8,1,1588445,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,7,28,1310721,4,1,1310721,2,4,1579081, +3,10,3,6,10,4,8,3,1589147,16,1579087,2,65,28,1,6, +1,10,28,34,63,38,3,26,1588539,16,3,1588589,14,1579087,2,19, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1588599,16,3,1588649,14,1579087,2,21,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1588659,16,3,1588709,14,1579087,2,27,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1588739,16,1585141,12,8,1579081,1,10,3,6,10,4,8,1588501, +14,1579087,2,95,28,1,6,1,10,28,34,63,38,1,10,28, +1588777,16,1589147,14,1585141,12,8,1579087,2,95,28,1,6,1,10,28, +34,63,38,3,26,1588923,16,1579087,2,1,40,3,36,1588887,16,1579087, +2,21,28,1,6,1,10,28,34,63,38,1,10,28,1,6, +1,10,28,34,63,38,1,10,28,1588889,14,1,1588903,16,1585141,12, +8,1588815,14,1579081,1,10,3,6,10,4,8,1588495,14,1579087,2,85, +28,1,6,1,10,28,34,63,38,3,26,1589091,16,1585141,12,8, +1579087,2,1,40,3,36,1589065,16,1579087,2,85,28,1,6,1,10, +28,34,63,38,3,26,1589055,16,1585141,12,8,1579087,2,95,28,1, +6,1,10,28,34,63,38,3,26,1589051,16,1589065,14,1589061,14,1585141, +12,8,1588961,14,1585141,12,8,1579081,1,10,3,6,10,4,8,1588495, +14,1579083,1579085,2,10,3,6,10,4,8,1579097,1,26,95,10,3, +6,10,4,8,3,1588191,12,8,1,1590431,14,1588495,14,1579083,1579085,2, +10,3,6,10,4,8,1579087,2,1,40,1589215,16,1579077,1,10,3, +6,10,4,8,1579079,1,10,3,6,10,4,8,1,1590431,14,1579087, +2,1587267,12,1589637,16,1310721,2,3,26,1,10,3,6,10,4,8, +1579087,2,97,28,1,6,1,10,28,34,63,38,3,26,1589525,16, +1585141,12,8,1579087,2,241,28,1,6,1,10,28,34,63,38,3, +26,1589325,16,3,1589375,14,1579087,2,177,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1589525, +16,1585141,12,8,1310721,2,5,26,1579087,2,1587623,12,10,3,6,10, +4,1,40,3,36,1589479,16,1310721,2,3,26,1310721,2,3,26,2, +33,30,1310721,2,5,26,2,26,10,3,6,10,4,8,1585141,12, +8,1589385,14,1579077,3,10,3,6,10,4,8,1579079,1310721,2,3,26, +2,10,3,6,10,4,8,1,1590431,14,1579087,2,1587267,12,1589591,16, +1310721,2,3,26,1310721,2,3,26,2,21,30,1579087,2,26,97,28, +10,3,6,10,4,8,1585141,12,8,1589525,14,1579077,3,10,3,6, +10,4,8,1579079,1310721,2,3,26,2,10,3,6,10,4,8,1, +1590431,14,1579087,2,1587367,12,1589847,16,1579087,2,1587367,12,1589667,16,3,1589697, +14,1579087,2,1587267,12,1,6,1,10,28,34,63,38,1,10,28, +1589781,16,1310721,2,2,2001,40,1589771,16,1579097,1310721,2,2,26,1579087,2, +10,3,6,10,4,8,1310721,2,1,6,2,1,6,3,26,5, +6,4,10,8,8,1585141,12,8,1589649,14,1579097,1310721,2,2,26,1, +10,3,6,10,4,8,1579077,5,10,3,6,10,4,8,1579079,1579097, +1582085,12,10,3,6,10,4,8,1,1590431,14,1579087,2,79,28,1, +6,1,10,28,34,63,38,3,26,1590021,16,1585141,12,8,1579079,1587865, +12,10,3,6,10,4,8,1579087,2,79,28,1,6,1,10,28, +34,63,38,1,10,28,1589993,16,1589985,14,98,97,100,32,99,104, +97,114,97,99,116,101,114,32,108,105,116,101,114,97,108,0, +1589941,1581413,12,8,1585141,12,8,1579077,3,10,3,6,10,4,8,1, +1590431,14,1579087,2,69,28,1,6,1,10,28,34,63,38,3,26, +1590313,16,1585141,12,8,1579087,2,1,40,3,36,1590131,16,1579087,2,69, +28,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,1,10,28,1590133,14,1,1590241,16,1310721,2,3,26, +1587865,12,10,3,6,10,4,8,1310721,2,2,2001,40,1590237,16,1579097, +1310721,2,2,26,1310721,2,3,26,2,10,3,6,10,4,8,1310721, +2,1,6,2,1,6,3,26,5,6,4,10,8,8,1590059,14, +1585141,12,8,1579097,1310721,2,2,26,1,10,3,6,10,4,8,1579077, +7,10,3,6,10,4,8,1579079,1579097,1582085,12,10,3,6,10,4, +8,1,1590431,14,1579097,1,26,1579087,2,10,3,6,10,4,8,1585141, +12,8,1579097,1,26,2,1586603,12,1590367,16,3,1588191,12,1590431,14,1579097, +3,26,1,10,3,6,10,4,8,1579077,9,10,3,6,10,4, +8,1579079,1579097,1582085,12,10,3,6,10,4,8,1,1590431,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1540609,1579095, +2,25,30,26,10,3,6,10,4,8,1310721,2,2,1,26,2, +3,28,1,6,1,10,28,34,63,38,1,10,28,1590539,16,1588459, +12,8,1,1590885,14,1310721,2,5,26,1310721,2,2,5,26,2,10, +3,6,10,4,8,1310721,2,5,26,2,1310721,2,2,7,26,2, +40,1590797,16,1310721,2,3,26,1310721,2,2,3,26,2,10,3,6, +10,4,8,1579077,1310721,2,3,26,2,3,1310721,2,5,26,2,26, +1310721,2,5,26,2,26,26,2,10,3,6,10,4,8,1579079,1310721, +2,3,26,2,5,1310721,2,5,26,2,26,1310721,2,5,26,2, +26,26,2,10,3,6,10,4,8,1579081,1,10,3,6,10,4, +8,1310721,2,2,5,26,1310721,2,5,26,2,3,26,10,3,6, +10,4,8,1,1590885,14,1310721,2,2,9,26,2,1,6,1,10, +28,34,63,38,3,26,1590871,16,1579077,1,10,3,6,10,4,8, +1579079,1,10,3,6,10,4,8,1,1590885,14,1586333,12,8,1,1590885, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,4,1579077,2,9,28,1,6,1,10,28,34,63,38,3,26, +1591007,16,1579079,2,1310721,2,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1591009,14,1, +1591015,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,4,1579077,2,5,28,1,6,1,10,28,34,63,38,3, +26,1591137,16,1579079,2,1310721,2,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1591139,14, +1,1591145,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,4,1579077,2,9,28,1,6,1,10,28,34,63,38, +3,26,1591215,16,3,1591265,14,1579077,2,5,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1591327,16,1579079,2,1310721,2,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1591329,14,1, +1591345,16,1590445,12,8,3,1591353,14,1,1591353,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,1591159, +12,1,6,1,10,28,34,63,38,3,26,1591523,16,1591443,14,122, +99,58,32,108,105,110,101,32,0,1591423,1573031,12,8,1579083,2,1573171, +12,8,1591489,14,58,32,101,120,112,101,99,116,101,100,32,0, +1591465,1573031,12,8,1310721,2,2,1573031,12,8,21,1572879,12,8,1572995,12, +8,1,1591531,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1579079,2,1310721,2,4,1579077,2,5,28,1,6,1,10,28, +34,63,38,1,10,28,1591645,16,1591637,14,101,120,112,101,99,116, +101,100,32,97,32,110,97,109,101,0,1591605,1581413,12,8,1590445,12, +8,1310721,2,2,1591663,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +15,28,1310721,4,1310721,2,4,1579027,2,1310721,2,3,26,4,3,1592763, +16,1310721,2,2,2,65,28,1,6,1,10,28,34,63,38,3, +26,1591785,16,1310721,2,1,6,2,1,6,3,26,5,6,4,10, +8,8,1591715,14,1310721,2,2,2,1,6,1,10,28,34,63,38, +3,26,1591821,16,1592763,14,1310721,2,5,26,1,10,3,6,10,4, +8,1310721,2,2,1310721,2,5,26,2,26,2,1591939,16,1310721,2,2, +1310721,2,5,26,2,26,2,65,28,1,6,1,10,28,34,63, +38,1,10,28,1,6,1,10,28,34,63,38,1,10,28,1591941, +14,1,1592029,16,1579097,1310721,2,5,26,2,26,1310721,2,2,1310721,2, +5,26,2,26,2,10,3,6,10,4,8,1310721,2,5,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1591843,14,1579097,1310721, +2,5,26,2,26,1,10,3,6,10,4,8,1310721,2,1310721,2, +2,1310721,2,5,26,2,26,10,3,6,10,4,8,1310721,2,7, +26,1579097,1,26,2,91,28,1,6,1,10,28,34,63,38,3, +26,1592173,16,1579097,3,26,2,1587267,12,1,6,1,10,28,34,63, +38,1,10,28,1592175,14,1,10,3,6,10,4,8,1579097,1310721,2, +7,26,2,26,2,1587267,12,1592503,16,1310721,2,9,26,1,10,3, +6,10,4,8,1310721,2,11,26,1310721,2,7,26,2,10,3,6, +10,4,8,1579097,1310721,2,11,26,2,26,2,1592377,16,1310721,2,9, +26,1310721,2,9,26,2,21,30,1579097,1310721,2,11,26,2,26,2, +26,97,28,10,3,6,10,4,8,1310721,2,11,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1592263,14,1310721,2,7,26, +2,1592425,16,1310721,2,9,26,1,1310721,2,9,26,2,28,10,3, +6,10,4,8,1542657,1579027,2,26,1310721,2,9,26,2,1310721,2,9, +26,2,26,3,26,10,3,6,10,4,8,1579027,1,6,2,1, +6,3,26,5,6,4,10,8,8,1592759,14,1310721,2,5,26,2, +3,28,1,6,1,10,28,34,63,38,3,26,1592605,16,1310721,2, +13,26,1579097,1,26,2,1592793,12,10,3,6,10,4,1,40,3, +36,1,6,1,10,28,34,63,38,1,10,28,1592607,14,1,1592685, +16,1542657,1579027,2,26,1310721,2,13,26,2,1310721,2,13,26,2,26, +10,3,6,10,4,8,1579027,1,6,2,1,6,3,26,5,6, +4,10,8,8,1592759,14,1542657,1579027,2,26,-3,10,3,6,10,4, +8,1542657,1579027,2,3,26,26,1579097,1582085,12,10,3,6,10,4,8, +1579027,1579027,2,5,26,10,3,6,10,4,8,1591709,14,1310721,2,3, +26,2,1592779,14,1,1310721,2,15,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,4,1,1310721,2,3,26,4,1579029,2,1310721,2,3, +26,2,26,2,1592947,16,1579029,2,1310721,2,3,26,2,26,2,1310721, +2,2,28,1,6,1,10,28,34,63,38,3,26,1592909,16,1310721, +2,3,26,2,1592961,14,1310721,2,3,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1592823,14,3,1,10,28,1592961,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,3, +26,4,1310721,2,4,1310721,2,2,1310721,2,3,26,2,26,1310721,2, +5,26,4,1310721,2,2,1310721,2,5,26,2,40,1593359,16,1542657,1310721, +2,2,26,2,-3,28,1,6,1,10,28,34,63,38,3,26, +1593307,16,1310721,2,7,26,1542657,1310721,2,2,3,26,26,2,1583029,12, +10,3,6,10,4,8,1310721,2,7,26,2,1,40,1593191,16,1310721, +2,7,26,1542657,1310721,2,2,3,26,26,2,1584495,12,10,3,6, +10,4,8,1417729,1310721,2,7,26,2,26,2,3,28,1,6,1, +10,28,34,63,38,3,26,1593255,16,1310721,2,7,26,2,1584595,12, +8,1593277,14,1425921,1310721,2,7,26,2,26,2,1584151,12,8,1310721,2, +1310721,2,2,5,26,10,3,6,10,4,8,1593355,14,1542657,1310721,2, +2,26,2,1583993,12,8,1310721,2,1,6,2,1,6,3,26,5, +6,4,10,8,8,1593031,14,1,1593367,14,1,1310721,2,9,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,4,1,1310721,2,3,26, +4,1310721,2,3,26,2,1579025,2,40,1593523,16,1547777,1310721,2,3,26, +2,26,2,1310721,2,2,28,1,6,1,10,28,34,63,38,3, +26,1593485,16,1,1593585,14,1310721,2,3,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1593411,14,1547777,1579025,2,26,1310721,2,2, +10,3,6,10,4,8,1579025,1,6,2,1,6,3,26,5,6, +4,10,8,8,1,1593585,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,4,1579019,2,1310721,2,3,26,4,1310721, +2,3,26,2,1593745,16,1310721,2,3,26,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1546753,1310721,2,3,26,2,26,2,1310721, +2,2,28,1,6,1,10,28,34,63,38,3,26,1593741,16,1310721, +2,3,26,2,1593759,14,1593631,14,3,1,10,28,1593759,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1579021, +2,1310721,2,3,26,4,1310721,2,3,26,2,1593919,16,1310721,2,3, +26,1,6,2,1,6,-1,26,5,6,4,10,8,8,1547265,1310721, +2,3,26,2,26,2,1310721,2,2,28,1,6,1,10,28,34, +63,38,3,26,1593915,16,1310721,2,3,26,2,1593933,14,1593805,14,3, +1,10,28,1593933,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,4,1579023,2,1310721,2,3,26,4,1310721,2,3, +26,2,1594093,16,1310721,2,3,26,1,6,2,1,6,-1,26,5, +6,4,10,8,8,1547457,1310721,2,3,26,2,26,2,1310721,2,2, +28,1,6,1,10,28,34,63,38,3,26,1594089,16,1310721,2,3, +26,2,1594107,14,1593979,14,3,1,10,28,1594107,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,5,26,4,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,1582085,12,1310721,2,7,26, +4,1310721,2,7,26,2,1593599,12,1310721,2,9,26,4,1310721,2,9, +26,2,1,40,1594273,16,1310721,2,9,26,1579019,2,10,3,6,10, +4,8,1579019,1,6,2,1,6,3,26,5,6,4,10,8,8, +1546753,1310721,2,9,26,2,26,1310721,2,7,26,2,10,3,6,10, +4,8,1546881,1310721,2,9,26,2,26,1310721,2,3,26,2,10,3, +6,10,4,8,1310721,2,3,26,2,1,40,1594497,16,1546881,1310721,2, +9,26,2,26,1,1310721,2,3,26,2,28,10,3,6,10,4, +8,1547137,1310721,2,9,26,2,26,1310721,2,3,26,2,10,3,6, +10,4,8,1547009,1310721,2,9,26,2,26,1,10,3,6,10,4, +8,1310721,2,7,26,2,1593381,12,8,1310721,2,9,26,2,1595125,14, +1547009,1310721,2,9,26,2,26,1310721,2,5,26,2,1591677,12,10,3, +6,10,4,8,1547137,1310721,2,9,26,2,26,1579027,2,1547009,1310721,2, +9,26,2,26,2,28,10,3,6,10,4,8,1310721,2,7,26, +2,1593381,12,8,1310721,2,13,26,1310721,2,2,1573535,12,10,3,6, +10,4,8,1579097,2001,26,1310721,2,2,1310721,2,13,26,2,1573943,12, +8,1579097,2001,1310721,2,13,26,2,26,26,123,10,3,6,10,4, +8,1579097,2003,1310721,2,13,26,2,26,26,1,10,3,6,10,4, +8,1310721,2,11,26,1579097,2001,26,1582085,12,10,3,6,10,4,8, +1310721,2,3,26,2,17,40,3,36,1594781,16,3,1594837,14,1310721,2, +3,26,2,11,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1594847,16,3,1594903,14,1310721, +2,3,26,2,9,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1594913,16,3,1594969,14, +1310721,2,3,26,2,7,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1595109,16,1310721,2, +11,26,2,1593947,12,1,40,1595053,16,1547457,1579023,2,26,1310721,2,11, +26,2,10,3,6,10,4,8,1579023,1,6,2,1,6,3,26, +5,6,4,10,8,8,1547585,1310721,2,11,26,2,1593947,12,26,1310721, +2,9,26,2,10,3,6,10,4,8,1310721,2,11,26,2,1593381, +12,8,1310721,2,9,26,2,1595125,14,1,1310721,2,15,26,1310721,4, +18,1310721,2,9,28,1310721,4,1310721,2,3,26,4,1310721,2,4,1310721, +2,2,1582085,12,1310721,2,5,26,4,1310721,2,5,26,2,1593773,12, +1310721,2,7,26,4,1310721,2,7,26,2,1,40,1595281,16,1310721,2, +7,26,1579021,2,10,3,6,10,4,8,1579021,1,6,2,1,6, +3,26,5,6,4,10,8,8,1547265,1310721,2,7,26,2,26,1310721, +2,5,26,2,10,3,6,10,4,8,1547329,1310721,2,7,26,2, +26,1310721,2,3,26,2,1591677,12,10,3,6,10,4,8,1547393,1310721, +2,7,26,2,26,1579027,2,1547329,1310721,2,7,26,2,26,2,28, +10,3,6,10,4,8,1310721,2,5,26,2,1593381,12,8,1310721,2, +7,26,2,1595437,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9, +28,1310721,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4, +1310721,2,2,1582085,12,11,1310721,2,3,26,2,1582581,12,1310721,2,7, +26,4,1442305,1310721,2,7,26,2,26,3,1310721,2,5,26,2,34, +10,3,6,10,4,8,1310721,2,7,26,2,1595581,14,1,1310721,2, +9,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1581305,2, +1310721,2,3,26,4,1310721,2,3,26,2,1581307,2,10,40,1595749,16, +1310721,2,3,26,1,6,2,1,6,-1,26,5,6,4,10,8, +8,1466881,1310721,2,3,26,2,26,2,1310721,2,2,28,1,6,1, +10,28,34,63,38,3,26,1595745,16,1310721,2,3,26,2,1595763,14, +1595627,14,3,1,10,28,1595763,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,4,1581305,2,1310721,2,3,26,4, +1581305,2,1025,40,3,36,1595869,16,1595861,14,116,111,111,32,109,97, +110,121,32,108,111,99,97,108,115,0,1595829,1581413,12,8,1581305,1, +6,2,1,6,3,26,5,6,4,10,8,8,1466881,1310721,2,3, +26,2,26,1310721,2,2,10,3,6,10,4,8,1467905,1310721,2,3, +26,2,26,1581311,2,10,3,6,10,4,8,1468929,1310721,2,3,26, +2,26,1581309,2,10,3,6,10,4,8,1469953,1310721,2,3,26,2, +26,1,10,3,6,10,4,8,1470977,1310721,2,3,26,2,26,1, +10,3,6,10,4,8,1472001,1310721,2,3,26,2,26,1,10,3, +6,10,4,8,1473025,1310721,2,3,26,2,26,1,10,3,6,10, +4,8,1474049,1310721,2,3,26,2,26,1,10,3,6,10,4,8, +1310721,2,3,26,2,1596145,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,4,1469953,1310721,2,2,26,2,11,28, +1,6,1,10,28,34,63,38,3,26,1596249,16,1310721,2,1470977,1310721, +2,2,26,2,10,3,6,10,4,8,1596177,14,1310721,2,2,1596261, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,4,1469953,1310721,2,2,26,2,1,28,1,6,1,10,28,34, +63,38,1,10,28,1596337,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,4,1472001,1310721,2,2,26,3,10,3, +6,10,4,8,1581313,2,1,6,1,10,28,34,63,38,3,26, +1596427,16,1,1596803,14,1310721,2,3,26,1310721,2,2,1596159,12,10,3, +6,10,4,8,1472001,1310721,2,3,26,2,26,3,10,3,6,10, +4,8,1469953,1310721,2,3,26,2,26,2,9,28,1,6,1,10, +28,34,63,38,3,26,1596611,16,1310721,2,2,1596597,14,117,115,101, +100,32,97,102,116,101,114,32,105,116,32,119,97,115,32,103, +105,118,101,110,32,97,119,97,121,0,1596539,1581805,12,8,1,1596803, +14,1469953,1310721,2,3,26,2,26,2,7,28,1,6,1,10,28, +34,63,38,3,26,1596703,16,1468929,1310721,2,3,26,2,26,2,1581309, +2,40,1,6,1,10,28,34,63,38,1,10,28,1596705,14,1, +1596795,16,1468929,1310721,2,3,26,2,26,1581309,2,10,3,6,10,4, +8,1469953,1310721,2,3,26,2,26,3,10,3,6,10,4,8,1474049, +1310721,2,3,26,2,26,3,10,3,6,10,4,8,1,1596803,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +4,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3,26, +1597019,16,1597011,14,97,32,110,101,119,32,111,98,106,101,99,116, +32,99,97,110,39,116,32,98,101,32,117,115,101,100,32,97, +115,32,97,32,112,108,97,105,110,32,118,97,108,117,101,59, +32,98,105,110,100,32,105,116,32,116,111,32,97,32,110,97, +109,101,32,102,105,114,115,116,0,1596873,1581709,12,8,1310721,2,2, +5,40,3,36,1597053,16,1310721,2,2,5,28,1596351,12,8,1,1597061, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,4,1467905,1310721,2,2,26,2,1584865,12,8,3,1584215,12,8,1581407, +2,1584733,12,8,9,1584215,12,8,1,1597145,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,3,26,4,1310721,2, +4,1581305,2,1310721,2,5,26,4,1581313,2,1,6,1,10,28,34, +63,38,3,26,1597235,16,3,1597281,14,1581317,2,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1597291,16,1,1597851,14,1310721,2,5,26,2,1581307,2,10,40,1597843,16, +1310721,2,5,26,1,6,2,1,6,-1,26,5,6,4,10,8, +8,1468929,1310721,2,5,26,2,26,2,1310721,2,2,40,1597379,16,1597291, +14,1310721,2,7,26,1469953,1310721,2,5,26,2,26,2,10,3,6, +10,4,8,1310721,2,7,26,2,3,28,1,6,1,10,28,34, +63,38,3,26,1597473,16,1310721,2,5,26,2,1597075,12,8,1597839,14, +1310721,2,7,26,2,5,28,1,6,1,10,28,34,63,38,3, +26,1597719,16,1310721,2,5,26,2,1597707,14,117,32,111,98,106,101, +99,116,32,109,117,115,116,32,108,101,97,118,101,32,116,104, +105,115,32,98,108,111,99,107,32,40,98,108,111,99,107,32, +118,97,108,117,101,44,32,97,115,115,105,103,110,109,101,110, +116,32,116,111,32,116,104,101,32,101,110,99,108,111,115,105, +110,103,32,98,108,111,99,107,44,32,111,114,32,114,101,116, +117,114,110,41,0,1597525,1581805,12,8,1597839,14,1310721,2,7,26,2, +7,28,1,6,1,10,28,34,63,38,3,26,1597839,16,1310721,2, +5,26,2,1597831,14,100,32,111,98,106,101,99,116,32,119,97, +115,32,110,101,118,101,114,32,103,105,118,101,110,32,97,119, +97,121,0,1597771,1581805,12,8,1597291,14,1,1597851,14,1,1310721,2,9, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2, +1581305,2,40,1598119,16,1581313,2,1597945,16,1474049,1310721,2,2,26,2,1, +6,1,10,28,34,63,38,1,10,28,1597947,14,1,1598009,16,1472001, +1310721,2,2,26,2,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1598011,14,1,1598085,16,1466881, +1310721,2,2,26,2,1598077,14,109,32,111,98,106,101,99,116,32, +105,115,32,110,101,118,101,114,32,117,115,101,100,0,1598031,1581539, +12,8,1310721,2,1,6,2,1,6,3,26,5,6,4,10,8, +8,1597883,14,1,1598127,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,4,1581307,2,1310721,2,3,26,4,1310721,2, +2,1597865,12,8,1581309,2,3,1597159,12,8,1310721,2,3,26,2,1310721, +2,2,40,1598349,16,1468929,1310721,2,3,26,2,26,2,1581309,2,40, +3,36,1598311,16,1469953,1310721,2,3,26,2,26,9,10,3,6,10, +4,8,1468929,1310721,2,3,26,2,26,1581309,2,3,28,10,3,6, +10,4,8,1310721,2,3,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1598197,14,1581305,1310721,2,2,10,3,6,10,4,8, +1,1598377,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28,1310721, +4,1581333,2,1310721,2,4,1581307,2,1310721,2,3,26,4,1310721,2,5, +26,1507841,1310721,2,2,26,10,3,6,10,4,8,1310721,2,5,26, +2,1,26,1581307,2,10,3,6,10,4,8,1310721,2,5,26,2, +3,26,1581305,2,10,3,6,10,4,8,1310721,2,5,26,1310721,2, +5,26,2,5,26,10,3,6,10,4,8,1310721,2,3,26,2, +1581305,2,40,1598769,16,1310721,2,5,26,2,1,26,1469953,1310721,2,3, +26,2,26,2,10,3,6,10,4,8,1310721,2,5,26,2,3, +26,1470977,1310721,2,3,26,2,26,2,10,3,6,10,4,8,1310721, +2,5,26,2,5,26,1468929,1310721,2,3,26,2,26,2,10,3, +6,10,4,8,1310721,2,5,26,1310721,2,5,26,2,7,26,10, +3,6,10,4,8,1310721,2,3,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1598551,14,1581333,1310721,2,5,26,2,1507841,28, +10,3,6,10,4,8,1581333,2,16001,40,3,36,1598893,16,1598885,14, +110,101,115,116,105,110,103,32,116,111,111,32,100,101,101,112, +32,102,111,114,32,116,104,101,32,97,110,97,108,121,122,101, +114,0,1598817,1581413,12,8,1310721,2,2,1598905,14,1,1310721,2,7,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1581333,1310721,2,2, +10,3,6,10,4,8,1,1598965,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,9,28,1310721,4,1310721,2,4,1507841,1310721,2,2,26,1310721, +2,3,26,4,1310721,2,3,26,2,1,26,2,1310721,2,5,26, +4,1310721,2,3,26,2,3,26,2,1310721,2,7,26,4,1310721,2, +7,26,2,1581305,2,10,40,1599115,16,1310721,2,7,26,1581305,2,10, +3,6,10,4,8,1310721,2,3,26,1310721,2,3,26,2,5,26, +10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,7,26,2, +40,1599373,16,1469953,1310721,2,5,26,2,26,1310721,2,3,26,2,1, +26,2,10,3,6,10,4,8,1470977,1310721,2,5,26,2,26,1310721, +2,3,26,2,3,26,2,10,3,6,10,4,8,1468929,1310721,2, +5,26,2,26,1310721,2,3,26,2,5,26,2,10,3,6,10, +4,8,1310721,2,3,26,1310721,2,3,26,2,7,26,10,3,6, +10,4,8,1310721,2,5,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1599149,14,1,1599381,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,1,28,1, +6,1,10,28,34,63,38,3,26,1599453,16,3,1599505,14,1310721,2, +2,9,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1599511,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,11,28,1310721,4,1310721,2,4,1507841,1310721,2,2,26, +1310721,2,3,26,4,1310721,2,3,26,2,1,26,2,1310721,2,5, +26,4,1310721,2,3,26,2,3,26,2,1310721,2,7,26,4,1310721, +2,7,26,2,1581305,2,10,40,1599661,16,1310721,2,7,26,1581305,2, +10,3,6,10,4,8,1310721,2,3,26,1310721,2,3,26,2,5, +26,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,7,26, +2,40,1600285,16,1310721,2,9,26,1469953,1310721,2,5,26,2,26,2, +10,3,6,10,4,8,1310721,2,9,26,2,1599395,12,1599821,16,1310721, +2,3,26,2,1,26,2,1599395,12,1,6,1,10,28,34,63, +38,1,10,28,1599823,14,1,1599903,16,1310721,2,3,26,2,1,26, +2,9,28,1,6,1,10,28,34,63,38,3,26,1599899,16,1469953, +1310721,2,5,26,2,26,9,10,3,6,10,4,8,1600213,14,1310721, +2,9,26,2,1310721,2,3,26,2,1,26,2,28,1,6,1, +10,28,34,63,38,1,10,28,1599963,16,3,1600041,14,1468929,1310721,2, +5,26,2,26,2,1310721,2,3,26,2,5,26,2,28,1,6, +1,10,28,34,63,38,1,10,28,1,6,1,10,28,34,63, +38,1,10,28,1600051,16,3,1600195,14,1310721,2,9,26,2,11,28, +1,6,1,10,28,34,63,38,3,26,1600171,16,1470977,1310721,2,5, +26,2,26,2,1310721,2,3,26,2,3,26,2,28,1,6,1, +10,28,34,63,38,1,10,28,1,6,1,10,28,34,63,38, +1,10,28,1600173,14,1,1,6,1,10,28,34,63,38,1,10, +28,1600213,16,1310721,2,5,26,2,1600299,14,1310721,2,3,26,1310721,2, +3,26,2,7,26,10,3,6,10,4,8,1310721,2,5,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1599695,14,3,1, +10,28,1600299,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1310721,2,2,1,28,1,6,1,10,28,34, +63,38,3,26,1600387,16,1600381,14,101,109,112,116,121,0,1600369,1600713, +14,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3,26, +1600435,16,1600429,14,109,0,1600425,1600713,14,1310721,2,2,5,28,1,6, +1,10,28,34,63,38,3,26,1600483,16,1600477,14,117,0,1600473,1600713, +14,1310721,2,2,7,28,1,6,1,10,28,34,63,38,3,26, +1600531,16,1600525,14,100,0,1600521,1600713,14,1310721,2,2,9,28,1,6, +1,10,28,34,63,38,3,26,1600597,16,1600591,14,103,105,118,101, +110,32,97,119,97,121,0,1600569,1600713,14,1310721,2,2,11,28,1, +6,1,10,28,34,63,38,3,26,1600683,16,1600677,14,111,119,110, +101,100,32,98,121,32,97,32,99,111,110,116,97,105,110,101, +114,0,1600635,1600713,14,1600705,14,98,111,114,114,111,119,101,100,0, +1600687,1600713,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1581313,2, +1,6,1,10,28,34,63,38,3,26,1600799,16,1,1601075,14,1600823, +14,122,99,58,32,108,105,110,101,32,0,1600803,1573031,12,8,1579083, +2,1573171,12,8,1600851,14,58,32,0,1600845,1573031,12,8,1466881,1310721,2, +2,26,2,1573031,12,8,1600887,14,58,32,0,1600881,1573031,12,8,1310721, +2,5,26,2,1573031,12,8,1600959,14,32,40,111,110,101,32,112, +97,116,104,32,108,101,97,118,101,115,32,105,116,32,0,1600915, +1573031,12,8,1310721,2,3,26,2,1600313,12,1573031,12,8,1601013,14,44, +32,97,110,111,116,104,101,114,32,0,1600991,1573031,12,8,1469953,1310721, +2,2,26,2,1600313,12,1573031,12,8,1601053,14,41,10,0,1601047,1573031, +12,8,1572995,12,8,1,1601075,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,3,26,4,1310721,2,4,1310721,2, +3,26,2,1,6,1,10,28,34,63,38,3,26,1601157,16,1, +1601475,14,1581317,2,1,6,1,10,28,34,63,38,3,26,1601219,16, +1310721,2,2,1598979,12,8,1581317,3,10,3,6,10,4,8,1,1601475, +14,1310721,2,5,26,1310721,2,2,1599525,12,10,3,6,10,4,8, +1310721,2,5,26,2,1,40,3,36,1601467,16,1310721,2,7,26,1507841, +1310721,2,2,26,5,26,7,1310721,2,5,26,2,1507841,1310721,2,2, +26,2,28,30,26,10,3,6,10,4,8,1310721,2,5,26,2, +1310721,2,7,26,2,1,26,2,1601459,14,101,110,100,115,32,116, +104,101,32,98,114,97,110,99,104,101,115,32,111,102,32,97, +110,32,105,102,32,105,110,32,100,105,102,102,101,114,101,110, +116,32,115,116,97,116,101,115,0,1601365,1600727,12,8,1,1601475,14, +1,1310721,2,9,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2, +4,1581313,2,1,6,1,10,28,34,63,38,3,26,1601541,16,3, +1601587,14,1581317,2,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1601597,16,1,1601899,14,1310721,2, +3,26,1310721,2,2,1599525,12,10,3,6,10,4,8,1310721,2,3, +26,2,1,40,3,36,1601891,16,1310721,2,5,26,1507841,1310721,2,2, +26,5,26,7,1310721,2,3,26,2,1507841,1310721,2,2,26,2,28, +30,26,10,3,6,10,4,8,1310721,2,3,26,2,1310721,2,5, +26,2,1,26,2,1601883,14,99,104,97,110,103,101,115,32,115, +116,97,116,101,32,105,110,115,105,100,101,32,97,32,108,111, +111,112,59,32,101,97,99,104,32,112,97,115,115,32,104,97, +115,32,116,111,32,108,101,97,118,101,32,105,116,32,97,115, +32,105,116,32,102,111,117,110,100,32,105,116,0,1601743,1600727,12, +8,1,1601899,14,1,1310721,2,7,26,1310721,4,18,1310721,2,9,28, +1310721,4,1310721,2,3,26,4,1310721,2,4,1581313,2,1,6,1,10, +28,34,63,38,3,26,1601979,16,1310721,2,2,1602949,14,1310721,2,2, +5,40,1602095,16,1602077,14,111,110,108,121,32,97,32,110,97,109, +101,100,32,111,119,110,101,100,32,111,98,106,101,99,116,32, +99,97,110,32,98,101,32,114,101,99,97,115,116,0,1601997,1581709, +12,8,1310721,2,2,1602949,14,1310721,2,5,26,1310721,2,2,5,28, +10,3,6,10,4,8,1310721,2,7,26,1469953,1310721,2,5,26,2, +26,2,10,3,6,10,4,8,1472001,1310721,2,5,26,2,26,3, +10,3,6,10,4,8,1310721,2,7,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1602359,16,1310721,2,5,26,2,1602347,14, +98,101,108,111,110,103,115,32,116,111,32,97,32,99,111,110, +116,97,105,110,101,114,59,32,114,101,99,97,115,116,32,116, +104,101,32,99,111,110,116,97,105,110,101,114,32,105,110,115, +116,101,97,100,0,1602241,1581805,12,8,1602937,14,1310721,2,7,26,2, +13,28,1,6,1,10,28,34,63,38,3,26,1602487,16,1310721,2, +5,26,2,1602475,14,105,115,32,98,111,114,114,111,119,101,100, +32,97,110,100,32,99,97,110,39,116,32,98,101,32,114,101, +99,97,115,116,0,1602411,1581805,12,8,1602937,14,1310721,2,7,26,2, +1,28,1,6,1,10,28,34,63,38,3,26,1602595,16,1310721,2, +5,26,2,1602583,14,105,115,110,39,116,32,97,110,32,111,119, +110,101,100,32,111,98,106,101,99,116,0,1602539,1581805,12,8,1602937, +14,1310721,2,7,26,2,9,28,1,6,1,10,28,34,63,38, +3,26,1602717,16,1310721,2,5,26,2,1602705,14,117,115,101,100,32, +97,102,116,101,114,32,105,116,32,119,97,115,32,103,105,118, +101,110,32,97,119,97,121,0,1602647,1581805,12,8,1602937,14,1310721,2, +3,26,2,3,28,1,6,1,10,28,34,63,38,3,26,1602817, +16,1310721,2,7,26,2,3,28,1,6,1,10,28,34,63,38, +1,10,28,1,6,1,10,28,34,63,38,1,10,28,1602819,14, +1,1602901,16,1310721,2,5,26,2,1602889,14,99,97,110,39,116,32, +98,101,32,114,101,99,97,115,116,32,98,97,99,107,32,116, +111,32,109,0,1602837,1581805,12,8,1602937,14,1469953,1310721,2,5,26,2, +26,1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,2,1602949, +14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721, +2,3,26,4,1310721,2,4,1581313,2,1,6,1,10,28,34,63, +38,3,26,1603025,16,1,1604681,14,1310721,2,2,3,28,1,6,1, +10,28,34,63,38,3,26,1603269,16,1310721,2,3,26,2,5,28, +1,6,1,10,28,34,63,38,1,10,28,1603263,16,1603255,14,97, +32,110,101,119,32,111,98,106,101,99,116,32,99,97,110,32, +111,110,108,121,32,103,111,32,115,116,114,97,105,103,104,116, +32,116,111,32,97,32,100,32,112,97,114,97,109,101,116,101, +114,59,32,98,105,110,100,32,105,116,32,116,111,32,97,32, +110,97,109,101,32,102,105,114,115,116,0,1603103,1581709,12,8,1, +1604681,14,1310721,2,2,5,40,1603289,16,3,1603345,14,1310721,2,2,5, +28,1596275,12,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1603355,16,1,1604681,14,1310721,2,5, +26,1310721,2,2,5,28,10,3,6,10,4,8,1310721,2,7,26, +1469953,1310721,2,5,26,2,26,2,10,3,6,10,4,8,1469953,1310721, +2,5,26,2,1596159,12,26,2,9,28,1,6,1,10,28,34, +63,38,3,26,1603555,16,1310721,2,5,26,2,1603541,14,117,115,101, +100,32,97,102,116,101,114,32,105,116,32,119,97,115,32,103, +105,118,101,110,32,97,119,97,121,0,1603483,1581805,12,8,1,1604681, +14,1310721,2,3,26,2,1,28,1,6,1,10,28,34,63,38, +3,26,1603751,16,1310721,2,5,26,2,1603737,14,105,115,32,97,110, +32,111,119,110,101,100,32,111,98,106,101,99,116,59,32,105, +116,32,99,97,110,32,111,110,108,121,32,98,101,32,112,97, +115,115,101,100,32,116,111,32,97,110,32,109,32,111,114,32, +100,32,112,97,114,97,109,101,116,101,114,0,1603607,1581805,12,8, +1,1604681,14,1310721,2,3,26,2,3,28,1,6,1,10,28,34, +63,38,3,26,1603993,16,1310721,2,7,26,2,7,28,1,6,1, +10,28,34,63,38,3,26,1603971,16,1310721,2,5,26,2,1603957,14, +105,115,32,100,59,32,112,97,115,115,32,105,116,32,116,111, +32,97,32,100,32,112,97,114,97,109,101,116,101,114,32,40, +108,101,110,100,105,110,103,32,105,116,32,119,111,117,108,100, +32,108,111,115,101,32,105,116,41,0,1603841,1581805,12,8,1,1604681, +14,1310721,2,5,26,2,1596351,12,8,1,1604681,14,1310721,2,7,26, +2,7,28,1,6,1,10,28,34,63,38,3,26,1604093,16,1469953, +1310721,2,5,26,2,26,9,10,3,6,10,4,8,1472001,1310721,2, +5,26,2,26,3,10,3,6,10,4,8,1,1604681,14,1310721,2, +7,26,2,3,28,1,6,1,10,28,34,63,38,3,26,1604227, +16,1310721,2,5,26,2,1604215,14,105,115,32,109,59,32,119,114, +105,116,101,32,39,97,115,32,100,39,32,116,111,32,103,105, +118,101,32,105,116,32,97,119,97,121,0,1604145,1581805,12,8,1604673, +14,1310721,2,7,26,2,5,28,1,6,1,10,28,34,63,38, +3,26,1604409,16,1310721,2,5,26,2,1604397,14,105,115,32,117,59, +32,119,114,105,116,101,32,39,97,115,32,100,39,32,116,111, +32,103,105,118,101,32,105,116,32,97,119,97,121,32,105,110, +115,116,101,97,100,32,111,102,32,114,101,116,117,114,110,105, +110,103,32,105,116,0,1604279,1581805,12,8,1604673,14,1310721,2,7,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1604579,16,1310721, +2,5,26,2,1604567,14,98,101,108,111,110,103,115,32,116,111, +32,97,32,99,111,110,116,97,105,110,101,114,32,97,110,100, +32,99,97,110,39,116,32,98,101,32,103,105,118,101,110,32, +97,119,97,121,32,97,108,111,110,101,0,1604461,1581805,12,8,1604673, +14,1310721,2,5,26,2,1604665,14,105,115,32,98,111,114,114,111, +119,101,100,32,97,110,100,32,99,97,110,39,116,32,98,101, +32,103,105,118,101,110,32,97,119,97,121,0,1604593,1581805,12,8, +1,1604681,14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,4,1467905,1310721,2,2,26,2,1584865,12,8,3,1584215,12, +8,1581409,2,1584733,12,8,1,1604757,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,15,28,1310721,4,1310721,2,5,26,4,1310721,2,3,26, +4,1310721,2,4,1581313,2,1,6,1,10,28,34,63,38,3,26, +1604843,16,1,1608095,14,1310721,2,9,26,3,1,10,28,10,3,6, +10,4,8,1310721,2,5,26,2,5,40,3,36,1604937,16,1310721,2, +5,26,2,5,28,1596275,12,1,6,1,10,28,34,63,38,1, +10,28,1604939,14,1,1604977,16,1310721,2,9,26,1310721,2,5,26,2, +5,28,10,3,6,10,4,8,1310721,2,9,26,2,1,40,3, +36,1605069,16,1469953,1310721,2,9,26,2,1596159,12,26,2,9,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1605071,14,1,1605161,16,1310721,2,9,26,2,1605147,14, +117,115,101,100,32,97,102,116,101,114,32,105,116,32,119,97, +115,32,103,105,118,101,110,32,97,119,97,121,0,1605089,1581805,12, +8,1,1608095,14,1310721,2,2,3,28,1,6,1,10,28,34,63, +38,3,26,1606493,16,1310721,2,7,26,1469953,1310721,2,3,26,2,26, +2,10,3,6,10,4,8,1310721,2,9,26,2,1,40,1605311,16, +1310721,2,5,26,2,3,28,1,6,1,10,28,34,63,38,1, +10,28,1,6,1,10,28,34,63,38,1,10,28,1605313,14,1, +1605517,16,1310721,2,7,26,2,1599395,12,1,6,1,10,28,34,63, +38,3,26,1605483,16,1310721,2,3,26,2,1605471,14,115,116,105,108, +108,32,111,119,110,115,32,97,110,32,111,98,106,101,99,116, +59,32,111,118,101,114,119,114,105,116,105,110,103,32,105,116, +32,119,111,117,108,100,32,108,101,97,107,32,105,116,0,1605369, +1581805,12,8,1605511,14,1469953,1310721,2,3,26,2,26,1,10,3,6, +10,4,8,1,1608095,14,1310721,2,7,26,2,1599395,12,1,6,1, +10,28,34,63,38,3,26,1605685,16,1310721,2,3,26,2,1605671,14, +115,116,105,108,108,32,111,119,110,115,32,97,110,32,111,98, +106,101,99,116,59,32,111,118,101,114,119,114,105,116,105,110, +103,32,105,116,32,119,111,117,108,100,32,108,101,97,107,32, +105,116,0,1605569,1581805,12,8,1,1608095,14,1310721,2,5,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1605813,16,1469953,1310721,2, +3,26,2,26,3,10,3,6,10,4,8,1472001,1310721,2,3,26, +2,26,1,10,3,6,10,4,8,1474049,1310721,2,3,26,2,26, +3,10,3,6,10,4,8,1,1608095,14,1310721,2,13,26,1469953,1310721, +2,9,26,2,26,2,10,3,6,10,4,8,1310721,2,13,26, +2,5,28,1,6,1,10,28,34,63,38,3,26,1605971,16,1468929, +1310721,2,3,26,2,26,2,1468929,1310721,2,9,26,2,26,2,3, +28,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1605973,14,1,1606123,16,1469953,1310721,2,3, +26,2,26,3,10,3,6,10,4,8,1472001,1310721,2,3,26,2, +26,1,10,3,6,10,4,8,1474049,1310721,2,3,26,2,26,3, +10,3,6,10,4,8,1469953,1310721,2,9,26,2,26,9,10,3, +6,10,4,8,1472001,1310721,2,9,26,2,26,3,10,3,6,10, +4,8,1,1608095,14,1310721,2,13,26,2,5,28,1,6,1,10, +28,34,63,38,3,26,1606343,16,1310721,2,9,26,2,1606331,14,105, +115,32,117,59,32,105,116,32,99,97,110,32,111,110,108,121, +32,98,101,32,104,97,110,100,101,100,32,116,111,32,97,32, +118,97,114,105,97,98,108,101,32,111,102,32,116,104,101,32, +101,110,99,108,111,115,105,110,103,32,98,108,111,99,107,44, +32,111,114,32,114,101,116,117,114,110,101,100,0,1606175,1581805,12, +8,1606487,14,1310721,2,9,26,2,1606479,14,105,115,32,97,110,32, +111,119,110,101,100,32,111,98,106,101,99,116,32,97,110,100, +32,99,97,110,39,116,32,98,101,32,99,111,112,105,101,100, +32,105,110,116,111,32,97,110,111,116,104,101,114,32,118,97, +114,105,97,98,108,101,0,1606357,1581805,12,8,1,1608095,14,1310721,2, +2,7,28,1,6,1,10,28,34,63,38,3,26,1607763,16,1310721, +2,11,26,1310721,2,3,26,2,1596159,12,10,3,6,10,4,8, +1310721,2,7,26,1469953,1310721,2,11,26,2,26,2,10,3,6,10, +4,8,1310721,2,3,26,2,1596351,12,8,1310721,2,5,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1606673,16,1310721,2,3, +26,2,1604695,12,8,1,1608095,14,1310721,2,9,26,2,1,40,1606697, +16,1,1608095,14,1310721,2,13,26,1469953,1310721,2,9,26,2,26,2, +10,3,6,10,4,8,1310721,2,13,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1606859,16,1310721,2,9,26,2,1606847,14, +97,108,114,101,97,100,121,32,98,101,108,111,110,103,115,32, +116,111,32,97,32,99,111,110,116,97,105,110,101,114,0,1606785, +1581805,12,8,1607757,14,1310721,2,13,26,2,13,28,1,6,1,10, +28,34,63,38,3,26,1606987,16,1310721,2,9,26,2,1606975,14,105, +115,32,98,111,114,114,111,119,101,100,32,97,110,100,32,99, +97,110,39,116,32,98,101,32,115,116,111,114,101,100,0,1606911, +1581805,12,8,1607757,14,1310721,2,7,26,2,13,28,1,6,1,10, +28,34,63,38,3,26,1607259,16,1310721,2,13,26,2,7,28,1, +6,1,10,28,34,63,38,1,10,28,1607183,16,1310721,2,9,26, +2,1607171,14,109,117,115,116,32,98,101,32,100,32,116,111,32, +98,101,32,115,116,111,114,101,100,32,105,110,116,111,32,97, +32,98,111,114,114,111,119,101,100,32,111,98,106,101,99,116, +0,1607079,1581805,12,8,1607255,14,1469953,1310721,2,9,26,2,26,9,10, +3,6,10,4,8,1472001,1310721,2,9,26,2,26,3,10,3,6, +10,4,8,1310721,2,3,26,2,1604695,12,8,1607757,14,1310721,2,13, +26,2,1310721,2,7,26,2,28,1,6,1,10,28,34,63,38, +1,10,28,1607465,16,1310721,2,9,26,2,1607453,14,105,116,115,32, +116,97,103,32,100,111,101,115,110,39,116,32,109,97,116,99, +104,32,105,116,115,32,99,111,110,116,97,105,110,101,114,39, +115,32,40,98,111,116,104,32,104,97,118,101,32,116,111,32, +98,101,32,109,44,32,117,32,111,114,32,100,41,0,1607321,1581805, +12,8,1607757,14,1468929,1310721,2,9,26,2,26,2,1468929,1310721,2,11, +26,2,26,2,40,1607649,16,1310721,2,9,26,2,1607637,14,108,105, +118,101,115,32,105,110,32,97,110,32,111,117,116,101,114,32, +98,108,111,99,107,32,116,104,97,110,32,116,104,101,32,99, +111,110,116,97,105,110,101,114,32,105,116,39,115,32,115,116, +111,114,101,100,32,105,110,116,111,0,1607517,1581805,12,8,1607757,14, +1469953,1310721,2,9,26,2,26,11,10,3,6,10,4,8,1470977,1310721, +2,9,26,2,26,1310721,2,3,26,2,10,3,6,10,4,8, +1472001,1310721,2,9,26,2,26,3,10,3,6,10,4,8,1310721,2, +3,26,2,1604695,12,8,1,1608095,14,1310721,2,9,26,2,1,40, +3,36,1608087,16,1469953,1310721,2,9,26,2,26,2,7,28,1,6, +1,10,28,34,63,38,3,26,1607889,16,1469953,1310721,2,9,26,2, +26,9,10,3,6,10,4,8,1472001,1310721,2,9,26,2,26,3, +10,3,6,10,4,8,1608087,14,1310721,2,9,26,2,1608079,14,109, +117,115,116,32,98,101,32,100,32,116,111,32,98,101,32,115, +116,111,114,101,100,32,105,110,32,97,32,103,108,111,98,97, +108,32,111,114,32,105,110,32,117,110,116,114,97,99,107,101, +100,32,109,101,109,111,114,121,32,40,116,104,101,32,99,111, +108,108,101,99,116,111,114,32,116,97,107,101,115,32,105,116, +32,111,118,101,114,41,0,1607903,1581805,12,8,1,1608095,14,1,1310721, +2,15,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1581313, +2,1,6,1,10,28,34,63,38,3,26,1608161,16,1,1609057,14, +1310721,2,3,26,3,1,10,28,10,3,6,10,4,8,1310721,2, +2,5,40,3,36,1608247,16,1310721,2,2,5,28,1596275,12,1,6, +1,10,28,34,63,38,1,10,28,1608249,14,1,1608283,16,1310721,2, +3,26,1310721,2,2,5,28,10,3,6,10,4,8,1310721,2,3, +26,2,1,40,3,36,1608375,16,1469953,1310721,2,3,26,2,1596159,12, +26,2,9,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1608377,14,1,1608467,16,1310721,2, +3,26,2,1608453,14,117,115,101,100,32,97,102,116,101,114,32, +105,116,32,119,97,115,32,103,105,118,101,110,32,97,119,97, +121,0,1608395,1581805,12,8,1,1609057,14,1581315,2,1608729,16,1310721,2,3, +26,2,1,40,3,36,1608723,16,1469953,1310721,2,3,26,2,26,2, +5,28,1,6,1,10,28,34,63,38,3,26,1608601,16,1469953,1310721, +2,3,26,2,26,9,10,3,6,10,4,8,1472001,1310721,2,3, +26,2,26,3,10,3,6,10,4,8,1608723,14,1310721,2,3,26, +2,1608715,14,104,97,115,32,116,111,32,98,101,32,117,32,116, +111,32,98,101,32,114,101,116,117,114,110,101,100,59,32,119, +114,105,116,101,32,39,114,101,116,117,114,110,32,120,32,97, +115,32,117,39,0,1608615,1581805,12,8,1,1609057,14,1310721,2,2,3, +28,1,6,1,10,28,34,63,38,3,26,1608885,16,1608873,14,114, +101,116,117,114,110,115,32,97,32,110,101,119,32,111,98,106, +101,99,116,59,32,100,101,99,108,97,114,101,32,116,104,101, +32,102,117,110,99,116,105,111,110,32,119,105,116,104,32,45, +62,32,117,0,1608767,1581709,12,8,1609049,14,1310721,2,3,26,2,1, +40,3,36,1609049,16,1310721,2,3,26,2,1609041,14,105,115,32,111, +119,110,101,100,32,97,110,100,32,99,97,110,39,116,32,98, +101,32,114,101,116,117,114,110,101,100,32,102,114,111,109,32, +97,32,102,117,110,99,116,105,111,110,32,119,105,116,104,111, +117,116,32,45,62,32,117,0,1608921,1581805,12,8,1,1609057,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4, +1581313,2,1,6,1,10,28,34,63,38,3,26,1609123,16,1,1609751, +14,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3,26, +1609163,16,3,1609751,14,1310721,2,2,5,40,1609183,16,3,1609239,14,1310721, +2,2,5,28,1596275,12,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1609249,16,1,1609751,14, +1310721,2,3,26,1310721,2,2,5,28,10,3,6,10,4,8,1469953, +1310721,2,3,26,2,26,2,5,28,1,6,1,10,28,34,63, +38,3,26,1609391,16,1468929,1310721,2,3,26,2,26,2,1581309,2,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1609393,14,1,1609459,16,1469953,1310721,2,3,26,2, +26,9,10,3,6,10,4,8,1472001,1310721,2,3,26,2,26,3, +10,3,6,10,4,8,3,1609751,14,1469953,1310721,2,3,26,2,26, +2,5,28,1,6,1,10,28,34,63,38,3,26,1609623,16,1310721, +2,3,26,2,1609611,14,111,110,108,121,32,97,32,117,32,111, +98,106,101,99,116,32,111,102,32,116,104,105,115,32,98,108, +111,99,107,32,99,97,110,32,98,101,32,105,116,115,32,118, +97,108,117,101,0,1609517,1581805,12,8,1609743,14,1310721,2,3,26,2, +1609735,14,104,97,115,32,116,111,32,98,101,32,117,32,116,111, +32,98,101,32,104,97,110,100,101,100,32,117,112,32,97,115, +32,116,104,101,32,98,108,111,99,107,39,115,32,118,97,108, +117,101,0,1609637,1581805,12,8,1,1609751,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,3,28, +1,6,1,10,28,34,63,38,3,26,1609933,16,1609921,14,97,32, +110,101,119,32,111,98,106,101,99,116,32,40,111,114,32,97, +32,117,32,114,101,115,117,108,116,41,32,99,97,110,39,116, +32,98,101,32,116,104,114,111,119,110,32,97,119,97,121,0, +1609821,1581709,12,8,1609967,14,1310721,2,2,5,40,3,36,1609967,16,1310721, +2,2,5,28,1596351,12,8,1,1609975,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,1,28,1310721,4,1581335,2,1610033,16,3,1584215,12,8, +1581335,1,10,3,6,10,4,8,1,1610041,14,1,1310721,2,1,26, +1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,3,26,4,1310721,2, +4,1425921,1310721,2,2,26,2,1310721,2,5,26,4,1581341,2,1310721,2, +7,26,4,1581341,1310721,2,3,26,2,10,3,6,10,4,8,1581343, +1,10,3,6,10,4,8,1310721,2,5,26,2,1,6,12,10, +8,8,1581341,1310721,2,7,26,2,10,3,6,10,4,8,1310721,2, +9,26,1581343,2,10,3,6,10,4,8,1581335,1,10,3,6,10, +4,8,1581337,1,10,3,6,10,4,8,1310721,2,9,26,2,1610277, +14,1,1310721,2,11,26,1310721,4,18,1310721,2,1,28,1310721,4,1581341, +2,1610403,16,1610395,14,116,104,105,115,32,99,97,110,39,116,32, +98,101,32,117,115,101,100,32,105,110,115,105,100,101,32,97, +110,32,101,120,112,114,101,115,115,105,111,110,0,1610315,1581413,12, +8,1,1610411,14,1,1310721,2,1,26,1310721,4,18,1310721,2,11,28, +1310721,4,1310721,2,4,1,1310721,2,3,26,4,1,1310721,2,5,26, +4,1,1310721,2,7,26,4,1442305,1310721,2,2,26,2,5,32,1610575, +16,1310721,2,5,26,1434113,1310721,2,2,26,2,13,38,10,3,6, +10,4,8,1310721,2,7,26,1434113,1310721,2,2,26,2,3,32,10, +3,6,10,4,8,1610613,14,1442305,1310721,2,2,26,1442305,1310721,2,2, +26,2,9,34,10,3,6,10,4,8,1581345,2,1591367,12,8,1581347, +2,1590899,12,1,6,1,10,28,34,63,38,3,26,1610819,16,3, +1610819,16,1310721,2,9,26,1616659,12,10,3,6,10,4,8,1609989,12, +8,1310721,2,9,26,2,1310721,2,5,26,2,1310721,2,3,26,2, +1310721,2,3,26,2,26,38,7,32,1602963,12,8,1310721,2,3,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1581357,2,1591159, +12,1,6,1,10,28,34,63,38,3,26,1610815,16,1610819,14,1610655, +14,1581347,2,1591367,12,8,1442305,1310721,2,2,26,2,5,32,1610929,16, +1310721,2,3,26,2,1434113,1310721,2,2,26,2,3,38,63,32,28, +1,6,1,10,28,34,63,38,1,10,28,1,6,1,10,28, +34,63,38,1,10,28,1610931,14,1,1611011,16,1409537,1310721,2,2,26, +2,1611003,14,119,114,111,110,103,32,110,117,109,98,101,114,32, +111,102,32,97,114,103,117,109,101,110,116,115,0,1610951,1581539,12, +8,1310721,2,2,1584595,12,8,13,1584215,12,8,1581335,1,10,3,6, +10,4,8,1581337,1,10,3,6,10,4,8,1310721,2,7,26,2, +1611083,16,3,1611091,14,1,1611091,14,1,1310721,2,11,26,1310721,4,18, +1310721,2,9,28,1310721,4,1581335,1,10,3,6,10,4,8,1581337,1, +10,3,6,10,4,8,1579077,2,3,28,1,6,1,10,28,34, +63,38,3,26,1611203,16,1579079,2,1584151,12,8,1590445,12,8,1,1612793, +14,1579077,2,7,28,1,6,1,10,28,34,63,38,3,26,1611257, +16,1579079,2,1584951,12,8,1590445,12,8,1,1612793,14,1579077,2,9,28, +1,6,1,10,28,34,63,38,3,26,1611477,16,1579079,2,1581345,2, +28,1,6,1,10,28,34,63,38,3,26,1611377,16,1590445,12,8, +1310721,2,7,26,1616659,12,10,3,6,10,4,8,1581347,2,1591367,12, +8,1310721,2,7,26,2,1612793,14,1579079,2,1581349,2,28,1,6,1, +10,28,34,63,38,3,26,1611419,16,1618013,12,1612793,14,1611469,14,101, +120,112,101,99,116,101,100,32,97,110,32,101,120,112,114,101, +115,115,105,111,110,0,1611423,1581413,12,8,1579077,2,5,28,1,6, +1,10,28,34,63,38,1,10,28,1611569,16,1611561,14,101,120,112, +101,99,116,101,100,32,97,110,32,101,120,112,114,101,115,115, +105,111,110,0,1611515,1581413,12,8,1310721,2,1579079,2,10,3,6,10, +4,8,1310721,2,3,26,1310721,2,2,1595595,12,10,3,6,10,4, +8,1310721,2,3,26,2,1,40,3,36,1612011,16,1590445,12,8,1581313, +2,1,6,1,10,28,34,63,38,3,26,1611715,16,1310721,2,3, +26,2,1596275,12,1,6,1,10,28,34,63,38,1,10,28,1611717, +14,1,1611865,16,1310721,2,2,1611857,14,105,115,32,116,114,97,99, +107,101,100,32,98,121,32,116,104,101,32,97,110,97,108,121, +122,101,114,32,97,110,100,32,99,97,110,39,116,32,98,101, +32,117,115,101,100,32,105,110,32,117,110,99,104,101,99,107, +101,100,32,99,111,100,101,0,1611731,1581539,12,8,1467905,1310721,2,3, +26,2,26,2,1584865,12,8,1473025,1310721,2,3,26,2,26,2,1611913, +16,1,1612793,14,1581335,3,10,3,6,10,4,8,1581337,3,10,3, +6,10,4,8,1581339,1310721,2,3,26,2,10,3,6,10,4,8, +1310721,2,3,26,2,1596275,12,1612005,16,5,1310721,2,3,26,2,26, +1612793,14,1,1612793,14,1310721,2,5,26,1310721,2,2,1583029,12,10,3, +6,10,4,8,1310721,2,5,26,2,1,40,3,36,1612129,16,1417729, +1310721,2,5,26,2,26,2,11,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1612131,14, +1,1612287,16,1442305,1310721,2,5,26,2,26,2,33,32,1,6,1, +10,28,34,63,38,3,26,1612267,16,1310721,2,2,1612259,14,99,97, +110,39,116,32,98,101,32,117,115,101,100,32,105,110,115,105, +100,101,32,97,110,32,101,120,112,114,101,115,115,105,111,110, +0,1612189,1581539,12,8,1310721,2,5,26,2,3,1610055,12,1612793,14,1590445, +12,8,1310721,2,5,26,2,1,40,3,36,1612381,16,1417729,1310721,2, +5,26,2,26,2,9,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1612383,14,1,1612415, +16,1425921,1310721,2,5,26,2,26,2,1584151,12,8,1,1612793,14,1310721, +2,5,26,2,1,40,3,36,1612503,16,1417729,1310721,2,5,26,2, +26,2,5,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1612505,14,1,1612569,16,1425921,1310721, +2,5,26,2,26,2,1584151,12,8,1581335,3,10,3,6,10,4, +8,1581337,5,10,3,6,10,4,8,1,1612793,14,1310721,2,5,26, +2,1,40,3,36,1612657,16,1417729,1310721,2,5,26,2,26,2,7, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1612659,14,1,1612691,16,1425921,1310721,2,5,26, +2,26,2,1584151,12,8,1,1612793,14,1310721,2,5,26,2,1,40, +1612739,16,1310721,2,5,26,1310721,2,2,1584495,12,10,3,6,10,4, +8,1581345,2,1590899,12,1612769,16,1310721,2,5,26,2,1610425,12,1612793,14, +1310721,2,5,26,2,1584595,12,8,1,1612793,14,1,1310721,2,9,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3,26,4,1310721,2, +4,1581335,2,1,6,1,10,28,34,63,38,3,26,1612951,16,1612943, +14,43,43,32,97,110,100,32,45,45,32,110,101,101,100,32, +115,111,109,101,116,104,105,110,103,32,116,111,32,97,115,115, +105,103,110,32,116,111,0,1612867,1581413,12,8,1581337,2,3,28,1, +6,1,10,28,34,63,38,3,26,1613013,16,1581313,2,1,6,1, +10,28,34,63,38,1,10,28,1613015,14,1,1613053,16,1581339,2,1596275, +12,1,6,1,10,28,34,63,38,1,10,28,1613055,14,1,1613155, +16,1581339,2,1613147,14,111,119,110,115,32,97,110,32,111,98,106, +101,99,116,32,97,110,100,32,99,97,110,39,116,32,98,101, +32,105,110,99,114,101,109,101,110,116,101,100,0,1613067,1581805,12, +8,1581335,1,10,3,6,10,4,8,1581337,1,10,3,6,10,4, +8,1,1584151,12,8,7,1584215,12,8,3,1584215,12,8,1310721,2,2, +1613289,16,1,1584151,12,8,7,1584215,12,8,1310721,2,3,26,2,1584151, +12,8,27,1584215,12,8,5,1584151,12,8,7,1584215,12,8,5,1584215, +12,8,1613353,14,1310721,2,3,26,2,1584151,12,8,27,1584215,12,8, +1,1584151,12,8,7,1584215,12,8,5,1584151,12,8,7,1584215,12,8, +5,1584215,12,8,11,1584215,12,8,9,1584215,12,8,1,1613377,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721,4,1611105,12,1310721, +2,4,3,1614945,16,1579077,2,5,28,1,6,1,10,28,34,63, +38,3,26,1613507,16,1579079,2,1581391,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1613509, +14,1,1613935,16,1590445,12,8,1579077,2,5,28,1,6,1,10,28, +34,63,38,1,10,28,1613621,16,1613613,14,101,120,112,101,99,116, +101,100,32,117,44,32,100,32,111,114,32,109,32,97,102,116, +101,114,32,97,115,0,1613557,1581413,12,8,1310721,2,7,26,3,10, +3,6,10,4,8,1579079,2,1581401,2,28,1,6,1,10,28,34, +63,38,3,26,1613703,16,1310721,2,7,26,5,10,3,6,10,4, +8,1613867,14,1579079,2,1581399,2,28,1,6,1,10,28,34,63,38, +3,26,1613763,16,1310721,2,7,26,7,10,3,6,10,4,8,1613867, +14,1579079,2,1581397,2,28,1,6,1,10,28,34,63,38,1,10, +28,1613867,16,1613859,14,101,120,112,101,99,116,101,100,32,117,44, +32,100,32,111,114,32,109,32,97,102,116,101,114,32,97,115, +0,1613803,1581413,12,8,1590445,12,8,1609989,12,8,1310721,2,1310721,2,2, +1310721,2,7,26,2,1601913,12,10,3,6,10,4,8,1581337,1,10, +3,6,10,4,8,1613413,14,1579077,2,9,28,1,6,1,10,28, +34,63,38,1,10,28,1613979,16,1310721,2,2,1614957,14,1579079,2,1581353, +2,28,1,6,1,10,28,34,63,38,3,26,1614445,16,1590445,12, +8,1609989,12,8,1310721,2,3,26,3,1,10,28,10,3,6,10, +4,8,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3, +26,1614205,16,1614193,14,105,110,100,101,120,32,97,32,110,101,119, +32,111,98,106,101,99,116,32,111,110,108,121,32,97,102,116, +101,114,32,98,105,110,100,105,110,103,32,105,116,32,116,111, +32,97,32,110,97,109,101,0,1614091,1581709,12,8,1614269,14,1310721,2, +2,5,40,3,36,1614269,16,1310721,2,2,5,28,1596351,12,8,1310721, +2,3,26,1310721,2,2,5,28,10,3,6,10,4,8,1310721,2, +1616659,12,10,3,6,10,4,8,1609989,12,8,1310721,2,2,1596817,12, +8,1581355,2,1591367,12,8,27,1584215,12,8,1581335,3,10,3,6,10, +4,8,1310721,2,3,26,2,1,40,3,36,1614407,16,1581337,7,10, +3,6,10,4,8,1581339,1310721,2,3,26,2,10,3,6,10,4, +8,1614423,14,1581337,9,10,3,6,10,4,8,1310721,2,1,10,3, +6,10,4,8,1613413,14,1579079,2,1581345,2,28,1,6,1,10,28, +34,63,38,3,26,1614789,16,1609989,12,8,1310721,2,2,1596817,12,8, +1590445,12,8,1310721,2,5,26,1,10,3,6,10,4,8,1581347,2, +1590899,12,1,6,1,10,28,34,63,38,3,26,1614677,16,3,1614677, +16,1310721,2,1616659,12,10,3,6,10,4,8,1609989,12,8,1310721,2, +2,1,1602963,12,8,1310721,2,5,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1581357,2,1591159,12,1,6,1,10,28,34, +63,38,3,26,1614673,16,1614677,14,1614557,14,1581347,2,1591367,12,8,1310721, +2,5,26,2,1584151,12,8,7,1584215,12,8,13,1584215,12,8,11, +1584215,12,8,9,1584215,12,8,1581335,1,10,3,6,10,4,8,1581337, +1,10,3,6,10,4,8,1310721,2,1,10,3,6,10,4,8, +1613413,14,1579079,2,1581365,2,28,1,6,1,10,28,34,63,38,3, +26,1614857,16,1590445,12,8,1310721,2,3,3,1612807,12,10,3,6,10, +4,8,1613413,14,1579079,2,1581367,2,28,1,6,1,10,28,34,63, +38,3,26,1614931,16,1590445,12,8,1310721,2,3,3,1,10,28,1612807, +12,10,3,6,10,4,8,1613413,14,1310721,2,2,1614957,14,1613413,14, +1310721,2,2,1614957,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5, +28,1310721,4,1579077,2,9,28,1,6,1,10,28,34,63,38,3, +26,1615655,16,1579079,2,1581369,2,28,1,6,1,10,28,34,63,38, +3,26,1615131,16,1590445,12,8,1310721,2,1614971,12,10,3,6,10,4, +8,1609989,12,8,1310721,2,2,1596817,12,8,1581335,3,10,3,6,10, +4,8,1581337,9,10,3,6,10,4,8,1,1615665,14,1579079,2,1581371, +2,28,1,6,1,10,28,34,63,38,3,26,1615363,16,1590445,12, +8,1310721,2,1614971,12,10,3,6,10,4,8,1581335,2,1,6,1, +10,28,34,63,38,3,26,1615291,16,1615283,14,38,32,110,101,101, +100,115,32,115,111,109,101,116,104,105,110,103,32,97,100,100, +114,101,115,115,97,98,108,101,0,1615223,1581413,12,8,1310721,2,2, +5,40,3,36,1615325,16,1310721,2,2,5,28,1596351,12,8,1581335,1, +10,3,6,10,4,8,1581337,1,10,3,6,10,4,8,1,1615665, +14,1579079,2,1581365,2,28,1,6,1,10,28,34,63,38,3,26, +1615421,16,1590445,12,8,1614971,12,8,1,3,1612807,12,1615665,14,1579079,2, +1581367,2,28,1,6,1,10,28,34,63,38,3,26,1615485,16,1590445, +12,8,1614971,12,8,1,3,1,10,28,1612807,12,1615665,14,1310721,2, +3,26,1579079,2,1593773,12,10,3,6,10,4,8,1310721,2,3,26, +2,1,40,3,36,1615655,16,1590445,12,8,1310721,2,1614971,12,10,3, +6,10,4,8,1609989,12,8,1310721,2,2,1596817,12,8,1547329,1310721,2, +3,26,2,26,2,1547393,1310721,2,3,26,2,26,2,1592975,12,8, +1581335,1,10,3,6,10,4,8,1581337,1,10,3,6,10,4,8, +1,1615665,14,1613391,12,1615665,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,13,28,1310721,4,1310721,2,4,1614971,12,1310721,2,3,26,4,1579077, +2,9,28,1,6,1,10,28,34,63,38,3,26,1616555,16,1310721, +2,5,26,1579079,2,1593599,12,10,3,6,10,4,8,1310721,2,5, +26,2,1,40,1615803,16,1310721,2,3,26,2,1616571,14,1310721,2,7, +26,1546881,1310721,2,5,26,2,26,2,10,3,6,10,4,8,1310721, +2,7,26,2,1310721,2,2,40,1615875,16,1310721,2,3,26,2,1616571, +14,1590445,12,8,1609989,12,8,1310721,2,3,26,2,1596817,12,8,1547137, +1310721,2,5,26,2,26,2,3,1,10,28,28,1,6,1,10, +28,34,63,38,3,26,1616151,16,1310721,2,9,26,1584435,12,10,3, +6,10,4,8,17,1584215,12,8,1310721,2,3,26,1310721,2,7,26, +2,3,26,1615679,12,10,3,6,10,4,8,1609989,12,8,1310721,2, +3,26,2,1596817,12,8,1547329,3,26,2,1547393,3,26,2,1592975,12, +8,1310721,2,11,26,1584435,12,10,3,6,10,4,8,15,1584215,12, +8,1310721,2,9,26,2,1581297,2,1584275,12,8,1,1584151,12,8,1310721, +2,11,26,2,1581297,2,1584275,12,8,1616497,14,1547137,1310721,2,5,26, +2,26,2,5,1,10,28,28,1,6,1,10,28,34,63,38, +3,26,1616399,16,1310721,2,9,26,1584435,12,10,3,6,10,4,8, +17,1584215,12,8,3,1584151,12,8,1310721,2,11,26,1584435,12,10,3, +6,10,4,8,15,1584215,12,8,1310721,2,9,26,2,1581297,2,1584275, +12,8,1310721,2,3,26,1310721,2,7,26,2,3,26,1615679,12,10, +3,6,10,4,8,1609989,12,8,1310721,2,3,26,2,1596817,12,8, +1547329,3,26,2,1547393,3,26,2,1592975,12,8,1310721,2,11,26,2, +1581297,2,1584275,12,8,1616497,14,1310721,2,3,26,1310721,2,7,26,2, +3,26,1615679,12,10,3,6,10,4,8,1609989,12,8,1310721,2,3, +26,2,1596817,12,8,1547009,1310721,2,5,26,2,26,2,1547137,1310721,2, +5,26,2,26,2,1592975,12,8,1581335,1,10,3,6,10,4,8, +1581337,1,10,3,6,10,4,8,1310721,2,3,26,1,10,3,6, +10,4,8,1615711,14,1310721,2,3,26,2,1616571,14,1,1310721,2,13, +26,1310721,4,18,1310721,2,1,28,1310721,4,11,1584215,12,8,3,1584151, +12,8,7,1584215,12,8,11,1584215,12,8,5,1584215,12,8,1,1616645, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,11,28,1310721,4,3, +1615679,12,1310721,2,4,1579077,2,9,28,1,6,1,10,28,34,63, +38,1,10,28,1616727,16,1310721,2,2,1617577,14,1579079,2,1581361,2,28, +1,6,1,10,28,34,63,38,3,26,1617013,16,1581335,2,1,6, +1,10,28,34,63,38,3,26,1616853,16,1616845,14,116,104,105,115, +32,99,97,110,39,116,32,98,101,32,97,115,115,105,103,110, +101,100,32,116,111,0,1616793,1581413,12,8,1310721,2,3,26,1581337,2, +10,3,6,10,4,8,1310721,2,5,26,1581339,2,10,3,6,10, +4,8,1590445,12,8,1310721,2,9,26,1616659,12,10,3,6,10,4, +8,1609989,12,8,1616585,12,8,1581335,1,10,3,6,10,4,8,1581337, +1,10,3,6,10,4,8,1310721,2,3,26,2,1310721,2,5,26, +2,1310721,2,9,26,2,1604771,12,1617577,14,1310721,2,7,26,1579079,2, +1593947,12,10,3,6,10,4,8,1310721,2,7,26,2,1,40,3, +36,1617565,16,1581335,2,1,6,1,10,28,34,63,38,3,26,1617155, +16,1617147,14,116,104,105,115,32,99,97,110,39,116,32,98,101, +32,97,115,115,105,103,110,101,100,32,116,111,0,1617095,1581413,12, +8,1581337,2,3,28,1,6,1,10,28,34,63,38,3,26,1617217, +16,1581313,2,1,6,1,10,28,34,63,38,1,10,28,1617219,14, +1,1617257,16,1581339,2,1596275,12,1,6,1,10,28,34,63,38,1, +10,28,1617259,14,1,1617379,16,1581339,2,1617371,14,111,119,110,115,32, +97,110,32,111,98,106,101,99,116,59,32,99,111,109,112,111, +117,110,100,32,97,115,115,105,103,110,109,101,110,116,32,119, +111,117,108,100,32,108,111,115,101,32,105,116,0,1617271,1581805,12, +8,1590445,12,8,1,1584151,12,8,7,1584215,12,8,3,1584215,12,8, +1581335,1,10,3,6,10,4,8,1310721,2,9,26,1616659,12,10,3, +6,10,4,8,1609989,12,8,1310721,2,9,26,2,1596817,12,8,1547009, +1547585,1310721,2,7,26,2,26,2,26,2,1547137,1547585,1310721,2,7,26, +2,26,2,26,2,1592975,12,8,1616585,12,8,1581335,1,10,3,6, +10,4,8,1581337,1,10,3,6,10,4,8,1,1617577,14,1310721,2, +2,1617577,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28,1310721, +4,1579077,2,9,28,1,6,1,10,28,34,63,38,3,26,1617731, +16,1579079,2,1581359,2,28,1,6,1,10,28,34,63,38,3,26, +1617675,16,3,1617727,14,1579079,2,1581349,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1617999, +14,1579077,2,5,28,1,6,1,10,28,34,63,38,1,10,28, +1617771,16,3,1617809,14,1579079,2,1595595,12,1,40,3,36,1,6,1, +10,28,34,63,38,1,10,28,1617819,16,1,1617999,14,1310721,2,1579079, +2,1583029,12,10,3,6,10,4,8,1310721,2,2,1,40,3,36, +1617923,16,1417729,1310721,2,2,26,2,11,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1617925, +14,1,1617991,16,1442305,1310721,2,2,26,2,33,32,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1617993,14,1,1617999,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +7,28,1310721,4,1581305,2,1310721,2,4,1,1310721,2,3,26,4,1, +1310721,2,5,26,4,1590445,12,8,1581309,1,6,2,1,6,3,26, +5,6,4,10,8,8,1581319,1,6,2,1,6,3,26,5,6, +4,10,8,8,1581351,2,1590899,12,1,6,1,10,28,34,63,38, +3,26,1618469,16,1579077,2,1,28,1,6,1,10,28,34,63,38, +3,26,1618217,16,1618209,14,109,105,115,115,105,110,103,32,125,0, +1618189,1581413,12,8,1617591,12,1618235,16,1620153,12,8,1618121,14,1310721,2,3, +26,1616659,12,10,3,6,10,4,8,1609989,12,8,1581359,2,1591159,12, +1618327,16,9,1584215,12,8,1310721,2,3,26,2,1609765,12,8,1310721,2, +3,26,1,10,3,6,10,4,8,1618121,14,1581351,2,1590899,12,1, +6,1,10,28,34,63,38,3,26,1618443,16,1618435,14,101,120,112, +101,99,116,101,100,32,59,32,111,114,32,125,32,97,102,116, +101,114,32,97,110,32,101,120,112,114,101,115,115,105,111,110, +0,1618363,1581413,12,8,1310721,2,5,26,3,10,3,6,10,4,8, +1618121,14,1590445,12,8,1310721,2,5,26,2,1618527,16,1310721,2,3,26, +1310721,2,3,26,2,1609071,12,10,3,6,10,4,8,1618535,14,1, +1584151,12,8,1310721,2,2,1598141,12,8,1581309,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1581319,1,6,2,1,6,-1,26,5, +6,4,10,8,8,1581335,1,10,3,6,10,4,8,1581337,1,10, +3,6,10,4,8,1310721,2,3,26,2,1618651,14,1,1310721,2,7, +26,1310721,4,18,1310721,2,5,28,1310721,4,1579077,2,3,28,1,6, +1,10,28,34,63,38,3,26,1618745,16,1310721,2,1579079,2,10,3, +6,10,4,8,1590445,12,8,1310721,2,2,1619445,14,1581377,2,1591159,12, +1618769,16,1,1618665,12,28,1619445,14,1579077,2,9,28,1,6,1,10, +28,34,63,38,3,26,1618861,16,1579079,2,1547265,5,26,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1618863,14,1,1618885,16,1590445,12,8,1618665,12,-1,36, +1619445,14,1581345,2,1591159,12,1618937,16,1310721,2,1619459,12,10,3,6,10, +4,8,1581347,2,1591367,12,8,1310721,2,2,1619445,14,1579077,2,5,28, +1,6,1,10,28,34,63,38,3,26,1619385,16,1310721,2,3,26, +1579079,2,1583029,12,10,3,6,10,4,8,1310721,2,3,26,2,1, +40,3,36,1619353,16,1417729,1310721,2,3,26,2,26,2,9,28,1, +6,1,10,28,34,63,38,3,26,1619069,16,3,1619131,14,1417729,1310721, +2,3,26,2,26,2,7,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1619141,16,3, +1619255,14,1417729,1310721,2,3,26,2,26,2,3,28,1,6,1,10, +28,34,63,38,3,26,1619231,16,1442305,1310721,2,3,26,2,26,2, +3,32,1,6,1,10,28,34,63,38,1,10,28,1619233,14,1, +1,6,1,10,28,34,63,38,1,10,28,1619265,16,3,1619327,14, +1417729,1310721,2,3,26,2,26,2,5,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1, +6,1,10,28,34,63,38,1,10,28,1619355,14,1,1619385,16,1590445, +12,8,1425921,1310721,2,3,26,2,26,2,1619445,14,1619429,14,101,120, +112,101,99,116,101,100,32,97,32,99,111,110,115,116,97,110, +116,0,1619389,1581413,12,8,1,1619445,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,5,28,1310721,4,1618665,12,1310721,2,4,1579077,2,9,28, +1,6,1,10,28,34,63,38,3,26,1620127,16,1310721,2,3,26, +1579079,2,10,3,6,10,4,8,1310721,2,3,26,2,1546753,7,26, +2,28,1,6,1,10,28,34,63,38,3,26,1619619,16,1590445,12, +8,1310721,2,1310721,2,2,1618665,12,26,10,3,6,10,4,8,1620123, +14,1310721,2,3,26,2,1546753,9,26,2,28,1,6,1,10,28, +34,63,38,3,26,1619701,16,1590445,12,8,1310721,2,1310721,2,2,1618665, +12,28,10,3,6,10,4,8,1620123,14,1310721,2,3,26,2,1546753, +1,26,2,28,1,6,1,10,28,34,63,38,3,26,1619783,16, +1590445,12,8,1310721,2,1310721,2,2,1618665,12,30,10,3,6,10,4, +8,1620123,14,1310721,2,3,26,2,1546753,31,26,2,28,1,6,1, +10,28,34,63,38,3,26,1619865,16,1590445,12,8,1310721,2,1310721,2, +2,1618665,12,34,10,3,6,10,4,8,1620123,14,1310721,2,3,26, +2,1546753,27,26,2,28,1,6,1,10,28,34,63,38,3,26, +1619947,16,1590445,12,8,1310721,2,1310721,2,2,1618665,12,32,10,3,6, +10,4,8,1620123,14,1310721,2,3,26,2,1546753,11,26,2,28,1, +6,1,10,28,34,63,38,3,26,1620031,16,1590445,12,8,1310721,2, +1310721,2,2,1618665,12,1575289,12,10,3,6,10,4,8,1620123,14,1310721, +2,3,26,2,1546753,13,26,2,28,1,6,1,10,28,34,63, +38,3,26,1620113,16,1590445,12,8,1310721,2,1310721,2,2,1618665,12,38, +10,3,6,10,4,8,1620123,14,1310721,2,2,1620139,14,1619481,14,1310721, +2,2,1620139,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28, +1310721,4,1579077,2,5,28,1,6,1,10,28,34,63,38,3,26, +1620235,16,1579079,2,1595595,12,1,40,1,6,1,10,28,34,63,38, +1,10,28,1620237,14,1,1620419,16,1310721,2,1579079,2,1583029,12,10,3, +6,10,4,8,1310721,2,2,1,40,3,36,1620345,16,1417729,1310721,2, +2,26,2,11,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1620347,14,1,1620393,16,1442305, +1310721,2,2,26,2,17,32,1,6,1,10,28,34,63,38,1, +10,28,1620395,14,1,1620419,16,1310721,2,2,1,1610055,12,8,1,1620615, +14,1579077,2,9,28,1,6,1,10,28,34,63,38,3,26,1620543, +16,1579079,2,1581359,2,28,1,6,1,10,28,34,63,38,3,26, +1620497,16,1590445,12,8,1,1620615,14,1579079,2,1581349,2,28,1,6,1, +10,28,34,63,38,3,26,1620543,16,1620629,12,8,1,1620615,14,1310721, +2,3,26,1616659,12,10,3,6,10,4,8,1609989,12,8,9,1584215, +12,8,1581359,2,1591367,12,8,1310721,2,3,26,2,1609765,12,8,1, +1620615,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4, +1581305,2,1310721,2,4,1581349,2,1591367,12,8,1581309,1,6,2,1,6, +3,26,5,6,4,10,8,8,1581351,2,1590899,12,1,6,1,10, +28,34,63,38,3,26,1620795,16,1579077,2,1,28,1,6,1,10, +28,34,63,38,3,26,1620785,16,1620777,14,109,105,115,115,105,110, +103,32,125,0,1620757,1581413,12,8,1620153,12,8,1620689,14,1590445,12,8, +1310721,2,2,1598141,12,8,1581309,1,6,2,1,6,-1,26,5,6, +4,10,8,8,1,1620849,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1581305,2,1310721,2,4,1581349,2,1590899,12,1620905,16, +1620629,12,1620987,14,1581309,1,6,2,1,6,3,26,5,6,4,10, +8,8,1620153,12,8,1310721,2,2,1598141,12,8,1581309,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1,1620987,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,9,28,1310721,4,1610291,12,8,1590445,12,8, +3,1621357,16,1310721,2,1591545,12,10,3,6,10,4,8,1310721,2,3, +26,1310721,2,2,1595777,12,10,3,6,10,4,8,1581353,2,1591159,12, +1621189,16,1310721,2,7,26,1619459,12,10,3,6,10,4,8,1581355,2, +1591367,12,8,1473025,1310721,2,3,26,2,26,3,10,3,6,10,4, +8,1581311,1581311,2,1310721,2,7,26,2,26,10,3,6,10,4,8, +1621217,14,1581311,1,6,2,1,6,3,26,5,6,4,10,8,8, +1581361,2,1591159,12,1621317,16,1310721,2,5,26,1616659,12,10,3,6,10, +4,8,1609989,12,8,1467905,1310721,2,3,26,2,26,2,1584865,12,8, +5,1584215,12,8,3,1310721,2,3,26,2,1310721,2,5,26,2,1604771, +12,8,1581357,2,1591159,12,1,6,1,10,28,34,63,38,3,26, +1621353,16,1621357,14,1621025,14,1581359,2,1591367,12,8,1,1621375,14,1,1310721, +2,9,26,1310721,4,18,1310721,2,15,28,1310721,4,1610291,12,8,1590445, +12,8,1581345,2,1591367,12,8,1310721,2,5,26,1616659,12,10,3,6, +10,4,8,1609989,12,8,1310721,2,5,26,2,1596817,12,8,1581347,2, +1591367,12,8,1310721,2,1584435,12,10,3,6,10,4,8,17,1584215,12, +8,1310721,2,11,26,1581317,2,10,3,6,10,4,8,1310721,2,7, +26,1598391,12,10,3,6,10,4,8,1620863,12,8,1310721,2,13,26, +1581317,2,10,3,6,10,4,8,1310721,2,9,26,1598391,12,10,3, +6,10,4,8,1581389,2,1591029,12,1621745,16,1590445,12,8,1310721,2,3, +26,1584435,12,10,3,6,10,4,8,15,1584215,12,8,1310721,2,2, +1581297,2,1584275,12,8,1310721,2,7,26,2,1598979,12,8,1581317,1310721,2, +11,26,2,10,3,6,10,4,8,1620863,12,8,1310721,2,3,26, +2,1581297,2,1584275,12,8,1621801,14,1310721,2,2,1581297,2,1584275,12,8, +1310721,2,7,26,2,1598979,12,8,1581317,1310721,2,11,26,2,10,3, +6,10,4,8,1310721,2,9,26,2,1310721,2,13,26,2,1601089,12, +8,1310721,2,7,26,2,1598919,12,8,1,1621851,14,1,1310721,2,15, +26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,3,26,4,1310721, +2,4,1552897,1581327,2,13,30,26,1310721,2,5,26,4,1581327,2,121, +40,3,36,1621991,16,1621983,14,108,111,111,112,115,32,110,101,115, +116,101,100,32,116,111,111,32,100,101,101,112,108,121,0,1621935, +1581413,12,8,1310721,2,5,26,2,1,26,1310721,2,2,10,3,6, +10,4,8,1310721,2,5,26,2,3,26,1,10,3,6,10,4, +8,1310721,2,5,26,2,5,26,1581309,2,10,3,6,10,4,8, +1310721,2,5,26,2,7,26,1310721,2,3,26,2,10,3,6,10, +4,8,1310721,2,5,26,2,9,26,1581319,2,10,3,6,10,4, +8,1581327,1,6,2,1,6,3,26,5,6,4,10,8,8,1, +1622183,14,1,1310721,2,7,26,1310721,4,18,1310721,2,1,28,1310721,4, +1581327,1,6,2,1,6,-1,26,5,6,4,10,8,8,1552897,1581327, +2,13,30,3,26,26,2,1581297,2,1583797,12,8,1,1622273,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,9,28,1310721,4,1581297,2,1310721, +2,4,1610291,12,8,1590445,12,8,1310721,2,5,26,1598391,12,10,3, +6,10,4,8,1581345,2,1591367,12,8,1310721,2,7,26,1616659,12,10, +3,6,10,4,8,1609989,12,8,1310721,2,7,26,2,1596817,12,8, +1581347,2,1591367,12,8,1310721,2,3,26,1584435,12,10,3,6,10,4, +8,17,1584215,12,8,1310721,2,2,1310721,2,5,26,2,1621865,12,8, +1620863,12,8,1310721,2,5,26,2,1601489,12,8,1310721,2,2,1584375,12, +8,1310721,2,3,26,2,1581297,2,1584275,12,8,1622197,12,8,1310721,2, +5,26,2,1598979,12,8,1581317,3,10,3,6,10,4,8,1310721,2, +5,26,2,1598919,12,8,1,1622581,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,15,28,1310721,4,1581305,2,1310721,2,4,1610291,12,8,1590445, +12,8,1581345,2,1591367,12,8,1581309,1,6,2,1,6,3,26,5, +6,4,10,8,8,1581385,2,1591029,12,1622689,16,1621001,12,8,1622785,14, +1581359,2,1590899,12,1,6,1,10,28,34,63,38,3,26,1622775,16, +1310721,2,13,26,1616659,12,10,3,6,10,4,8,1609989,12,8,9, +1584215,12,8,1310721,2,13,26,2,1609765,12,8,1581359,2,1591367,12,8, +1310721,2,3,26,1598391,12,10,3,6,10,4,8,1310721,2,5,26, +1581297,2,10,3,6,10,4,8,1581359,2,1590899,12,1,6,1,10, +28,34,63,38,3,26,1622915,16,1310721,2,13,26,1616659,12,10,3, +6,10,4,8,1609989,12,8,1310721,2,13,26,2,1596817,12,8,1622923, +14,3,1584151,12,8,1581359,2,1591367,12,8,1310721,2,7,26,1584435,12, +10,3,6,10,4,8,17,1584215,12,8,1310721,2,9,26,1584435,12, +10,3,6,10,4,8,15,1584215,12,8,1310721,2,11,26,1581297,2, +10,3,6,10,4,8,1581347,2,1590899,12,1,6,1,10,28,34, +63,38,3,26,1623107,16,1310721,2,13,26,1616659,12,10,3,6,10, +4,8,1609989,12,8,9,1584215,12,8,1310721,2,13,26,2,1609765,12, +8,1581347,2,1591367,12,8,1310721,2,5,26,2,1584375,12,8,1310721,2, +9,26,2,1581297,2,1584275,12,8,1310721,2,11,26,2,1310721,2,3, +26,2,1621865,12,8,1620863,12,8,1310721,2,3,26,2,1601489,12,8, +1310721,2,11,26,2,1584375,12,8,1310721,2,7,26,2,1581297,2,1584275, +12,8,1622197,12,8,1310721,2,3,26,2,1598979,12,8,1581317,3,10, +3,6,10,4,8,1310721,2,3,26,2,1598919,12,8,1310721,2,2, +1598141,12,8,1581309,1,6,2,1,6,-1,26,5,6,4,10,8, +8,1,1623339,14,1,1310721,2,15,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1581327,2,1581329,2,10,40,3,36,1623469,16,1623461, +14,98,114,101,97,107,32,111,114,32,99,111,110,116,105,110, +117,101,32,111,117,116,115,105,100,101,32,97,32,108,111,111, +112,0,1623395,1581413,12,8,1310721,2,2,9,26,2,1581319,2,28,1, +6,1,10,28,34,63,38,1,10,28,1623625,16,1623617,14,98,114, +101,97,107,32,97,110,100,32,99,111,110,116,105,110,117,101, +32,99,97,110,39,116,32,108,101,97,118,101,32,97,32,98, +108,111,99,107,32,101,120,112,114,101,115,115,105,111,110,0, +1623517,1581413,12,8,1310721,2,2,7,26,2,1601489,12,8,1310721,2,2, +5,26,2,3,26,1,1597159,12,8,1,1623675,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1552897,1581327,2,3,28,13, +30,26,1310721,2,4,1610291,12,8,1590445,12,8,1581359,2,1591367,12,8, +1310721,2,2,1623353,12,8,1310721,2,2,3,26,1581297,2,1310721,2,2, +3,26,2,1583467,12,10,3,6,10,4,8,2097153,3,28,1584151,12, +8,15,1584215,12,8,1581317,1,10,3,6,10,4,8,1,1623843,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1552897,1581327, +2,3,28,13,30,26,1310721,2,4,1610291,12,8,1590445,12,8,1581359, +2,1591367,12,8,1310721,2,2,1623353,12,8,1310721,2,2,1,26,2, +1584375,12,8,1581317,1,10,3,6,10,4,8,1,1623967,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1610291,12,8,1590445, +12,8,1581325,2,1,6,1,10,28,34,63,38,3,26,1624097,16, +1624089,14,114,101,116,117,114,110,32,111,117,116,115,105,100,101, +32,97,32,102,117,110,99,116,105,111,110,0,1624037,1581413,12,8, +1581319,2,1624193,16,1624185,14,114,101,116,117,114,110,32,99,97,110, +39,116,32,108,101,97,118,101,32,97,32,98,108,111,99,107, +32,101,120,112,114,101,115,115,105,111,110,0,1624109,1581413,12,8, +1581359,2,1590899,12,1624235,16,1,1584151,12,8,1310721,2,1,10,3,6, +10,4,8,1624261,14,1310721,2,1616659,12,10,3,6,10,4,8,1609989, +12,8,1581359,2,1591367,12,8,1310721,2,2,1608109,12,8,3,1,1597159, +12,8,1581321,1581297,2,1581321,2,1583467,12,10,3,6,10,4,8,2097153, +3,28,1584151,12,8,15,1584215,12,8,1581317,1,10,3,6,10,4, +8,1,1624363,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1581313,2,1310721,2,4,1610291,12,8,1590445,12,8,1581313,1,10, +3,6,10,4,8,1620863,12,8,1581313,1310721,2,2,10,3,6,10, +4,8,1,1624461,14,1,1310721,2,3,26,1310721,4,18,1310721,2,21, +28,1310721,4,1,1310721,2,4,1,1310721,2,3,26,4,1554945,1310721,2, +13,26,4,1554945,129,26,1310721,2,15,26,4,1554945,257,26,1310721,2, +17,26,4,1554945,769,26,1310721,2,19,26,4,1581349,2,1591367,12,8, +1581351,2,1590899,12,1,6,1,10,28,34,63,38,3,26,1626417,16, +1579077,2,1,28,1,6,1,10,28,34,63,38,3,26,1624699,16, +1624691,14,117,110,116,101,114,109,105,110,97,116,101,100,32,97, +115,109,32,98,108,111,99,107,0,1624645,1581413,12,8,1579077,2,3, +28,1,6,1,10,28,34,63,38,3,26,1624751,16,1579079,2,1584151, +12,8,1590445,12,8,1624577,14,1579077,2,7,28,1,6,1,10,28, +34,63,38,3,26,1624803,16,1579079,2,1584951,12,8,1590445,12,8,1624577, +14,1581375,2,1590899,12,1624921,16,1590445,12,8,1579077,2,3,28,1,6, +1,10,28,34,63,38,1,10,28,1624901,16,1624893,14,35,32,110, +101,101,100,115,32,97,32,110,117,109,98,101,114,0,1624859,1581413, +12,8,1579079,2,1583993,12,8,1590445,12,8,1624577,14,1581377,2,1590899,12, +1625043,16,1590445,12,8,1579077,2,3,28,1,6,1,10,28,34,63, +38,3,26,1625001,16,1579081,2,1,6,1,10,28,34,63,38,1, +10,28,1625003,14,1,1625031,16,1,1579079,2,28,1584151,12,8,1590445,12, +8,1625039,14,29,1584215,12,8,1624577,14,1581373,2,1590899,12,1625233,16,1590445, +12,8,1310721,2,2,129,40,3,36,1625131,16,1625123,14,116,111,111, +32,109,97,110,121,32,97,115,109,32,108,97,98,101,108,115, +0,1625083,1581413,12,8,1310721,2,13,26,2,1310721,2,2,26,1591545,12, +10,3,6,10,4,8,1310721,2,15,26,2,1310721,2,2,26,1581297, +2,10,3,6,10,4,8,1310721,2,1,6,2,1,6,3,26, +5,6,4,10,8,8,1624577,14,1579079,2,1,26,2,1625303,16,1579079, +2,3,26,2,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1625305,14,1,1625375,16,1310721,2, +9,26,1579079,2,1,26,2,1592793,12,10,3,6,10,4,1,40, +3,36,1,6,1,10,28,34,63,38,1,10,28,1625377,14,1, +1625407,16,1310721,2,9,26,2,1584215,12,8,1590445,12,8,1624577,14,1579077, +2,5,28,1,6,1,10,28,34,63,38,1,10,28,1625487,16, +1625479,14,98,97,100,32,116,111,107,101,110,32,105,110,32,97, +115,109,0,1625445,1581413,12,8,1310721,2,5,26,1579079,2,1595595,12,10, +3,6,10,4,8,1310721,2,5,26,2,1,40,3,36,1625597,16, +1472001,1310721,2,5,26,2,26,3,10,3,6,10,4,8,1467905,1310721, +2,5,26,2,26,2,1584865,12,8,1590445,12,8,1624577,14,1310721,2, +7,26,3,1,10,28,10,3,6,10,4,8,1310721,2,5,26, +1,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,2,40, +1625791,16,1310721,2,13,26,2,1310721,2,5,26,2,26,2,1579079,2, +28,1,6,1,10,28,34,63,38,3,26,1625753,16,1310721,2,7, +26,1310721,2,5,26,2,10,3,6,10,4,8,1310721,2,5,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1625647,14,1310721, +2,7,26,2,1,40,3,36,1625853,16,1310721,2,15,26,2,1310721, +2,7,26,2,26,2,1584151,12,8,1590445,12,8,1624577,14,1310721,2, +11,26,1579079,2,1583029,12,10,3,6,10,4,8,1310721,2,11,26, +2,1,40,3,36,1625971,16,1417729,1310721,2,11,26,2,26,2,3, +28,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,1,10,28,1625973,14,1,1626045,16,1417729,1310721,2,11, +26,2,26,2,11,28,1,6,1,10,28,34,63,38,1,10, +28,1,6,1,10,28,34,63,38,1,10,28,1626047,14,1,1626083, +16,1425921,1310721,2,11,26,2,26,2,1584151,12,8,1590445,12,8,1624577, +14,1310721,2,11,26,2,1,40,3,36,1626171,16,1417729,1310721,2,11, +26,2,26,2,3,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1626173,14,1,1626203,16, +1310721,2,11,26,2,1584595,12,8,1590445,12,8,1624577,14,1310721,2,3, +26,2,501,40,3,36,1626297,16,1626289,14,116,111,111,32,109,97, +110,121,32,97,115,109,32,108,97,98,101,108,32,114,101,102, +101,114,101,110,99,101,115,0,1626229,1581413,12,8,1310721,2,17,26, +2,1310721,2,3,26,2,26,1579079,2,10,3,6,10,4,8,1310721, +2,19,26,2,1310721,2,3,26,2,26,1584435,12,10,3,6,10, +4,8,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1590445,12,8,1624577,14,1590445,12,8,1310721,2,5,26,1, +10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,3,26,2, +40,1626871,16,1310721,2,7,26,3,1,10,28,10,3,6,10,4, +8,1310721,2,9,26,1,10,3,6,10,4,8,1310721,2,9,26, +2,1310721,2,2,40,1626685,16,1310721,2,13,26,2,1310721,2,9,26, +2,26,2,1310721,2,17,26,2,1310721,2,5,26,2,26,2,28, +1,6,1,10,28,34,63,38,3,26,1626647,16,1310721,2,7,26, +1310721,2,9,26,2,10,3,6,10,4,8,1310721,2,9,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1626521,14,1310721,2, +7,26,2,1,40,1626779,16,1310721,2,17,26,2,1310721,2,5,26, +2,26,2,1626771,14,117,110,107,110,111,119,110,32,110,97,109, +101,32,105,110,32,97,115,109,0,1626731,1581539,12,8,1310721,2,19, +26,2,1310721,2,5,26,2,26,2,1310721,2,15,26,2,1310721,2, +7,26,2,26,2,1584275,12,8,1310721,2,5,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1626445,14,1,1626879,14,1,1310721, +2,21,26,1310721,4,18,1310721,2,1,28,1310721,4,1590445,12,8,1624475, +12,8,1581343,1,10,3,6,10,4,8,1,1626941,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,7,28,1310721,4,1,1310721,2,4,1, +1310721,2,3,26,4,1581349,2,1590899,12,1,6,1,10,28,34,63, +38,3,26,1627053,16,1627045,14,101,120,112,101,99,116,101,100,32, +123,0,1627023,1581413,12,8,1590445,12,8,3,1627449,16,1579077,2,1,28, +1,6,1,10,28,34,63,38,3,26,1627147,16,1627139,14,117,110, +116,101,114,109,105,110,97,116,101,100,32,113,117,111,116,101, +0,1627101,1581413,12,8,1581349,2,1590899,12,1627193,16,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1581351,2,1590899,12, +1627277,16,1310721,2,3,26,2,1,6,1,10,28,34,63,38,3, +26,1627243,16,1627449,14,1310721,2,3,26,1,6,2,1,6,-1,26, +5,6,4,10,8,8,1310721,2,2,8001,40,3,36,1627337,16,1627329, +14,113,117,111,116,101,32,116,111,111,32,108,111,110,103,0, +1627299,1581413,12,8,1524225,1310721,2,2,1310721,2,2,26,26,1579077,2,10, +3,6,10,4,8,1524225,1310721,2,2,1310721,2,2,26,3,26,26, +1579079,2,10,3,6,10,4,8,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1590445,12,8,1627059,14,1590445,12,8,1310721, +2,5,26,1310721,2,2,1310721,2,2,26,3,26,1575967,12,10,3, +6,10,4,8,1310721,2,5,26,2,1,26,1310721,2,2,10,3, +6,10,4,8,1310721,2,5,26,2,3,26,1524225,1310721,2,2,1310721, +2,2,26,1573943,12,8,1310721,2,5,26,2,1627581,14,1,1310721,2, +7,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,4,1310721,2, +2,1,26,2,5,30,3,26,1310721,2,3,26,4,1310721,2,3, +26,2,1575967,12,1310721,2,5,26,4,1310721,2,5,26,2,1310721,2, +2,1310721,2,3,26,2,1573943,12,8,1310721,2,5,26,2,1627715,14, +1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2, +4,1310721,2,2,1,26,2,5,30,3,26,1310721,2,3,26,4, +1310721,2,3,26,2,1575967,12,1310721,2,5,26,4,1310721,2,5,26, +2,1310721,2,2,1310721,2,3,26,2,1573943,12,8,1310721,2,5,26, +2,1627849,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,3,26,4,1310721,2,4,1,1310721,2,5,26,4,1310721, +2,5,26,2,1310721,2,3,26,2,40,1627993,16,1310721,2,2,1310721, +2,5,26,2,26,2,1583993,12,8,1310721,2,5,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1627903,14,1,1628001,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,9,28,1310721,4,1590445,12,8, +1310721,2,1626955,12,10,3,6,10,4,8,1310721,2,3,26,1584435,12, +10,3,6,10,4,8,15,1584215,12,8,1310721,2,5,26,1581297,2, +10,3,6,10,4,8,1310721,2,7,26,1310721,2,2,1,26,2, +5,30,3,26,10,3,6,10,4,8,1310721,2,2,1310721,2,7, +26,2,1627863,12,8,1310721,2,2,1577415,12,8,1310721,2,3,26,2, +1581297,2,1584275,12,8,1310721,2,5,26,2,1584151,12,8,1581411,2,1584733, +12,8,1581343,3,10,3,6,10,4,8,1,1628253,14,1,1310721,2, +9,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,4,1,1310721, +2,3,26,4,5,1310721,2,2,1,1,1585519,12,8,1590445,12,8, +1579077,2,1,28,1,6,1,10,28,34,63,38,1,10,28,1628553, +16,1310721,2,3,26,2,8001,40,3,36,1628421,16,1628413,14,116,111, +111,32,109,97,110,121,32,116,111,107,101,110,115,0,1628381,1581413, +12,8,1524225,1310721,2,3,26,2,1310721,2,3,26,2,26,26,1579077, +2,10,3,6,10,4,8,1524225,1310721,2,3,26,2,1310721,2,3, +26,2,26,3,26,26,1579079,2,10,3,6,10,4,8,1310721,2, +3,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1590445, +12,8,1628321,14,1586333,12,8,1310721,2,5,26,1310721,2,3,26,2, +1310721,2,3,26,2,26,3,26,1575967,12,10,3,6,10,4,8, +1310721,2,5,26,2,1,26,1310721,2,3,26,2,10,3,6,10, +4,8,1310721,2,5,26,2,3,26,1524225,1310721,2,3,26,2,1310721, +2,3,26,2,26,1573943,12,8,1310721,2,5,26,2,1628705,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4, +3,1310721,2,2,3,3,1585519,12,8,1590445,12,8,1,1628769,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1548801,1581331,2, +49,30,26,1310721,2,4,1581331,2,61,40,3,36,1628895,16,1628887,14, +99,111,109,112,105,108,101,115,32,110,101,115,116,101,100,32, +116,111,111,32,100,101,101,112,108,121,0,1628833,1581413,12,8,1581331, +1,6,2,1,6,3,26,5,6,4,10,8,8,1310721,2,2, +1,26,1581305,2,10,3,6,10,4,8,1310721,2,2,3,26,1581307, +2,10,3,6,10,4,8,1310721,2,2,5,26,1581309,2,10,3, +6,10,4,8,1310721,2,2,7,26,1581311,2,10,3,6,10,4, +8,1310721,2,2,9,26,1581313,2,10,3,6,10,4,8,1310721,2, +2,11,26,1581315,2,10,3,6,10,4,8,1310721,2,2,13,26, +1581317,2,10,3,6,10,4,8,1310721,2,2,15,26,1581319,2,10, +3,6,10,4,8,1310721,2,2,17,26,1581321,2,10,3,6,10, +4,8,1310721,2,2,19,26,1581323,2,10,3,6,10,4,8,1310721, +2,2,21,26,1581325,2,10,3,6,10,4,8,1310721,2,2,23, +26,1581327,2,10,3,6,10,4,8,1310721,2,2,25,26,1581329,2, +10,3,6,10,4,8,1310721,2,2,27,26,1581335,2,10,3,6, +10,4,8,1310721,2,2,29,26,1581337,2,10,3,6,10,4,8, +1310721,2,2,31,26,1581339,2,10,3,6,10,4,8,1310721,2,2, +33,26,1581341,2,10,3,6,10,4,8,1310721,2,2,35,26,1581343, +2,10,3,6,10,4,8,1310721,2,2,37,26,1581333,2,10,3, +6,10,4,8,1,1629425,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1581331,1,6,2,1,6,-1,26,5,6,4, +10,8,8,1310721,2,1548801,1581331,2,49,30,26,10,3,6,10,4, +8,1581305,1310721,2,2,1,26,2,10,3,6,10,4,8,1581307,1310721, +2,2,3,26,2,10,3,6,10,4,8,1581309,1310721,2,2,5, +26,2,10,3,6,10,4,8,1581311,1310721,2,2,7,26,2,10, +3,6,10,4,8,1581313,1310721,2,2,9,26,2,10,3,6,10, +4,8,1581315,1310721,2,2,11,26,2,10,3,6,10,4,8,1581317, +1310721,2,2,13,26,2,10,3,6,10,4,8,1581319,1310721,2,2, +15,26,2,10,3,6,10,4,8,1581321,1310721,2,2,17,26,2, +10,3,6,10,4,8,1581323,1310721,2,2,19,26,2,10,3,6, +10,4,8,1581325,1310721,2,2,21,26,2,10,3,6,10,4,8, +1581327,1310721,2,2,23,26,2,10,3,6,10,4,8,1581329,1310721,2, +2,25,26,2,10,3,6,10,4,8,1581335,1310721,2,2,27,26, +2,10,3,6,10,4,8,1581337,1310721,2,2,29,26,2,10,3, +6,10,4,8,1581339,1310721,2,2,31,26,2,10,3,6,10,4, +8,1581341,1310721,2,2,33,26,2,10,3,6,10,4,8,1581343,1310721, +2,2,35,26,2,10,3,6,10,4,8,1581333,1310721,2,2,37, +26,2,10,3,6,10,4,8,1,1630009,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3,26,4,1310721,2, +4,1581307,1581305,2,10,3,6,10,4,8,1581309,3,10,3,6,10, +4,8,1581311,1,10,3,6,10,4,8,1581313,1310721,2,2,1630143,16, +1579075,2,1,6,1,10,28,34,63,38,1,10,28,1630145,14,1, +10,3,6,10,4,8,1581315,1310721,2,3,26,2,10,3,6,10, +4,8,1581317,3,10,3,6,10,4,8,1581319,1,10,3,6,10, +4,8,1581321,1,10,3,6,10,4,8,1581325,3,10,3,6,10, +4,8,1581329,1581327,2,10,3,6,10,4,8,1581335,1,10,3,6, +10,4,8,1581337,1,10,3,6,10,4,8,1,1630303,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,1584151,12,8, +3,1584215,12,8,1581323,1584435,12,10,3,6,10,4,8,29,1584215,12, +8,1310721,1584151,12,8,5,1584215,12,8,1,1630395,14,1,1310721,2,1, +26,1310721,4,18,1310721,2,1,28,1310721,4,1,1584151,12,8,1581321,2, +1581297,2,1583797,12,8,1310721,1584151,12,8,3,1584215,12,8,1581311,2,1584151, +12,8,27,1584215,12,8,1310721,1584151,12,8,5,1584215,12,8,19,1584215, +12,8,1581323,2,1581311,2,1584275,12,8,1581325,1,10,3,6,10,4, +8,1581305,1581307,2,10,3,6,10,4,8,1,1630557,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1581349,2,1591367,12,8, +1581351,2,1590899,12,1,6,1,10,28,34,63,38,3,26,1630749,16, +1579077,2,1,28,1,6,1,10,28,34,63,38,3,26,1630739,16, +1630731,14,109,105,115,115,105,110,103,32,125,32,97,116,32,116, +104,101,32,101,110,100,32,111,102,32,97,32,102,117,110,99, +116,105,111,110,0,1630661,1581413,12,8,1620153,12,8,1630593,14,1590445,12, +8,1581307,2,1597865,12,8,1581313,2,1630803,16,1581317,2,1,6,1,10, +28,34,63,38,1,10,28,1630805,14,1,1630921,16,3,3,1597159,12, +8,1581315,2,1630921,16,1630913,14,97,32,45,62,32,117,32,102,117, +110,99,116,105,111,110,32,104,97,115,32,116,111,32,101,110, +100,32,119,105,116,104,32,97,32,114,101,116,117,114,110,0, +1630831,1581709,12,8,1,1630929,14,1,1310721,2,1,26,1310721,4,18,1310721, +2,115,28,1310721,4,1310721,2,4,1,1310721,2,7,26,4,1,1310721, +2,9,26,4,1,1310721,2,13,26,4,1590445,12,8,1310721,2,3, +26,1591545,12,10,3,6,10,4,8,1310721,2,5,26,1310721,2,3, +26,2,1583029,12,10,3,6,10,4,8,1310721,2,5,26,2,1, +40,1631085,16,3,1631123,14,1310721,2,5,26,2,1579011,2,40,1,6, +1,10,28,34,63,38,1,10,28,1631133,16,3,1631197,14,1417729,1310721, +2,5,26,2,26,2,3,28,1,6,1,10,28,34,63,38, +1,10,28,1,6,1,10,28,34,63,38,1,10,28,1631207,16, +3,1631249,14,1442305,1310721,2,5,26,2,26,2,3,32,1,6,1, +10,28,34,63,38,1,10,28,1631319,16,1310721,2,5,26,1310721,2, +3,26,2,3,1,1582581,12,10,3,6,10,4,8,1442305,1310721,2, +5,26,2,26,1,10,3,6,10,4,8,1581345,2,1591367,12,8, +1581347,2,1590899,12,1,6,1,10,28,34,63,38,3,26,1632237,16, +3,1632237,16,1310721,2,11,26,1,10,3,6,10,4,8,1579077,2, +5,28,1,6,1,10,28,34,63,38,3,26,1631539,16,1579079,2, +1581397,2,28,1,6,1,10,28,34,63,38,3,26,1631461,16,3, +1631513,14,1579079,2,1581399,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,1,10,28,1631541,14,1,1631763,16,1310721,2,11,26, +3,10,3,6,10,4,8,1579079,2,1581399,2,28,1,6,1,10, +28,34,63,38,3,26,1631623,16,1310721,2,11,26,5,10,3,6, +10,4,8,1310721,2,19,26,1310721,2,7,26,2,26,1579079,2,10, +3,6,10,4,8,1590445,12,8,1579077,2,5,28,1,6,1,10, +28,34,63,38,3,26,1631737,16,1310721,2,19,26,1310721,2,7,26, +2,26,1591545,12,10,3,6,10,4,8,1631759,14,1310721,2,11,26, +1,10,3,6,10,4,8,1631799,14,1310721,2,19,26,1310721,2,7, +26,2,26,1591545,12,10,3,6,10,4,8,1310721,2,7,26,2, +25,40,3,36,1631857,16,1310721,2,11,26,2,1,6,1,10,28, +34,63,38,1,10,28,1631859,14,1,1631961,16,1631953,14,111,110,108, +121,32,116,104,101,32,102,105,114,115,116,32,49,50,32,112, +97,114,97,109,101,116,101,114,115,32,99,97,110,32,98,101, +32,116,97,103,103,101,100,0,1631867,1581413,12,8,1310721,2,67,26, +1310721,2,7,26,2,26,1310721,2,11,26,2,10,3,6,10,4, +8,1310721,2,7,26,2,25,40,1632089,16,1310721,2,9,26,1310721,2, +9,26,2,1310721,2,11,26,2,1310721,2,7,26,2,1310721,2,7, +26,2,26,1575289,12,26,10,3,6,10,4,8,1310721,2,7,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1310721,2,7, +26,2,49,40,3,36,1632197,16,1632189,14,116,111,111,32,109,97, +110,121,32,112,97,114,97,109,101,116,101,114,115,0,1632149,1581413, +12,8,1581357,2,1591159,12,1,6,1,10,28,34,63,38,3,26, +1632233,16,1632237,14,1631361,14,1581347,2,1591367,12,8,1581363,2,1591159,12,1632387, +16,1581401,2,1591029,12,1,6,1,10,28,34,63,38,3,26,1632359, +16,1632351,14,116,104,101,32,111,110,108,121,32,114,101,116,117, +114,110,32,116,97,103,32,105,115,32,45,62,32,117,0,1632295, +1581413,12,8,1590445,12,8,1310721,2,13,26,3,10,3,6,10,4, +8,1310721,2,15,26,1310721,2,13,26,2,1310721,2,7,26,2,26, +1310721,2,7,26,2,26,1310721,2,9,26,2,129,30,26,10,3, +6,10,4,8,1442305,1310721,2,5,26,2,26,2,5,32,1632637,16, +1434113,1310721,2,5,26,2,26,2,1310721,2,15,26,2,28,1,6, +1,10,28,34,63,38,1,10,28,1632633,16,1310721,2,3,26,2, +1632625,14,100,111,101,115,110,39,116,32,109,97,116,99,104,32, +105,116,115,32,101,97,114,108,105,101,114,32,100,101,99,108, +97,114,97,116,105,111,110,0,1632549,1581539,12,8,1632925,14,1442305,1310721, +2,5,26,2,26,2,9,32,1632739,16,1310721,2,9,26,2,1632681, +16,3,1632713,14,1310721,2,13,26,2,1,6,1,10,28,34,63, +38,1,10,28,1,6,1,10,28,34,63,38,1,10,28,1632741, +14,1,1632925,16,1310721,2,3,26,2,1632917,14,119,97,115,32,99, +97,108,108,101,100,32,98,101,102,111,114,101,32,105,116,115, +32,116,97,103,115,32,119,101,114,101,32,100,101,99,108,97, +114,101,100,59,32,112,117,116,32,97,32,112,114,111,116,111, +116,121,112,101,32,97,98,111,118,101,32,116,104,101,32,102, +105,114,115,116,32,99,97,108,108,0,1632759,1581539,12,8,1434113,1310721, +2,5,26,2,26,1310721,2,15,26,2,10,3,6,10,4,8, +1442305,1310721,2,5,26,2,26,1442305,1310721,2,5,26,2,26,2,5, +34,10,3,6,10,4,8,1581359,2,1591159,12,1633033,16,1310721,2,5, +26,2,1633821,14,1442305,1310721,2,5,26,2,26,2,3,32,1633113,16, +1310721,2,3,26,2,1633105,14,105,115,32,100,101,102,105,110,101, +100,32,116,119,105,99,101,0,1633071,1581539,12,8,1425921,1310721,2,5, +26,2,26,1581297,2,10,3,6,10,4,8,1442305,1310721,2,5,26, +2,26,1442305,1310721,2,5,26,2,26,2,3,34,10,3,6,10, +4,8,1450497,1310721,2,5,26,2,26,2,1581297,2,1583797,12,8,1450497, +1310721,2,5,26,2,26,1,10,3,6,10,4,8,1310721,2,2, +1310721,2,13,26,2,1630023,12,8,1630317,12,8,1310721,2,17,26,1, +10,3,6,10,4,8,1310721,2,17,26,2,1310721,2,7,26,2, +40,1633687,16,1310721,2,11,26,1310721,2,19,26,1310721,2,17,26,2, +26,2,1595777,12,10,3,6,10,4,8,1581311,1,6,2,1,6, +3,26,5,6,4,10,8,8,1581313,2,1633473,16,1310721,2,67,26, +1310721,2,17,26,2,26,2,3,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1633475,14, +1,1633507,16,1469953,1310721,2,11,26,2,26,13,10,3,6,10,4, +8,1581313,2,1633587,16,1310721,2,67,26,1310721,2,17,26,2,26,2, +5,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1633589,14,1,1633649,16,1469953,1310721,2,11, +26,2,26,3,10,3,6,10,4,8,1474049,1310721,2,11,26,2, +26,3,10,3,6,10,4,8,1310721,2,17,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1633293,14,1310721,2,17,26,1310721, +2,7,26,2,10,3,6,10,4,8,1310721,2,17,26,2,1633793, +16,1310721,2,17,26,1,6,2,1,6,-1,26,5,6,4,10, +8,8,1310721,2,17,26,2,1584865,12,8,5,1584215,12,8,1633717,14, +1630571,12,8,1630409,12,8,1310721,2,5,26,2,1633821,14,1,1310721,2, +115,26,1310721,4,18,1310721,2,7,28,1310721,4,1590445,12,8,3,1634325, +16,1310721,2,1591545,12,10,3,6,10,4,8,1581353,2,1591159,12,1634007, +16,1310721,2,5,26,1619459,12,10,3,6,10,4,8,1581355,2,1591367, +12,8,1310721,2,2,7,1581297,2,1582581,12,8,1310721,2,5,26,2, +1634003,16,1,1583993,12,8,1310721,2,5,26,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1633943,14,1634285,14,1310721,2,3,26,1581297, +2,10,3,6,10,4,8,1310721,2,2,5,1310721,2,3,26,2, +1582581,12,8,1,1583993,12,8,1581361,2,1591159,12,1634285,16,1579077,2,7, +28,1,6,1,10,28,34,63,38,3,26,1634253,16,1310721,2,3, +26,2,1581299,2,26,1581297,2,10,3,6,10,4,8,1310721,2,5, +26,1579079,2,10,3,6,10,4,8,1310721,2,5,26,2,2,1634235, +16,1310721,2,5,26,2,2,1583993,12,8,1310721,2,5,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1634163,14,1,1583993,12, +8,1590445,12,8,1634285,14,1310721,2,3,26,2,1581299,2,26,1619459,12, +10,3,6,10,4,8,1581357,2,1591159,12,1,6,1,10,28,34, +63,38,3,26,1634321,16,1634325,14,1633853,14,1581359,2,1591367,12,8,1, +1634343,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4, +1590445,12,8,3,1634469,16,1310721,2,1591545,12,10,3,6,10,4,8, +1581361,2,1591367,12,8,1310721,2,2,9,1619459,12,1582581,12,8,1581357,2, +1591159,12,1,6,1,10,28,34,63,38,3,26,1634465,16,1634469,14, +1634375,14,1581359,2,1591367,12,8,1,1634487,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,9,28,1310721,4,3,1310721,2,4,1,1310721,2,3, +26,4,1581393,2,1591029,12,1634603,16,1590445,12,8,1581359,2,1591159,12,1634585, +16,1579075,1,10,3,6,10,4,8,1,1635379,14,1310721,2,1,10, +3,6,10,4,8,1581395,2,1591029,12,1634643,16,1590445,12,8,1310721,2, +3,26,3,10,3,6,10,4,8,1581383,2,1591029,12,1634929,16,1310721, +2,5,26,1310721,2,2,1630943,12,10,3,6,10,4,8,1310721,2, +3,26,2,1634923,16,1581299,2,1634825,16,1634817,14,112,97,114,115,101, +32,119,111,114,100,115,32,99,97,110,39,116,32,98,101,32, +100,101,102,105,110,101,100,32,119,104,105,108,101,32,98,117, +105,108,100,105,110,103,32,97,110,32,105,109,97,103,101,0, +1634711,1581413,12,8,1310721,2,7,26,1409537,1310721,2,5,26,2,26,2, +11,1425921,1310721,2,5,26,2,26,2,1582581,12,10,3,6,10,4, +8,1442305,1310721,2,7,26,2,26,3,17,34,33,34,65,34,10, +3,6,10,4,8,1,1635379,14,1310721,2,2,1,6,1,10,28, +34,63,38,3,26,1634965,16,3,1634997,14,1310721,2,3,26,2,1, +6,1,10,28,34,63,38,1,10,28,1635037,16,1635029,14,101,120, +112,101,99,116,101,100,32,102,110,0,1635005,1581413,12,8,1581385,2, +1591029,12,1635057,16,1633835,12,1635379,14,1581387,2,1591029,12,1635077,16,1634357,12, +1635379,14,1579077,2,5,28,1,6,1,10,28,34,63,38,3,26, +1635307,16,1310721,2,5,26,1579079,2,1583029,12,10,3,6,10,4,8, +1310721,2,5,26,2,1,40,3,36,1635225,16,1417729,1310721,2,5,26, +2,26,2,11,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1635227,14,1,1635277,16,1442305, +1310721,2,5,26,2,26,2,65,32,1,6,1,10,28,34,63, +38,1,10,28,1635279,14,1,1635307,16,1310721,2,5,26,2,1,1610055, +12,8,1,1635379,14,1635363,14,101,120,112,101,99,116,101,100,32, +102,110,44,32,118,97,114,32,111,114,32,99,111,110,115,116, +0,1635311,1581413,12,8,1,1635379,14,1,1310721,2,9,26,1310721,4,18, +1310721,2,1,28,1310721,4,1579077,2,1,28,1,6,1,10,28,34, +63,38,1,10,28,1635449,16,1634501,12,8,1635405,14,1,1635457,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4, +1310721,2,2,1310721,2,3,26,4,1310721,2,3,26,2,1579009,2,40, +1635807,16,1417729,1310721,2,3,26,2,26,2,3,28,1,6,1,10, +28,34,63,38,3,26,1635635,16,1442305,1310721,2,3,26,2,26,2, +3,32,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1635637,14,1,1635683,16,1450497,1310721,2,3, +26,2,26,2,1,6,1,10,28,34,63,38,1,10,28,1635685, +14,1,1635769,16,1409537,1310721,2,3,26,2,26,2,1635761,14,105,115, +32,117,115,101,100,32,98,117,116,32,110,101,118,101,114,32, +100,101,102,105,110,101,100,0,1635709,1581539,12,8,1310721,2,3,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1635505,14,1, +1635815,14,1,1310721,2,5,26,1310721,4,18,1310721,2,11,28,1310721,4, +1310721,2,3,26,4,1310721,2,4,3,1,10,28,1310721,2,5,26, +4,1,1310721,2,7,26,4,1579009,2,1310721,2,9,26,4,1628783,12, +8,1581325,2,1635947,16,1310721,2,5,26,1584435,12,10,3,6,10,4, +8,15,1584215,12,8,3,1310721,2,2,1,1,1585519,12,8,1590445,12, +8,1310721,2,3,26,2,1635995,16,1635393,12,8,1636149,14,1310721,2,7, +26,1581297,2,10,3,6,10,4,8,3,1,1630023,12,8,1630317,12, +8,1579077,2,1,28,1,6,1,10,28,34,63,38,1,10,28, +1636079,16,1620153,12,8,1636035,14,1581307,2,1597865,12,8,1581313,2,1636127,16, +1581317,2,1,6,1,10,28,34,63,38,1,10,28,1636129,14,1, +1636143,16,3,3,1597159,12,8,1630409,12,8,1586333,12,8,1310721,2,9, +26,2,1635471,12,8,1310721,2,5,26,2,1,40,3,36,1636213,16, +1310721,2,5,26,2,1581297,2,1584275,12,8,1581297,2,1581303,2,10,40, +1636247,16,1581303,1581297,2,10,3,6,10,4,8,1629439,12,8,1310721,2, +7,26,2,1636269,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,4,1310721,2,2,1,1635829,12,1636319,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721, +2,2,3,1635829,12,8,1,1636373,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,4,1310721,2,2,1,1635829,12, +1310721,2,3,26,4,1310721,2,3,26,2,1,6,12,10,8,1636453, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721, +2,4,1310721,2,2,1628267,12,1310721,2,3,26,4,1310721,2,3,26, +2,1636387,12,1310721,2,5,26,4,1310721,2,3,26,2,1577415,12,8, +1310721,2,5,26,2,1636561,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,4,1310721,2,2,1310721,2,3,26,4, +1310721,2,3,26,2,1579009,2,40,1636935,16,1417729,1310721,2,3,26,2, +26,2,3,40,3,36,1636709,16,1417729,1310721,2,3,26,2,26,2, +9,10,40,3,36,1,6,1,10,28,34,63,38,1,10,28, +1636711,14,1,1636897,16,1417729,1310721,2,3,26,2,26,2,1583993,12,8, +1425921,1310721,2,3,26,2,26,2,1583993,12,8,1434113,1310721,2,3,26, +2,26,2,1583993,12,8,1310721,2,5,26,1409537,1310721,2,3,26,2, +26,2,10,3,6,10,4,8,1310721,2,5,26,2,2,1636889,16, +1310721,2,5,26,2,2,1583993,12,8,1310721,2,5,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1636817,14,1,1583993,12,8, +1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1636609,14,1,1583993,12,8,1,1636951,14,1,1310721,2,7,26,1310721, +4,18,1310721,2,7,28,1310721,4,1310721,2,4,1310721,2,2,2,1637207, +16,1310721,2,5,26,1310721,2,2,7,26,1582085,12,10,3,6,10, +4,8,1310721,2,3,26,1310721,2,5,26,2,1310721,2,2,1,26, +2,1310721,2,2,3,26,2,1582581,12,10,3,6,10,4,8,1434113, +1310721,2,3,26,2,26,1310721,2,2,5,26,2,10,3,6,10, +4,8,1442305,1310721,2,3,26,2,26,3,5,34,10,3,6,10, +4,8,1310721,2,1310721,2,2,7,26,1310721,2,2,7,26,1573535,12, +26,3,26,10,3,6,10,4,8,1636983,14,1,1637215,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,19,28,1310721,4,1310721,2,3,26, +4,1310721,2,4,1581297,2,1310721,2,5,26,4,1581299,2,1310721,2,7, +26,4,1581301,2,1310721,2,9,26,4,1579011,2,1310721,2,11,26,4, +1579013,2,1310721,2,13,26,4,1579009,2,1310721,2,15,26,4,1579011,1579009, +2,10,3,6,10,4,8,1579013,1579009,2,10,3,6,10,4,8, +1581297,1310721,2,2,10,3,6,10,4,8,1581299,1310721,2,3,26,2, +1310721,2,2,28,10,3,6,10,4,8,1581301,1310721,2,2,393217,26, +10,3,6,10,4,8,1966081,1584151,12,8,1310721,1584151,12,8,5,1584215, +12,8,1581403,2,1584495,12,1584595,12,8,15,1584215,12,8,1,1583993,12, +8,1,1583993,12,8,1,1,1,1,1585519,12,8,1590445,12,8,1635393, +12,8,1579011,2,1635471,12,8,1586333,12,8,1310721,2,3,26,2,11, +26,1581297,2,10,3,6,10,4,8,1579011,2,1636575,12,8,1310721,2, +3,26,2,13,26,1581297,2,10,3,6,10,4,8,1310721,2,17, +26,1581297,2,1310721,2,2,28,10,3,6,10,4,8,1310721,2,15, +26,2,1583283,12,8,1579011,1310721,2,11,26,2,10,3,6,10,4, +8,1579013,1310721,2,13,26,2,10,3,6,10,4,8,1581297,1310721,2, +5,26,2,10,3,6,10,4,8,1581299,1310721,2,7,26,2,10, +3,6,10,4,8,1581301,1310721,2,9,26,2,10,3,6,10,4, +8,1310721,2,17,26,2,1637811,14,1,1310721,2,19,26,1310721,4,18, +1310721,2,1,28,1310721,4,1,1581303,2,1577865,12,8,1581299,2,1,6, +1,10,28,34,63,38,3,26,1637915,16,1581297,2,1581303,2,10,40, +1,6,1,10,28,34,63,38,1,10,28,1637917,14,1,1637935,16, +1581303,2,1581297,2,1577865,12,8,1572865,1572865,13,26,2,1577865,12,8,1540609, +1540609,801,26,1577865,12,8,1310721,2,1966081,1577865,12,8,2064385,2097121,1577865,12, +8,1,1637995,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28, +1310721,4,1579007,1327617,10,3,6,10,4,8,1311233,1,16385,1574133,12,8, +1579009,1,10,3,6,10,4,8,1579015,1,10,3,6,10,4,8, +1579017,1,10,3,6,10,4,8,1579019,1,10,3,6,10,4,8, +1579021,1,10,3,6,10,4,8,1579023,1,10,3,6,10,4,8, +1579025,1,10,3,6,10,4,8,1579027,1,10,3,6,10,4,8, +1581327,1,10,3,6,10,4,8,1581331,1,10,3,6,10,4,8, +1581333,1,10,3,6,10,4,8,1581305,1,10,3,6,10,4,8, +1581307,1,10,3,6,10,4,8,1581345,1638267,14,40,0,1638263,1582085,12, +10,3,6,10,4,8,1581347,1638295,14,41,0,1638291,1582085,12,10,3, +6,10,4,8,1581349,1638323,14,123,0,1638319,1582085,12,10,3,6,10, +4,8,1581351,1638351,14,125,0,1638347,1582085,12,10,3,6,10,4,8, +1581353,1638379,14,91,0,1638375,1582085,12,10,3,6,10,4,8,1581355,1638407, +14,93,0,1638403,1582085,12,10,3,6,10,4,8,1581357,1638435,14,44, +0,1638431,1582085,12,10,3,6,10,4,8,1581359,1638463,14,59,0,1638459, +1582085,12,10,3,6,10,4,8,1581361,1638491,14,61,0,1638487,1582085,12, +10,3,6,10,4,8,1581363,1638521,14,45,62,0,1638515,1582085,12,10, +3,6,10,4,8,1581365,1638551,14,43,43,0,1638545,1582085,12,10,3, +6,10,4,8,1581367,1638581,14,45,45,0,1638575,1582085,12,10,3,6, +10,4,8,1581369,1638609,14,42,0,1638605,1582085,12,10,3,6,10,4, +8,1581371,1638637,14,38,0,1638633,1582085,12,10,3,6,10,4,8,1581373, +1638665,14,58,0,1638661,1582085,12,10,3,6,10,4,8,1581375,1638693,14, +35,0,1638689,1582085,12,10,3,6,10,4,8,1581377,1638721,14,45,0, +1638717,1582085,12,10,3,6,10,4,8,1581379,1638751,14,38,38,0,1638745, +1582085,12,10,3,6,10,4,8,1581381,1638781,14,124,124,0,1638775,1582085, +12,10,3,6,10,4,8,1581383,1638811,14,102,110,0,1638805,1582085,12, +10,3,6,10,4,8,1581385,1638843,14,118,97,114,0,1638835,1582085,12, +10,3,6,10,4,8,1581387,1638879,14,99,111,110,115,116,0,1638867, +1582085,12,10,3,6,10,4,8,1581389,1638913,14,101,108,115,101,0, +1638903,1582085,12,10,3,6,10,4,8,1581391,1638943,14,97,115,0,1638937, +1582085,12,10,3,6,10,4,8,1581393,1638987,14,117,110,99,104,101, +99,107,101,100,0,1638967,1582085,12,10,3,6,10,4,8,1581395,1639031, +14,105,109,109,101,100,105,97,116,101,0,1639011,1582085,12,10,3, +6,10,4,8,1581397,1639059,14,109,0,1639055,1582085,12,10,3,6,10, +4,8,1581399,1639087,14,100,0,1639083,1582085,12,10,3,6,10,4,8, +1581401,1639115,14,117,0,1639111,1582085,12,10,3,6,10,4,8,1581403,1639151, +14,115,116,97,114,116,0,1639139,1582085,12,10,3,6,10,4,8, +1581405,1639185,14,109,97,105,110,0,1639175,1582085,12,10,3,6,10,4, +8,1581407,1639219,14,102,114,101,101,0,1639209,1582085,12,10,3,6,10, +4,8,1581409,1639251,14,111,119,110,0,1639243,1582085,12,10,3,6,10, +4,8,1581411,1639285,14,113,110,101,119,0,1639275,1582085,12,10,3,6, +10,4,8,1,1639311,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +1,28,1310721,4,1639345,14,33,0,1639341,1639393,14,48,32,36,32,48, +32,126,32,45,32,124,32,51,49,32,62,32,49,32,43,0, +1639351,1595139,12,8,1639411,14,33,33,0,1639405,1639463,14,48,32,36,32, +48,32,126,32,45,32,124,32,51,49,32,62,32,48,32,126, +32,45,0,1639417,1595139,12,8,1639479,14,126,0,1639475,1639495,14,45,49, +32,94,0,1639485,1595139,12,8,1639511,14,45,0,1639507,1639529,14,48,32, +126,32,45,0,1639517,1595139,12,8,1639545,14,42,0,1639541,21,1639557,14, +42,0,1639553,1594121,12,8,1639573,14,47,0,1639569,21,1639595,14,122,100, +105,118,32,99,0,1639581,1594121,12,8,1639611,14,37,0,1639607,21,1639633, +14,122,109,111,100,32,99,0,1639619,1594121,12,8,1639649,14,43,0, +1639645,19,1639661,14,43,0,1639657,1594121,12,8,1639677,14,45,0,1639673,19, +1639689,14,45,0,1639685,1594121,12,8,1639707,14,60,60,0,1639701,17,1639729, +14,122,115,104,108,32,99,0,1639715,1594121,12,8,1639747,14,62,62, +0,1639741,17,1639759,14,62,0,1639755,1594121,12,8,1639775,14,60,0,1639771, +15,1639787,14,60,0,1639783,1594121,12,8,1639803,14,62,0,1639799,15,1639819, +14,126,32,60,0,1639811,1594121,12,8,1639837,14,60,61,0,1639831,15, +1639861,14,126,32,60,32,49,32,94,0,1639845,1594121,12,8,1639879,14, +62,61,0,1639873,15,1639899,14,60,32,49,32,94,0,1639887,1594121,12, +8,1639917,14,61,61,0,1639911,13,1639971,14,45,32,48,32,36,32, +48,32,126,32,45,32,124,32,51,49,32,62,32,49,32,43, +0,1639925,1594121,12,8,1639989,14,33,61,0,1639983,13,1640047,14,45,32, +48,32,36,32,48,32,126,32,45,32,124,32,51,49,32,62, +32,48,32,126,32,45,0,1639997,1594121,12,8,1640063,14,38,0,1640059, +11,1640075,14,38,0,1640071,1594121,12,8,1640091,14,94,0,1640087,9,1640103, +14,94,0,1640099,1594121,12,8,1640119,14,124,0,1640115,7,1640131,14,124, +0,1640127,1594121,12,8,1640149,14,38,38,0,1640143,3,1,10,28,1, +1594121,12,8,1640177,14,124,124,0,1640171,5,1,10,28,1,1594121,12, +8,1581361,2,1593381,12,8,1581363,2,1593381,12,8,1581365,2,1593381,12,8, +1581367,2,1593381,12,8,1640247,14,118,97,114,0,1640239,1621001,17,1595451,12, +8,1640269,14,105,102,0,1640263,1621389,17,1595451,12,8,1640297,14,119,104, +105,108,101,0,1640285,1622287,17,1595451,12,8,1640321,14,102,111,114,0, +1640313,1622595,17,1595451,12,8,1640349,14,98,114,101,97,107,0,1640337,1623689, +17,1595451,12,8,1640383,14,99,111,110,116,105,110,117,101,0,1640365, +1623857,17,1595451,12,8,1640413,14,114,101,116,117,114,110,0,1640399,1623981, +17,1595451,12,8,1640449,14,117,110,99,104,101,99,107,101,100,0, +1640429,1624377,17,1595451,12,8,1640473,14,97,115,109,0,1640465,1626893,17,33, +34,1595451,12,8,1640505,14,113,117,111,116,101,0,1640493,1628015,33,1595451, +12,8,1,1640525,14,1,1310721,2,1,26,1310721,4,18,1310721,2,5, +28,1310721,4,1575437,12,8,1638009,12,8,1572865,11,26,2,1636965,12,8, +1639325,12,8,1581297,1,10,3,6,10,4,8,1581299,1,10,3,6, +10,4,8,1581301,524289,10,3,6,10,4,8,1581303,1,10,3,6, +10,4,8,1579011,1579009,2,10,3,6,10,4,8,1579013,1,10,3, +6,10,4,8,1,1,1,1,1585519,12,8,1590445,12,8,1635393,12, +8,1579011,2,1635471,12,8,1581297,2,1581303,2,10,40,1640751,16,1581303,1581297, +2,10,3,6,10,4,8,1310721,2,1581405,2,1583029,12,10,3,6, +10,4,8,1310721,2,2,1,40,3,36,1640855,16,1417729,1310721,2,2, +26,2,3,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1640857,14,1,1640903,16,1442305,1310721, +2,2,26,2,3,32,1,6,1,10,28,34,63,38,1,10, +28,1640905,14,1,1640963,16,1310721,2,3,26,1425921,1310721,2,2,26,2, +10,3,6,10,4,8,1310721,2,3,26,2,1,6,12,10,8, +8,1572995,12,8,1,1640977,14,1,1310721,2,5,26,1310721,4,18,1, +820269,0,115,116,97,114,116,0,4,1048576,0,77,87,0,4,262144, +0,72,69,65,80,95,76,79,0,4,655360,0,72,69,65,80, +95,72,73,0,4,655360,0,90,70,80,0,4,786432,0,71,79, +82,71,0,4,917504,0,70,66,79,84,0,4,983040,0,70,84, +79,80,0,4,983040,0,82,83,48,0,4,1015808,0,77,65,82, +75,48,0,4,16384,0,77,65,82,75,78,0,4,1032192,0,68, +83,76,79,0,4,1048560,0,68,83,72,73,0,4,729683222,0,77, +65,71,73,67,0,1,786439,2,112,117,116,99,0,1,786463,0, +103,101,116,99,0,1,786480,0,101,111,102,0,1,786497,0,104, +97,108,116,0,1,786515,66,112,117,116,115,0,1,786585,2,112, +117,116,110,0,1,787584,4,122,109,111,100,0,1,787407,4,122, +100,105,118,0,1,786767,66,115,116,114,108,101,110,0,1,786828, +324,115,116,114,101,113,0,1,786971,326,119,99,111,112,121,0, +1,787066,70,119,102,105,108,108,0,3,787154,0,112,111,119,50, +0,2,787186,0,122,114,101,109,0,1,787187,4,122,117,100,105, +118,0,1,787644,4,122,115,104,108,0,2,787682,0,104,98,117, +109,112,0,3,787683,0,102,114,101,101,108,0,2,787715,0,103, +99,95,114,117,110,115,0,2,787716,0,103,99,95,102,114,101, +101,100,0,2,787717,0,103,99,95,97,117,116,111,0,1,787718, +0,104,101,97,112,95,105,110,105,116,0,1,787815,66,105,115, +111,98,106,0,1,787933,0,111,111,109,0,1,787983,3,110,101, +119,0,1,789063,0,103,99,0,1,788423,66,111,115,105,122,101, +0,1,788473,2,114,101,108,101,97,115,101,0,1,788707,130,102, +114,101,101,0,1,788740,4,111,119,110,0,2,788793,0,109,115, +95,116,111,112,0,2,788794,0,109,115,95,111,118,101,114,0, +2,788795,0,103,99,95,108,111,0,2,788796,0,103,99,95,104, +105,0,1,788797,2,109,97,114,107,0,1,788932,4,109,97,114, +107,114,97,110,103,101,0,1,788992,0,100,114,97,105,110,0, +1,818912,0,103,99,95,114,111,111,116,115,0,1,789417,0,108, +105,118,101,95,111,98,106,101,99,116,115,0,4,8192,0,73, +72,78,0,4,655616,0,82,95,73,72,0,4,663808,0,82,95, +80,79,79,76,0,4,704512,0,82,95,80,79,79,76,69,78, +68,0,4,4096,0,78,83,0,4,704768,0,82,95,83,89,77, +0,4,704768,0,115,110,97,109,101,0,4,708864,0,115,107,105, +110,100,0,4,712960,0,115,118,97,108,0,4,717056,0,115,115, +105,103,0,4,721152,0,115,102,108,97,103,0,4,725248,0,115, +102,105,120,0,4,729344,0,115,110,101,120,116,0,4,512,0, +78,76,0,4,733440,0,108,110,97,109,101,0,4,733952,0,108, +115,108,111,116,0,4,734464,0,108,104,111,109,101,0,4,734976, +0,108,115,116,97,116,101,0,4,735488,0,108,111,119,110,101, +114,0,4,736000,0,108,117,115,101,100,0,4,736512,0,108,97, +114,114,0,4,737024,0,108,111,119,110,0,4,8192,0,78,70, +0,4,737536,0,102,115,105,116,101,0,4,745728,0,102,110,101, +120,116,0,4,753920,0,82,95,83,78,65,80,0,4,762112,0, +82,95,81,66,85,70,0,4,770304,0,82,95,83,82,67,0, +4,771328,0,82,95,83,69,81,0,4,773376,0,98,110,97,109, +101,0,4,773440,0,98,112,114,101,99,0,4,773504,0,98,115, +101,113,0,4,773568,0,98,108,101,110,0,4,773632,0,117,110, +97,109,101,0,4,773664,0,117,115,101,113,0,4,773696,0,117, +108,101,110,0,4,773728,0,97,110,97,109,101,0,4,773792,0, +97,98,105,110,0,4,773888,0,107,111,112,115,0,4,774400,0, +82,95,67,84,88,0,4,776448,0,82,95,76,79,79,80,0, +4,777472,0,82,95,65,83,77,0,4,0,0,84,95,69,79, +70,0,4,1,0,84,95,78,85,77,0,4,2,0,84,95, +73,68,0,4,3,0,84,95,83,84,82,0,4,4,0,84, +95,79,80,0,4,1,0,75,95,70,78,0,4,2,0,75, +95,71,86,65,82,0,4,3,0,75,95,71,65,82,82,0, +4,4,0,75,95,67,79,78,83,84,0,4,5,0,75,95, +75,87,0,4,1,0,70,95,68,69,70,0,4,2,0,70, +95,83,73,71,0,4,4,0,70,95,85,78,84,89,80,69, +68,0,4,8,0,70,95,83,84,77,84,0,4,16,0,70, +95,69,88,80,82,0,4,32,0,70,95,84,79,80,0,4, +0,0,83,95,80,76,65,73,78,0,4,1,0,83,95,77, +0,4,2,0,83,95,85,0,4,3,0,83,95,68,0,4, +4,0,83,95,68,69,65,68,0,4,5,0,83,95,67,72, +73,76,68,0,4,6,0,83,95,66,79,82,82,79,87,0, +4,0,0,67,95,80,76,65,73,78,0,4,1,0,67,95, +70,82,69,83,72,0,4,2,0,67,95,86,65,82,0,4, +0,0,76,86,95,78,79,78,69,0,4,1,0,76,86,95, +76,79,67,65,76,0,4,2,0,76,86,95,71,76,79,66, +65,76,0,4,3,0,76,86,95,69,76,69,77,0,4,4, +0,76,86,95,79,84,72,69,82,0,4,0,0,79,95,81, +0,4,1,0,79,95,76,68,0,4,2,0,79,95,83,84, +0,4,3,0,79,95,80,73,67,75,0,4,4,0,79,95, +68,82,79,80,0,4,5,0,79,95,83,87,65,80,0,4, +6,0,79,95,67,65,76,76,0,4,7,0,79,95,74,77, +80,0,4,8,0,79,95,74,90,0,4,9,0,79,95,82, +69,84,0,4,13,0,79,95,65,68,68,0,4,14,0,79, +95,83,85,66,0,4,-2,0,83,69,81,82,69,70,0,2, +789503,0,112,111,111,108,116,111,112,0,2,789504,0,110,115,121, +109,0,2,789505,0,117,98,97,115,101,0,2,789506,0,118,105, +115,108,111,0,2,789507,0,110,102,105,120,117,0,2,789508,0, +102,105,120,102,114,101,101,0,2,789509,0,110,98,105,110,0, +2,789510,0,110,117,110,0,2,789511,0,110,97,115,103,0,2, +789512,0,110,107,111,112,0,2,789513,0,115,101,113,116,111,112, +0,2,789514,0,109,110,101,109,0,2,789537,0,99,104,101,99, +107,95,111,110,0,2,789538,0,116,107,0,2,789539,0,116,118, +0,2,789540,0,116,103,108,117,101,0,2,789541,0,116,108,105, +110,101,0,2,789542,0,108,105,110,101,0,2,789543,0,99,104, +0,2,789544,0,99,104,107,105,110,100,0,2,789545,0,99,104, +112,116,114,0,2,789546,0,113,100,111,110,101,0,2,789547,0, +105,115,112,0,3,789548,0,116,98,117,102,0,2,790648,0,104, +101,114,101,0,2,790649,0,104,100,101,108,116,97,0,2,790650, +0,104,108,105,109,105,116,0,2,790651,0,112,116,111,112,0, +2,790652,0,110,108,111,99,0,2,790653,0,108,98,97,115,101, +0,2,790654,0,102,100,101,112,116,104,0,2,790655,0,102,115, +108,111,116,115,0,2,790656,0,102,99,104,107,0,2,790657,0, +102,114,101,116,0,2,790658,0,108,105,118,101,0,2,790659,0, +98,120,100,101,112,116,104,0,2,790660,0,101,112,105,99,104, +97,105,110,0,2,790661,0,102,102,114,97,109,101,0,2,790662, +0,105,110,102,110,0,2,790663,0,108,115,112,0,2,790664,0, +108,111,111,112,98,97,115,101,0,2,790665,0,99,116,120,115, +112,0,2,790666,0,115,110,97,112,116,111,112,0,2,790667,0, +108,118,0,2,790668,0,108,118,107,0,2,790669,0,108,118,105, +0,2,790670,0,107,119,95,101,120,112,114,0,2,790671,0,120, +99,108,115,0,2,790672,0,115,95,108,112,0,2,790673,0,115, +95,114,112,0,2,790674,0,115,95,108,98,0,2,790675,0,115, +95,114,98,0,2,790676,0,115,95,108,107,0,2,790677,0,115, +95,114,107,0,2,790678,0,115,95,99,111,109,109,97,0,2, +790679,0,115,95,115,101,109,105,0,2,790680,0,115,95,101,113, +0,2,790681,0,115,95,97,114,114,111,119,0,2,790682,0,115, +95,105,110,99,0,2,790683,0,115,95,100,101,99,0,2,790684, +0,115,95,115,116,97,114,0,2,790685,0,115,95,97,109,112, +0,2,790686,0,115,95,99,111,108,111,110,0,2,790687,0,115, +95,104,97,115,104,0,2,790688,0,115,95,109,105,110,117,115, +0,2,790689,0,115,95,97,110,100,97,110,100,0,2,790690,0, +115,95,111,114,111,114,0,2,790691,0,115,95,102,110,0,2, +790692,0,115,95,118,97,114,0,2,790693,0,115,95,99,111,110, +115,116,0,2,790694,0,115,95,101,108,115,101,0,2,790695,0, +115,95,97,115,0,2,790696,0,115,95,117,110,99,104,101,99, +107,101,100,0,2,790697,0,115,95,105,109,109,101,100,105,97, +116,101,0,2,790698,0,115,95,109,0,2,790699,0,115,95,100, +0,2,790700,0,115,95,117,0,2,790701,0,115,95,115,116,97, +114,116,0,2,790702,0,115,95,109,97,105,110,0,2,790703,0, +115,95,102,114,101,101,0,2,790704,0,115,95,111,119,110,0, +2,790705,0,115,95,113,110,101,119,0,1,790706,2,100,105,101, +0,1,790769,4,100,105,101,110,0,1,790854,2,99,101,114,114, +0,1,790902,4,99,101,114,114,110,0,1,790963,2,104,97,115, +104,115,0,1,791042,2,105,110,116,101,114,110,0,1,791290,6, +97,100,100,115,121,109,0,1,791514,2,108,111,111,107,117,112, +0,1,791641,2,112,111,112,115,121,109,115,0,1,791707,2,108, +111,111,107,117,112,115,0,1,791733,4,102,105,120,110,101,119, +0,1,791898,4,102,105,120,97,108,108,0,1,792137,4,115,101, +116,108,105,116,0,1,791996,2,101,109,105,116,0,1,792075,2, +108,105,116,0,1,792107,2,111,112,0,1,792187,2,106,109,112, +0,1,792217,0,104,111,108,101,0,1,792247,2,102,119,100,102, +110,0,1,792297,2,102,110,114,101,102,0,1,792366,2,99,97, +108,108,110,97,109,101,0,1,792432,2,108,97,100,100,114,0, +1,792475,2,115,116,114,108,105,116,0,1,792570,0,110,101,120, +116,99,104,0,1,792759,8,115,114,99,95,112,117,115,104,0, +1,793166,0,115,114,99,95,112,111,112,0,1,793301,2,105,115, +111,112,99,104,0,1,793401,4,111,112,112,114,101,102,105,120, +0,1,793633,2,105,115,100,105,103,0,1,793683,2,105,115,97, +108,0,1,793811,2,104,101,120,118,0,1,793932,0,101,115,99, +99,104,0,1,794095,2,111,112,108,101,120,0,1,794229,0,108, +101,120,0,1,795222,0,110,101,120,116,0,1,795449,2,105,115, +95,111,112,0,1,795514,2,105,115,95,105,100,0,1,795579,2, +97,99,99,101,112,116,0,1,795683,2,101,120,112,101,99,116, +0,1,795772,0,110,97,109,101,0,1,795838,2,115,101,113,97, +115,109,0,1,796396,2,109,110,101,109,105,100,120,0,1,796487, +4,101,109,105,116,115,101,113,0,1,796690,2,97,100,100,107, +111,112,0,1,796799,2,98,105,110,102,105,110,100,0,1,796886, +2,117,110,102,105,110,100,0,1,796973,2,97,115,103,102,105, +110,100,0,1,797060,6,97,100,100,95,98,105,110,111,112,0, +1,797569,4,97,100,100,95,117,110,111,112,0,1,797725,6,97, +100,100,95,107,119,0,1,797797,2,102,105,110,100,108,111,99, +0,1,797888,2,110,101,119,108,111,99,0,1,798079,2,108,114, +111,111,116,0,1,798137,2,116,114,97,99,107,101,100,0,1, +798175,2,116,111,117,99,104,0,1,798408,2,112,108,97,105,110, +117,115,101,0,1,798537,2,102,114,101,101,118,97,114,0,1, +798579,4,101,120,105,116,95,118,97,114,115,0,1,798932,2,117, +110,117,115,101,100,95,99,104,101,99,107,0,1,799070,2,98, +108,111,99,107,95,99,108,111,115,101,0,1,799195,0,115,110, +97,112,95,112,117,115,104,0,1,799459,2,115,110,97,112,95, +112,111,112,0,1,799489,2,115,110,97,112,95,114,101,115,116, +111,114,101,0,1,799697,2,101,109,112,116,121,0,1,799762,2, +115,110,97,112,95,99,109,112,0,1,800156,2,115,116,97,116, +101,110,97,109,101,0,1,800363,6,109,101,114,103,101,95,101, +114,114,0,1,800544,4,109,101,114,103,101,0,1,800744,2,108, +111,111,112,99,104,101,99,107,0,1,800956,4,114,101,99,97, +115,116,0,1,801481,4,97,114,103,99,104,101,99,107,0,1, +802347,2,101,109,105,116,111,119,110,0,1,802385,6,97,115,115, +105,103,110,99,104,101,99,107,0,1,804054,2,114,101,116,99, +104,101,99,107,0,1,804535,2,104,97,110,100,117,112,0,1, +804882,2,100,105,115,99,97,114,100,0,1,804994,0,114,118,97, +108,0,1,805027,4,107,119,99,97,108,108,0,1,805145,0,115, +116,109,116,111,110,108,121,0,1,805212,2,99,97,108,108,0, +1,808329,0,101,120,112,114,0,1,805552,0,112,114,105,109,97, +114,121,0,1,809006,0,98,108,111,99,107,101,120,112,114,0, +1,806403,4,105,110,99,100,101,99,0,1,806695,0,112,111,115, +116,102,105,120,0,1,807485,0,117,110,97,114,121,0,1,807839, +2,98,105,110,0,1,808292,0,115,116,111,114,101,107,101,101, +112,0,1,808795,0,115,116,109,116,115,116,97,114,116,0,1, +810076,0,115,116,109,116,0,1,809332,0,99,112,114,105,109,0, +1,809729,0,99,101,120,112,114,0,1,810314,0,98,108,111,99, +107,0,1,810431,0,115,117,98,115,116,109,116,0,1,810500,0, +107,119,95,118,97,114,0,1,810694,0,107,119,95,105,102,0, +1,810932,4,108,111,111,112,95,112,117,115,104,0,1,811098,0, +108,111,111,112,95,112,111,112,0,1,811143,0,107,119,95,119, +104,105,108,101,0,1,811297,0,107,119,95,102,111,114,0,1, +811676,2,108,111,111,112,101,120,105,116,0,1,811844,0,107,119, +95,98,114,101,97,107,0,1,811928,0,107,119,95,99,111,110, +116,105,110,117,101,0,1,811990,0,107,119,95,114,101,116,117, +114,110,0,1,812188,0,107,119,95,117,110,99,104,101,99,107, +101,100,0,1,812237,0,97,115,109,98,108,111,99,107,0,1, +813446,0,107,119,95,97,115,109,0,1,813477,1,103,114,97,98, +0,1,813797,3,113,110,101,119,0,1,813864,67,113,100,117,112, +0,1,813931,68,119,99,111,112,121,116,111,0,1,814007,0,107, +119,95,113,117,111,116,101,0,1,814133,3,116,111,107,101,110, +115,0,1,814359,130,102,101,101,100,0,1,814391,0,99,116,120, +95,112,117,115,104,0,1,814719,0,99,116,120,95,112,111,112, +0,1,815011,4,102,110,95,98,101,103,105,110,0,1,815158,0, +112,114,111,108,111,103,117,101,0,1,815204,0,101,112,105,108, +111,103,117,101,0,1,815285,0,98,111,100,121,0,1,815471,2, +102,110,100,101,102,0,1,816917,0,103,118,97,114,0,1,817178, +0,103,99,111,110,115,116,0,1,817250,0,116,111,112,105,116, +101,109,0,1,817696,0,117,110,105,116,95,116,111,112,0,1, +817735,2,117,110,105,116,95,101,110,100,0,1,817914,68,99,111, +109,112,105,108,101,95,108,105,115,116,0,1,818141,66,99,111, +109,112,105,108,101,0,1,818166,66,108,111,97,100,0,1,818193, +66,101,118,97,108,0,1,818233,2,101,118,97,108,115,0,1, +818287,2,98,108,111,98,95,101,109,105,116,0,1,818482,2,98, +108,111,98,95,108,111,97,100,0,1,818614,4,98,117,105,108, +100,95,105,109,97,103,101,0,1,819004,0,122,99,95,105,110, +105,116,0,1,819662,0,122,99,95,116,97,98,108,101,115,0, +0 +}; +#define GLEN 37505 diff --git a/docs/history/10-zc/code/io_linux.c b/docs/history/10-zc/code/io_linux.c new file mode 100644 index 0000000..7ea34e0 --- /dev/null +++ b/docs/history/10-zc/code/io_linux.c @@ -0,0 +1,6 @@ +#include <stdio.h> +int J; +static int pk(void){int c=getchar();ungetc(c,stdin);return c==EOF;} +char Q(void){int c=getchar();J=pk();return c;} +void G(char c){putchar(c);} +__attribute__((constructor)) static void init(void){J=pk();} diff --git a/docs/history/10-zc/code/mkgenome.c b/docs/history/10-zc/code/mkgenome.c new file mode 100644 index 0000000..8fb2cc5 --- /dev/null +++ b/docs/history/10-zc/code/mkgenome.c @@ -0,0 +1,16 @@ +/* turns a genome image (little-endian 32-bit words on stdin, as written by + tools/build.zc) into genome.h */ +#include <stdio.h> +#define GORG 0xC0000 +int main(void) +{ + unsigned char b[4]; int n = 0; + printf("#define GORG %d\nstatic const int genome[] = {", GORG); + while (fread(b, 1, 4, stdin) == 4) { + int w = (int)(b[0] | b[1] << 8 | b[2] << 16 | (unsigned)b[3] << 24); + printf("%s%d", !n ? "\n" : n % 16 ? "," : ",\n", w); + n++; + } + printf("\n};\n#define GLEN %d\n", n); + return n ? 0 : 1; +} diff --git a/docs/history/10-zc/code/src/compiler.zc b/docs/history/10-zc/code/src/compiler.zc new file mode 100644 index 0000000..29116fa --- /dev/null +++ b/docs/history/10-zc/code/src/compiler.zc @@ -0,0 +1,1591 @@ +// ============================================================================ +// compiler.zc: the resident zc compiler. it lives in the genome next to the +// runtime, compiles source straight to vm words in memory, and is visible to +// the programs it compiles: every function and global here can be called or +// patched by name, and parse words (immediate fns) run inside it. +// ============================================================================ + +// ---- compiler data region (fixed addresses, 0xA0100 .. 0xBE100) ---- +const IHN = 8192; +const R_IH = 0xA0100; // intern hash table +const R_POOL = 0xA2100; // interned strings: [symbol head] chars 0 +const R_POOLEND = 0xAC000; +const NS = 4096; // symbol table, one array per field +const R_SYM = 0xAC100; +const sname = 0xAC100, skind = 0xAD100, sval = 0xAE100, ssig = 0xAF100; +const sflag = 0xB0100, sfix = 0xB1100, snext = 0xB2100; +const NL = 512; // locals, one array per field +const lname = 0xB3100, lslot = 0xB3300, lhome = 0xB3500, lstate = 0xB3700; +const lowner = 0xB3900, lused = 0xB3B00, larr = 0xB3D00, lown = 0xB3F00; // lown: has owned an object +const NF = 8192; // patch nodes: a site and a link +const fsite = 0xB4100, fnext = 0xB6100; +const R_SNAP = 0xB8100; // analyzer snapshots +const R_QBUF = 0xBA100; // token buffer for quote and grab +const R_SRC = 0xBC100; // input source stack, 12 words per frame +const R_SEQ = 0xBC500; // operator code sequences +const bname = 0xBCD00, bprec = 0xBCD40, bseq = 0xBCD80, blen = 0xBCDC0; // binary operators +const uname = 0xBCE00, useq = 0xBCE20, ulen = 0xBCE40; // unary operators +const aname = 0xBCE60, abin = 0xBCEA0; // compound assignment +const kops = 0xBCF00; // every operator spelling the lexer knows +const R_CTX = 0xBD100; // saved compiler contexts for nested compiles +const R_LOOP = 0xBD900; // loop stack, 6 words per loop +const R_ASM = 0xBDD00; // asm block labels + +// ---- token kinds, symbol kinds and flags ---- +const T_EOF = 0, T_NUM = 1, T_ID = 2, T_STR = 3, T_OP = 4; +const K_FN = 1, K_GVAR = 2, K_GARR = 3, K_CONST = 4, K_KW = 5; +const F_DEF = 1, F_SIG = 2, F_UNTYPED = 4, F_STMT = 8, F_EXPR = 16, F_TOP = 32; +// variable states for the lifetime analyzer +const S_PLAIN = 0, S_M = 1, S_U = 2, S_D = 3, S_DEAD = 4, S_CHILD = 5, S_BORROW = 6; +// expression classes: plain word, a new object, or a bare variable (C_VAR + index) +const C_PLAIN = 0, C_FRESH = 1, C_VAR = 2; +// lvalue kinds +const LV_NONE = 0, LV_LOCAL = 1, LV_GLOBAL = 2, LV_ELEM = 3, LV_OTHER = 4; +// opcodes +const O_Q = 0, O_LD = 1, O_ST = 2, O_PICK = 3, O_DROP = 4, O_SWAP = 5, O_CALL = 6, O_JMP = 7; +const O_JZ = 8, O_RET = 9, O_ADD = 13, O_SUB = 14; +const SEQREF = -2; // in an operator sequence: the next word names a symbol + +// ---- state ---- +var pooltop, nsym, ubase, vislo, nfixu, fixfree; +var nbin, nun, nasg, nkop, seqtop; +var mnem = "q@!$_~cjzr,?.+-*&|^><"; +var check_on = 1; // set to 0 to switch the analyzer off for what follows +var tk, tv, tglue, tline, line = 1, ch, chkind, chptr, qdone, isp = -1; +var tbuf[1100]; +var here, hdelta, hlimit, ptop; +var nloc, lbase, fdepth, fslots, fchk, fret, live, bxdepth, epichain, fframe, infn; +var lsp, loopbase, ctxsp, snaptop; +var lv, lvk, lvi, kw_expr, xcls; +// interned spellings the parser compares against +var s_lp, s_rp, s_lb, s_rb, s_lk, s_rk, s_comma, s_semi, s_eq, s_arrow, s_inc, s_dec; +var s_star, s_amp, s_colon, s_hash, s_minus, s_andand, s_oror; +var s_fn, s_var, s_const, s_else, s_as, s_unchecked, s_immediate, s_m, s_d, s_u; +var s_start, s_main, s_free, s_own, s_qnew; + +// ---- errors ---- +fn die(msg) { puts("zc: line "); putn(tline); puts(": "); puts(msg); putc(10); halt(); return 0; } +fn dien(name, msg) { puts("zc: line "); putn(tline); puts(": "); puts(name); puts(": "); puts(msg); putc(10); halt(); return 0; } +// analyzer errors only count in checked, reachable code +fn cerr(msg) { if (fchk && live) die(msg); return 0; } +fn cerrn(i, msg) { if (fchk && live) dien(lname[i], msg); return 0; } + +// ---- interning ---- +fn hashs(s) { var h = 0; while (*s) { h = h * 31 + *s; s++; } return h & (IHN - 1); } +fn intern(s) +{ + var h = hashs(s), p, n; + while (1) { + p = R_IH[h]; + if (!p) break; + if (streq(p, s)) return p; + h = (h + 1) & (IHN - 1); + } + n = strlen(s); + if (pooltop + n + 2 >= R_POOLEND) die("string pool full"); + pooltop[0] = 0; + p = pooltop + 1; + wcopy(p, s, n + 1); + pooltop = pooltop + n + 2; + R_IH[h] = p; + return p; +} + +// ---- symbols ---- +// each interned name keeps the index (+1) of its newest symbol in p[-1], and +// each symbol links to the one it shadows, so lookup is one step. +fn addsym(name, kind, val) +{ + var i = nsym; + if (nsym >= NS) die("symbol table full"); + nsym++; + sname[i] = name; skind[i] = kind; sval[i] = val; ssig[i] = 0; sflag[i] = F_DEF; sfix[i] = 0; + snext[i] = name[-1]; + name[-1] = i + 1; + return i; +} +// while an image builds, names below vislo are hidden, except keywords +fn lookup(name) +{ + var i = name[-1] - 1; + while (i >= 0) { + if (i >= vislo || skind[i] == K_KW) return i; + i = snext[i] - 1; + } + return -1; +} +fn popsyms(to) { while (nsym > to) { nsym--; sname[nsym][-1] = snext[nsym]; } return 0; } +fn lookups(s) { return lookup(intern(s)); } + +// patch nodes +fn fixnew(site, link) +{ + var i = fixfree; + if (i) fixfree = fnext[i]; + else { nfixu++; i = nfixu; if (i >= NF) die("too many forward references"); } + fsite[i] = site; fnext[i] = link; + return i; +} +// patch every lit in a chain to point at v, and recycle the nodes +fn fixall(head, v) +{ + var n; + while (head) { setlit(fsite[head], v); n = fnext[head]; fnext[head] = fixfree; fixfree = head; head = n; } + return 0; +} + +// ---- code emission ---- +fn emit(w) { if (here >= hlimit) die("program too big"); *(here + hdelta) = w; here++; return 0; } +fn lit(v) { emit(v + v + 1); return 0; } +fn op(k) { emit(k + k); return 0; } +fn setlit(at, v) { *(at + hdelta) = v + v + 1; return 0; } +fn jmp(t) { lit(t); op(O_JMP); return 0; } +// a lit that will be patched later; returns its address +fn hole() { var a = here; lit(MW - 1); return a; } +fn fwdfn(name) { var s = addsym(name, K_FN, 0); sflag[s] = 0; return s; } +fn fnref(s) +{ + if (sflag[s] & F_DEF) { lit(sval[s]); return 0; } + sfix[s] = fixnew(here, sfix[s]); + lit(MW - 1); // a jump to MW-1 halts if it ever runs unpatched + return 0; +} +fn callname(name) { var s = lookup(name); if (s < 0) s = fwdfn(name); fnref(s); op(O_CALL); return 0; } +fn laddr(k) { lit(ZFP); op(O_LD); if (k) { lit(k); op(O_ADD); } return 0; } +fn strlit(s) +{ + var j = hole(), a; + op(O_JMP); + a = here; + while (*s) { emit(*s); s++; } + emit(0); + setlit(j, here); + lit(a); + return 0; +} + +// ---- input sources ---- +// frame: 0 kind (0 stdin, 1 token list, 2 string) 1 object 2 index 3 end +// 4 transparent 5..7 saved token 8..10 saved char state 11 owned +fn nextch() +{ + if (chkind == 0) { + if (qdone || eof()) { ch = -1; return 0; } + ch = getc(); + if (ch == 96) { qdone = 1; ch = -1; return 0; } // a backtick ends the source + } else { + ch = *chptr; + if (ch) chptr++; else ch = -1; + } + if (ch == 10) line++; + return 0; +} +fn src_push(kind, obj, trans, owned) +{ + var f; + isp++; + if (isp >= 32) die("sources nested too deeply"); + f = R_SRC + isp * 12; + f[0] = kind; f[1] = obj; f[2] = 0; f[3] = 0; f[4] = trans; f[11] = owned; + f[5] = tk; f[6] = tv; f[7] = tglue; f[8] = ch; f[9] = chkind; f[10] = chptr; + if (kind == 1) f[3] = obj[0]; + if (kind == 0) { chkind = 0; qdone = 0; nextch(); } + if (kind == 2) { chkind = 2; chptr = obj; nextch(); } + return 0; +} +fn src_pop() +{ + var f = R_SRC + isp * 12; + tk = f[5]; tv = f[6]; tglue = f[7]; ch = f[8]; chkind = f[9]; chptr = f[10]; + isp--; + if (f[11]) free(f[1]); + return 0; +} +fn isopch(c) +{ + var s = "+-*/%=<>!&|^~?:.@#$"; + while (*s) { if (*s == c) return 1; s++; } + return 0; +} +// is buf[0..n) followed by c the start of some operator the lexer knows? +fn opprefix(n, c) +{ + var i = 0, k, j; + while (i < nkop) { + k = kops[i]; + j = 0; + while (j < n && k[j] == tbuf[j]) j++; + if (j == n && k[n] == c) return 1; + i++; + } + return 0; +} +fn isdig(c) { return c >= '0' && c <= '9'; } +fn isal(c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; } +fn hexv(c) +{ + if (isdig(c)) return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return -1; +} +fn escch() +{ + var c = ch; + nextch(); + if (c != 92) return c; + c = ch; + nextch(); + if (c == 'n') return 10; + if (c == 't') return 9; + if (c == 'r') return 13; + if (c == '0') return 0; + if (c == 'e') return 27; + return c; +} +fn oplex(n) +{ + while (ch >= 0 && isopch(ch) && opprefix(n, ch)) { tbuf[n] = ch; n++; nextch(); } + tbuf[n] = 0; + tk = T_OP; tv = intern(tbuf); + return 0; +} +fn lex() +{ + var n = 0, v, d; + tglue = 1; + while (1) { + while (ch == 32 || ch == 9 || ch == 10 || ch == 13) { nextch(); tglue = 0; } + if (ch != '/') break; + nextch(); + if (ch == '/') { while (ch >= 0 && ch != 10) nextch(); tglue = 0; continue; } + if (ch == '*') { + nextch(); + while (ch >= 0) { if (ch == '*') { nextch(); if (ch == '/') break; } else nextch(); } + nextch(); tglue = 0; continue; + } + tline = line; tbuf[0] = '/'; oplex(1); return 0; + } + tline = line; + if (ch < 0) { tk = T_EOF; tv = 0; return 0; } + if (isdig(ch)) { + v = 0; + if (ch == '0') { + nextch(); + if (ch == 'x' || ch == 'X') { + nextch(); + while ((d = hexv(ch)) >= 0) { v = v * 16 + d; nextch(); } + tk = T_NUM; tv = v; return 0; + } + } + while (isdig(ch)) { v = v * 10 + ch - '0'; nextch(); } + tk = T_NUM; tv = v; return 0; + } + if (isal(ch)) { + while (isal(ch) || isdig(ch)) { if (n < 1000) { tbuf[n] = ch; n++; } nextch(); } + tbuf[n] = 0; + tk = T_ID; tv = intern(tbuf); return 0; + } + if (ch == 39) { nextch(); tv = escch(); if (ch != 39) die("bad character literal"); nextch(); tk = T_NUM; return 0; } + if (ch == 34) { + nextch(); + while (ch >= 0 && ch != 34) { v = escch(); if (n < 1000) { tbuf[n] = v; n++; } } + nextch(); + tbuf[n] = 0; + tk = T_STR; tv = intern(tbuf); return 0; + } + tbuf[0] = ch; + nextch(); + if (isopch(tbuf[0])) return oplex(1); + tbuf[1] = 0; + tk = T_OP; tv = intern(tbuf); + return 0; +} +fn next() +{ + var f, q, i; + f = R_SRC + isp * 12; + if (f[0] != 1) { lex(); return 0; } + i = f[2]; + if (i < f[3]) { q = f[1]; tk = q[1 + i + i]; tv = q[2 + i + i]; tglue = 0; f[2] = i + 1; return 0; } + if (!f[4]) { tk = T_EOF; tv = 0; return 0; } + src_pop(); // a fed list ran out: continue with the token that followed it + return 0; +} +fn is_op(s) { return tk == T_OP && tv == s; } +fn is_id(s) { return tk == T_ID && tv == s; } +fn accept(s) { if ((tk == T_OP || tk == T_ID) && tv == s) { next(); return 1; } return 0; } +fn expect(s) { if (!accept(s)) { puts("zc: line "); putn(tline); puts(": expected "); puts(s); putc(10); halt(); } return 0; } +fn name() +{ + var n = tv; + if (tk != T_ID) die("expected a name"); + next(); + return n; +} + +// ---- operator tables ---- +// a sequence is written like asm: one-char mnemonics, numbers, and names +// (resolved when the operator is used, so image builds stay self-contained) +fn seqasm(s) +{ + var start = seqtop, n, neg, v, k, c; + while (1) { + while (*s == 32) s++; + if (!*s) break; + n = 0; + while (s[n] && s[n] != 32) { tbuf[n] = s[n]; n++; } + tbuf[n] = 0; + s = s + n; + neg = tbuf[0] == '-' && isdig(tbuf[1]); + if (isdig(tbuf[neg])) { + v = 0; k = neg; + while (tbuf[k]) { v = v * 10 + tbuf[k] - '0'; k++; } + if (neg) v = 0 - v; + R_SEQ[seqtop] = v + v + 1; seqtop++; + } else if (n == 1 && (c = mnemidx(tbuf[0])) >= 0) { + R_SEQ[seqtop] = c + c; seqtop++; + } else { + R_SEQ[seqtop] = SEQREF; R_SEQ[seqtop + 1] = intern(tbuf); seqtop = seqtop + 2; + } + } + return start; +} +fn mnemidx(c) { var i = 0; while (mnem[i]) { if (mnem[i] == c) return i; i++; } return -1; } +fn emitseq(a, n) +{ + var e = a + n, s; + while (a < e) { + if (R_SEQ[a] == SEQREF) { + s = lookup(R_SEQ[a + 1]); + if (s < 0) s = fwdfn(R_SEQ[a + 1]); + if (skind[s] == K_FN) fnref(s); else lit(sval[s]); + a = a + 2; + } else { emit(R_SEQ[a]); a++; } + } + return 0; +} +fn addkop(p) { var i = 0; while (i < nkop) { if (kops[i] == p) return 0; i++; } kops[nkop] = p; nkop++; return 0; } +fn binfind(p) { var i = nbin; while (i) { i--; if (bname[i] == p) return i; } return -1; } +fn unfind(p) { var i = nun; while (i) { i--; if (uname[i] == p) return i; } return -1; } +fn asgfind(p) { var i = nasg; while (i) { i--; if (aname[i] == p) return i; } return -1; } +// add or replace a binary operator. code is a sequence string, or 0 for the +// built-in && (prec 2) and || (prec 1) behaviour, chosen by -1 / -2 in prec. +fn add_binop(nm, prec, code) +{ + var p = intern(nm), i = binfind(p), a, n; + if (i < 0) { i = nbin; nbin++; } + bname[i] = p; bprec[i] = prec; + if (prec < 0) { bprec[i] = 0 - prec; blen[i] = prec; bseq[i] = 0; addkop(p); return i; } + bseq[i] = seqasm(code); blen[i] = seqtop - bseq[i]; + addkop(p); + // and its compound assignment, x op= y + n = strlen(nm); + wcopy(tbuf + 1000, nm, n); + tbuf[1000 + n] = '='; tbuf[1001 + n] = 0; + a = intern(tbuf + 1000); + if (prec >= 8 || prec == 5 || prec == 4 || prec == 3) { + if (asgfind(a) < 0) { aname[nasg] = a; nasg++; } + abin[asgfind(a)] = i; + addkop(a); + } + return i; +} +fn add_unop(nm, code) +{ + var p = intern(nm), i = unfind(p); + if (i < 0) { i = nun; nun++; } + uname[i] = p; useq[i] = seqasm(code); ulen[i] = seqtop - useq[i]; + addkop(p); + return i; +} +fn add_kw(nm, handler, flags) { var s = addsym(intern(nm), K_KW, handler); sflag[s] = F_DEF | flags; return s; } + +// ---- locals and the analyzer's view of them ---- +fn findloc(n) { var i = nloc; while (i > lbase) { i--; if (lname[i] == n) return i; } return -1; } +fn newloc(n) +{ + var i = nloc; + if (nloc >= NL) die("too many locals"); + nloc++; + lname[i] = n; lslot[i] = fslots; lhome[i] = fdepth; lstate[i] = S_PLAIN; + lowner[i] = 0; lused[i] = 0; larr[i] = 0; lown[i] = 0; + return i; +} +fn lroot(i) { while (lstate[i] == S_CHILD) i = lowner[i]; return i; } +fn tracked(i) { return lstate[i] != S_PLAIN; } +// a use that doesn't give the object away +fn touch(i) +{ + var r; + lused[i] = 1; + if (!fchk) return 0; + r = lroot(i); + lused[r] = 1; + if (lstate[r] == S_DEAD) { cerrn(i, "used after it was given away"); return 0; } + // a d object that shows up in a deeper block is given to that block + if (lstate[r] == S_D && lhome[r] < fdepth) { lhome[r] = fdepth; lstate[r] = S_M; lown[r] = 1; } + return 0; +} +fn plainuse(c) +{ + if (c == C_FRESH) cerr("a new object can't be used as a plain value; bind it to a name first"); + if (c >= C_VAR) touch(c - C_VAR); + return C_PLAIN; +} +fn freevar(i) { laddr(lslot[i]); op(O_LD); callname(s_free); op(O_DROP); return 0; } +// leaving every block deeper than or equal to dep: free what is owned, and +// complain about what should have left already. final means the block really +// ends here rather than an early exit. +fn exit_vars(dep, final) +{ + var i = nloc, st; + if (!fchk || !live) return 0; + while (i > lbase) { + i--; + if (lhome[i] < dep) continue; + st = lstate[i]; + if (st == S_M) freevar(i); else if (st == S_U) cerrn(i, "u object must leave this block (block value, assignment to the enclosing block, or return)"); + else if (st == S_D) cerrn(i, "d object was never given away"); + } + return 0; +} +// an m object has to be used somewhere in the block that owns it, on any path +fn unused_check(from) +{ + while (from < nloc) { if (fchk && lown[from] && !lused[from]) dien(lname[from], "m object is never used"); from++; } + return 0; +} +fn block_close(save) +{ + var i = lbase; + unused_check(save); + exit_vars(fdepth, 1); + while (i < save) { if (lhome[i] >= fdepth) { lstate[i] = S_DEAD; lhome[i] = fdepth - 1; } i++; } + nloc = save; + return 0; +} + +// snapshots: [lbase] [nloc] then state, owner, home per local +fn snap_push() +{ + var b = snaptop, i = lbase, p; + p = R_SNAP + b; + p[0] = lbase; p[1] = nloc; + p = p + 2; + while (i < nloc) { p[0] = lstate[i]; p[1] = lowner[i]; p[2] = lhome[i]; p = p + 3; i++; } + snaptop = p - R_SNAP; + if (snaptop >= 8000) die("nesting too deep for the analyzer"); + return b; +} +fn snap_pop(b) { snaptop = b; return 0; } +fn snap_restore(b) +{ + var p = R_SNAP + b, i = p[0], e = p[1]; + if (e > nloc) e = nloc; + p = p + 2; + while (i < e) { lstate[i] = p[0]; lowner[i] = p[1]; lhome[i] = p[2]; p = p + 3; i++; } + return 0; +} +fn empty(s) { return s == S_PLAIN || s == S_DEAD; } +// compare the current states with a snapshot: -1 if they agree, else the +// first local that differs. plain and dead agree and merge to dead. +fn snap_cmp(b) +{ + var p = R_SNAP + b, i = p[0], e = p[1], s; + if (e > nloc) e = nloc; + p = p + 2; + while (i < e) { + s = lstate[i]; + if (empty(s) && empty(p[0])) { if (p[0] == S_DEAD) lstate[i] = S_DEAD; } + else if (s != p[0] || lhome[i] != p[2] || (s == S_CHILD && lowner[i] != p[1])) return i; + p = p + 3; i++; + } + return -1; +} +fn statename(s) +{ + if (s == S_PLAIN) return "empty"; + if (s == S_M) return "m"; + if (s == S_U) return "u"; + if (s == S_D) return "d"; + if (s == S_DEAD) return "given away"; + if (s == S_CHILD) return "owned by a container"; + return "borrowed"; +} +fn merge_err(i, sa, what) +{ + if (!fchk) return 0; + puts("zc: line "); putn(tline); puts(": "); puts(lname[i]); puts(": "); puts(what); + puts(" (one path leaves it "); puts(statename(sa)); puts(", another "); puts(statename(lstate[i])); puts(")\n"); + halt(); + return 0; +} +// after an if: the current state is the else path, sa is the then path +fn merge(sa, livea) +{ + var i, p; + if (!livea) return 0; + if (!live) { snap_restore(sa); live = 1; return 0; } + i = snap_cmp(sa); + if (i >= 0) { p = R_SNAP + sa + 2 + 3 * (i - R_SNAP[sa]); merge_err(i, p[0], "ends the branches of an if in different states"); } + return 0; +} +fn loopcheck(s0) +{ + var i, p; + if (!fchk || !live) return 0; + i = snap_cmp(s0); + if (i >= 0) { p = R_SNAP + s0 + 2 + 3 * (i - R_SNAP[s0]); merge_err(i, p[0], "changes state inside a loop; each pass has to leave it as it found it"); } + return 0; +} + +// ---- analyzer rules for the places values flow ---- +// recast: x as u / x as d / x as m +fn recast(c, t) +{ + var i, st; + if (!fchk) return c; + if (c < C_VAR) { cerr("only a named owned object can be recast"); return c; } + i = c - C_VAR; + st = lstate[i]; + lused[i] = 1; + if (st == S_CHILD) cerrn(i, "belongs to a container; recast the container instead"); + else if (st == S_BORROW) cerrn(i, "is borrowed and can't be recast"); + else if (st == S_PLAIN) cerrn(i, "isn't an owned object"); + else if (st == S_DEAD) cerrn(i, "used after it was given away"); + else if (t == S_M && st != S_M) cerrn(i, "can't be recast back to m"); + else lstate[i] = t; + return c; +} +// an argument for a parameter tagged t (0 plain, 1 m, 2 d) +fn argcheck(c, t) +{ + var i, st; + if (!fchk) return 0; + if (c == C_FRESH) { if (t != 2) cerr("a new object can only go straight to a d parameter; bind it to a name first"); return 0; } + if (c < C_VAR || !tracked(c - C_VAR)) return 0; + i = c - C_VAR; + st = lstate[i]; + if (lstate[lroot(i)] == S_DEAD) { cerrn(i, "used after it was given away"); return 0; } + if (t == 0) { cerrn(i, "is an owned object; it can only be passed to an m or d parameter"); return 0; } + if (t == 1) { + if (st == S_D) { cerrn(i, "is d; pass it to a d parameter (lending it would lose it)"); return 0; } + touch(i); + return 0; + } + if (st == S_D) { lstate[i] = S_DEAD; lused[i] = 1; return 0; } + if (st == S_M) cerrn(i, "is m; write 'as d' to give it away"); + else if (st == S_U) cerrn(i, "is u; write 'as d' to give it away instead of returning it"); + else if (st == S_CHILD) cerrn(i, "belongs to a container and can't be given away alone"); + else cerrn(i, "is borrowed and can't be given away"); + return 0; +} +fn emitown(p) { laddr(lslot[p]); op(O_LD); callname(s_own); return 0; } +// a store of class rc into an lvalue of kind k (local or container index i) +fn assigncheck(k, i, rc) +{ + var st, j, r, js; + if (!fchk) return C_PLAIN; + j = -1; + if (rc >= C_VAR && tracked(rc - C_VAR)) j = rc - C_VAR; + if (j >= 0 && lstate[lroot(j)] == S_DEAD) { cerrn(j, "used after it was given away"); return C_PLAIN; } + if (k == LV_LOCAL) { + st = lstate[i]; + if (j < 0 && rc != C_FRESH) { + if (!empty(st)) cerrn(i, "still owns an object; overwriting it would leak it"); + else lstate[i] = S_PLAIN; + return C_PLAIN; + } + if (!empty(st)) { cerrn(i, "still owns an object; overwriting it would leak it"); return C_PLAIN; } + if (rc == C_FRESH) { lstate[i] = S_M; lused[i] = 0; lown[i] = 1; return C_PLAIN; } + js = lstate[j]; + if (js == S_U && lhome[i] == lhome[j] - 1) { // handing a u object up one block + lstate[i] = S_M; lused[i] = 0; lown[i] = 1; lstate[j] = S_DEAD; lused[j] = 1; + return C_PLAIN; + } + if (js == S_U) cerrn(j, "is u; it can only be handed to a variable of the enclosing block, or returned"); + else cerrn(j, "is an owned object and can't be copied into another variable"); + return C_PLAIN; + } + if (k == LV_ELEM) { + r = lroot(i); + st = lstate[r]; + touch(i); + if (rc == C_FRESH) { emitown(i); return C_PLAIN; } + if (j < 0) return C_PLAIN; + js = lstate[j]; + if (js == S_CHILD) cerrn(j, "already belongs to a container"); + else if (js == S_BORROW) cerrn(j, "is borrowed and can't be stored"); + else if (st == S_BORROW) { + if (js != S_D) cerrn(j, "must be d to be stored into a borrowed object"); + else { lstate[j] = S_DEAD; lused[j] = 1; emitown(i); } + } else if (js != st) cerrn(j, "its tag doesn't match its container's (both have to be m, u or d)"); + else if (lhome[j] < lhome[r]) cerrn(j, "lives in an outer block than the container it's stored into"); + else { lstate[j] = S_CHILD; lowner[j] = i; lused[j] = 1; emitown(i); } + return C_PLAIN; + } + // a global, or memory the analyzer doesn't track: the collector takes it + if (j >= 0) { + if (lstate[j] == S_D) { lstate[j] = S_DEAD; lused[j] = 1; } + else cerrn(j, "must be d to be stored in a global or in untracked memory (the collector takes it over)"); + } + return C_PLAIN; +} +fn retcheck(c) +{ + var i; + if (!fchk) return 0; + i = -1; + if (c >= C_VAR && tracked(c - C_VAR)) i = c - C_VAR; + if (i >= 0 && lstate[lroot(i)] == S_DEAD) { cerrn(i, "used after it was given away"); return 0; } + if (fret) { + if (i >= 0) { + if (lstate[i] == S_U) { lstate[i] = S_DEAD; lused[i] = 1; } + else cerrn(i, "has to be u to be returned; write 'return x as u'"); + } + return 0; + } + if (c == C_FRESH) cerr("returns a new object; declare the function with -> u"); + else if (i >= 0) cerrn(i, "is owned and can't be returned from a function without -> u"); + return 0; +} +// the last expression of a block expression +fn handup(c) +{ + var i; + if (!fchk) return C_PLAIN; + if (c == C_FRESH) return C_FRESH; + if (c < C_VAR || !tracked(c - C_VAR)) return C_PLAIN; + i = c - C_VAR; + if (lstate[i] == S_U && lhome[i] == fdepth) { lstate[i] = S_DEAD; lused[i] = 1; return C_FRESH; } + if (lstate[i] == S_U) cerrn(i, "only a u object of this block can be its value"); + else cerrn(i, "has to be u to be handed up as the block's value"); + return C_PLAIN; +} +fn discard(c) +{ + if (c == C_FRESH) cerr("a new object (or a u result) can't be thrown away"); + else if (c >= C_VAR) touch(c - C_VAR); + return 0; +} + +// ---- expressions ---- +fn rval() { if (lv) { op(O_LD); lv = 0; } return 0; } +fn kwcall(s, e) +{ + var f = sval[s], old = kw_expr, c; + kw_expr = e; xcls = C_PLAIN; + f(); + kw_expr = old; + c = xcls; + lv = 0; lvk = LV_NONE; + return c; +} +fn stmtonly() { if (kw_expr) die("this can't be used inside an expression"); return 0; } +fn call(s) +{ + var np = 0, tags = 0, ret = 0, c; + if (sflag[s] & F_SIG) { tags = ssig[s] >> 6; ret = ssig[s] & 1; } + else sflag[s] = sflag[s] | F_UNTYPED; + expect(s_lp); + if (!is_op(s_rp)) { + while (1) { + c = expr(); rval(); + argcheck(c, (tags >> (np + np)) & 3); + np++; + if (!accept(s_comma)) break; + } + } + expect(s_rp); + if ((sflag[s] & F_SIG) && np != ((ssig[s] >> 1) & 31)) dien(sname[s], "wrong number of arguments"); + fnref(s); op(O_CALL); + lv = 0; lvk = LV_NONE; + if (ret) return C_FRESH; + return C_PLAIN; +} +fn primary() +{ + var n, i, s, c; + lv = 0; lvk = LV_NONE; + if (tk == T_NUM) { lit(tv); next(); return C_PLAIN; } + if (tk == T_STR) { strlit(tv); next(); return C_PLAIN; } + if (tk == T_OP) { + if (tv == s_lp) { next(); c = expr(); expect(s_rp); return c; } + if (tv == s_lb) return blockexpr(); + die("expected an expression"); + } + if (tk != T_ID) die("expected an expression"); + n = tv; + i = findloc(n); + if (i >= 0) { + next(); + if (!fchk && tracked(i)) dien(n, "is tracked by the analyzer and can't be used in unchecked code"); + laddr(lslot[i]); + if (larr[i]) return C_PLAIN; + lv = 1; lvk = LV_LOCAL; lvi = i; + if (tracked(i)) return C_VAR + i; + return C_PLAIN; + } + s = lookup(n); + if (s >= 0 && skind[s] == K_KW) { + if (!(sflag[s] & F_EXPR)) dien(n, "can't be used inside an expression"); + return kwcall(s, 1); + } + next(); + if (s >= 0 && skind[s] == K_CONST) { lit(sval[s]); return C_PLAIN; } + if (s >= 0 && skind[s] == K_GVAR) { lit(sval[s]); lv = 1; lvk = LV_GLOBAL; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GARR) { lit(sval[s]); return C_PLAIN; } + if (s < 0) s = fwdfn(n); + if (is_op(s_lp)) return call(s); + fnref(s); + return C_PLAIN; +} +// ++ and -- on the address at the top of the stack +fn incdec(post, d) +{ + if (!lv) die("++ and -- need something to assign to"); + if (lvk == LV_LOCAL && fchk && tracked(lvi)) cerrn(lvi, "owns an object and can't be incremented"); + lv = 0; lvk = LV_NONE; + lit(0); op(O_PICK); op(O_LD); + if (post) { lit(0); op(O_PICK); lit(d); op(O_ADD); lit(2); op(O_PICK); op(O_ST); } + else { lit(d); op(O_ADD); lit(0); op(O_PICK); lit(2); op(O_PICK); op(O_ST); } + op(O_SWAP); op(O_DROP); + return C_PLAIN; +} +fn postfix() +{ + var c = primary(), b, n, t; + while (1) { + if (tk == T_ID && tv == s_as) { + next(); + if (tk != T_ID) die("expected u, d or m after as"); + t = S_M; + if (tv == s_u) t = S_U; else if (tv == s_d) t = S_D; else if (tv != s_m) die("expected u, d or m after as"); + next(); + rval(); + c = recast(c, t); + lvk = LV_NONE; + continue; + } + if (tk != T_OP) return c; + if (tv == s_lk) { + next(); + rval(); + b = -1; + if (c == C_FRESH) cerr("index a new object only after binding it to a name"); + else if (c >= C_VAR) { touch(c - C_VAR); b = c - C_VAR; } + c = expr(); rval(); plainuse(c); + expect(s_rk); + op(O_ADD); + lv = 1; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + c = C_PLAIN; + continue; + } + if (tv == s_lp) { // call through a value + rval(); plainuse(c); + next(); + n = 0; + if (!is_op(s_rp)) { while (1) { c = expr(); rval(); argcheck(c, 0); n++; if (!accept(s_comma)) break; } } + expect(s_rp); + lit(n); op(O_PICK); op(O_CALL); op(O_SWAP); op(O_DROP); + lv = 0; lvk = LV_NONE; c = C_PLAIN; + continue; + } + if (tv == s_inc) { next(); c = incdec(1, 1); continue; } + if (tv == s_dec) { next(); c = incdec(1, -1); continue; } + return c; + } + return c; +} +fn unary() +{ + var c, u; + if (tk == T_OP) { + if (tv == s_star) { next(); c = unary(); rval(); plainuse(c); lv = 1; lvk = LV_OTHER; return C_PLAIN; } + if (tv == s_amp) { + next(); c = unary(); + if (!lv) die("& needs something addressable"); + if (c >= C_VAR) touch(c - C_VAR); + lv = 0; lvk = LV_NONE; + return C_PLAIN; + } + if (tv == s_inc) { next(); unary(); return incdec(0, 1); } + if (tv == s_dec) { next(); unary(); return incdec(0, -1); } + u = unfind(tv); + if (u >= 0) { + next(); c = unary(); rval(); plainuse(c); + emitseq(useq[u], ulen[u]); + lv = 0; lvk = LV_NONE; + return C_PLAIN; + } + } + return postfix(); +} +fn bin(minp) +{ + var c = unary(), b, p, a, j; + while (tk == T_OP) { + b = binfind(tv); + if (b < 0) return c; + p = bprec[b]; + if (p < minp) return c; + next(); rval(); plainuse(c); + if (blen[b] == -1) { // && : 0 if the left side is 0, else the right side as 0 or 1 + a = hole(); op(O_JZ); + c = bin(p + 1); rval(); plainuse(c); + emitseq(useq[1], ulen[1]); // !! normalizes + j = hole(); op(O_JMP); + setlit(a, here); lit(0); setlit(j, here); + } else if (blen[b] == -2) { // || : 1 if the left side isn't 0, else the right side as 0 or 1 + a = hole(); op(O_JZ); + lit(1); j = hole(); op(O_JMP); + setlit(a, here); + c = bin(p + 1); rval(); plainuse(c); + emitseq(useq[1], ulen[1]); + setlit(j, here); + } else { + c = bin(p + 1); rval(); plainuse(c); + emitseq(bseq[b], blen[b]); + } + lv = 0; lvk = LV_NONE; c = C_PLAIN; + } + return c; +} +// [addr v] -> [v], storing v at addr +fn storekeep() { op(O_SWAP); lit(1); op(O_PICK); op(O_SWAP); op(O_ST); return 0; } +fn expr() +{ + var c = bin(1), k, i, a, rc; + if (tk != T_OP) return c; + if (tv == s_eq) { + if (!lv) die("this can't be assigned to"); + k = lvk; i = lvi; + next(); + rc = expr(); rval(); + storekeep(); + lv = 0; lvk = LV_NONE; + return assigncheck(k, i, rc); + } + a = asgfind(tv); + if (a >= 0) { + if (!lv) die("this can't be assigned to"); + if (lvk == LV_LOCAL && fchk && tracked(lvi)) cerrn(lvi, "owns an object; compound assignment would lose it"); + next(); + lit(0); op(O_PICK); op(O_LD); + lv = 0; + rc = expr(); rval(); plainuse(rc); + emitseq(bseq[abin[a]], blen[abin[a]]); + storekeep(); + lv = 0; lvk = LV_NONE; + return C_PLAIN; + } + return c; +} +// does the current token start a statement rather than an expression? +fn stmtstart() +{ + var s; + if (tk == T_OP) return tv == s_semi || tv == s_lb; + if (tk != T_ID || findloc(tv) >= 0) return 0; + s = lookup(tv); + return s >= 0 && skind[s] == K_KW && !(sflag[s] & F_EXPR); +} +// { stmts; tail } as an expression: its value is the tail, or 0 +fn blockexpr() +{ + var save = nloc, c = C_PLAIN, tail = 0; + next(); + fdepth++; bxdepth++; + while (!is_op(s_rb)) { + if (tk == T_EOF) die("missing }"); + if (stmtstart()) { stmt(); continue; } + c = expr(); rval(); + if (accept(s_semi)) { op(O_DROP); discard(c); c = C_PLAIN; continue; } + if (!is_op(s_rb)) die("expected ; or } after an expression"); + tail = 1; + } + next(); + if (tail) c = handup(c); else lit(0); + block_close(save); + fdepth--; bxdepth--; + lv = 0; lvk = LV_NONE; + return c; +} + +// ---- constant expressions ---- +fn cprim() +{ + var v, s; + if (tk == T_NUM) { v = tv; next(); return v; } + if (accept(s_minus)) return 0 - cprim(); + if (tk == T_OP && tv == uname[2]) { next(); return ~cprim(); } + if (accept(s_lp)) { v = cexpr(); expect(s_rp); return v; } + if (tk == T_ID) { + s = lookup(tv); + if (s >= 0 && (skind[s] == K_CONST || skind[s] == K_GARR || (skind[s] == K_FN && (sflag[s] & F_DEF)) || skind[s] == K_GVAR)) { next(); return sval[s]; } + } + die("expected a constant"); + return 0; +} +fn cexpr() +{ + var v = cprim(), o; + while (tk == T_OP) { + o = tv; + if (o == bname[3]) { next(); v = v + cprim(); } + else if (o == bname[4]) { next(); v = v - cprim(); } + else if (o == bname[0]) { next(); v = v * cprim(); } + else if (o == bname[15]) { next(); v = v | cprim(); } + else if (o == bname[13]) { next(); v = v & cprim(); } + else if (o == bname[5]) { next(); v = v << cprim(); } + else if (o == bname[6]) { next(); v = v >> cprim(); } + else return v; + } + return v; +} + +// ---- statements ---- +fn stmt() +{ + var s, c; + if (tk == T_ID && findloc(tv) < 0) { + s = lookup(tv); + if (s >= 0 && skind[s] == K_KW && (sflag[s] & F_STMT)) { kwcall(s, 0); return 0; } + } + if (tk == T_OP) { + if (tv == s_semi) { next(); return 0; } + if (tv == s_lb) { block(); return 0; } + } + c = expr(); rval(); op(O_DROP); + expect(s_semi); + discard(c); + return 0; +} +fn block() +{ + var save = nloc; + expect(s_lb); + fdepth++; + while (!is_op(s_rb)) { if (tk == T_EOF) die("missing }"); stmt(); } + next(); + block_close(save); + fdepth--; + return 0; +} +// the body of if/while/for: its own block, even without braces +fn substmt() +{ + var save = nloc; + if (is_op(s_lb)) return block(); + fdepth++; + stmt(); + block_close(save); + fdepth--; + return 0; +} +fn kw_var() +{ + var n, i, c, k; + stmtonly(); + next(); + while (1) { + n = name(); + i = newloc(n); + if (accept(s_lk)) { k = cexpr(); expect(s_rk); larr[i] = 1; fslots = fslots + k; } + else fslots++; + if (accept(s_eq)) { c = expr(); rval(); laddr(lslot[i]); op(O_ST); assigncheck(LV_LOCAL, i, c); } + if (!accept(s_comma)) break; + } + expect(s_semi); + return 0; +} +fn kw_if() +{ + var a, b, c, s0, sa, live0, livea; + stmtonly(); + next(); + expect(s_lp); c = expr(); rval(); plainuse(c); expect(s_rp); + a = hole(); op(O_JZ); + live0 = live; + s0 = snap_push(); + substmt(); + livea = live; sa = snap_push(); + if (is_id(s_else)) { + next(); + b = hole(); op(O_JMP); + setlit(a, here); + snap_restore(s0); live = live0; + substmt(); + setlit(b, here); + } else { setlit(a, here); snap_restore(s0); live = live0; } + merge(sa, livea); + snap_pop(s0); + return 0; +} +// loop frame: 0 continue target 1 break chain 2 depth 3 snapshot 4 block-expression depth +fn loop_push(cont, s0) +{ + var f = R_LOOP + lsp * 6; + if (lsp >= 60) die("loops nested too deeply"); + f[0] = cont; f[1] = 0; f[2] = fdepth; f[3] = s0; f[4] = bxdepth; + lsp++; + return 0; +} +fn loop_pop() { lsp--; fixall(R_LOOP[lsp * 6 + 1], here); return 0; } +fn kw_while() +{ + var c0 = here, a, s0, c; + stmtonly(); + next(); + s0 = snap_push(); + expect(s_lp); c = expr(); rval(); plainuse(c); expect(s_rp); + a = hole(); op(O_JZ); + loop_push(c0, s0); + substmt(); + loopcheck(s0); + jmp(c0); + setlit(a, here); + loop_pop(); + snap_restore(s0); live = 1; + snap_pop(s0); + return 0; +} +fn kw_for() +{ + var save = nloc, s0, c0, a, b, d, c; + stmtonly(); + next(); + expect(s_lp); + fdepth++; + if (is_id(s_var)) kw_var(); + else { if (!is_op(s_semi)) { c = expr(); rval(); op(O_DROP); discard(c); } expect(s_semi); } + s0 = snap_push(); + c0 = here; + if (!is_op(s_semi)) { c = expr(); rval(); plainuse(c); } else lit(1); + expect(s_semi); + a = hole(); op(O_JZ); + b = hole(); op(O_JMP); + d = here; + if (!is_op(s_rp)) { c = expr(); rval(); op(O_DROP); discard(c); } + expect(s_rp); + jmp(c0); + setlit(b, here); + loop_push(d, s0); + substmt(); + loopcheck(s0); + jmp(d); + setlit(a, here); + loop_pop(); + snap_restore(s0); live = 1; + snap_pop(s0); + block_close(save); + fdepth--; + return 0; +} +fn loopexit(f) +{ + if (lsp <= loopbase) die("break or continue outside a loop"); + if (f[4] != bxdepth) die("break and continue can't leave a block expression"); + loopcheck(f[3]); + exit_vars(f[2] + 1, 0); + return 0; +} +fn kw_break() +{ + var f = R_LOOP + (lsp - 1) * 6; + stmtonly(); + next(); expect(s_semi); + loopexit(f); + f[1] = fixnew(here, f[1]); + lit(MW - 1); op(O_JMP); + live = 0; + return 0; +} +fn kw_continue() +{ + var f = R_LOOP + (lsp - 1) * 6; + stmtonly(); + next(); expect(s_semi); + loopexit(f); + jmp(f[0]); + live = 0; + return 0; +} +fn kw_return() +{ + var c; + stmtonly(); + next(); + if (!infn) die("return outside a function"); + if (bxdepth) die("return can't leave a block expression"); + if (is_op(s_semi)) { lit(0); c = C_PLAIN; } else { c = expr(); rval(); } + expect(s_semi); + retcheck(c); + exit_vars(1, 0); + epichain = fixnew(here, epichain); + lit(MW - 1); op(O_JMP); + live = 0; + return 0; +} +fn kw_unchecked() +{ + var old = fchk; + stmtonly(); + next(); + fchk = 0; + substmt(); + fchk = old; + return 0; +} + +// ---- asm blocks: raw vm words, one per token ---- +// numbers push, -n pushes a negative number, #n emits a raw word, one-char +// tokens from the mnemonic table are opcodes, names push the address of a +// variable or function, :name defines a label for this block. +fn asmblock() +{ + var nl = 0, nr = 0, i, k, c, s, ln = R_ASM, la = R_ASM + 64, rn = R_ASM + 128, ra = R_ASM + 384; + expect(s_lb); + while (!is_op(s_rb)) { + if (tk == T_EOF) die("unterminated asm block"); + if (tk == T_NUM) { lit(tv); next(); continue; } + if (tk == T_STR) { strlit(tv); next(); continue; } + if (is_op(s_hash)) { next(); if (tk != T_NUM) die("# needs a number"); emit(tv); next(); continue; } + if (is_op(s_minus)) { next(); if (tk == T_NUM && tglue) { lit(0 - tv); next(); } else op(O_SUB); continue; } + if (is_op(s_colon)) { next(); if (nl >= 64) die("too many asm labels"); ln[nl] = name(); la[nl] = here; nl++; continue; } + if (tv[0] && !tv[1] && (c = mnemidx(tv[0])) >= 0) { op(c); next(); continue; } + if (tk != T_ID) die("bad token in asm"); + i = findloc(tv); + if (i >= 0) { lused[i] = 1; laddr(lslot[i]); next(); continue; } + k = -1; i = 0; + while (i < nl) { if (ln[i] == tv) k = i; i++; } + if (k >= 0) { lit(la[k]); next(); continue; } + s = lookup(tv); + if (s >= 0 && skind[s] != K_FN && skind[s] != K_KW) { lit(sval[s]); next(); continue; } + if (s >= 0 && skind[s] == K_FN) { fnref(s); next(); continue; } + if (nr >= 250) die("too many asm label references"); + rn[nr] = tv; ra[nr] = hole(); nr++; next(); // a label further down this block + } + next(); + i = 0; + while (i < nr) { + k = -1; c = 0; + while (c < nl) { if (ln[c] == rn[i]) k = c; c++; } + if (k < 0) dien(rn[i], "unknown name in asm"); + setlit(ra[i], la[k]); + i++; + } + return 0; +} +fn kw_asm() { next(); asmblock(); xcls = C_PLAIN; return 0; } + +// ---- quote: code as data ---- +// a token list is an object: [n] then kind, value for each token. names, +// strings and operators are interned pointers. +fn grab() -> u +{ + var n = 0, depth = 0, q; + if (!is_op(s_lb)) die("expected {"); + next(); + while (1) { + if (tk == T_EOF) die("unterminated quote"); + if (is_op(s_lb)) depth++; + if (is_op(s_rb)) { if (!depth) break; depth--; } + if (n >= 4000) die("quote too long"); + R_QBUF[n + n] = tk; R_QBUF[n + n + 1] = tv; n++; + next(); + } + next(); + q = new(n + n + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n + n); + return q as u; +} +unchecked fn qnew(src) -> u { var n = src[0] * 2 + 1, q = new(n); wcopy(q, src, n); return q; } +fn qdup(m q) -> u { var n = q[0] * 2 + 1, r = new(n); wcopy(r, q, n); return r as u; } +fn wcopyto(m q, n) { var i = 0; while (i < n) { emit(q[i]); i++; } return 0; } +fn kw_quote() +{ + var q, j, a, n; + next(); + q = grab(); + j = hole(); op(O_JMP); + a = here; + n = q[0] * 2 + 1; + wcopyto(q, n); + free(q as d); + setlit(j, here); + lit(a); + callname(s_qnew); + xcls = C_FRESH; + return 0; +} +// tokens of a string, as a token list +fn tokens(s) -> u +{ + var n = 0, q; + src_push(2, s, 0, 0); + next(); + while (tk != T_EOF) { + if (n >= 4000) die("too many tokens"); + R_QBUF[n + n] = tk; R_QBUF[n + n + 1] = tv; n++; + next(); + } + src_pop(); + q = new(n + n + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n + n); + return q as u; +} +// feed a token list into the input: the parser reads it next, then carries +// on where it was. the list is freed once it has been read. +unchecked fn feed(d q) { src_push(1, q, 1, 1); next(); return 0; } + +// ---- nested compiles ---- +// compile() and load() can run while another function is being compiled (from +// a parse word). the function context is saved, the new code is emitted in +// place with a jump around it, and then everything is put back. +fn ctx_push() +{ + var f = R_CTX + ctxsp * 24; + if (ctxsp >= 30) die("compiles nested too deeply"); + ctxsp++; + f[0] = nloc; f[1] = lbase; f[2] = fdepth; f[3] = fslots; f[4] = fchk; f[5] = fret; f[6] = live; + f[7] = bxdepth; f[8] = epichain; f[9] = fframe; f[10] = infn; f[11] = lsp; f[12] = loopbase; + f[13] = lv; f[14] = lvk; f[15] = lvi; f[16] = kw_expr; f[17] = xcls; f[18] = snaptop; + return 0; +} +fn ctx_pop() +{ + var f; + ctxsp--; + f = R_CTX + ctxsp * 24; + nloc = f[0]; lbase = f[1]; fdepth = f[2]; fslots = f[3]; fchk = f[4]; fret = f[5]; live = f[6]; + bxdepth = f[7]; epichain = f[8]; fframe = f[9]; infn = f[10]; lsp = f[11]; loopbase = f[12]; + lv = f[13]; lvk = f[14]; lvi = f[15]; kw_expr = f[16]; xcls = f[17]; snaptop = f[18]; + return 0; +} + +// ---- functions and the top level ---- +fn fn_begin(chk, ret) +{ + lbase = nloc; fdepth = 1; fslots = 0; fchk = chk && check_on; fret = ret; + live = 1; bxdepth = 0; epichain = 0; infn = 1; loopbase = lsp; lv = 0; lvk = LV_NONE; + return 0; +} +fn prologue() { lit(ZFP); op(O_LD); fframe = hole(); op(O_SUB); lit(ZFP); op(O_ST); return 0; } +fn epilogue() +{ + lit(0); + fixall(epichain, here); + lit(ZFP); op(O_LD); lit(fslots); op(O_ADD); lit(ZFP); op(O_ST); op(O_RET); + setlit(fframe, fslots); + infn = 0; + nloc = lbase; + return 0; +} +fn body() +{ + expect(s_lb); + while (!is_op(s_rb)) { if (tk == T_EOF) die("missing } at the end of a function"); stmt(); } + next(); + unused_check(lbase); + if (fchk && live) { exit_vars(1, 1); if (fret) cerr("a -> u function has to end with a return"); } + return 0; +} +fn fndef(chk) +{ + var n, s, np = 0, tags = 0, t, ret = 0, sig, i, pn[24], pt[24]; + next(); + n = name(); + s = lookup(n); + if (s < 0 || s < ubase || skind[s] != K_FN || (sflag[s] & F_DEF)) { s = addsym(n, K_FN, 0); sflag[s] = 0; } + expect(s_lp); + if (!is_op(s_rp)) { + while (1) { + t = 0; + if (tk == T_ID && (tv == s_m || tv == s_d)) { + t = 1; if (tv == s_d) t = 2; + pn[np] = tv; + next(); + if (tk == T_ID) pn[np] = name(); else t = 0; // a parameter called m or d + } else pn[np] = name(); + if (np >= 12 && t) die("only the first 12 parameters can be tagged"); + pt[np] = t; + if (np < 12) tags = tags + (t << (np + np)); + np++; + if (np >= 24) die("too many parameters"); + if (!accept(s_comma)) break; + } + } + expect(s_rp); + if (accept(s_arrow)) { if (!is_id(s_u)) die("the only return tag is -> u"); next(); ret = 1; } + sig = ret + np + np + tags * 64; + if (sflag[s] & F_SIG) { if (ssig[s] != sig) dien(n, "doesn't match its earlier declaration"); } + else if ((sflag[s] & F_UNTYPED) && (tags || ret)) dien(n, "was called before its tags were declared; put a prototype above the first call"); + ssig[s] = sig; + sflag[s] = sflag[s] | F_SIG; + if (accept(s_semi)) return s; + if (sflag[s] & F_DEF) dien(n, "is defined twice"); + sval[s] = here; + sflag[s] = sflag[s] | F_DEF; + fixall(sfix[s], here); sfix[s] = 0; + fn_begin(chk, ret); + prologue(); + i = 0; + while (i < np) { + t = newloc(pn[i]); fslots++; + if (fchk && pt[i] == 1) lstate[t] = S_BORROW; + if (fchk && pt[i] == 2) { lstate[t] = S_M; lown[t] = 1; } + i++; + } + i = np; + while (i) { i--; laddr(i); op(O_ST); } + body(); + epilogue(); + return s; +} +fn gvar() +{ + var n, a, k; + next(); + while (1) { + n = name(); + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + addsym(n, K_GARR, here); + while (k) { emit(0); k--; } + } else { + a = here; + addsym(n, K_GVAR, a); + emit(0); + if (accept(s_eq)) { + if (tk == T_STR) { *(a + hdelta) = here; k = tv; while (*k) { emit(*k); k++; } emit(0); next(); } + else *(a + hdelta) = cexpr(); + } + } + if (!accept(s_comma)) break; + } + expect(s_semi); + return 0; +} +fn gconst() +{ + var n; + next(); + while (1) { n = name(); expect(s_eq); addsym(n, K_CONST, cexpr()); if (!accept(s_comma)) break; } + expect(s_semi); + return 0; +} +fn topitem() +{ + var chk = 1, imm = 0, s, k; + if (is_id(s_unchecked)) { + next(); + if (accept(s_semi)) { check_on = 0; return 0; } // unchecked; switches the analyzer off from here on + chk = 0; + } + if (is_id(s_immediate)) { next(); imm = 1; } + if (is_id(s_fn)) { + s = fndef(chk); + if (imm) { + if (hdelta) die("parse words can't be defined while building an image"); + k = addsym(sname[s], K_KW, sval[s]); + sflag[k] = F_DEF | F_STMT | F_EXPR | F_TOP; + } + return 0; + } + if (!chk || imm) die("expected fn"); + if (is_id(s_var)) return gvar(); + if (is_id(s_const)) return gconst(); + if (tk == T_ID) { + s = lookup(tv); + if (s >= 0 && skind[s] == K_KW && (sflag[s] & F_TOP)) { kwcall(s, 0); return 0; } + } + die("expected fn, var or const"); + return 0; +} +fn unit_top() { while (tk != T_EOF) topitem(); return 0; } +fn unit_end(from) +{ + var i = from; + while (i < nsym) { + if (skind[i] == K_FN && !(sflag[i] & F_DEF) && sfix[i]) dien(sname[i], "is used but never defined"); + i++; + } + return 0; +} + +// compile a token list as the body of a new function, or (top) as top-level +// declarations. returns the entry address of the function. +unchecked fn compile_list(m q, top) +{ + var hop = -1, entry = 0, from = nsym; + ctx_push(); + if (infn) { hop = hole(); op(O_JMP); } + src_push(1, q, 0, 0); + next(); + if (top) unit_top(); + else { + entry = here; + fn_begin(1, 0); + prologue(); + while (tk != T_EOF) stmt(); + unused_check(lbase); + if (fchk && live) exit_vars(1, 1); + epilogue(); + } + src_pop(); + unit_end(from); + if (hop >= 0) setlit(hop, here); + if (here > ptop) ptop = here; + ctx_pop(); + return entry; +} +fn compile(m q) { return compile_list(q, 0); } +fn load(m q) { compile_list(q, 1); return 0; } +fn eval(m q) { var f = compile_list(q, 0); return f(); } +fn evals(s) { var q = tokens(s), r = eval(q); free(q as d); return r; } + +// ---- symbol blob ---- +// an image ends with its own symbol table so the genome knows its names: +// kind, value, signature, name chars, 0 ... then a 0 kind. +fn blob_emit(from) +{ + var i = from, p; + while (i < nsym) { + if (skind[i] >= K_FN && skind[i] <= K_CONST) { + emit(skind[i]); emit(sval[i]); emit(ssig[i]); + p = sname[i]; + while (*p) { emit(*p); p++; } + emit(0); + } + i++; + } + emit(0); + return 0; +} +fn blob_load(p) +{ + var s, n; + while (*p) { + n = intern(p + 3); + s = addsym(n, p[0], p[1]); + ssig[s] = p[2]; + sflag[s] = F_DEF | F_SIG; + p = p + 3 + strlen(p + 3) + 1; + } + return 0; +} +// compile the rest of stdin as a genome image that will run at org, writing +// it to dst. only the source's own names are visible while it compiles. +// returns the image length in words. +fn build_image(org, dst) +{ + var sh = here, sd = hdelta, sl = hlimit, sub = ubase, svl = vislo, sns = nsym, n; + ubase = nsym; vislo = nsym; + here = org; hdelta = dst - org; hlimit = org + 0x30000; + lit(FTOP); lit(ZFP); op(O_ST); fnref(fwdfn(s_start)); op(O_JMP); emit(0); emit(0); + src_push(0, 0, 0, 0); + next(); + unit_top(); + unit_end(ubase); + src_pop(); + *(dst + 5) = here; + blob_emit(ubase); + *(dst + 6) = here; + n = here - org; + popsyms(sns); + ubase = sub; vislo = svl; here = sh; hdelta = sd; hlimit = sl; + return n; +} + +// ---- setup ---- +fn gc_roots() +{ + markrange(0, ptop); + if (!hdelta && here > ptop) markrange(ptop, here); // globals of a unit still compiling + markrange(GORG, GORG[6]); + markrange(R_SRC, R_SRC + 400); + markrange(*ZFP, FTOP); + markrange(DSLO, DSHI); + return 0; +} +fn zc_init() +{ + pooltop = R_POOL; + wfill(R_IH, 0, IHN); + nsym = 0; nfixu = 0; fixfree = 0; nbin = 0; nun = 0; nasg = 0; nkop = 0; seqtop = 0; + lsp = 0; ctxsp = 0; snaptop = 0; nloc = 0; lbase = 0; + s_lp = intern("("); s_rp = intern(")"); s_lb = intern("{"); s_rb = intern("}"); + s_lk = intern("["); s_rk = intern("]"); s_comma = intern(","); s_semi = intern(";"); + s_eq = intern("="); s_arrow = intern("->"); s_inc = intern("++"); s_dec = intern("--"); + s_star = intern("*"); s_amp = intern("&"); s_colon = intern(":"); s_hash = intern("#"); + s_minus = intern("-"); s_andand = intern("&&"); s_oror = intern("||"); + s_fn = intern("fn"); s_var = intern("var"); s_const = intern("const"); s_else = intern("else"); + s_as = intern("as"); s_unchecked = intern("unchecked"); s_immediate = intern("immediate"); + s_m = intern("m"); s_d = intern("d"); s_u = intern("u"); + s_start = intern("start"); s_main = intern("main"); s_free = intern("free"); + s_own = intern("own"); s_qnew = intern("qnew"); + return 0; +} +// operators and keywords. these are plain tables in memory: a program can +// add operators, change precedences or replace keywords with its own. +fn zc_tables() +{ + add_unop("!", "0 $ 0 ~ - | 31 > 1 +"); // index 0 + add_unop("!!", "0 $ 0 ~ - | 31 > 0 ~ -"); // index 1: normalize to 0 or 1 + add_unop("~", "-1 ^"); // index 2 + add_unop("-", "0 ~ -"); + add_binop("*", 10, "*"); // the first few indexes are used by cexpr + add_binop("/", 10, "zdiv c"); + add_binop("%", 10, "zmod c"); + add_binop("+", 9, "+"); // 3 + add_binop("-", 9, "-"); // 4 + add_binop("<<", 8, "zshl c"); // 5 + add_binop(">>", 8, ">"); // 6 + add_binop("<", 7, "<"); + add_binop(">", 7, "~ <"); + add_binop("<=", 7, "~ < 1 ^"); + add_binop(">=", 7, "< 1 ^"); + add_binop("==", 6, "- 0 $ 0 ~ - | 31 > 1 +"); + add_binop("!=", 6, "- 0 $ 0 ~ - | 31 > 0 ~ -"); + add_binop("&", 5, "&"); // 13 + add_binop("^", 4, "^"); + add_binop("|", 3, "|"); // 15 + add_binop("&&", -1, 0); + add_binop("||", -2, 0); + addkop(s_eq); addkop(s_arrow); addkop(s_inc); addkop(s_dec); + add_kw("var", kw_var, F_STMT); + add_kw("if", kw_if, F_STMT); + add_kw("while", kw_while, F_STMT); + add_kw("for", kw_for, F_STMT); + add_kw("break", kw_break, F_STMT); + add_kw("continue", kw_continue, F_STMT); + add_kw("return", kw_return, F_STMT); + add_kw("unchecked", kw_unchecked, F_STMT); + add_kw("asm", kw_asm, F_STMT | F_EXPR); + add_kw("quote", kw_quote, F_EXPR); + return 0; +} +fn start() +{ + var s, f; + heap_init(); + zc_init(); + blob_load(GORG[5]); + zc_tables(); + here = 0; hdelta = 0; hlimit = HEAP_LO; ptop = 0; + ubase = nsym; vislo = 0; + src_push(0, 0, 0, 0); + next(); + unit_top(); + unit_end(ubase); + if (here > ptop) ptop = here; + s = lookup(s_main); + if (s >= 0 && skind[s] == K_FN && (sflag[s] & F_DEF)) { f = sval[s]; f(); } + halt(); + return 0; +} diff --git a/docs/history/10-zc/code/src/rt.zc b/docs/history/10-zc/code/src/rt.zc new file mode 100644 index 0000000..139924b --- /dev/null +++ b/docs/history/10-zc/code/src/rt.zc @@ -0,0 +1,168 @@ +// ============================================================================ +// rt.zc: the runtime half of the genome. memory map, i/o, arithmetic helpers, +// the heap (size-class free lists) and the mark-sweep collector. +// ============================================================================ + +// ---- memory map (words) ---- +const MW = 0x100000; // 1m words of memory +const HEAP_LO = 0x40000; // heap: 0x40000 .. 0xA0000 +const HEAP_HI = 0xA0000; +const ZFP = 0xA0000; // frame pointer word, used by every prologue +const GORG = 0xC0000; // the genome (this code) lives here +const FBOT = 0xE0000; // frame stack: FBOT .. FTOP, grows down +const FTOP = 0xF0000; +const RS0 = 0xF0000; // return stack grows up from here +const MARK0 = 0xF8000; // mark stack for the collector +const MARKN = 0x4000; +const DSLO = 0xFC000; // data stack: DSLO .. MW-16, grows down +const DSHI = 0xFFFF0; +const MAGIC = 0x2B7E1516; + +// ---- i/o ---- +fn putc(ch) { asm { ch @ . } return 0; } +fn getc() { return asm { , }; } +fn eof() { return asm { ? }; } +fn halt() { asm { q } return 0; } +fn puts(m s) { var i = 0; while (s[i]) { putc(s[i]); i++; } return 0; } +fn putn(n) +{ + var b[12], i = 0; + if (n < 0) { putc('-'); n = 0 - n; } + if (n < 0) { puts("2147483648"); return 0; } + while (1) { b[i++] = '0' + n % 10; n = n / 10; if (!n) break; } + while (i) putc(b[--i]); + return 0; +} +fn strlen(m s) { var n = 0; while (s[n]) n++; return n; } +fn streq(m a, m b) { var i = 0; while (a[i] && a[i] == b[i]) i++; return a[i] == b[i]; } +fn wcopy(m dst, m src, n) { var i = 0; while (i < n) { dst[i] = src[i]; i++; } return 0; } +fn wfill(m dst, v, n) { var i = 0; while (i < n) { dst[i] = v; i++; } return 0; } + +// ---- arithmetic the hardware doesn't have ---- +var pow2[32]; +var zrem; +fn zudiv(n, d) +{ + var q = 0, r = 0, i = 30; + if (n < d) { zrem = n; return 0; } + while (i >= 0) { + r = r + r + ((n >> i) & 1); + q = q + q; + if (r >= d) { r = r - d; q++; } + i--; + } + zrem = r; + return q; +} +fn zdiv(a, b) +{ + var s = 0, q; + if (b == 0) { zrem = a; return 0; } + if (a < 0) { a = 0 - a; s = 1; } + if (b < 0) { b = 0 - b; s = s ^ 1; } + q = zudiv(a, b); + if (s) return 0 - q; + return q; +} +fn zmod(a, b) { var neg = a < 0; zdiv(a, b); if (neg) return 0 - zrem; return zrem; } +fn zshl(a, b) { return a * pow2[b & 31]; } + +// ---- heap ---- +// every block is a power of two words with a 5 word header before the +// pointer the program sees: +// p[-5] block size p[-4] size class p[-3] flags (1 live, 2 marked) +// p[-2] p ^ MAGIC p[-1] owner (the container that owns it, or 0) +// freed blocks keep size and class so the sweep can walk the heap linearly, +// and go on a free list per class (the link is in p[0]). +var hbump, freel[32], gc_runs, gc_freed, gc_auto = 1; + +fn heap_init() +{ + var i = 1; + pow2[0] = 1; + while (i < 32) { pow2[i] = pow2[i - 1] + pow2[i - 1]; i++; } + hbump = HEAP_LO; + wfill(freel, 0, 32); + return 0; +} +fn isobj(m x) { return x >= HEAP_LO + 5 && x < hbump && x[-2] == (x ^ MAGIC) && (x[-3] & 1); } + +fn oom() { puts("zc: out of heap memory\n"); halt(); return 0; } +unchecked fn new(n) -> u +{ + var need = n + 5, k = 3, sz = 8, b = 0, p; + if (n < 0) need = 5; + while (sz < need) { sz = sz + sz; k++; } + if (freel[k]) { b = freel[k]; freel[k] = b[5]; } + else if (hbump + sz <= HEAP_HI) { b = hbump; hbump = hbump + sz; } + else { + if (gc_auto) gc(); + if (freel[k]) { b = freel[k]; freel[k] = b[5]; } + else if (hbump + sz <= HEAP_HI) { b = hbump; hbump = hbump + sz; } + else oom(); + } + p = b + 5; + b[0] = sz; b[1] = k; b[2] = 1; b[3] = p ^ MAGIC; b[4] = 0; + wfill(p, 0, sz - 5); + return p; +} +fn osize(m p) { if (!isobj(p)) return 0; return p[-5] - 5; } + +// frees p and, recursively, every object p owns +fn release(p) +{ + var b = p - 5, n = b[0] - 5, i = 0, w; + b[2] = 0; + while (i < n) { w = p[i]; if (isobj(w) && w[-1] == p) release(w); i++; } + b[4] = 0; + b[5] = freel[b[1]]; + freel[b[1]] = b; + return 0; +} +unchecked fn free(d p) { if (isobj(p)) release(p); return 0; } +fn own(c, p) { if (isobj(c)) c[-1] = p; return c; } + +// ---- mark-sweep ---- +// conservative and non-moving. roots: the program area (globals live +// between functions), the genome's globals, the compiler's input stack, +// the live part of the frame stack and the whole data stack region. +var ms_top, ms_over, gc_lo, gc_hi; +fn mark(w) +{ + if (!isobj(w) || (w[-3] & 2)) return 0; + w[-3] = w[-3] | 2; + if (ms_top < MARKN) { MARK0[ms_top] = w; ms_top++; } else ms_over = 1; + return 0; +} +fn markrange(a, b) { while (a < b) { mark(*a); a++; } return 0; } +fn drain() +{ + var p; + while (ms_top) { ms_top--; p = MARK0[ms_top]; markrange(p, p + p[-5] - 5); } + return 0; +} +fn gc_roots(); +unchecked fn gc() +{ + var b, sz, n = 0; + ms_top = 0; ms_over = 0; + gc_roots(); + drain(); + while (ms_over) { // the mark stack overflowed: rescan marked objects + ms_over = 0; + b = HEAP_LO; + while (b < hbump) { if (b[2] == 3) markrange(b + 5, b + b[0]); b = b + b[0]; drain(); } + } + b = HEAP_LO; + while (b < hbump) { + sz = b[0]; + if (b[2] == 1) { b[2] = 0; b[4] = 0; b[5] = freel[b[1]]; freel[b[1]] = b; n++; } + else if (b[2] == 3) b[2] = 1; + b = b + sz; + } + gc_runs++; + gc_freed = gc_freed + n; + return n; +} +// number of live objects, for tests +fn live_objects() { var b = HEAP_LO, n = 0; while (b < hbump) { if (b[2] & 1) n++; b = b + b[0]; } return n; } diff --git a/docs/history/10-zc/code/test.sh b/docs/history/10-zc/code/test.sh new file mode 100755 index 0000000..09b92c3 --- /dev/null +++ b/docs/history/10-zc/code/test.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# full check: bootstraps the compiler from zc0, verifies the fixpoint, then runs +# the examples and tests on the portable interpreter (host) and on the arm64 +# jit under qemu. needs gcc; the jit half needs aarch64-linux-gnu-gcc and +# qemu-aarch64 (it's skipped if they're missing). +cd "$(dirname "$0")"; T=$(mktemp -d); trap 'rm -rf $T' EXIT +ok=0; bad=0 +chk(){ if [ "$1" = "$2" ]; then echo "ok $3"; ok=$((ok+1)); else echo "FAIL $3: got [$1]"; bad=$((bad+1)); fi; } +src(){ cat src/rt.zc src/compiler.zc; } +selfc(){ (cat tools/build.zc; printf '`'; src) | $1 > $2; } + +# bootstrap: zc0 (c) -> g0, g0 compiles compiler.zc -> g1, g1 compiles it -> g2 +gcc -O1 -w zc0.c -o $T/zc0 && gcc -O1 -w mkgenome.c -o $T/mkg || exit 1 +mkdir $T/s0 $T/s1 +cp core.c io_linux.c $T/s0/; cp core.c io_linux.c $T/s1/ +src | $T/zc0 > $T/s0/genome.h || exit 1 +gcc -O2 -w -DJTYPE=int $T/s0/core.c $T/s0/io_linux.c -o $T/zy0 +selfc $T/zy0 $T/g1.bin; $T/mkg < $T/g1.bin > $T/s1/genome.h +gcc -O2 -w -DJTYPE=int $T/s1/core.c $T/s1/io_linux.c -o $T/zy1 +selfc $T/zy1 $T/g2.bin +cmp -s $T/g1.bin $T/g2.bin && chk 1 1 "fixpoint: the compiler compiles itself to the same $(($(stat -c %s $T/g1.bin) / 4)) words" || chk 0 1 "fixpoint" +cmp -s $T/s1/genome.h genome.h && chk 1 1 "genome.h is up to date" || chk 0 1 "genome.h is stale (cp the bootstrap output over it)" + +run(){ # $1 = vm command, $2 = label + local vm="$1" l="$2" + chk "$($vm < examples/hello.zc)" "hello, world!" "$l hello" + chk "$($vm < examples/fact.zc | tr '\n' '/')" "1101110101111100000000/3628800/" "$l factorial" + chk "$( (cat examples/echo.zc; printf '`abc\n') | $vm)" "abc" "$l echo after the backtick" + chk "$($vm < examples/selfpatch.zc)" "ABC" "$l self-patching code" + chk "$($vm < examples/lists.zc | tr '\n' '/')" "[0 1 4 9 16 25]/live: 7/after the block: 0/" "$l ownership frees everything" + chk "$( (cat examples/repl.zc; printf '`fn sq(x) { return x * x; }`putn(sq(7)); putc(10);`puts("hi\\n");') | $vm | tr '\n' '/')" "49/hi/" "$l repl on the resident compiler" + chk "$($vm < tests/basics.zc | tr '\n' '/')" "285 610 42 512/hey 65 -3 -2 1024 -8/12456/757/9 100-101/5/ok/" "$l language basics" + chk "$($vm < tests/umd.zc)" "100 6 0 15 99 5 5" "$l u m d lifetimes" + chk "$($vm < tests/gc.zc)" "1000 1 900 1 199900" "$l mark-sweep collector" + chk "$($vm < tests/meta.zc | tr '\n' '/')" "1024 19/unless ok/rrr/15 42/7/42/7/144/" "$l parse words, quote, eval, load, operator tables" + chk "$($vm < tests/misc.zc | tr '\n' '/')" "45/54321/ok/" "$l compile-time eval, patched mnemonics, unchecked" + local r; r=$(tests/runerr.sh "$vm" | tail -1) + chk "$r" "analyzer rejects: $(ls tests/errors/*.zc | wc -l) passed, 0 failed" "$l analyzer rejects every bad program" +} +gcc -O2 -w -DJTYPE=int core.c io_linux.c -o $T/zy +run $T/zy "interp" +if command -v aarch64-linux-gnu-gcc >/dev/null && command -v qemu-aarch64 >/dev/null; then + aarch64-linux-gnu-gcc -O2 -w -DJTYPE=int -static core.c io_linux.c -o $T/zyj || exit 1 + printf '#!/bin/sh\nexec qemu-aarch64 %s "$@"\n' $T/zyj > $T/jit; chmod +x $T/jit + run $T/jit "jit" + selfc $T/jit $T/gj.bin; cmp -s $T/g1.bin $T/gj.bin && chk 1 1 "jit self-compile matches" || chk 0 1 "jit self-compile matches" +else echo "skip jit (no aarch64 toolchain or qemu)"; fi +echo "$ok passed, $bad failed"; [ $bad = 0 ] diff --git a/docs/history/10-zc/code/tests/basics.zc b/docs/history/10-zc/code/tests/basics.zc new file mode 100644 index 0000000..9dfb44e --- /dev/null +++ b/docs/history/10-zc/code/tests/basics.zc @@ -0,0 +1,22 @@ +var table[10]; +var greeting = "hey"; +const N = 10, BIG = 0x100 * 2; +fn fib(n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +fn twice(f, x) { return f(f(x)); } +fn inc(x) { return x + 1; } +fn main() +{ + var i, s = 0, a[5]; + for (i = 0; i < N; i++) table[i] = i * i; + for (var j = 0; j < N; j++) s += table[j]; + putn(s); putc(' '); putn(fib(15)); putc(' '); putn(twice(inc, 40)); putc(' '); putn(BIG); putc(10); + puts(greeting); putc(' '); putn('A'); putc(' '); putn(-17 / 5); putc(' '); putn(-17 % 5); putc(' '); putn(1 << 10); putc(' '); putn(-64 >> 3); putc(10); + i = 0; while (1) { i++; if (i == 3) continue; if (i > 6) break; putn(i); } putc(10); + a[0] = 5; a[1] = a[0]++; a[2] = ++a[0]; putn(a[0]); putn(a[1]); putn(a[2]); putc(10); + var b = { var t = 3; t * t }; + putn(b); putc(' '); putn(3 > 2 && 2 > 1); putn(0 || 0); putn(!5); putn(~0); putn(5 != 5); putn(4 >= 4); putc(10); + var x = asm { 2 3 + }; + putn(x); putc(10); + asm { 'o' . 'k' . 10 . } + return 0; +} diff --git a/docs/history/10-zc/code/tests/errors/back_to_m.zc b/docs/history/10-zc/code/tests/errors/back_to_m.zc new file mode 100644 index 0000000..ee25096 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/back_to_m.zc @@ -0,0 +1,2 @@ +// expect: x: can't be recast back to m +fn main() { var x = new(3); x as d; x as m; return 0; } diff --git a/docs/history/10-zc/code/tests/errors/borrow_escape.zc b/docs/history/10-zc/code/tests/errors/borrow_escape.zc new file mode 100644 index 0000000..725bc61 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/borrow_escape.zc @@ -0,0 +1,3 @@ +// expect: p: is owned and can't be returned +fn f(m p) { return p; } +fn main() { var x = new(1); f(x); return 0; } diff --git a/docs/history/10-zc/code/tests/errors/branch_mismatch.zc b/docs/history/10-zc/code/tests/errors/branch_mismatch.zc new file mode 100644 index 0000000..62cb18b --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/branch_mismatch.zc @@ -0,0 +1,3 @@ +// expect: x: ends the branches of an if in different states +fn take(d p) { return p[0]; } +fn main() { var x = new(1); x as d; if (x[0]) take(x); return 0; } diff --git a/docs/history/10-zc/code/tests/errors/child_dies.zc b/docs/history/10-zc/code/tests/errors/child_dies.zc new file mode 100644 index 0000000..16e1935 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/child_dies.zc @@ -0,0 +1,3 @@ +// expect: c: used after it was given away +fn take(d p) { return p[0]; } +fn main() { var p = new(2), c = new(1); p[0] = c; take(p as d); return c[0]; } diff --git a/docs/history/10-zc/code/tests/errors/child_recast.zc b/docs/history/10-zc/code/tests/errors/child_recast.zc new file mode 100644 index 0000000..f4be23e --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/child_recast.zc @@ -0,0 +1,2 @@ +// expect: c: belongs to a container; recast the container instead +fn main() { var p = new(2), c = new(1); p[0] = c; c as d; return 0; } diff --git a/docs/history/10-zc/code/tests/errors/copy_owned.zc b/docs/history/10-zc/code/tests/errors/copy_owned.zc new file mode 100644 index 0000000..42d2ab0 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/copy_owned.zc @@ -0,0 +1,2 @@ +// expect: x: is an owned object and can't be copied +fn main() { var x = new(1); var y = x; return y[0]; } diff --git a/docs/history/10-zc/code/tests/errors/d_into_block.zc b/docs/history/10-zc/code/tests/errors/d_into_block.zc new file mode 100644 index 0000000..02189ab --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/d_into_block.zc @@ -0,0 +1,2 @@ +// expect: x: used after it was given away +fn main() { var x = new(1); x as d; { x[0] = 5; } return x[0]; } diff --git a/docs/history/10-zc/code/tests/errors/d_kept.zc b/docs/history/10-zc/code/tests/errors/d_kept.zc new file mode 100644 index 0000000..28eaccf --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/d_kept.zc @@ -0,0 +1,2 @@ +// expect: x: d object was never given away +fn main() { var x = new(3); x as d; x[0] = 1; return 0; } diff --git a/docs/history/10-zc/code/tests/errors/discard_u.zc b/docs/history/10-zc/code/tests/errors/discard_u.zc new file mode 100644 index 0000000..18bc810 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/discard_u.zc @@ -0,0 +1,3 @@ +// expect: can't be thrown away +fn mk() -> u { var p = new(1); return p as u; } +fn main() { mk(); return 0; } diff --git a/docs/history/10-zc/code/tests/errors/give_m.zc b/docs/history/10-zc/code/tests/errors/give_m.zc new file mode 100644 index 0000000..537fa0c --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/give_m.zc @@ -0,0 +1,3 @@ +// expect: x: is m; write 'as d' +fn take(d p) { return p[0]; } +fn main() { var x = new(3); take(x); return 0; } diff --git a/docs/history/10-zc/code/tests/errors/global_store.zc b/docs/history/10-zc/code/tests/errors/global_store.zc new file mode 100644 index 0000000..13882b9 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/global_store.zc @@ -0,0 +1,3 @@ +// expect: x: must be d to be stored in a global +var g; +fn main() { var x = new(1); g = x; return 0; } diff --git a/docs/history/10-zc/code/tests/errors/leak_overwrite.zc b/docs/history/10-zc/code/tests/errors/leak_overwrite.zc new file mode 100644 index 0000000..42773fb --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/leak_overwrite.zc @@ -0,0 +1,2 @@ +// expect: x: still owns an object +fn main() { var x = new(1); x = new(2); return x[0]; } diff --git a/docs/history/10-zc/code/tests/errors/lend_d.zc b/docs/history/10-zc/code/tests/errors/lend_d.zc new file mode 100644 index 0000000..e1e37d5 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/lend_d.zc @@ -0,0 +1,4 @@ +// expect: x: is d; pass it to a d parameter +fn look(m p) { return p[0]; } +fn take(d p) { return p[0]; } +fn main() { var x = new(3); x as d; look(x); take(x); return 0; } diff --git a/docs/history/10-zc/code/tests/errors/loop_move.zc b/docs/history/10-zc/code/tests/errors/loop_move.zc new file mode 100644 index 0000000..b1a6019 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/loop_move.zc @@ -0,0 +1,3 @@ +// expect: x: changes state inside a loop +fn take(d p) { return p[0]; } +fn main() { var x = new(1); var i = 0; x as d; while (i < 3) { take(x); i++; } return 0; } diff --git a/docs/history/10-zc/code/tests/errors/plain_return.zc b/docs/history/10-zc/code/tests/errors/plain_return.zc new file mode 100644 index 0000000..61f546f --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/plain_return.zc @@ -0,0 +1,3 @@ +// expect: returns a new object; declare the function with -> u +fn mk() { return new(1); } +fn main() { return mk(); } diff --git a/docs/history/10-zc/code/tests/errors/proto_needed.zc b/docs/history/10-zc/code/tests/errors/proto_needed.zc new file mode 100644 index 0000000..2613b9d --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/proto_needed.zc @@ -0,0 +1,3 @@ +// expect: f: was called before its tags were declared +fn main() { var x = new(1); f(1); return x[0]; } +fn f(d p) { return 0; } diff --git a/docs/history/10-zc/code/tests/errors/return_m.zc b/docs/history/10-zc/code/tests/errors/return_m.zc new file mode 100644 index 0000000..c361760 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/return_m.zc @@ -0,0 +1,3 @@ +// expect: x: has to be u to be returned +fn mk() -> u { var x = new(1); return x; } +fn main() { var y = mk(); return y[0]; } diff --git a/docs/history/10-zc/code/tests/errors/tag_mismatch.zc b/docs/history/10-zc/code/tests/errors/tag_mismatch.zc new file mode 100644 index 0000000..f9631d6 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/tag_mismatch.zc @@ -0,0 +1,2 @@ +// expect: c: its tag doesn't match its container's +fn main() { var p = new(2), c = new(1); p as u; p[0] = c; return 0; } diff --git a/docs/history/10-zc/code/tests/errors/u_dropped.zc b/docs/history/10-zc/code/tests/errors/u_dropped.zc new file mode 100644 index 0000000..76b7765 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/u_dropped.zc @@ -0,0 +1,2 @@ +// expect: x: u object must leave this block +fn main() { var x = new(3); x as u; return 0; } diff --git a/docs/history/10-zc/code/tests/errors/u_skip_level.zc b/docs/history/10-zc/code/tests/errors/u_skip_level.zc new file mode 100644 index 0000000..b8a024f --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/u_skip_level.zc @@ -0,0 +1,2 @@ +// expect: t: is u; it can only be handed to a variable of the enclosing block +fn main() { var r; { { var t = new(1); t as u; r = t; } } return r[0]; } diff --git a/docs/history/10-zc/code/tests/errors/unchecked_touch.zc b/docs/history/10-zc/code/tests/errors/unchecked_touch.zc new file mode 100644 index 0000000..1f57466 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/unchecked_touch.zc @@ -0,0 +1,2 @@ +// expect: x: is tracked by the analyzer and can't be used in unchecked code +fn main() { var x = new(1); unchecked { x[0] = 1; } return 0; } diff --git a/docs/history/10-zc/code/tests/errors/untagged_param.zc b/docs/history/10-zc/code/tests/errors/untagged_param.zc new file mode 100644 index 0000000..5a044c6 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/untagged_param.zc @@ -0,0 +1,3 @@ +// expect: x: is an owned object; it can only be passed to an m or d parameter +fn f(p) { return 0; } +fn main() { var x = new(1); f(x); return 0; } diff --git a/docs/history/10-zc/code/tests/errors/unused.zc b/docs/history/10-zc/code/tests/errors/unused.zc new file mode 100644 index 0000000..cbc6129 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/unused.zc @@ -0,0 +1,2 @@ +// expect: x: m object is never used +fn main() { var x = new(3); return 0; } diff --git a/docs/history/10-zc/code/tests/errors/use_after_give.zc b/docs/history/10-zc/code/tests/errors/use_after_give.zc new file mode 100644 index 0000000..5225462 --- /dev/null +++ b/docs/history/10-zc/code/tests/errors/use_after_give.zc @@ -0,0 +1,3 @@ +// expect: x: used after it was given away +fn take(d p) { return p[0]; } +fn main() { var x = new(3); take(x as d); return x[0]; } diff --git a/docs/history/10-zc/code/tests/gc.zc b/docs/history/10-zc/code/tests/gc.zc new file mode 100644 index 0000000..e5ff7f7 --- /dev/null +++ b/docs/history/10-zc/code/tests/gc.zc @@ -0,0 +1,20 @@ +var keep; +unchecked fn churn(n) +{ + var i = 0, p; + while (i < n) { p = new(10); p[0] = i; if (i % 100 == 0) keep = p; i++; } + return 0; +} +fn main() +{ + var base = live_objects(), f; + churn(1000); + putn(live_objects() - base); putc(' '); + f = gc(); + putn(f >= 990); putc(' '); // conservative: a stale word or two may keep one alive + putn(keep[0]); putc(' '); // the one a global still points at survives + churn(200000); // 3.2m words through a 393k word heap: needs the automatic collector + putn(gc_runs > 1); putc(' '); + putn(keep[0]); putc(10); + return 0; +} diff --git a/docs/history/10-zc/code/tests/meta.zc b/docs/history/10-zc/code/tests/meta.zc new file mode 100644 index 0000000..9c81616 --- /dev/null +++ b/docs/history/10-zc/code/tests/meta.zc @@ -0,0 +1,46 @@ +fn ipow(a, b) { var r = 1; while (b > 0) { r *= a; b--; } return r; } +// a parse word that adds an operator to the compiler's tables +immediate fn pow_op() { next(); add_binop("**", 11, "ipow c"); return 0; } +pow_op + +// unless (cond) stmt: a parse word that emits code itself +immediate fn unless() +{ + var a; + next(); + expect(intern("(")); rval(); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not + a = hole(); op(O_JZ); // skip the body when the condition was true + substmt(); + setlit(a, here); + return 0; +} +// repeat N { body }: a macro, built from token lists +immediate fn repeat() +{ + var n, body, i = 0; + next(); n = tv; next(); + body = grab(); + while (i < n) { feed(qdup(body)); i++; } + free(body as d); + return 0; +} +fn main() +{ + putn(2 ** 10); putc(' '); putn(3 + 2 ** 3 * 2); putc(10); + unless (1 > 2) puts("unless ok\n"); + unless (2 > 1) puts("wrong\n"); + repeat 3 { putc('r'); } + putc(10); + var q = quote { putn(40 + 2); putc(10); return 7; }; + putn(q[0]); putc(' '); + putn(eval(q)); putc(10); + var f = compile(q); + putn(f()); putc(10); + free(q as d); + var d = quote { fn sq(x) { return x * x; } }; + load(d); + free(d as d); + putn(evals("return sq(12);")); putc(10); + return 0; +} diff --git a/docs/history/10-zc/code/tests/misc.zc b/docs/history/10-zc/code/tests/misc.zc new file mode 100644 index 0000000..4a8ceef --- /dev/null +++ b/docs/history/10-zc/code/tests/misc.zc @@ -0,0 +1,30 @@ +// ct { ... } runs a block while compiling and leaves its result as a constant +immediate fn ct() +{ + var q, v; + next(); + q = grab(); + v = eval(q); + free(q as d); + lit(v); + return 0; +} +// teach the asm syntax that p means out, like the old repl demo +immediate fn teach() { next(); mnem[12] = 'p'; return 0; } +teach + +fn countdown() +{ + asm { 5 :top 0 $ '0' + p 1 - 0 $ done z top j :done _ 10 p } + return 0; +} +fn main() +{ + putn(ct { var i = 0, s = 0; while (i < 10) { s += i; i++; } return s; }); putc(10); + countdown(); + puts(lazy()); putc(10); + return 0; +} +// the analyzer is off from here on +unchecked; +fn lazy() { var p = new(3); p[0] = 'o'; p[1] = 'k'; return p; } diff --git a/docs/history/10-zc/code/tests/runerr.sh b/docs/history/10-zc/code/tests/runerr.sh new file mode 100755 index 0000000..c1d42c5 --- /dev/null +++ b/docs/history/10-zc/code/tests/runerr.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# runs every tests/errors/*.zc and checks the compiler rejects it with the expected message +vm=${1:-zy}; pass=0; fail=0 +for f in "$(dirname "$0")"/errors/*.zc; do + want=$(head -1 "$f" | sed 's#^// expect: ##') + got=$($vm < "$f" 2>&1 | head -1) + if [[ "$got" == *"$want"* ]]; then pass=$((pass+1)); else fail=$((fail+1)); echo "FAIL $(basename $f): got [$got]"; fi +done +echo "analyzer rejects: $pass passed, $fail failed" diff --git a/docs/history/10-zc/code/tests/umd.zc b/docs/history/10-zc/code/tests/umd.zc new file mode 100644 index 0000000..7d1bffc --- /dev/null +++ b/docs/history/10-zc/code/tests/umd.zc @@ -0,0 +1,52 @@ +// lists as [len, items...], items owned by the list +fn mklist(n) -> u +{ + var l = new(n + 1); + l[0] = 0; + return l as u; +} +fn push(m l, d item) { l[l[0] + 1] = item as d; l[0] = l[0] + 1; return 0; } +fn sum(m l) { var s = 0, i = 1; while (i <= l[0]) { s += l[i][0]; i++; } return s; } +fn box(v) -> u { var b = new(1); b[0] = v; return b as u; } +fn consume(d b) { return b[0]; } + +fn main() +{ + var base = live_objects(); + { + var l = mklist(8); // u from mklist arrives here as m + var i = 0; + while (i < 5) { + var b = box(i * 10); // m in the loop body + b as d; // give it down + push(l, b); + i++; + } + putn(sum(l)); putc(' '); + putn(live_objects() - base); putc(' '); // list + 5 boxes + } + putn(live_objects() - base); putc(' '); // freed at the block's end, children too + + // u handed up one block by assignment, and as a block value + var outer; + { + var t = box(7); + t as u; + outer = t; + } + var v = { var w = box(8); w as u }; + putn(outer[0] + v[0]); putc(' '); + + // d given away to a callee + var g = box(99); + putn(consume(g as d)); putc(' '); + + // containers: child takes its parent's tag + var p = new(2), c = new(1); + c[0] = 5; + p[0] = c; + p[1] = new(3); + putn(p[0][0]); putc(' '); + putn(live_objects() - base); putc(10); + return 0; +} diff --git a/docs/history/10-zc/code/tools/build.zc b/docs/history/10-zc/code/tools/build.zc new file mode 100644 index 0000000..afa1626 --- /dev/null +++ b/docs/history/10-zc/code/tools/build.zc @@ -0,0 +1,13 @@ +// compiles the rest of stdin (after the backtick) as a genome image at GORG +// and writes it to stdout as little-endian 32-bit words. +const OUT = 0x10000; +fn main() +{ + var n = build_image(GORG, OUT), i = 0, w; + while (i < n) { + w = OUT[i]; + putc(w); putc(w >> 8); putc(w >> 16); putc(w >> 24); + i++; + } + return 0; +} diff --git a/docs/history/10-zc/code/zc0.c b/docs/history/10-zc/code/zc0.c new file mode 100644 index 0000000..23df463 --- /dev/null +++ b/docs/history/10-zc/code/zc0.c @@ -0,0 +1,439 @@ +/* zc0: stage 0 of the bootstrap. a small c compiler for the subset of zc that + compiler.zc is written in. it reads zc source on stdin and writes a genome + header (vm words placed at GORG) on stdout, in the same image layout the + resident compiler's image mode produces. no lifetime analysis, no quote, no + parse words, no block expressions: those only exist in compiler.zc. tags + (m, d, -> u) and casts (as u, as d) are parsed and recorded in signatures + but not checked. */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define GORG 0xC0000 +#define ZFP 0xA0000 /* frame pointer word */ +#define FTOP 0xF0000 /* frame stack grows down from here */ +#define MAXW 0x40000 + +enum { T_EOF, T_NUM, T_ID, T_STR, T_OP }; +enum { K_FN = 1, K_GVAR, K_GARR, K_CONST }; +enum { O_Q, O_LD, O_ST, O_PICK, O_DROP, O_SWAP, O_CALL, O_JMP, O_JZ, O_RET, + O_IN, O_EMPTY, O_OUT, O_ADD, O_SUB, O_MUL, O_AND, O_OR, O_XOR, O_SHR, O_LT }; +static const char *mn = "q@!$_~cjzr,?.+-*&|^><"; + +static char *src; static int pos, line = 1; +static int tk, tv, glue; static char ts[4096]; /* current token */ + +static int img[MAXW], here = GORG; +static void emit(int w) { if (here - GORG >= MAXW) { fprintf(stderr, "image too big\n"); exit(1); } img[here++ - GORG] = w; } +static void lit(int v) { emit((int)((unsigned)v * 2 + 1)); } +static void op(int k) { emit(k * 2); } +static void setlit(int at, int v) { img[at - GORG] = (int)((unsigned)v * 2 + 1); } + +static void die(const char *m) { fprintf(stderr, "zc0: line %d: %s (at '%s')\n", line, m, ts); exit(1); } + +/* ---- lexer ---- */ +static const char *ops3[] = { "<<=", ">>=", 0 }; +static const char *ops2[] = { "==", "!=", "<=", ">=", "<<", ">>", "&&", "||", "++", "--", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "->", 0 }; +static int esc(void) +{ + int c = src[pos++]; + if (c != '\\') return c; + c = src[pos++]; + switch (c) { case 'n': return 10; case 't': return 9; case 'r': return 13; case '0': return 0; case 'e': return 27; } + return c; +} +static void next(void) +{ + int ws = 0, i; + for (;;) { + while (src[pos] && isspace((unsigned char)src[pos])) { if (src[pos] == '\n') line++; pos++; ws = 1; } + if (src[pos] == '/' && src[pos + 1] == '/') { while (src[pos] && src[pos] != '\n') pos++; ws = 1; continue; } + if (src[pos] == '/' && src[pos + 1] == '*') { pos += 2; while (src[pos] && !(src[pos] == '*' && src[pos + 1] == '/')) { if (src[pos] == '\n') line++; pos++; } if (src[pos]) pos += 2; ws = 1; continue; } + break; + } + glue = !ws; + if (!src[pos] || src[pos] == '`') { tk = T_EOF; strcpy(ts, "<eof>"); return; } + if (isdigit((unsigned char)src[pos])) { + char *e; tv = (int)strtoul(src + pos, &e, 0); memcpy(ts, src + pos, e - src - pos); ts[e - src - pos] = 0; pos = e - src; tk = T_NUM; return; + } + if (isalpha((unsigned char)src[pos]) || src[pos] == '_') { + i = 0; while (isalnum((unsigned char)src[pos]) || src[pos] == '_') ts[i++] = src[pos++]; + ts[i] = 0; tk = T_ID; return; + } + if (src[pos] == '\'') { pos++; tv = esc(); if (src[pos++] != '\'') die("bad char literal"); tk = T_NUM; strcpy(ts, "'c'"); return; } + if (src[pos] == '"') { pos++; i = 0; while (src[pos] && src[pos] != '"') ts[i++] = (char)esc(); ts[i] = 0; pos++; tk = T_STR; return; } + tk = T_OP; + for (i = 0; ops3[i]; i++) if (!strncmp(src + pos, ops3[i], 3)) { strcpy(ts, ops3[i]); pos += 3; return; } + for (i = 0; ops2[i]; i++) if (!strncmp(src + pos, ops2[i], 2)) { strcpy(ts, ops2[i]); pos += 2; return; } + ts[0] = src[pos++]; ts[1] = 0; +} +static int is(const char *s) { return (tk == T_OP || tk == T_ID) && !strcmp(ts, s); } +static int accept(const char *s) { if (is(s)) { next(); return 1; } return 0; } +static void expect(const char *s) { if (!accept(s)) { char b[64]; sprintf(b, "expected '%s'", s); die(b); } } +static char *ident(void) { static char b[8][256]; static int k; char *r = b[k++ & 7]; if (tk != T_ID) die("expected a name"); strcpy(r, ts); next(); return r; } + +/* ---- symbols ---- */ +typedef struct { char name[64]; int kind, val, sig, defd; } Sym; +static Sym sy[4096]; static int nsy; +typedef struct { int at, sym; } Fix; +static Fix fx[65536]; static int nfx; +static Sym *find(const char *n) { int i; for (i = nsy; i--;) if (!strcmp(sy[i].name, n)) return &sy[i]; return 0; } +static Sym *add(const char *n, int kind, int val) +{ + Sym *s = find(n); + if (s && s->kind == K_FN && kind == K_FN && !s->defd) { s->val = val; return s; } /* prototype or forward use */ + s = &sy[nsy++]; strncpy(s->name, n, 63); s->kind = kind; s->val = val; s->defd = 1; s->sig = 0; return s; +} +static void fnref(const char *n) /* push a function address, fixing it up later if needed */ +{ + Sym *s = find(n); + if (!s) { s = add(n, K_FN, 0); s->defd = 0; } + if (s->kind != K_FN) die("not a function"); + if (s->defd) { lit(s->val); return; } + fx[nfx].at = here; fx[nfx++].sym = (int)(s - sy); lit(0); +} + +/* ---- locals ---- */ +typedef struct { char name[64]; int slot, arr; } Loc; +static Loc lo[1024]; static int nlo, nslot, infn; +static Loc *findl(const char *n) { int i; for (i = nlo; i--;) if (!strcmp(lo[i].name, n)) return &lo[i]; return 0; } +static void laddr(int k) { lit(ZFP); op(O_LD); if (k) { lit(k); op(O_ADD); } } + +/* ---- operator tables ---- */ +static void seq_isz(void) { lit(0); op(O_PICK); lit(0); op(O_SWAP); op(O_SUB); op(O_OR); lit(31); op(O_SHR); lit(1); op(O_ADD); } +static void seq_nz(void) { lit(0); op(O_PICK); lit(0); op(O_SWAP); op(O_SUB); op(O_OR); lit(31); op(O_SHR); lit(0); op(O_SWAP); op(O_SUB); } +static int binprec(void) +{ + static const char *n[] = { "*", "/", "%", "+", "-", "<<", ">>", "<", ">", "<=", ">=", "==", "!=", "&", "^", "|", "&&", "||", 0 }; + static int p[] = { 10, 10, 10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 1 }; + int i; + if (tk != T_OP) return 0; + for (i = 0; n[i]; i++) if (!strcmp(ts, n[i])) return p[i]; + return 0; +} +static void binop(const char *o) +{ + if (!strcmp(o, "*")) op(O_MUL); + else if (!strcmp(o, "/")) { fnref("zdiv"); op(O_CALL); } + else if (!strcmp(o, "%")) { fnref("zmod"); op(O_CALL); } + else if (!strcmp(o, "+")) op(O_ADD); + else if (!strcmp(o, "-")) op(O_SUB); + else if (!strcmp(o, "<<")) { fnref("zshl"); op(O_CALL); } + else if (!strcmp(o, ">>")) op(O_SHR); + else if (!strcmp(o, "<")) op(O_LT); + else if (!strcmp(o, ">")) { op(O_SWAP); op(O_LT); } + else if (!strcmp(o, "<=")) { op(O_SWAP); op(O_LT); lit(1); op(O_XOR); } + else if (!strcmp(o, ">=")) { op(O_LT); lit(1); op(O_XOR); } + else if (!strcmp(o, "==")) { op(O_SUB); seq_isz(); } + else if (!strcmp(o, "!=")) { op(O_SUB); seq_nz(); } + else if (!strcmp(o, "&")) op(O_AND); + else if (!strcmp(o, "^")) op(O_XOR); + else if (!strcmp(o, "|")) op(O_OR); + else die("bad operator"); +} + +/* ---- constant expressions (globals, array sizes, const) ---- */ +static int cexpr(void); +static int cprim(void) +{ + int v; Sym *s; + if (tk == T_NUM) { v = tv; next(); return v; } + if (accept("-")) return -cprim(); + if (accept("~")) return ~cprim(); + if (accept("(")) { v = cexpr(); expect(")"); return v; } + if (tk == T_ID && (s = find(ts)) && (s->kind == K_CONST || (s->kind != K_GVAR && s->defd))) { next(); return s->val; } + die("constant expected"); return 0; +} +static int cexpr(void) +{ + int v = cprim(); + for (;;) { + if (accept("+")) v += cprim(); else if (accept("-")) v -= cprim(); + else if (accept("*")) v *= cprim(); else if (accept("|")) v |= cprim(); + else if (accept("&")) v &= cprim(); else if (accept("<<")) v <<= cprim(); + else if (accept(">>")) v >>= cprim(); else return v; + } +} + +/* ---- expressions ---- */ +static int lv; /* the stack top is an address not yet loaded */ +static void rval(void) { if (lv) { op(O_LD); lv = 0; } } +static void expr(void); +static void strlit(void) /* inline string: jump over it, push its address */ +{ + int j = here, a, i, n = (int)strlen(ts); + lit(0); op(O_JMP); a = here; + for (i = 0; i < n; i++) emit((unsigned char)ts[i]); + emit(0); setlit(j, here); lit(a); next(); +} +static int args(void) { int n = 0; expect("("); if (!accept(")")) { do { expr(); rval(); n++; } while (accept(",")); expect(")"); } return n; } +static void asmblock(void); +static void primary(void) +{ + char *n; Loc *l; Sym *s; + lv = 0; + if (tk == T_NUM) { lit(tv); next(); return; } + if (tk == T_STR) { strlit(); return; } + if (accept("(")) { expr(); expect(")"); return; } + if (is("asm")) { next(); asmblock(); return; } + n = ident(); + if ((l = findl(n))) { laddr(l->slot); lv = !l->arr; return; } + s = find(n); + if (s && s->kind == K_CONST) { lit(s->val); return; } + if (s && s->kind == K_GVAR) { lit(s->val); lv = 1; return; } + if (s && s->kind == K_GARR) { lit(s->val); return; } + if (is("(")) { args(); fnref(n); op(O_CALL); return; } + fnref(n); +} +static void incdec(int post, int d) +{ + if (!lv) die("++/-- needs an lvalue"); + lv = 0; + if (post) { lit(0); op(O_PICK); op(O_LD); lit(0); op(O_PICK); lit(d); op(O_ADD); lit(2); op(O_PICK); op(O_ST); op(O_SWAP); op(O_DROP); } + else { lit(0); op(O_PICK); op(O_LD); lit(d); op(O_ADD); lit(0); op(O_PICK); lit(2); op(O_PICK); op(O_ST); op(O_SWAP); op(O_DROP); } +} +static void postfix(void) +{ + int n; + primary(); + for (;;) { + if (accept("[")) { rval(); expr(); rval(); expect("]"); op(O_ADD); lv = 1; } + else if (is("(")) { rval(); n = args(); lit(n); op(O_PICK); op(O_CALL); op(O_SWAP); op(O_DROP); } + else if (accept("++")) incdec(1, 1); + else if (accept("--")) incdec(1, -1); + else if (accept("as")) ident(); + else return; + } +} +static void unary(void) +{ + if (accept("-")) { unary(); rval(); lit(0); op(O_SWAP); op(O_SUB); } + else if (accept("!")) { unary(); rval(); seq_isz(); } + else if (accept("~")) { unary(); rval(); lit(-1); op(O_XOR); } + else if (accept("*")) { unary(); rval(); lv = 1; } + else if (accept("&")) { unary(); if (!lv) die("& needs an lvalue"); lv = 0; } + else if (accept("++")) { unary(); incdec(0, 1); } + else if (accept("--")) { unary(); incdec(0, -1); } + else postfix(); +} +static void bin(int minp) +{ + int p, a, b; char o[8]; + unary(); + while ((p = binprec()) && p >= minp) { + strcpy(o, ts); next(); rval(); + if (!strcmp(o, "&&")) { + a = here; lit(0); op(O_JZ); bin(p + 1); rval(); seq_nz(); + b = here; lit(0); op(O_JMP); setlit(a, here); lit(0); setlit(b, here); + } else if (!strcmp(o, "||")) { + a = here; lit(0); op(O_JZ); lit(1); b = here; lit(0); op(O_JMP); + setlit(a, here); bin(p + 1); rval(); seq_nz(); setlit(b, here); + } else { bin(p + 1); rval(); binop(o); } + lv = 0; + } +} +static void expr(void) +{ + char o[8]; + bin(1); + if (is("=")) { + if (!lv) die("assignment needs an lvalue"); + next(); expr(); rval(); + op(O_SWAP); lit(1); op(O_PICK); op(O_SWAP); op(O_ST); lv = 0; + } else if (tk == T_OP && strlen(ts) >= 2 && ts[strlen(ts) - 1] == '=' && strcmp(ts, "==") && strcmp(ts, "!=") && strcmp(ts, "<=") && strcmp(ts, ">=")) { + if (!lv) die("assignment needs an lvalue"); + strcpy(o, ts); o[strlen(o) - 1] = 0; next(); + lit(0); op(O_PICK); op(O_LD); lv = 0; expr(); rval(); binop(o); + op(O_SWAP); lit(1); op(O_PICK); op(O_SWAP); op(O_ST); lv = 0; + } +} + +/* ---- asm blocks: raw vm words ---- */ +static void asmblock(void) +{ + char ln[128][64], rn[256][64]; int la[128], nl = 0, ra[256], nr = 0, i, k; const char *c; + Loc *l; Sym *s; + expect("{"); + while (!accept("}")) { + if (tk == T_EOF) die("unterminated asm"); + if (tk == T_NUM) { lit(tv); next(); continue; } + if (tk == T_STR) { strlit(); continue; } + if (accept("#")) { if (tk != T_NUM) die("# needs a number"); emit(tv); next(); continue; } + if (is("-")) { next(); if (tk == T_NUM && glue) { lit(-tv); next(); } else op(O_SUB); continue; } + if (accept(":")) { strcpy(ln[nl], ident()); la[nl++] = here; continue; } + if (strlen(ts) == 1 && (c = strchr(mn, ts[0]))) { op((int)(c - mn)); next(); continue; } + if (tk != T_ID) die("bad asm token"); + if ((l = findl(ts))) { laddr(l->slot); next(); continue; } + if ((s = find(ts)) && s->kind != K_FN) { lit(s->val); next(); continue; } + if (s) { fnref(ts); next(); continue; } + strcpy(rn[nr], ts); ra[nr++] = here; lit(0); next(); /* a label of this block */ + } + for (i = 0; i < nr; i++) { + for (k = -1; ++k < nl && strcmp(ln[k], rn[i]);) ; + if (k == nl) die("unknown asm label"); + setlit(ra[i], la[k]); + } +} + +/* ---- statements ---- */ +static int brk[256][64], nbrk[256], cont[256], nloop; +static int epi[1024], nepi; +static void stmt(void); +static void block(void) +{ + int save = nlo; + expect("{"); + while (!accept("}")) { if (tk == T_EOF) die("missing }"); stmt(); } + nlo = save; +} +static void jmp_to(int t) { lit(t); op(O_JMP); } +static void loopbody(int contaddr) +{ + nbrk[nloop] = 0; cont[nloop++] = contaddr; + stmt(); + nloop--; +} +static void patchbreaks(void) { int i; for (i = 0; i < nbrk[nloop]; i++) setlit(brk[nloop][i], here); } +static void stmt(void) +{ + int a, b, c, d; + if (accept(";")) return; + if (is("{")) { block(); return; } + if (accept("var")) { + do { + Loc *l = &lo[nlo++]; strcpy(l->name, ident()); l->arr = 0; + if (accept("[")) { int n = cexpr(); expect("]"); nslot += n; l->slot = nslot - n; l->arr = 1; } + else l->slot = nslot++; + if (accept("=")) { expr(); rval(); laddr(l->slot); op(O_ST); } + } while (accept(",")); + expect(";"); return; + } + if (accept("unchecked")) { stmt(); return; } + if (accept("if")) { + expect("("); expr(); rval(); expect(")"); + a = here; lit(0); op(O_JZ); stmt(); + if (accept("else")) { b = here; lit(0); op(O_JMP); setlit(a, here); stmt(); setlit(b, here); } + else setlit(a, here); + return; + } + if (accept("while")) { + c = here; expect("("); expr(); rval(); expect(")"); + a = here; lit(0); op(O_JZ); + loopbody(c); jmp_to(c); setlit(a, here); patchbreaks(); return; + } + if (accept("for")) { + int save = nlo; + expect("("); + if (!is(";")) { if (is("var")) { stmt(); goto cond; } expr(); rval(); op(O_DROP); } + expect(";"); + cond: c = here; + if (!is(";")) { expr(); rval(); } else lit(1); + expect(";"); + a = here; lit(0); op(O_JZ); b = here; lit(0); op(O_JMP); + d = here; + if (!is(")")) { expr(); rval(); op(O_DROP); } + expect(")"); jmp_to(c); + setlit(b, here); + loopbody(d); jmp_to(d); setlit(a, here); patchbreaks(); + nlo = save; return; + } + if (accept("break")) { if (!nloop) die("break outside a loop"); brk[nloop - 1][nbrk[nloop - 1]++] = here; lit(0); op(O_JMP); expect(";"); return; } + if (accept("continue")) { if (!nloop) die("continue outside a loop"); jmp_to(cont[nloop - 1]); expect(";"); return; } + if (accept("return")) { + if (!is(";")) { expr(); rval(); } else lit(0); + expect(";"); epi[nepi++] = here; lit(0); op(O_JMP); return; + } + if (is("asm")) { next(); asmblock(); return; } + expr(); rval(); op(O_DROP); expect(";"); +} + +/* ---- top level ---- */ +static void fndef(void) +{ + char *n = ident(); Sym *s; int np = 0, tags = 0, t, ret = 0, frame, i; + char pn[16][64]; + s = find(n); + if (!s || s->kind != K_FN) { s = add(n, K_FN, 0); s->defd = 0; } + expect("("); + if (!accept(")")) { + do { + t = 0; + if (tk == T_ID && (!strcmp(ts, "m") || !strcmp(ts, "d"))) { + char k = ts[0]; next(); + if (tk == T_ID) t = k == 'm' ? 1 : 2; + else { pn[np][0] = k; pn[np][1] = 0; np++; continue; } /* a parameter called m or d */ + } + if (np < 12) tags += t << (2 * np); + strcpy(pn[np++], ident()); + } while (accept(",")); + expect(")"); + } + if (accept("->")) { if (strcmp(ident(), "u")) die("only -> u is a return tag"); ret = 1; } + s->sig = ret + 2 * np + 64 * tags; + if (accept(";")) return; /* prototype */ + if (s->defd) die("function defined twice"); + s->val = here; s->defd = 1; + nlo = 0; nslot = 0; nepi = 0; infn = 1; + for (i = 0; i < np; i++) { strcpy(lo[nlo].name, pn[i]); lo[nlo].arr = 0; lo[nlo++].slot = nslot++; } + /* prologue: fp -= frame, then pop the arguments into their slots */ + lit(ZFP); op(O_LD); frame = here; lit(0); op(O_SUB); lit(ZFP); op(O_ST); + for (i = np; i--;) { laddr(i); op(O_ST); } + block(); + lit(0); + for (i = 0; i < nepi; i++) setlit(epi[i], here); + lit(ZFP); op(O_LD); lit(nslot); op(O_ADD); lit(ZFP); op(O_ST); op(O_RET); + setlit(frame, nslot); + infn = 0; +} +static void top(void) +{ + while (tk != T_EOF) { + if (accept("unchecked")) continue; + if (accept("fn")) { fndef(); continue; } + if (accept("const")) { do { char *n = ident(); expect("="); add(n, K_CONST, cexpr()); } while (accept(",")); expect(";"); continue; } + if (accept("var")) { + do { + char *n = ident(); + if (accept("[")) { int k = cexpr(), a = here; expect("]"); while (k--) emit(0); add(n, K_GARR, a); } + else { + int a = here; add(n, K_GVAR, a); emit(0); + if (accept("=")) { + if (tk == T_STR) { int i, l = (int)strlen(ts); img[a - GORG] = here; for (i = 0; i < l; i++) emit((unsigned char)ts[i]); emit(0); next(); } + else img[a - GORG] = cexpr(); + } + } + } while (accept(",")); + expect(";"); continue; + } + die("expected fn, var or const"); + } +} + +int main(void) +{ + static char buf[1 << 22]; int n = (int)fread(buf, 1, sizeof buf - 1, stdin), i, j; Sym *st; + buf[n] = 0; src = buf; next(); + /* image header: set the frame pointer, jump to start, then the symbol blob pointer and image end */ + lit(FTOP); lit(ZFP); op(O_ST); fnref("start"); op(O_JMP); emit(0); emit(0); + top(); + for (i = 0; i < nfx; i++) { + Sym *s = &sy[fx[i].sym]; + if (!s->defd) { fprintf(stderr, "zc0: undefined function %s\n", s->name); return 1; } + setlit(fx[i].at, s->val); + } + if (!(st = find("start")) || !st->defd) { fprintf(stderr, "zc0: no start\n"); return 1; } + /* symbol blob: kind, value, sig, name chars, 0 ... then a 0 kind */ + img[5] = here; + for (i = 0; i < nsy; i++) { + emit(sy[i].kind); emit(sy[i].val); emit(sy[i].sig); + for (j = 0; sy[i].name[j]; j++) emit((unsigned char)sy[i].name[j]); + emit(0); + } + emit(0); + img[6] = here; + printf("#define GORG %d\n#define GLEN %d\nstatic const int genome[] = {", GORG, here - GORG); + for (i = 0; i < here - GORG; i++) printf("%s%d", !i ? "\n" : i % 16 ? "," : ",\n", img[i]); + printf("\n};\n"); + return 0; +} |
