From ecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 Mon Sep 17 00:00:00 2001 From: Moon Flower Date: Mon, 12 Oct 2026 08:46:23 +0330 Subject: a --- docs/BORROW.md | 89 + docs/LEARN.md | 718 +++ docs/design/adt.md | 19 + docs/design/handoff.md | 20 + docs/design/memory.md | 106 + docs/design/storage-analysis.md | 33 + docs/design/struct-by-value.md | 9 + docs/design/tiering.md | 7 + docs/history/01-golf/notes.md | 10 + docs/history/02-hardware/notes.md | 46 + docs/history/04-darwin-compiler/notes.md | 9 + docs/history/05-hybrid/notes.md | 9 + docs/history/06-choosing/notes.md | 10 + docs/history/07-zygote/code/README.md | 168 + docs/history/07-zygote/code/aslib.s | 67 + docs/history/07-zygote/code/core.c | 276 + docs/history/07-zygote/code/examples/asmain.s | 9 + docs/history/07-zygote/code/examples/echo.s | 1 + docs/history/07-zygote/code/examples/fact.s | 3 + docs/history/07-zygote/code/examples/hello.s | 2 + docs/history/07-zygote/code/examples/sm.s | 3 + docs/history/07-zygote/code/gen.s | 9 + docs/history/07-zygote/code/genome.h | 39 + docs/history/07-zygote/code/io_linux.c | 6 + docs/history/07-zygote/code/mkgenome.c | 35 + docs/history/07-zygote/code/repl.s | 11 + docs/history/07-zygote/code/test.sh | 18 + docs/history/07-zygote/notes.md | 10 + docs/history/08-packaging/notes.md | 17 + docs/history/10-zc/code/README.md | 300 ++ docs/history/10-zc/code/core.c | 332 ++ docs/history/10-zc/code/examples/echo.zc | 2 + docs/history/10-zc/code/examples/fact.zc | 4 + docs/history/10-zc/code/examples/hello.zc | 1 + docs/history/10-zc/code/examples/lists.zc | 35 + docs/history/10-zc/code/examples/repl.zc | 27 + docs/history/10-zc/code/examples/selfpatch.zc | 17 + docs/history/10-zc/code/genome.h | 2349 +++++++++ docs/history/10-zc/code/io_linux.c | 6 + docs/history/10-zc/code/mkgenome.c | 16 + docs/history/10-zc/code/src/compiler.zc | 1591 ++++++ docs/history/10-zc/code/src/rt.zc | 168 + docs/history/10-zc/code/test.sh | 48 + docs/history/10-zc/code/tests/basics.zc | 22 + docs/history/10-zc/code/tests/errors/back_to_m.zc | 2 + .../10-zc/code/tests/errors/borrow_escape.zc | 3 + .../10-zc/code/tests/errors/branch_mismatch.zc | 3 + docs/history/10-zc/code/tests/errors/child_dies.zc | 3 + .../10-zc/code/tests/errors/child_recast.zc | 2 + docs/history/10-zc/code/tests/errors/copy_owned.zc | 2 + .../10-zc/code/tests/errors/d_into_block.zc | 2 + docs/history/10-zc/code/tests/errors/d_kept.zc | 2 + docs/history/10-zc/code/tests/errors/discard_u.zc | 3 + docs/history/10-zc/code/tests/errors/give_m.zc | 3 + .../10-zc/code/tests/errors/global_store.zc | 3 + .../10-zc/code/tests/errors/leak_overwrite.zc | 2 + docs/history/10-zc/code/tests/errors/lend_d.zc | 4 + docs/history/10-zc/code/tests/errors/loop_move.zc | 3 + .../10-zc/code/tests/errors/plain_return.zc | 3 + .../10-zc/code/tests/errors/proto_needed.zc | 3 + docs/history/10-zc/code/tests/errors/return_m.zc | 3 + .../10-zc/code/tests/errors/tag_mismatch.zc | 2 + docs/history/10-zc/code/tests/errors/u_dropped.zc | 2 + .../10-zc/code/tests/errors/u_skip_level.zc | 2 + .../10-zc/code/tests/errors/unchecked_touch.zc | 2 + .../10-zc/code/tests/errors/untagged_param.zc | 3 + docs/history/10-zc/code/tests/errors/unused.zc | 2 + .../10-zc/code/tests/errors/use_after_give.zc | 3 + docs/history/10-zc/code/tests/gc.zc | 20 + docs/history/10-zc/code/tests/meta.zc | 46 + docs/history/10-zc/code/tests/misc.zc | 30 + docs/history/10-zc/code/tests/runerr.sh | 9 + docs/history/10-zc/code/tests/umd.zc | 52 + docs/history/10-zc/code/tools/build.zc | 13 + docs/history/10-zc/code/zc0.c | 439 ++ docs/history/10-zc/notes.md | 37 + docs/history/11-types-enhancements/code/README.md | 389 ++ docs/history/11-types-enhancements/code/core.c | 1157 +++++ .../11-types-enhancements/code/examples/echo.zc | 2 + .../11-types-enhancements/code/examples/fact.zc | 4 + .../11-types-enhancements/code/examples/hello.zc | 1 + .../11-types-enhancements/code/examples/lists.zc | 35 + .../11-types-enhancements/code/examples/repl.zc | 27 + .../code/examples/selfpatch.zc | 17 + .../11-types-enhancements/code/examples/typed.zc | 47 + .../11-types-enhancements/code/examples/wiring.zc | 19 + docs/history/11-types-enhancements/code/genome.h | 3596 +++++++++++++ docs/history/11-types-enhancements/code/io_linux.c | 6 + docs/history/11-types-enhancements/code/mkgenome.c | 16 + .../11-types-enhancements/code/src/compiler.zc | 2253 +++++++++ docs/history/11-types-enhancements/code/src/rt.zc | 183 + docs/history/11-types-enhancements/code/test.sh | 64 + .../11-types-enhancements/code/tests/basics.zc | 22 + .../11-types-enhancements/code/tests/enhance.zc | 29 + .../code/tests/errors/back_to_m.zc | 2 + .../code/tests/errors/borrow_escape.zc | 3 + .../code/tests/errors/branch_mismatch.zc | 3 + .../code/tests/errors/child_dies.zc | 3 + .../code/tests/errors/child_recast.zc | 2 + .../code/tests/errors/copy_owned.zc | 2 + .../code/tests/errors/d_into_block.zc | 2 + .../code/tests/errors/d_kept.zc | 2 + .../code/tests/errors/discard_u.zc | 3 + .../code/tests/errors/give_m.zc | 3 + .../code/tests/errors/global_store.zc | 3 + .../code/tests/errors/leak_overwrite.zc | 2 + .../code/tests/errors/lend_d.zc | 4 + .../code/tests/errors/loop_move.zc | 3 + .../code/tests/errors/plain_return.zc | 3 + .../code/tests/errors/proto_needed.zc | 3 + .../code/tests/errors/return_m.zc | 3 + .../code/tests/errors/tag_mismatch.zc | 2 + .../code/tests/errors/u_dropped.zc | 2 + .../code/tests/errors/u_skip_level.zc | 2 + .../code/tests/errors/unchecked_touch.zc | 2 + .../code/tests/errors/unused.zc | 2 + .../code/tests/errors/use_after_give.zc | 3 + .../history/11-types-enhancements/code/tests/gc.zc | 20 + .../11-types-enhancements/code/tests/meta.zc | 46 + .../11-types-enhancements/code/tests/misc.zc | 30 + .../11-types-enhancements/code/tests/runerr.sh | 10 + .../code/tests/typeerrors/arg.zc | 5 + .../code/tests/typeerrors/arith.zc | 3 + .../code/tests/typeerrors/assign.zc | 3 + .../code/tests/typeerrors/call.zc | 3 + .../code/tests/typeerrors/deref.zc | 3 + .../code/tests/typeerrors/field.zc | 3 + .../code/tests/typeerrors/generic.zc | 4 + .../code/tests/typeerrors/notstruct.zc | 2 + .../code/tests/typeerrors/ret.zc | 4 + .../code/tests/typeerrors/voidret.zc | 4 + .../11-types-enhancements/code/tests/typeoff.zc | 2 + .../11-types-enhancements/code/tests/typeok.zc | 22 + .../11-types-enhancements/code/tests/types.zc | 57 + .../11-types-enhancements/code/tests/umd.zc | 52 + .../11-types-enhancements/code/tools/build.zc | 13 + docs/history/11-types-enhancements/code/zc0.c | 460 ++ docs/history/11-types-enhancements/notes.md | 73 + docs/history/13-gap-fixes/code/README.md | 422 ++ docs/history/13-gap-fixes/code/core.c | 1183 +++++ docs/history/13-gap-fixes/code/examples/echo.zc | 2 + docs/history/13-gap-fixes/code/examples/fact.zc | 4 + docs/history/13-gap-fixes/code/examples/hello.zc | 1 + docs/history/13-gap-fixes/code/examples/lists.zc | 35 + docs/history/13-gap-fixes/code/examples/repl.zc | 27 + .../13-gap-fixes/code/examples/selfpatch.zc | 17 + docs/history/13-gap-fixes/code/examples/typed.zc | 47 + docs/history/13-gap-fixes/code/examples/wiring.zc | 19 + docs/history/13-gap-fixes/code/genome.h | 4443 +++++++++++++++++ docs/history/13-gap-fixes/code/io_linux.c | 6 + docs/history/13-gap-fixes/code/mkgenome.c | 16 + docs/history/13-gap-fixes/code/src/compiler.zc | 2638 ++++++++++ docs/history/13-gap-fixes/code/src/rt.zc | 240 + docs/history/13-gap-fixes/code/test.sh | 71 + docs/history/13-gap-fixes/code/tests/basics.zc | 22 + docs/history/13-gap-fixes/code/tests/borrowmove.zc | 2 + docs/history/13-gap-fixes/code/tests/buddy.zc | 15 + docs/history/13-gap-fixes/code/tests/enhance.zc | 29 + .../13-gap-fixes/code/tests/errors/back_to_m.zc | 2 + .../code/tests/errors/borrow_escape.zc | 3 + .../code/tests/errors/branch_mismatch.zc | 3 + .../13-gap-fixes/code/tests/errors/child_dies.zc | 3 + .../13-gap-fixes/code/tests/errors/child_recast.zc | 2 + .../13-gap-fixes/code/tests/errors/copy_owned.zc | 2 + .../13-gap-fixes/code/tests/errors/d_into_block.zc | 2 + .../13-gap-fixes/code/tests/errors/d_kept.zc | 2 + .../13-gap-fixes/code/tests/errors/discard_u.zc | 3 + .../13-gap-fixes/code/tests/errors/give_m.zc | 3 + .../13-gap-fixes/code/tests/errors/global_store.zc | 3 + .../code/tests/errors/leak_overwrite.zc | 2 + .../13-gap-fixes/code/tests/errors/lend_d.zc | 4 + .../13-gap-fixes/code/tests/errors/loop_move.zc | 3 + .../13-gap-fixes/code/tests/errors/plain_return.zc | 3 + .../13-gap-fixes/code/tests/errors/return_m.zc | 3 + .../13-gap-fixes/code/tests/errors/tag_mismatch.zc | 2 + .../13-gap-fixes/code/tests/errors/u_dropped.zc | 2 + .../13-gap-fixes/code/tests/errors/u_skip_level.zc | 2 + .../code/tests/errors/unchecked_touch.zc | 2 + .../13-gap-fixes/code/tests/errors/unused.zc | 2 + .../code/tests/errors/use_after_give.zc | 3 + docs/history/13-gap-fixes/code/tests/gc.zc | 20 + docs/history/13-gap-fixes/code/tests/joins.zc | 32 + docs/history/13-gap-fixes/code/tests/manyerrors.zc | 6 + docs/history/13-gap-fixes/code/tests/meta.zc | 46 + docs/history/13-gap-fixes/code/tests/misc.zc | 30 + .../13-gap-fixes/code/tests/overflow_data.zc | 1 + .../13-gap-fixes/code/tests/overflow_frame.zc | 2 + .../13-gap-fixes/code/tests/overflow_return.zc | 2 + docs/history/13-gap-fixes/code/tests/runerr.sh | 10 + .../13-gap-fixes/code/tests/typeerrors/arg.zc | 5 + .../13-gap-fixes/code/tests/typeerrors/arith.zc | 3 + .../13-gap-fixes/code/tests/typeerrors/assign.zc | 3 + .../13-gap-fixes/code/tests/typeerrors/call.zc | 3 + .../13-gap-fixes/code/tests/typeerrors/deref.zc | 3 + .../13-gap-fixes/code/tests/typeerrors/field.zc | 3 + .../13-gap-fixes/code/tests/typeerrors/generic.zc | 4 + .../code/tests/typeerrors/notstruct.zc | 2 + .../13-gap-fixes/code/tests/typeerrors/ret.zc | 4 + .../13-gap-fixes/code/tests/typeerrors/voidret.zc | 4 + docs/history/13-gap-fixes/code/tests/typeoff.zc | 2 + docs/history/13-gap-fixes/code/tests/typeok.zc | 22 + docs/history/13-gap-fixes/code/tests/types.zc | 57 + docs/history/13-gap-fixes/code/tests/umd.zc | 52 + docs/history/13-gap-fixes/code/tools/build.zc | 13 + docs/history/13-gap-fixes/code/zc0.c | 460 ++ docs/history/13-gap-fixes/notes.md | 48 + docs/history/15-o3/code/README.md | 511 ++ docs/history/15-o3/code/bench.sh | 26 + docs/history/15-o3/code/core.c | 2019 ++++++++ docs/history/15-o3/code/examples/bf.zc | 50 + docs/history/15-o3/code/examples/dump.zc | 32 + docs/history/15-o3/code/examples/echo.zc | 2 + docs/history/15-o3/code/examples/fact.zc | 4 + docs/history/15-o3/code/examples/hello.zc | 1 + docs/history/15-o3/code/examples/lang.zc | 53 + docs/history/15-o3/code/examples/life.zc | 38 + docs/history/15-o3/code/examples/lists.zc | 34 + docs/history/15-o3/code/examples/mandel.zc | 36 + docs/history/15-o3/code/examples/primes.zc | 38 + docs/history/15-o3/code/examples/quine.zc | 1 + docs/history/15-o3/code/examples/repl.zc | 27 + docs/history/15-o3/code/examples/selfpatch.zc | 17 + docs/history/15-o3/code/examples/staged.zc | 35 + docs/history/15-o3/code/examples/tree.zc | 28 + docs/history/15-o3/code/examples/typed.zc | 44 + docs/history/15-o3/code/examples/wiring.zc | 19 + docs/history/15-o3/code/genome.h | 4893 ++++++++++++++++++ docs/history/15-o3/code/io_linux.c | 6 + docs/history/15-o3/code/mkgenome.c | 16 + docs/history/15-o3/code/src/compiler.zc | 2832 +++++++++++ docs/history/15-o3/code/src/rt.zc | 290 ++ docs/history/15-o3/code/test.sh | 88 + docs/history/15-o3/code/tests/arrays.zc | 24 + docs/history/15-o3/code/tests/basics.zc | 22 + docs/history/15-o3/code/tests/bench.zc | 30 + docs/history/15-o3/code/tests/borrowmove.zc | 2 + docs/history/15-o3/code/tests/buddy.zc | 15 + docs/history/15-o3/code/tests/enhance.zc | 29 + docs/history/15-o3/code/tests/errors/back_to_m.zc | 2 + .../15-o3/code/tests/errors/borrow_escape.zc | 3 + .../15-o3/code/tests/errors/branch_mismatch.zc | 3 + docs/history/15-o3/code/tests/errors/child_dies.zc | 3 + .../15-o3/code/tests/errors/child_recast.zc | 2 + docs/history/15-o3/code/tests/errors/copy_owned.zc | 2 + .../15-o3/code/tests/errors/d_into_block.zc | 2 + docs/history/15-o3/code/tests/errors/d_kept.zc | 2 + docs/history/15-o3/code/tests/errors/discard_u.zc | 3 + docs/history/15-o3/code/tests/errors/give_m.zc | 3 + .../15-o3/code/tests/errors/global_store.zc | 3 + .../15-o3/code/tests/errors/leak_overwrite.zc | 2 + docs/history/15-o3/code/tests/errors/lend_d.zc | 4 + docs/history/15-o3/code/tests/errors/loop_move.zc | 3 + .../15-o3/code/tests/errors/plain_return.zc | 3 + docs/history/15-o3/code/tests/errors/return_m.zc | 3 + .../15-o3/code/tests/errors/tag_mismatch.zc | 2 + docs/history/15-o3/code/tests/errors/u_dropped.zc | 2 + .../15-o3/code/tests/errors/u_skip_level.zc | 2 + .../15-o3/code/tests/errors/unchecked_touch.zc | 2 + docs/history/15-o3/code/tests/errors/unused.zc | 2 + .../15-o3/code/tests/errors/use_after_give.zc | 3 + docs/history/15-o3/code/tests/gc.zc | 20 + docs/history/15-o3/code/tests/joins.zc | 32 + .../15-o3/code/tests/langerrors/const_index.zc | 2 + .../15-o3/code/tests/langerrors/fixed_nolen.zc | 2 + .../15-o3/code/tests/langerrors/fixed_push.zc | 2 + .../15-o3/code/tests/langerrors/fixed_to_dyn.zc | 4 + .../history/15-o3/code/tests/langerrors/o3_addr.zc | 2 + docs/history/15-o3/code/tests/langerrors/o3_asm.zc | 2 + docs/history/15-o3/code/tests/langerrors/o3_let.zc | 2 + .../15-o3/code/tests/langerrors/o3_param.zc | 3 + docs/history/15-o3/code/tests/manyerrors.zc | 6 + docs/history/15-o3/code/tests/meta.zc | 46 + docs/history/15-o3/code/tests/misc.zc | 30 + docs/history/15-o3/code/tests/o3.zc | 83 + docs/history/15-o3/code/tests/o3_bounds.zc | 2 + docs/history/15-o3/code/tests/overflow_data.zc | 1 + docs/history/15-o3/code/tests/overflow_frame.zc | 2 + docs/history/15-o3/code/tests/overflow_return.zc | 2 + docs/history/15-o3/code/tests/runerr.sh | 10 + docs/history/15-o3/code/tests/typeerrors/arg.zc | 5 + docs/history/15-o3/code/tests/typeerrors/arith.zc | 3 + docs/history/15-o3/code/tests/typeerrors/assign.zc | 3 + docs/history/15-o3/code/tests/typeerrors/call.zc | 3 + docs/history/15-o3/code/tests/typeerrors/deref.zc | 3 + docs/history/15-o3/code/tests/typeerrors/field.zc | 3 + .../history/15-o3/code/tests/typeerrors/generic.zc | 4 + .../15-o3/code/tests/typeerrors/notstruct.zc | 2 + docs/history/15-o3/code/tests/typeerrors/ret.zc | 4 + .../history/15-o3/code/tests/typeerrors/voidret.zc | 4 + docs/history/15-o3/code/tests/typeoff.zc | 2 + docs/history/15-o3/code/tests/typeok.zc | 21 + docs/history/15-o3/code/tests/types.zc | 56 + docs/history/15-o3/code/tests/umd.zc | 51 + docs/history/15-o3/code/tools/build.zc | 13 + docs/history/15-o3/code/zc0.c | 461 ++ docs/history/15-o3/notes.md | 49 + docs/history/17-o3-boundaries/code/README.md | 528 ++ docs/history/17-o3-boundaries/code/bench.sh | 36 + docs/history/17-o3-boundaries/code/core.c | 2030 ++++++++ docs/history/17-o3-boundaries/code/examples/bf.zc | 50 + .../history/17-o3-boundaries/code/examples/dump.zc | 32 + .../history/17-o3-boundaries/code/examples/echo.zc | 2 + .../history/17-o3-boundaries/code/examples/fact.zc | 4 + .../17-o3-boundaries/code/examples/hello.zc | 1 + .../history/17-o3-boundaries/code/examples/lang.zc | 53 + .../history/17-o3-boundaries/code/examples/life.zc | 38 + .../17-o3-boundaries/code/examples/lists.zc | 34 + .../17-o3-boundaries/code/examples/mandel.zc | 36 + .../17-o3-boundaries/code/examples/primes.zc | 38 + .../17-o3-boundaries/code/examples/quine.zc | 1 + .../history/17-o3-boundaries/code/examples/repl.zc | 27 + .../17-o3-boundaries/code/examples/selfpatch.zc | 17 + .../17-o3-boundaries/code/examples/staged.zc | 35 + .../history/17-o3-boundaries/code/examples/tree.zc | 28 + .../17-o3-boundaries/code/examples/typed.zc | 44 + .../17-o3-boundaries/code/examples/wiring.zc | 19 + docs/history/17-o3-boundaries/code/genome.h | 5262 ++++++++++++++++++++ docs/history/17-o3-boundaries/code/io_linux.c | 6 + docs/history/17-o3-boundaries/code/mkgenome.c | 16 + docs/history/17-o3-boundaries/code/src/compiler.zc | 2980 +++++++++++ docs/history/17-o3-boundaries/code/src/rt.zc | 291 ++ docs/history/17-o3-boundaries/code/test.sh | 90 + docs/history/17-o3-boundaries/code/tests/arrays.zc | 24 + docs/history/17-o3-boundaries/code/tests/basics.zc | 22 + docs/history/17-o3-boundaries/code/tests/bench.zc | 30 + .../17-o3-boundaries/code/tests/borrowmove.zc | 2 + docs/history/17-o3-boundaries/code/tests/buddy.zc | 15 + .../history/17-o3-boundaries/code/tests/enhance.zc | 29 + .../code/tests/errors/back_to_m.zc | 2 + .../code/tests/errors/borrow_escape.zc | 3 + .../code/tests/errors/branch_mismatch.zc | 3 + .../code/tests/errors/child_dies.zc | 3 + .../code/tests/errors/child_recast.zc | 2 + .../code/tests/errors/copy_owned.zc | 2 + .../code/tests/errors/d_into_block.zc | 2 + .../17-o3-boundaries/code/tests/errors/d_kept.zc | 2 + .../code/tests/errors/discard_u.zc | 3 + .../17-o3-boundaries/code/tests/errors/give_m.zc | 3 + .../code/tests/errors/global_store.zc | 3 + .../code/tests/errors/leak_overwrite.zc | 2 + .../17-o3-boundaries/code/tests/errors/lend_d.zc | 4 + .../code/tests/errors/loop_move.zc | 3 + .../code/tests/errors/plain_return.zc | 3 + .../17-o3-boundaries/code/tests/errors/return_m.zc | 3 + .../code/tests/errors/tag_mismatch.zc | 2 + .../code/tests/errors/u_dropped.zc | 2 + .../code/tests/errors/u_skip_level.zc | 2 + .../code/tests/errors/unchecked_touch.zc | 2 + .../17-o3-boundaries/code/tests/errors/unused.zc | 2 + .../code/tests/errors/use_after_give.zc | 3 + docs/history/17-o3-boundaries/code/tests/gc.zc | 20 + docs/history/17-o3-boundaries/code/tests/joins.zc | 32 + .../code/tests/langerrors/const_index.zc | 2 + .../code/tests/langerrors/fixed_nolen.zc | 2 + .../code/tests/langerrors/fixed_push.zc | 2 + .../code/tests/langerrors/fixed_to_dyn.zc | 4 + .../code/tests/langerrors/gen_undeclared.zc | 3 + .../code/tests/langerrors/o3_addr.zc | 2 + .../code/tests/langerrors/o3_asm.zc | 2 + .../code/tests/langerrors/o3_let.zc | 2 + .../code/tests/langerrors/o3_param.zc | 3 + .../17-o3-boundaries/code/tests/manyerrors.zc | 6 + docs/history/17-o3-boundaries/code/tests/meta.zc | 46 + docs/history/17-o3-boundaries/code/tests/misc.zc | 30 + docs/history/17-o3-boundaries/code/tests/o3.zc | 83 + .../17-o3-boundaries/code/tests/o3_bounds.zc | 2 + docs/history/17-o3-boundaries/code/tests/o3fat.zc | 22 + .../17-o3-boundaries/code/tests/o3scopes.zc | 19 + .../17-o3-boundaries/code/tests/overflow_data.zc | 1 + .../17-o3-boundaries/code/tests/overflow_frame.zc | 2 + .../17-o3-boundaries/code/tests/overflow_return.zc | 2 + docs/history/17-o3-boundaries/code/tests/runerr.sh | 10 + .../17-o3-boundaries/code/tests/typeerrors/arg.zc | 5 + .../code/tests/typeerrors/arith.zc | 3 + .../code/tests/typeerrors/assign.zc | 3 + .../17-o3-boundaries/code/tests/typeerrors/call.zc | 3 + .../code/tests/typeerrors/deref.zc | 3 + .../code/tests/typeerrors/field.zc | 3 + .../code/tests/typeerrors/generic.zc | 4 + .../code/tests/typeerrors/notstruct.zc | 2 + .../17-o3-boundaries/code/tests/typeerrors/ret.zc | 4 + .../code/tests/typeerrors/voidret.zc | 4 + .../history/17-o3-boundaries/code/tests/typeoff.zc | 2 + docs/history/17-o3-boundaries/code/tests/typeok.zc | 21 + docs/history/17-o3-boundaries/code/tests/types.zc | 56 + docs/history/17-o3-boundaries/code/tests/umd.zc | 51 + docs/history/17-o3-boundaries/code/tools/build.zc | 13 + docs/history/17-o3-boundaries/code/zc0.c | 461 ++ docs/history/17-o3-boundaries/notes.md | 48 + docs/history/18-aliases/notes.md | 13 + docs/history/19-tools/notes.md | 25 + docs/history/20-words/notes.md | 22 + docs/history/21-micro/notes.md | 23 + docs/history/22-size/notes.md | 82 + docs/history/23-baremetal/notes.md | 85 + docs/history/24-backends/notes.md | 49 + docs/history/25-genmap/notes.md | 28 + docs/history/26-bareapi/notes.md | 25 + docs/history/27-float/notes.md | 19 + docs/history/28-bytes/notes.md | 21 + docs/history/29-strings/notes.md | 21 + docs/history/30-sharing/notes.md | 17 + docs/history/31-fpu/notes.md | 23 + docs/history/32-ftype/notes.md | 17 + docs/history/33-fo3/notes.md | 24 + docs/history/34-ftext/notes.md | 11 + docs/history/35-bench/notes.md | 82 + docs/history/36-alloc/notes.md | 47 + docs/history/37-call/notes.md | 43 + docs/history/38-bounds/notes.md | 43 + docs/history/39-blocks/notes.md | 43 + docs/history/40-fatten/notes.md | 41 + docs/history/41-obytes/notes.md | 39 + docs/history/42-roots/notes.md | 41 + docs/history/43-stdlib/notes.md | 47 + docs/history/44-check-mode/notes.md | 33 + docs/history/45-fast-alloc/notes.md | 13 + docs/history/46-c-abi/notes.md | 17 + docs/history/47-limits/notes.md | 15 + docs/history/48-landing/notes.md | 7 + docs/history/49-generics/notes.md | 5 + docs/history/50-adt/notes.md | 9 + docs/history/51-llvm-inline-stdlib/notes.md | 19 + docs/history/52-closures/notes.md | 14 + docs/history/53-typed-source/notes.md | 16 + docs/history/README.md | 50 + docs/history/baremetal-measurements.md | 55 + docs/history/maintenance-notes.md | 30 + docs/history/transcript.md | 257 + 429 files changed, 52850 insertions(+) create mode 100644 docs/BORROW.md create mode 100644 docs/LEARN.md create mode 100644 docs/design/adt.md create mode 100644 docs/design/handoff.md create mode 100644 docs/design/memory.md create mode 100644 docs/design/storage-analysis.md create mode 100644 docs/design/struct-by-value.md create mode 100644 docs/design/tiering.md create mode 100644 docs/history/01-golf/notes.md create mode 100644 docs/history/02-hardware/notes.md create mode 100644 docs/history/04-darwin-compiler/notes.md create mode 100644 docs/history/05-hybrid/notes.md create mode 100644 docs/history/06-choosing/notes.md create mode 100644 docs/history/07-zygote/code/README.md create mode 100644 docs/history/07-zygote/code/aslib.s create mode 100644 docs/history/07-zygote/code/core.c create mode 100644 docs/history/07-zygote/code/examples/asmain.s create mode 100644 docs/history/07-zygote/code/examples/echo.s create mode 100644 docs/history/07-zygote/code/examples/fact.s create mode 100644 docs/history/07-zygote/code/examples/hello.s create mode 100644 docs/history/07-zygote/code/examples/sm.s create mode 100644 docs/history/07-zygote/code/gen.s create mode 100644 docs/history/07-zygote/code/genome.h create mode 100644 docs/history/07-zygote/code/io_linux.c create mode 100644 docs/history/07-zygote/code/mkgenome.c create mode 100644 docs/history/07-zygote/code/repl.s create mode 100755 docs/history/07-zygote/code/test.sh create mode 100644 docs/history/07-zygote/notes.md create mode 100644 docs/history/08-packaging/notes.md create mode 100644 docs/history/10-zc/code/README.md create mode 100644 docs/history/10-zc/code/core.c create mode 100644 docs/history/10-zc/code/examples/echo.zc create mode 100644 docs/history/10-zc/code/examples/fact.zc create mode 100644 docs/history/10-zc/code/examples/hello.zc create mode 100644 docs/history/10-zc/code/examples/lists.zc create mode 100644 docs/history/10-zc/code/examples/repl.zc create mode 100644 docs/history/10-zc/code/examples/selfpatch.zc create mode 100644 docs/history/10-zc/code/genome.h create mode 100644 docs/history/10-zc/code/io_linux.c create mode 100644 docs/history/10-zc/code/mkgenome.c create mode 100644 docs/history/10-zc/code/src/compiler.zc create mode 100644 docs/history/10-zc/code/src/rt.zc create mode 100755 docs/history/10-zc/code/test.sh create mode 100644 docs/history/10-zc/code/tests/basics.zc create mode 100644 docs/history/10-zc/code/tests/errors/back_to_m.zc create mode 100644 docs/history/10-zc/code/tests/errors/borrow_escape.zc create mode 100644 docs/history/10-zc/code/tests/errors/branch_mismatch.zc create mode 100644 docs/history/10-zc/code/tests/errors/child_dies.zc create mode 100644 docs/history/10-zc/code/tests/errors/child_recast.zc create mode 100644 docs/history/10-zc/code/tests/errors/copy_owned.zc create mode 100644 docs/history/10-zc/code/tests/errors/d_into_block.zc create mode 100644 docs/history/10-zc/code/tests/errors/d_kept.zc create mode 100644 docs/history/10-zc/code/tests/errors/discard_u.zc create mode 100644 docs/history/10-zc/code/tests/errors/give_m.zc create mode 100644 docs/history/10-zc/code/tests/errors/global_store.zc create mode 100644 docs/history/10-zc/code/tests/errors/leak_overwrite.zc create mode 100644 docs/history/10-zc/code/tests/errors/lend_d.zc create mode 100644 docs/history/10-zc/code/tests/errors/loop_move.zc create mode 100644 docs/history/10-zc/code/tests/errors/plain_return.zc create mode 100644 docs/history/10-zc/code/tests/errors/proto_needed.zc create mode 100644 docs/history/10-zc/code/tests/errors/return_m.zc create mode 100644 docs/history/10-zc/code/tests/errors/tag_mismatch.zc create mode 100644 docs/history/10-zc/code/tests/errors/u_dropped.zc create mode 100644 docs/history/10-zc/code/tests/errors/u_skip_level.zc create mode 100644 docs/history/10-zc/code/tests/errors/unchecked_touch.zc create mode 100644 docs/history/10-zc/code/tests/errors/untagged_param.zc create mode 100644 docs/history/10-zc/code/tests/errors/unused.zc create mode 100644 docs/history/10-zc/code/tests/errors/use_after_give.zc create mode 100644 docs/history/10-zc/code/tests/gc.zc create mode 100644 docs/history/10-zc/code/tests/meta.zc create mode 100644 docs/history/10-zc/code/tests/misc.zc create mode 100755 docs/history/10-zc/code/tests/runerr.sh create mode 100644 docs/history/10-zc/code/tests/umd.zc create mode 100644 docs/history/10-zc/code/tools/build.zc create mode 100644 docs/history/10-zc/code/zc0.c create mode 100644 docs/history/10-zc/notes.md create mode 100644 docs/history/11-types-enhancements/code/README.md create mode 100644 docs/history/11-types-enhancements/code/core.c create mode 100644 docs/history/11-types-enhancements/code/examples/echo.zc create mode 100644 docs/history/11-types-enhancements/code/examples/fact.zc create mode 100644 docs/history/11-types-enhancements/code/examples/hello.zc create mode 100644 docs/history/11-types-enhancements/code/examples/lists.zc create mode 100644 docs/history/11-types-enhancements/code/examples/repl.zc create mode 100644 docs/history/11-types-enhancements/code/examples/selfpatch.zc create mode 100644 docs/history/11-types-enhancements/code/examples/typed.zc create mode 100644 docs/history/11-types-enhancements/code/examples/wiring.zc create mode 100644 docs/history/11-types-enhancements/code/genome.h create mode 100644 docs/history/11-types-enhancements/code/io_linux.c create mode 100644 docs/history/11-types-enhancements/code/mkgenome.c create mode 100644 docs/history/11-types-enhancements/code/src/compiler.zc create mode 100644 docs/history/11-types-enhancements/code/src/rt.zc create mode 100755 docs/history/11-types-enhancements/code/test.sh create mode 100644 docs/history/11-types-enhancements/code/tests/basics.zc create mode 100644 docs/history/11-types-enhancements/code/tests/enhance.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/back_to_m.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/borrow_escape.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/branch_mismatch.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/child_dies.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/child_recast.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/copy_owned.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/d_into_block.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/d_kept.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/discard_u.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/give_m.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/global_store.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/leak_overwrite.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/lend_d.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/loop_move.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/plain_return.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/proto_needed.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/return_m.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/tag_mismatch.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/u_dropped.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/u_skip_level.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/unchecked_touch.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/unused.zc create mode 100644 docs/history/11-types-enhancements/code/tests/errors/use_after_give.zc create mode 100644 docs/history/11-types-enhancements/code/tests/gc.zc create mode 100644 docs/history/11-types-enhancements/code/tests/meta.zc create mode 100644 docs/history/11-types-enhancements/code/tests/misc.zc create mode 100755 docs/history/11-types-enhancements/code/tests/runerr.sh create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/arg.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/arith.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/assign.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/call.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/deref.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/field.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/generic.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/notstruct.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/ret.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeerrors/voidret.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeoff.zc create mode 100644 docs/history/11-types-enhancements/code/tests/typeok.zc create mode 100644 docs/history/11-types-enhancements/code/tests/types.zc create mode 100644 docs/history/11-types-enhancements/code/tests/umd.zc create mode 100644 docs/history/11-types-enhancements/code/tools/build.zc create mode 100644 docs/history/11-types-enhancements/code/zc0.c create mode 100644 docs/history/11-types-enhancements/notes.md create mode 100644 docs/history/13-gap-fixes/code/README.md create mode 100644 docs/history/13-gap-fixes/code/core.c create mode 100644 docs/history/13-gap-fixes/code/examples/echo.zc create mode 100644 docs/history/13-gap-fixes/code/examples/fact.zc create mode 100644 docs/history/13-gap-fixes/code/examples/hello.zc create mode 100644 docs/history/13-gap-fixes/code/examples/lists.zc create mode 100644 docs/history/13-gap-fixes/code/examples/repl.zc create mode 100644 docs/history/13-gap-fixes/code/examples/selfpatch.zc create mode 100644 docs/history/13-gap-fixes/code/examples/typed.zc create mode 100644 docs/history/13-gap-fixes/code/examples/wiring.zc create mode 100644 docs/history/13-gap-fixes/code/genome.h create mode 100644 docs/history/13-gap-fixes/code/io_linux.c create mode 100644 docs/history/13-gap-fixes/code/mkgenome.c create mode 100644 docs/history/13-gap-fixes/code/src/compiler.zc create mode 100644 docs/history/13-gap-fixes/code/src/rt.zc create mode 100755 docs/history/13-gap-fixes/code/test.sh create mode 100644 docs/history/13-gap-fixes/code/tests/basics.zc create mode 100644 docs/history/13-gap-fixes/code/tests/borrowmove.zc create mode 100644 docs/history/13-gap-fixes/code/tests/buddy.zc create mode 100644 docs/history/13-gap-fixes/code/tests/enhance.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/back_to_m.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/borrow_escape.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/branch_mismatch.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/child_dies.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/child_recast.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/copy_owned.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/d_into_block.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/d_kept.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/discard_u.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/give_m.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/global_store.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/leak_overwrite.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/lend_d.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/loop_move.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/plain_return.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/return_m.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/tag_mismatch.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/u_dropped.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/u_skip_level.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/unchecked_touch.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/unused.zc create mode 100644 docs/history/13-gap-fixes/code/tests/errors/use_after_give.zc create mode 100644 docs/history/13-gap-fixes/code/tests/gc.zc create mode 100644 docs/history/13-gap-fixes/code/tests/joins.zc create mode 100644 docs/history/13-gap-fixes/code/tests/manyerrors.zc create mode 100644 docs/history/13-gap-fixes/code/tests/meta.zc create mode 100644 docs/history/13-gap-fixes/code/tests/misc.zc create mode 100644 docs/history/13-gap-fixes/code/tests/overflow_data.zc create mode 100644 docs/history/13-gap-fixes/code/tests/overflow_frame.zc create mode 100644 docs/history/13-gap-fixes/code/tests/overflow_return.zc create mode 100755 docs/history/13-gap-fixes/code/tests/runerr.sh create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/arg.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/arith.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/assign.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/call.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/deref.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/field.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/generic.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/notstruct.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/ret.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeerrors/voidret.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeoff.zc create mode 100644 docs/history/13-gap-fixes/code/tests/typeok.zc create mode 100644 docs/history/13-gap-fixes/code/tests/types.zc create mode 100644 docs/history/13-gap-fixes/code/tests/umd.zc create mode 100644 docs/history/13-gap-fixes/code/tools/build.zc create mode 100644 docs/history/13-gap-fixes/code/zc0.c create mode 100644 docs/history/13-gap-fixes/notes.md create mode 100644 docs/history/15-o3/code/README.md create mode 100755 docs/history/15-o3/code/bench.sh create mode 100644 docs/history/15-o3/code/core.c create mode 100644 docs/history/15-o3/code/examples/bf.zc create mode 100644 docs/history/15-o3/code/examples/dump.zc create mode 100644 docs/history/15-o3/code/examples/echo.zc create mode 100644 docs/history/15-o3/code/examples/fact.zc create mode 100644 docs/history/15-o3/code/examples/hello.zc create mode 100644 docs/history/15-o3/code/examples/lang.zc create mode 100644 docs/history/15-o3/code/examples/life.zc create mode 100644 docs/history/15-o3/code/examples/lists.zc create mode 100644 docs/history/15-o3/code/examples/mandel.zc create mode 100644 docs/history/15-o3/code/examples/primes.zc create mode 100644 docs/history/15-o3/code/examples/quine.zc create mode 100644 docs/history/15-o3/code/examples/repl.zc create mode 100644 docs/history/15-o3/code/examples/selfpatch.zc create mode 100644 docs/history/15-o3/code/examples/staged.zc create mode 100644 docs/history/15-o3/code/examples/tree.zc create mode 100644 docs/history/15-o3/code/examples/typed.zc create mode 100644 docs/history/15-o3/code/examples/wiring.zc create mode 100644 docs/history/15-o3/code/genome.h create mode 100644 docs/history/15-o3/code/io_linux.c create mode 100644 docs/history/15-o3/code/mkgenome.c create mode 100644 docs/history/15-o3/code/src/compiler.zc create mode 100644 docs/history/15-o3/code/src/rt.zc create mode 100755 docs/history/15-o3/code/test.sh create mode 100644 docs/history/15-o3/code/tests/arrays.zc create mode 100644 docs/history/15-o3/code/tests/basics.zc create mode 100644 docs/history/15-o3/code/tests/bench.zc create mode 100644 docs/history/15-o3/code/tests/borrowmove.zc create mode 100644 docs/history/15-o3/code/tests/buddy.zc create mode 100644 docs/history/15-o3/code/tests/enhance.zc create mode 100644 docs/history/15-o3/code/tests/errors/back_to_m.zc create mode 100644 docs/history/15-o3/code/tests/errors/borrow_escape.zc create mode 100644 docs/history/15-o3/code/tests/errors/branch_mismatch.zc create mode 100644 docs/history/15-o3/code/tests/errors/child_dies.zc create mode 100644 docs/history/15-o3/code/tests/errors/child_recast.zc create mode 100644 docs/history/15-o3/code/tests/errors/copy_owned.zc create mode 100644 docs/history/15-o3/code/tests/errors/d_into_block.zc create mode 100644 docs/history/15-o3/code/tests/errors/d_kept.zc create mode 100644 docs/history/15-o3/code/tests/errors/discard_u.zc create mode 100644 docs/history/15-o3/code/tests/errors/give_m.zc create mode 100644 docs/history/15-o3/code/tests/errors/global_store.zc create mode 100644 docs/history/15-o3/code/tests/errors/leak_overwrite.zc create mode 100644 docs/history/15-o3/code/tests/errors/lend_d.zc create mode 100644 docs/history/15-o3/code/tests/errors/loop_move.zc create mode 100644 docs/history/15-o3/code/tests/errors/plain_return.zc create mode 100644 docs/history/15-o3/code/tests/errors/return_m.zc create mode 100644 docs/history/15-o3/code/tests/errors/tag_mismatch.zc create mode 100644 docs/history/15-o3/code/tests/errors/u_dropped.zc create mode 100644 docs/history/15-o3/code/tests/errors/u_skip_level.zc create mode 100644 docs/history/15-o3/code/tests/errors/unchecked_touch.zc create mode 100644 docs/history/15-o3/code/tests/errors/unused.zc create mode 100644 docs/history/15-o3/code/tests/errors/use_after_give.zc create mode 100644 docs/history/15-o3/code/tests/gc.zc create mode 100644 docs/history/15-o3/code/tests/joins.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/const_index.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/fixed_nolen.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/fixed_push.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/fixed_to_dyn.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/o3_addr.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/o3_asm.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/o3_let.zc create mode 100644 docs/history/15-o3/code/tests/langerrors/o3_param.zc create mode 100644 docs/history/15-o3/code/tests/manyerrors.zc create mode 100644 docs/history/15-o3/code/tests/meta.zc create mode 100644 docs/history/15-o3/code/tests/misc.zc create mode 100644 docs/history/15-o3/code/tests/o3.zc create mode 100644 docs/history/15-o3/code/tests/o3_bounds.zc create mode 100644 docs/history/15-o3/code/tests/overflow_data.zc create mode 100644 docs/history/15-o3/code/tests/overflow_frame.zc create mode 100644 docs/history/15-o3/code/tests/overflow_return.zc create mode 100755 docs/history/15-o3/code/tests/runerr.sh create mode 100644 docs/history/15-o3/code/tests/typeerrors/arg.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/arith.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/assign.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/call.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/deref.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/field.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/generic.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/notstruct.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/ret.zc create mode 100644 docs/history/15-o3/code/tests/typeerrors/voidret.zc create mode 100644 docs/history/15-o3/code/tests/typeoff.zc create mode 100644 docs/history/15-o3/code/tests/typeok.zc create mode 100644 docs/history/15-o3/code/tests/types.zc create mode 100644 docs/history/15-o3/code/tests/umd.zc create mode 100644 docs/history/15-o3/code/tools/build.zc create mode 100644 docs/history/15-o3/code/zc0.c create mode 100644 docs/history/15-o3/notes.md create mode 100644 docs/history/17-o3-boundaries/code/README.md create mode 100755 docs/history/17-o3-boundaries/code/bench.sh create mode 100644 docs/history/17-o3-boundaries/code/core.c create mode 100644 docs/history/17-o3-boundaries/code/examples/bf.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/dump.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/echo.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/fact.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/hello.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/lang.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/life.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/lists.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/mandel.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/primes.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/quine.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/repl.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/selfpatch.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/staged.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/tree.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/typed.zc create mode 100644 docs/history/17-o3-boundaries/code/examples/wiring.zc create mode 100644 docs/history/17-o3-boundaries/code/genome.h create mode 100644 docs/history/17-o3-boundaries/code/io_linux.c create mode 100644 docs/history/17-o3-boundaries/code/mkgenome.c create mode 100644 docs/history/17-o3-boundaries/code/src/compiler.zc create mode 100644 docs/history/17-o3-boundaries/code/src/rt.zc create mode 100755 docs/history/17-o3-boundaries/code/test.sh create mode 100644 docs/history/17-o3-boundaries/code/tests/arrays.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/basics.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/bench.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/borrowmove.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/buddy.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/enhance.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/back_to_m.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/borrow_escape.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/branch_mismatch.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/child_dies.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/child_recast.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/copy_owned.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/d_into_block.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/d_kept.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/discard_u.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/give_m.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/global_store.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/leak_overwrite.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/lend_d.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/loop_move.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/plain_return.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/return_m.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/tag_mismatch.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/u_dropped.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/u_skip_level.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/unchecked_touch.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/unused.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/errors/use_after_give.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/gc.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/joins.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/const_index.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/fixed_nolen.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/fixed_push.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/fixed_to_dyn.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/gen_undeclared.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/o3_addr.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/o3_asm.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/o3_let.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/langerrors/o3_param.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/manyerrors.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/meta.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/misc.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/o3.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/o3_bounds.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/o3fat.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/o3scopes.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/overflow_data.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/overflow_frame.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/overflow_return.zc create mode 100755 docs/history/17-o3-boundaries/code/tests/runerr.sh create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/arg.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/arith.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/assign.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/call.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/deref.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/field.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/generic.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/notstruct.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/ret.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeerrors/voidret.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeoff.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/typeok.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/types.zc create mode 100644 docs/history/17-o3-boundaries/code/tests/umd.zc create mode 100644 docs/history/17-o3-boundaries/code/tools/build.zc create mode 100644 docs/history/17-o3-boundaries/code/zc0.c create mode 100644 docs/history/17-o3-boundaries/notes.md create mode 100644 docs/history/18-aliases/notes.md create mode 100644 docs/history/19-tools/notes.md create mode 100644 docs/history/20-words/notes.md create mode 100644 docs/history/21-micro/notes.md create mode 100644 docs/history/22-size/notes.md create mode 100644 docs/history/23-baremetal/notes.md create mode 100644 docs/history/24-backends/notes.md create mode 100644 docs/history/25-genmap/notes.md create mode 100644 docs/history/26-bareapi/notes.md create mode 100644 docs/history/27-float/notes.md create mode 100644 docs/history/28-bytes/notes.md create mode 100644 docs/history/29-strings/notes.md create mode 100644 docs/history/30-sharing/notes.md create mode 100644 docs/history/31-fpu/notes.md create mode 100644 docs/history/32-ftype/notes.md create mode 100644 docs/history/33-fo3/notes.md create mode 100644 docs/history/34-ftext/notes.md create mode 100644 docs/history/35-bench/notes.md create mode 100644 docs/history/36-alloc/notes.md create mode 100644 docs/history/37-call/notes.md create mode 100644 docs/history/38-bounds/notes.md create mode 100644 docs/history/39-blocks/notes.md create mode 100644 docs/history/40-fatten/notes.md create mode 100644 docs/history/41-obytes/notes.md create mode 100644 docs/history/42-roots/notes.md create mode 100644 docs/history/43-stdlib/notes.md create mode 100644 docs/history/44-check-mode/notes.md create mode 100644 docs/history/45-fast-alloc/notes.md create mode 100644 docs/history/46-c-abi/notes.md create mode 100644 docs/history/47-limits/notes.md create mode 100644 docs/history/48-landing/notes.md create mode 100644 docs/history/49-generics/notes.md create mode 100644 docs/history/50-adt/notes.md create mode 100644 docs/history/51-llvm-inline-stdlib/notes.md create mode 100644 docs/history/52-closures/notes.md create mode 100644 docs/history/53-typed-source/notes.md create mode 100644 docs/history/README.md create mode 100644 docs/history/baremetal-measurements.md create mode 100644 docs/history/maintenance-notes.md create mode 100644 docs/history/transcript.md (limited to 'docs') diff --git a/docs/BORROW.md b/docs/BORROW.md new file mode 100644 index 0000000..78b28e9 --- /dev/null +++ b/docs/BORROW.md @@ -0,0 +1,89 @@ +# a quieter ownership and lifetime checker + +## objective + +accept ordinary, safe code with little annotation. infer ownership transfers and borrow duration when the compiler can prove them, and explain the cases it cannot prove. measure this on a corpus of small programs rather than claiming the checker is generally smarter than rust's. + +rust already infers non-lexical lifetimes from control flow; reproducing that idea would not establish an advantage. its checker also tracks initialization and moves. zc can choose different ergonomics for its single-threaded ownership model and collector, while documenting where that model provides fewer guarantees. see the [rust compiler guide](https://rustc-dev-guide.rust-lang.org/borrow-check.html). + +## current behavior + +the analyzer runs alongside parsing and code emission. a local records an owner, scope, and state: held here, moving up, moving down, borrowed, or dead. snapshots reconcile branches and loops; derived pointer aliases retain their owner. explicit `.m`, `.d`, and `.u` tags describe borrowing and transfers. + +passing a fresh owned result directly to a borrowing parameter is deliberately rejected by `argcheck`. only a consuming `.d` parameter can currently receive it without a named local. naming the result gives the caller a place to insert cleanup. accepting the same call without generating that cleanup would change lifetime behavior and can leak the temporary until collection. + +```zc +char*.u message() { char* s = new(2); s[0] = 'x'; s[1] = 0; return u*s; } +fn main() { + let text = message(); + put_s(text); + return 0; +} +``` + +plain borrowing parameters do not provide a complete interprocedural escape contract. unchecked code, raw host calls, integer-to-pointer conversions, and unknown native functions remain boundaries of static reasoning. + +## proposed rules + +### temporary borrows + +allow `put_s(message())` when the callee is proved to borrow without retaining, freeing, or transferring the argument. evaluate arguments in their existing order, hold each owned temporary in a compiler-generated slot, call the function, then free the temporary after its last dependent use. keep a returned alias alive through the enclosing expression when necessary. + +do not substitute `.d`: the output function does not consume its argument. nested calls, short-circuit expressions, early returns, and error recovery need their own cleanup paths. a temporary cannot be destroyed while another argument or the result still refers to it. unknown or escaping callees keep the explicit binding requirement. + +rust also has temporary scopes and lifetime extension rules; the proposed benefit here is a smaller set of user-facing rules for zc, not the invention of temporary lifetimes. see the [rust reference](https://doc.rust-lang.org/reference/destructors.html#temporary-scopes). + +### function effects + +infer a summary for each parameter: read, write, retain, consume, or return an alias. distinguish a returned owned result from a returned borrow and record which argument the borrow depends on. compute summaries to a fixed point for recursive functions; cache them by function body and relevant callee summaries. + +start with the runtime and ordinary functions whose bodies are available. annotations remain useful for externs, separate compilation, and deliberately unchecked code. a missing summary means unknown effects, not a promise that the call is safe. + +### borrows end at their last use + +derive borrow duration from control flow. a temporary alias that is no longer used should not prevent a later move of its owner. infer ordinary moves into consuming calls and returns where there is one unambiguous owner; retain explicit tags for ambiguous transfers and low-level code. + +use one fact graph for ownership, initialization, aliases, and known bounds. keep the existing parser and parse words: record analysis events from the real compiler, rather than adding an independent source parser that can disagree with it. + +### fields, elements, and mutation + +track accesses by owner and projection: a struct field, a constant array index, or an element range. allow disjoint accesses when their projections are proved separate. invalidate those facts after an overlapping write, resize, unknown call, or unchecked operation. + +ordinary aliases may coexist in zc; mutation is safe only while the owner remains alive and the access stays valid. permitting aliases does not provide rust's concurrency guarantees. do not infer disjointness from uncertain indices, and do not treat a quarantined block's intact bytes as a valid lifetime. + +### useful diagnostics + +report the operation that makes a later use invalid, the later use, and the relevant owner or bound. show known size, ownership, borrow source, and lifetime end in hover text. use "unknown" when a fact is unavailable. + +preserve hard errors for existing definite lifetime violations. add warnings for newly detected definite out-of-bounds access or use after free in code the old analyzer did not track. keep heuristic suggestions separate from definite findings, and avoid claiming an uncertain path is definitely invalid. + +## implementation order + +1. finish the existing maintenance and memory work in `TODO.md`; analysis tables must grow without silently dropping facts. +2. add compiler events with source ranges and a small control-flow representation. reproduce the current analyzer's accepted and rejected corpus before changing its rules. +3. infer non-escaping summaries for the runtime and add temporary cleanup for proved borrowing calls. +4. implement last-use borrow endings and unambiguous ownership transfer inference. +5. add projection facts, bounds facts, and explanatory editor previews. perform the final warning phase only after the preceding maintenance is complete. +6. compare the old and new checker on the same programs. expose unexplained behavior changes as regressions, not as an improvement count. + +## acceptance cases + +| case | required behavior | +|---|---| +| an owned temporary passed to a proved non-escaping output function | accepted; one cleanup after its last use | +| a temporary passed to a callee that stores it globally | rejected unless ownership is transferred | +| a returned alias of a temporary used later in the same expression | accepted only with a proved lifetime extension | +| two arguments depending on the same owner | evaluate without freeing or moving that owner too early | +| an alias whose last use precedes an ownership transfer | accepted when no surviving alias escapes | +| independent struct fields or constant array elements | permit proved disjoint accesses | +| resize while an element alias remains live | reject or invalidate the alias according to an explicit rule | +| a use after a definite free or move | retain the error, with both source locations | +| an index definitely outside a known length | show a definite bounds finding | +| a dynamic index with no useful bound | retain runtime checks; no definite warning | +| unknown native or unchecked effects | require a contract or explicit escape hatch | + +verify cleanup counts, allocation counts, alias lifetimes, and output on the interpreter, microcore, and available native backends. tests must include safe neighbors of every rejected example. track annotations removed, safe programs accepted, compile time, and diagnostic precision as separate outcomes. + +## scope + +this is a design plan, not an implemented guarantee. lifetime inference must not change evaluation order or silently choose a different ownership contract. the initial work targets zc's present single-threaded execution model; shared mutable concurrency needs a separate model. diff --git a/docs/LEARN.md b/docs/LEARN.md new file mode 100644 index 0000000..676358a --- /dev/null +++ b/docs/LEARN.md @@ -0,0 +1,718 @@ +# learning zc + +zc is a small c-like language for a stack machine with 64-bit words. this guide starts with ordinary programs, then covers memory, types, native calls, and metaprogramming. every zc code block is a complete file in [examples/learn/](../examples/learn/). the output below it comes from the matching `.out` file. + +## setup + +build from the repository root, then run a source file on stdin: + +```sh +make +bin/zy < examples/learn/01-hello.zc +``` + +`bin/zy` is the native core: it uses the arm64 jit where available and otherwise interprets. `bin/zym` is the portable microcore, `bin/zc0` is the bootstrap compiler, and `bin/zclsp` checks source for the editor. the interactive runners are `./tinyvm.sh` on linux and `tinyvm.bat` on windows. + +run from the root throughout this guide. paths in `include` and `readfile` are resolved from the process's working directory. `tests/drivers/learn.py` checks the examples and verifies that the code blocks here match their source files: + +```sh +python3 tests/drivers/learn.py bin/zy +``` + +native c calls need the full native core. the raw syscall example needs linux on x86-64. the other examples use ordinary language features; availability of host services still depends on the port. + +## contents + +- [programs and control flow](#programs-and-control-flow) +- [numbers and strings](#numbers-and-strings) +- [ownership and the heap](#ownership-and-the-heap) +- [libraries and the host](#libraries-and-the-host) +- [types and containers](#types-and-containers) +- [optimized regions](#optimized-regions) +- [closures](#closures) +- [further reading](#further-reading) + +## programs and control flow + +### the first program + +a unit is read to eof or a backtick outside a comment or literal. after compiling the unit, the runtime calls `main`. an ordinary function returns one word; falling off its end returns 0. the return value of `main` is not the process exit status. `halt()` stops the machine. + +`put_s(s)` prints a string, `put_n(n)` prints an integer, and `put_c(c)` prints a character code. `put_c(10)` prints a newline. + +[example source](../examples/learn/01-hello.zc): + +```zc +fn main() { + put_s("hello, world!\n"); + return 0; +} +``` + +output: + +```text +hello, world! +``` + +### variables and while + +`let` infers a variable's type from its initializer. an integer literal stays a plain word. `int i = 0;` writes the type explicitly. the lifetime analyzer runs by default; the optional typechecker is enabled separately with `typecheck on;`. + +`while` tests before entering the body. `i++` increments the variable, and `break` leaves the loop. + +[example source](../examples/learn/02-loops.zc): + +```zc +fn main() { + let i = 0, n = 0; + while (i < 4) { n = n + i; i++; } + put_n(n); put_c(10); + return 0; +} +``` + +output: + +```text +6 +``` + +### do and continue + +`do` runs the body once before testing the condition. in a `do` loop, `continue` jumps to the condition; in a `for` loop, it jumps to the increment step. this example skips adding 2. + +[example source](../examples/learn/03-do-continue.zc): + +```zc +fn main() { + int n = 0, i = 0; + do { i++; if (i == 2) continue; n = n + i; } while (i < 5); + put_n(n); put_c(10); + return 0; +} +``` + +output: + +```text +13 +``` + +### switch + +`switch` selects the matching `case`; `default` handles the rest. cases do not fall through, so `break` is optional at the end of an arm. + +[example source](../examples/learn/17-switch.zc): + +```zc +fn main() { + int k = 2; + switch (k) { case 1: put_s("one"); break; case 2: put_s("two"); break; default: put_s("other"); } + put_c(10); + return 0; +} +``` + +output: + +```text +two +``` + +### plain enums + +members without an explicit value increase by one, starting at 0. `GREEN = 5` makes `BLUE` equal 6. members can also be written as `color.BLUE` and used as case labels. + +with the typechecker enabled, `color` is its own type: members have that type, an enum value can become an `int`, and an arbitrary integer does not become a `color`. + +[example source](../examples/learn/04-enums.zc): + +```zc +enum color { RED, GREEN = 5, BLUE }; +fn main() { + put_n(RED); put_c(32); put_n(GREEN); put_c(32); put_n(BLUE); put_c(10); + return 0; +} +``` + +output: + +```text +0 5 6 +``` + +## numbers and strings + +### sized integers + +`u8`, `i8`, `u16`, `i16`, `u32`, and `i32` narrow on assignment. adding 10 to an unsigned byte holding 250 leaves 4. arrays and pointers of these types use packed storage. + +addresses normally count words. `sizeof` also counts words, so `[100]u8` occupies 13 words. an `int*` points to word-sized integers; `p + 1` advances one word. a sized pointer such as `u8*` indexes packed elements. + +[example source](../examples/learn/05-small-ints.zc): + +```zc +fn main() { + u8 a = 250; a = a + 10; + put_n(a); put_c(10); + put_n(sizeof([100]u8)); put_c(10); + u8* px = new(u8, 4096); + px[10] = 300; + put_n(px[10]); put_c(10); + return 0; +} +``` + +output: + +```text +4 +13 +44 +``` + +### floating point + +a literal such as `1.5` is an ieee binary64 value in one word. `float` and `f64` name that type; `f32` rounds on store. integer operands are promoted when mixed with floats in arithmetic. + +`put_n` prints integers. the helper `put_f` below calls the vm's float printer with encoded instruction `#1220`. division by zero gives `inf`; `0.0 / 0.0` gives `nan`. both `0.0` and `-0.0` are false in conditions. + +[example source](../examples/learn/06-floats.zc): + +```zc +fn put_f(x) { asm { x @ #1220 } return 0; } +fn main() { + let a = 1.5; + put_f(a + 2.5); put_c(10); + return 0; +} +``` + +output: + +```text +4.000000 +``` + +### byte addresses + +`addr_b(p)` converts a word address to a byte address; `addr_w(b)` converts back. `ld8`, `ld16`, and `ld32` load little-endian values; `st8`, `st16`, and `st32` store them. byte addresses name the same memory as word addresses. + +this example stores `0x11` in the low byte and `0x22` in the next byte. the resulting word is `0x2211`, or 8721. + +[example source](../examples/learn/07-bytes.zc): + +```zc +fn main() { + let w = 0; + st8(addr_b(&w), 0x11); + st8(addr_b(&w) + 1, 0x22); + put_n(ld8(addr_b(&w))); put_c(32); put_n(w); put_c(10); + return 0; +} +``` + +output: + +```text +17 8721 +``` + +### packed byte strings + +`"text"` is a word string: one character per word, followed by a zero word. `b"text"` is a packed byte string: a length word, then eight characters per word and a terminating zero byte. write the `b` directly against the quote. + +for byte strings, `len`, indexing, and `put_s` use the packed representation. indexing reads a byte and cannot be assigned through. `+` concatenates strings, `s[i:j]` makes a slice with an exclusive end, and comparisons order unsigned bytes. `s_to_n` parses an integer; `n_to_s` creates a byte string containing its decimal form. + +[example source](../examples/learn/08-byte-strings.zc): + +```zc +fn main() { + let name = b"zc"; + let hi = b"hello, " + name; + put_s(hi); put_c(10); + put_n(len(hi)); put_c(32); + put_n(s_to_n(b"40") + 2); put_c(10); + return 0; +} +``` + +output: + +```text +hello, zc +9 42 +``` + +## ownership and the heap + +### shared cells + +`cons(a, b)` creates an immutable pair, read with `car` and `cdr`. `triple` and `tget` do the same for three values. several pointers may share a cell. `share(p)` publishes an existing object, and `is_shared(p)` reports whether it is shared. + +`free` leaves shared cells intact. `gc()` reclaims them once no root points to them, including cycles. `scrub()` clears unused stack words that would otherwise look like roots. here, `left` and `right` share the same tail. + +[example source](../examples/learn/09-shared.zc): + +```zc +fn main() { + let tail = cons(1, 2); + let left = cons(tail, 3); + let right = cons(tail, 4); + put_n(car(car(left))); put_c(32); + put_n(car(left) == car(right)); put_c(10); + return 0; +} +``` + +output: + +```text +1 1 +``` + +### owned objects + +binding a fresh `new` result to a local makes that local its owner. the analyzer inserts a free when the scope ends and reports an owned object that is never used. you normally do not write the free yourself. + +`int*` is a pointer to an integer. `*p` accesses that integer. + +[example source](../examples/learn/10-owned.zc): + +```zc +fn main() { + int* p = new(int); + *p = 7; + put_n(*p); put_c(10); + return 0; +} +``` + +output: + +```text +7 +``` + +### moving ownership + +tags describe where an owned object goes: + +- `.m` keeps it in the current block. +- `.d` hands it down to a callee or container; the previous owner cannot use it afterward. +- `.u` hands it up through a return, block value, or assignment to an enclosing scope. + +`m*p`, `d*p`, and `u*p` recast the tag. a plain parameter lends the object without transferring ownership; `.m` on a parameter adds a checked borrow. `free(d*p)` hands the object to `free`. an owned result can be declared with `.u` or inferred from its return. + +[example source](../examples/learn/11-tags.zc): + +```zc +int*.u box(int v) { int* b = new(int); *b = v; return u*b; } +fn main() { + int* p = box(4); + put_n(*p); put_c(10); + return 0; +} +``` + +output: + +```text +4 +``` + +### aliases + +a pointer derived from an owner is an alias. pointer arithmetic, pointer fields, and pointer elements retain the relationship to that owner. an alias can be copied or passed to a call, but it does not free the object at scope end. using it after its owner is handed away is an error. + +in this example, `a` owns `b` after `a.next = b`, and `c` borrows the child. indexing an untyped word array is not tracked as a pointer operation. + +[example source](../examples/learn/12-aliases.zc): + +```zc +struct node { int v; node* next; }; +fn main() { + node* a = new(node), b = new(node); + a.v = 3; b.v = 4; a.next = b; + node* c = a.next; + put_n(c.v); put_c(10); + return 0; +} +``` + +output: + +```text +4 +``` + +### runtime memory checks + +`unchecked fn` and `unchecked { }` disable lifetime analysis for their scope. allocations there rely on the collector. checked variables cannot be accessed from an unchecked block. + +`memdebug on;` adds runtime checks for heap loads and stores, use after free, and double free. `memreport()` lists live allocations made while debugging was on. the allocation line below is the line containing `new`; the reported size is the buddy block's payload capacity. + +`memdebug scrub;` also fills freed payloads with `0xDEAD`; `memdebug off;` disables debugging. ordinary `free` quarantines an owned block until collection can safely reuse it. stale contents surviving quarantine are not permission to use a dead object. + +[example source](../examples/learn/13-memdebug.zc): + +```zc +memdebug on; +int* g; +fn main() { + int* p = new(int); + *p = 1; + g = d*p; + put_n(memreport()); + put_c(10); + return 0; +} +``` + +output: + +```text +leak: line 4 3 words +1 +``` + +## libraries and the host + +### including a library + +`include "src/lib/std.zc";` reads and compiles that file at the include. place it before code that uses the library. the path is relative to the process's working directory. + +the library groups related helpers in structs and calls them as `Group.name(args)`. for example, `Text.itoa` writes a decimal integer into a caller-provided word-string buffer. + +[example source](../examples/learn/14-include.zc): + +```zc +include "src/lib/std.zc"; +fn main() { + let s = readfile("tests/data/hi.txt"); + put_n(len_w(s)); put_c(10); + free(d*s); + return 0; +} +``` + +output: + +```text +6 +``` + +### text and number helpers + +`Text` provides word-string parsing, formatting, copying, search, and case conversion. `Num` provides helpers such as `gcd`, `pow`, `isqrt`, and `clamp`. `Bytes` provides packed-string helpers. `Host`, `File`, `Arena`, and `Buf` cover host services, files, allocation arenas, and byte buffers. + +check the signatures in `src/lib/std.zc` before passing a buffer: many text functions write into storage supplied by the caller. + +[example source](../examples/learn/20-text-num.zc): + +```zc +include "src/lib/std.zc"; +fn main() { + put_n(Num.gcd(12, 18)); put_c(32); put_n(Num.pow(2, 10)); put_c(32); put_n(Num.isqrt(50)); put_c(10); + put_n(Text.atoi("123") + 1); put_c(10); + return 0; +} +``` + +output: + +```text +6 1024 7 +124 +``` + +### host services + +`syscall(op, a, b, c)` passes a request through the vm's syscall gate. the runtime defines names such as `SYS_OPEN`, `SYS_READ`, `SYS_WRITE`, `SYS_GETENV`, and `SYS_TIME`. unsupported operations return -1. `Host.now()` wraps the clock request. + +`getenvs(name)` returns a fresh word string or 0. the library also supplies `argc`, `argv`, `envc`, and `envp`; a program read on stdin has `` as its first argument. gate calls must be made from ordinary code, outside an `o3` region. + +[example source](../examples/learn/21-host.zc): + +```zc +include "src/lib/std.zc"; +fn main() { + put_n(Host.now() > 0); put_c(10); + return 0; +} +``` + +output: + +```text +1 +``` + +### raw linux syscalls + +`Host.raw` uses the kernel's own syscall number and argument convention. it returns the result or a negated errno. the syscall numbers differ by architecture: this example uses x86-64 linux `getpid`, number 39. + +this path bypasses the vm's syscall checks. pointer arguments must use the host addresses required by that syscall. the example does not take pointer arguments and is skipped on other hosts. + +[example source](../examples/learn/22-raw-x86.zc): + +```zc +include "src/lib/std.zc"; +fn main() { + put_n(Host.raw(39, 0, 0, 0, 0, 0, 0) > 0); put_c(10); + return 0; +} +``` + +output: + +```text +1 +``` + +### input after the source + +a backtick outside a comment or literal ends the source unit. bytes after it are the program's input, read with `get_c`. `eof()` reports the end. this complete file includes both the program and the input `abc`; the program reads only the first two characters. + +[example source](../examples/learn/24-backtick.zc): + +```zc +fn main() { + put_c(get_c()); put_c(get_c()); put_c(10); + return 0; +} +`abc +``` + +output: + +```text +ab +``` + +### calling c + +`extern` declares a native function with its c types. `cfunc(f)` produces a native function pointer so c can call back into zc. use `word*` for a pointer to vm words, `char*` for the byte-string convention of a native c signature, and `double` for a zc float. + +this example calls `sqrt`, then calls `qsort` with a zc comparison callback. native calls require the full native core; the microcore and javascript runtime do not implement them. struct arguments have additional abi restrictions described in the reference. + +[example source](../examples/learn/23-c-abi.zc): + +```zc +fn put_f(x) { asm { x @ #1220 } return 0; } +extern double sqrt(double); +extern void qsort(word *base, long n, long size, void *cmp); +int cmp(int* a, int* b) { return *a - *b; } +fn main() { + let a[4]; + a[0] = 5; a[1] = 3; a[2] = 9; a[3] = 1; + put_f(sqrt(2.0)); put_c(10); + qsort(a, 4, 8, cfunc(cmp)); + put_n(a[0]); put_c(32); put_n(a[1]); put_c(32); put_n(a[2]); put_c(32); put_n(a[3]); put_c(10); + return 0; +} +``` + +output: + +```text +1.414214 +1 3 5 9 +``` + +## types and containers + +### arrays and methods + +`[n]T` is an array stored in place. `[]T` is a growable handle that owns its items, created with `new([]T)` or `new([]T, n)`. `push`, `pop`, `resize`, `len`, and `cap` operate on it. `fixed []T` has a length that cannot change. + +struct methods receive a hidden `this` parameter: `p.get()` passes `p`. static functions belong to the struct and are called as `cnt.make()`. freeing a container also frees its owned children. + +[example source](../examples/learn/19-growable.zc): + +```zc +struct cnt { + int n; + static int make() { return 3; } + int get() { return this.n; } +}; +fn main() { + []int xs = new([]int); + push(xs, 4); push(xs, 5); + put_n(len(xs)); put_c(10); + put_n(pop(xs)); put_c(10); + put_n(cnt.make()); put_c(10); + return 0; +} +``` + +output: + +```text +2 +5 +3 +``` + +### generic functions and structs + +type parameters follow the name: `record` and `keyof`. the compiler creates a distinct function instance for each set of concrete types. you can supply type arguments explicitly or infer them from the call. + +`record` stores its `point` field in place. inside an instantiated function, `sizeof` uses the concrete type. a generic body is checked when it is instantiated, so an unused template can contain a mistake that has not been reported yet. + +[example source](../examples/learn/15-generics.zc): + +```zc +struct record { K key; V val; }; +struct point { int x; int y; }; +K keyof(record* r) { return r.key; } +fn main() { + record* r = new(record); + r.key = 9; + put_n(keyof(r)); put_c(10); + return 0; +} +``` + +output: + +```text +9 +``` + +### tagged enums and matching + +an enum member can carry fields written as a block. a constructor such as `shape.circle(3)` returns an owned `shape*`. word 0 holds the member tag; the remaining words hold its payload. + +`case circle(r):` matches the tag and binds `r` only in that arm. a switch that misses a member without a `default` produces a warning. release or return the value according to the ordinary ownership rules. + +[example source](../examples/learn/16-tagged-enums.zc): + +```zc +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +int area(shape* s) { + switch (s) { + case circle(r): return r * r * 3; + case rect(w, h): return w * h; + case dot: return 0; + } + return -1; +} +fn main() { + shape* s = shape.circle(3); + put_n(area(s)); put_c(10); + free(d*s); + shape* t = shape.rect(2, 5); + put_n(area(t)); put_c(10); + free(d*t); + return 0; +} +``` + +output: + +```text +27 +10 +``` + +## optimized regions + +### requesting native optimization + +`o3` can mark a function, block, or variable. the compiler emits a region for the full core to optimize and compile into native code. the microcore and javascript runtime execute the ordinary bytecode fallback. + +inside a region, locals and parameters must be typed. promoted variables have no address, so `&x` is not allowed for one. gate calls and closures are restricted. an untyped `new(n)` is zeroed without a type stamp. the fixed array below keeps its length, while the optimized block counts 143 matching integers. + +[example source](../examples/learn/18-o3.zc): + +```zc +o3 int sum(fixed []int a) { int s = 0; for (int i = 0; i < len(a); i++) s += a[i]; return s; } +fn main() { + fixed []int a = new(fixed []int, 5); + for (int i = 0; i < 5; i++) a[i] = i * i; + put_n(sum(a)); put_c(10); + o3 int hits = 0; + o3 { for (int i = 0; i < 1000; i++) if (i % 7 == 3) hits++; } + put_n(hits); put_c(10); + return 0; +} +``` + +output: + +```text +30 +143 +``` + +## closures + +### capturing a value + +`fn(x) { ... }` in an expression creates an owned closure. it copies the variables it uses from the surrounding function when it is created. calls use ordinary function syntax. + +bind a closure to a local before lending it to a plain parameter. to return an owned closure, use an owned return such as `return u*f;`; the result tag can be inferred or declared as `.u`. + +[example source](../examples/learn/25-closures.zc): + +```zc +fn apply(f, x) { return f(x); } +fn main() { + let k = 10; + let add = fn(x) { return x + k; }; + put_n(add(1)); put_c(10); + put_n(apply(add, 5)); put_c(10); + return 0; +} +``` + +output: + +```text +11 +15 +``` + +### nested captures and mutable state + +a nested closure can capture a variable from more than one enclosing function. each enclosing closure carries the values needed by the next one. + +captures are by value, but a closure can change its own copy. `tick` keeps its counter between calls; the `count` in `main` stays 0. changing closure state does not write back into the function that made it. + +[example source](../examples/learn/26-closure-state.zc): + +```zc +fn main() { + let base = 2; + let outer = fn(x) { + let inner = fn(y) { return y + base + x; }; + return inner(100); + }; + put_n(outer(7)); put_c(10); + let count = 0; + let tick = fn(d) { count = count + d; return count; }; + put_n(tick(1)); put_c(32); put_n(tick(4)); put_c(10); + put_n(count); put_c(10); + return 0; +} +``` + +output: + +```text +109 +1 5 +0 +``` + +## the optional typechecker + +`typecheck on;` enables type checking for the declarations that follow; `typecheck off;` disables it. errors report the expected and actual types. the lifetime analyzer runs independently of this switch. a literal 0 can be a null pointer, `word` matches any type, and arrays can decay to pointers. + +## further reading + +[README.md](../README.md) is the full reference. `tests/` contains runnable feature checks, `tests/errors/` contains rejected lifetime examples, and `tests/typeerrors/` contains rejected type examples. `docs/design/` explains implementation decisions; `docs/history/` records earlier versions. + +use `make check` while editing and `make test` for the full available suite. enable `ZYTRACE=1` to inspect native translation, or `ZYHOT=1` on an llvm build to compile each block as early as possible. diff --git a/docs/design/adt.md b/docs/design/adt.md new file mode 100644 index 0000000..2011337 --- /dev/null +++ b/docs/design/adt.md @@ -0,0 +1,19 @@ +# tagged enums + +tagged enums let one pointer refer to a value with one of several payload shapes. a member with fields is declared using a block of field declarations; a member without fields has no block: + +```zc +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +int area(shape* s) { + switch (s) { + case circle(r): return r * r * 3; + case rect(w, h): return w * h; + case dot: return 0; + } + return -1; +} +``` + +each constructor allocates an owned enum object and returns a pointer. word zero stores the tag; payload fields follow it. the object is sized for the largest member, and unused payload words are zeroed. a `case member(names)` arm tests the tag and binds that member's fields as locals scoped to the arm. a member omitted from a switch without `default` produces a warning, in typed and untyped code. + +see [the tagged enum example](../../examples/learn/16-tagged-enums.zc). the syntax and behavior described here are implemented by the parser, typechecker, code generator and language server. diff --git a/docs/design/handoff.md b/docs/design/handoff.md new file mode 100644 index 0000000..0b08048 --- /dev/null +++ b/docs/design/handoff.md @@ -0,0 +1,20 @@ +# implementation notes + +this note summarizes implemented language and tooling features that were previously tracked across design documents. feature details live in the project readme and examples. + +## language and library + +- struct methods and static functions support typed parameters and return types. the existing untyped form remains available. +- `src/lib/std.zc` groups helpers in structs of static functions, called with `Group.name(args)`. `Text`, `Bytes`, `Host`, `Arena` and `Buf` provide string, byte, host, arena and buffer helpers. linux `syscall` is host-only and bypasses vm checks. +- tagged enums support payload members, constructors that return owned enum pointers, and `case member(fields)` bindings in ordinary `switch` statements. omitted members produce a warning when there is no `default`. +- struct values can cross native calls on x86-64 sysv and linux arm64 aapcs64 for the interpreter, o3, llvm and jit paths described in the readme. apple arm64 remains unchecked. + +## language server + +the language server runs the compiler in check mode, so diagnostics and semantic highlighting use the same parser and symbol tables as compilation. hover supports declarations, parameters, locals, built-ins and documented keywords. it does not follow declarations reached through `include` yet. + +## optimization + +o3 remains the explicit way to request native regions; automatic tiering was dropped. llvm inlining and global copy propagation are implemented. see [tiering](tiering.md) for the rationale and [struct-by-value](struct-by-value.md) for native aggregate limits. + +the runtime memory map is generated from a preset. fixed code and compiler tables have finite capacity; the heap grows within the configured machine memory. see the project readme's memory map section for the current build controls. diff --git a/docs/design/memory.md b/docs/design/memory.md new file mode 100644 index 0000000..bcbdf35 --- /dev/null +++ b/docs/design/memory.md @@ -0,0 +1,106 @@ +# memory configuration + +## one image and one layout + +the compiler, runtime, and host must agree on their addresses. `genmap` writes a matching `memmap.h`, runtime source, and compiler source; `src/tools/automap.sh` builds an image against those files. rebuild the host against the generated headers. changing a header alone does not relocate an existing genome. compact compiler and run-only maps also put their heap above the fixed regions, so compiler storage can grow after startup. + +```sh +bin/genmap --preset default --check +bash src/tools/automap.sh small build/small +bin/genmap --preset default --code 65536 --symbols 256 --locals 64 --fwd 512 --pool 8192 --hash 1024 -o build/custom +``` + +run `bin/genmap --help` for the table, heap, genome, and stack options. sizes are in vm words unless an option says otherwise; one word is eight bytes. `--snap-cap` selects the initial snapshot reservation and `--quote-cap` selects an initial token count, with three words per token. both regions grow after startup. + +## layout inventory + +the generated addresses reserve initial storage. native code-address tables start at `PW` and grow together when code needs new addresses; the microcore and javascript execute within their mapped memory. every host must use the same layout as its image. + +| region | build control | runtime behavior | +| --- | --- | --- | +| initial emitted program, through `CODE_END` | `--code` | links stable heap segments when full | +| type arena below `ZFP` | `--types` | stable type chunks and a growing index | +| compiler names and columns | `--hash`, `--pool`, `--symbols`, `--locals`, `--fwd` | grow independently | +| compiler scratch regions | `--snap`, `--quote`, `--src`, `--seq`, `--ctx`, `--loop` | grow independently | +| enum members, tagged-enum index, struct methods, generated source | `--enum-members`, `--tagged-enums`, `--methods`, `--generated-text` | grow independently | +| operator columns | `--binary`, `--unary`, `--assignments`, `--keywords` | grow independently | +| assembly labels and patches at `R_ASM` | `--asm-labels`, `--asm-refs` | columns grow | +| exit storage at `R_EXIT` | `--exit` | grows | +| genome reservation, from `GORG` to `FBOT` | `--genome` | existing image addresses stay fixed | +| frame region, from `FBOT` to `FTOP` | `--frame` | adds stable heap segments | +| return region, from `RS0` to `MARK0` | `--return` | copies live return addresses to larger storage | +| collector work at `MARK0` | `--mark` | grows during collection | +| data region, from `DSLO` to `DSHI` | `--data` | copies live operands to larger storage | +| initial heap | `--heap`, `--heap-lo` on compact maps | grows when the host supports it | +| total host memory | `--total`, host startup options | growth limit can change during execution | + +`--words` selects the fixed-map size; unused words extend the initial data region. `--total` selects the host reservation for a growing map. inside `genmap`, the fixed-map size is called `MW` and the host reservation `TW`; generated headers name them `PW` and `MW`. `HEAP_HI` is the initial heap end, not its eventual limit. `SYSGATE` stays at `ZFP + 2`, and the linked image supplies `GORG`. + +parameter tags, native calling conventions, packed token positions, and opcode formats also have limits. these describe the language or machine interface; they are separate from the storage capacities above. their parser buffers grow independently; for example, an enum index can grow while one tagged enum keeps its 63-member exhaustiveness mask. function parameter tags and generic arity retain their current encoding. packed token positions retain a 24-bit line, 16-bit token length, and 21-bit byte offset; this is an encoding constraint, not a growing buffer. + +## compiler tables during execution + +the generated layout supplies initial storage. the following tables grow when they fill: + +| storage | growth behavior | explicit reservation | +| --- | --- | --- | +| symbols and their types | copy columns; symbol indices stay valid | `reserve_symbols(n)` | +| locals and analyzer facts | copy every local column | `reserve_locals(n)` | +| forward references | copy patch columns; links retain indices | `reserve_fixes(n)` | +| intern hash | rehash pointers; interned spellings stay at their old addresses | `reserve_names(n)` | +| string pool | add larger chunks; old handles and symbol-chain heads stay valid | `poolchunk` sets the next chunk's minimum size | +| type records and type index | add stable chunks and grow the index | automatic | +| loop-range facts, joined paths, queued o3 regions | copy records before appending; build controls are `--facts`, `--paths`, `--regions` | automatic | +| analyzer snapshots and exits | copy storage; saved offsets stay valid | `reserve_R_SNAP(n)`, `reserve_R_EXIT(n)` | +| source, loop, and compiler-context stacks | copy complete frames | `reserve_R_SRC(n)`, `reserve_R_LOOP(n)`, `reserve_R_CTX(n)` | +| quote tokens and operator sequences | copy storage before appending | `reserve_R_QBUF(n)`, `reserve_R_SEQ(n)` | +| emitted code | link stable heap segments; code addresses remain valid | `reserve_code(n)`, `code_chunk` | +| operator columns | copy columns before adding an operator | `reserve_binary(n)`, `reserve_unary(n)`, `reserve_assignment(n)`, `reserve_operators(n)` | +| execution frames | add segments without moving older local addresses | `reserve_frames(n)` | + +reservation functions take minimum capacities and round upward. they can be called by running programs or immediate functions. scratch reservations count words; source frames use 32 words, loop frames use eight, and compiler contexts use 34. local and symbol capacities count entries. the intern hash stays a power of two and grows before it is half full. + +new chunks and columns are collector roots. garbage collection can reclaim replaced heap columns, while chunk chains retain interned text and type records for the current compiler state. fixed map storage remains reserved; growing a table does not reuse another map region. + +## language server + +document slots, uri text, hover text, declaration types, parsed type spans, resolved names, comment ranges, and diagnostics grow independently. hint deduplication uses a growing set of source positions. local name lookup uses growing name heads and shadow links; leaving a scope restores its previous bindings. a large source file must not lose its later diagnostics because earlier hints filled a buffer. the editor bundle must be rebuilt when the server changes; packaging always rebuilds its image. + +inference function records retain stable addresses while their index grows. inference edits, replacement text, and annotation verification buffers also grow; later declarations are not dropped at the original function-count or edit-count limits. protocol method names, request identifiers, json keys, nesting paths, and header lines also grow; request identifiers are echoed in full. + +## freestanding backing + +the stub and board ports reserve `MICRO_PORT_WORDS` cells at build time; it defaults to the initial image and heap size. the vm's active size and growth limit still change at runtime, within that physical backing. set the macro when linking a board with more reserved ram. a rejected physical allocation preserves the current memory. hosted maps keep their heap above the fixed regions; the historical `fixed` preset retains its bounded layout for compatibility. + +## host memory and image storage + +the default native map places a growing heap above the fixed regions. hosted runners accept `TINYVM_MEMORY_WORDS` for initial memory and `TINYVM_MAX_MEMORY_WORDS` for its growth limit. javascript also accepts `memoryWords` and `maxMemoryWords` when constructing a vm. invalid configurations are rejected before execution. + +```sh +TINYVM_MAX_MEMORY_WORDS=16777216 bin/zy < examples/hello.zc +TINYVM_MEMORY_WORDS=4194304 bin/zym < examples/hello.zc +``` + +the native core reserves a stable backing allocation up to its startup maximum; increasing the available size keeps addresses and native code pointers valid. the microcore and javascript vm replace backing allocations when they grow, preserving existing contents. native bounds use the reservation; portable bounds use the current allocation. memory syscall `9` with argument `4` requests growth, and argument `5` changes the growth limit during execution. a limit cannot fall below the current size. the native limit cannot exceed its startup reservation. + +data and return stacks grow automatically before their guard space is exhausted. `reserve_data(n)` and `reserve_returns(n)` request minimum capacities during execution; failure returns `-1` and preserves the old stack. live operands and return addresses are copied before old heap storage is returned to its free list. locals remain in frame storage, so pointers into locals keep their addresses. raw indices returned by `dsp()` describe the current operand stack and must be read again after a reservation. + +the host takes stack blocks directly from the runtime's buddy free lists. it does not call vm code or collect while servicing an overflow. when it needs another heap extent, the host's configured memory limit still applies. newly allocated stack blocks are excluded from user-object counts and are protected if collection is already running. operand-stack roots use the current stack's live range. + +frame segments grow on the heap, preserve pointers into older frames, and return empty segments to the allocator. collection scans only the live ranges of each segment. `frame_chunk` controls the minimum size of the next segment; `reserve_frames(n)` raises it. the growth helper uses a guard region to allocate without recursively growing its own frame. program emission links new segments through `reserve_code(n)`, with `code_chunk` controlling their minimum size. earlier functions and globals retain their addresses. strings, quotes, global arrays, and enhancement recipes reserve contiguous storage. + +optimizer regions that cross a segment boundary run as ordinary bytecode. image output grows independently through `build_image_grow(org, initial)`; its length is returned, and `image_words` and `image_size` expose its output. `build_image(org, dst)` retains the explicit-destination interface. a finished artifact still needs a host layout whose genome reservation fits it; `src/tools/automap.sh` sizes that reservation before linking. + +assembly columns, enum members, tagged-enum indices, struct methods, and generated source grow. native program-address metadata grows through memory syscall `9`, argument `9`; a denied request preserves the previous tables. annotation records and edit buffers also grow, within the host’s configured memory limit. generated initial addresses remain part of the image format; language and machine-interface limits do not change when storage grows. + +mark work grows through `reserve_mark(n)`, including during a collection. generic templates and instances grow through `reserve_generics(n)` and `reserve_instances(n)`. closure frames and capture rows grow through `reserve_closures(n)` and `reserve_captures(n)`. lexer text, documentation text, and stored signatures also grow. documentation objects keep stable addresses, and compiler storage is excluded from `live_objects()`. + +## verification + +`tests/drivers/compiler_growth_test.py` checks locals, distinct array types, long names, generic records, captures, and collector work, then reserves larger tables and scratch stacks and runs collection. `tests/drivers/frame_growth_test.py` checks deep recursion, oversized frames, and collection with a pointer into an older segment. `tests/drivers/inference_growth_test.py` checks 600 functions and 5000 local declarations. `tests/drivers/core_lsp_test.js` opens every maintained core zc source through the editor protocol and checks diagnostics and highlighting. `tests/drivers/memory_limits_test.py` checks startup validation and runtime growth on the native, microcore, and javascript hosts. a bootstrap fixpoint alone does not verify runtime growth. collection is conservative: code literals can resemble heap addresses, particularly on compact maps, so reclamation counts can differ between layouts. checks must verify collection progress and retained roots without assuming identical counts. + +## bootstrap storage + +stage 0 reads source and grows its temporary image buffer on the host. `MAXW`, when supplied at build time, selects an initial image reservation; it is not a final size limit. the resident compiler builds images with `build_image_grow(org, initial)` and returns their current buffer through `image_words`. image output is temporary storage, so it can move while the logical addresses recorded in the image stay unchanged. a matching generated layout must still fit the finished artifact before it is loaded. + +vm literals carry 63 signed bits in a single odd word. the compiler emits a short sequence for other 64-bit values; float payloads use their own full word. `setlit` patches one encoded word and requires a value that fits that single-word format. diff --git a/docs/design/storage-analysis.md b/docs/design/storage-analysis.md new file mode 100644 index 0000000..59fbcde --- /dev/null +++ b/docs/design/storage-analysis.md @@ -0,0 +1,33 @@ +# bounds and lifetime findings + +## what the compiler knows + +the compiler records constant element counts for `new(n)`, `new(T, n)`, fixed arrays, and newly created array handles. a direct local alias shares the allocation's facts. a definite `free` or `recycle` ends that allocation's lifetime; closing a scope ends its stack storage and automatically released owned objects. + +an index outside a known length produces a warning. dereferencing, indexing, or accessing a field after a recorded lifetime end also produces a warning. these findings apply to unchecked code too. existing ownership errors and fixed-array index errors keep their current behavior. warnings do not prevent compilation. + +```zc +unchecked fn example() { + let p = new(int, 3); + let q = p; + q[3] = 1; // warns: index 3 is outside length 3 + free(p); + return q[0]; // warns: this allocation was freed +} +``` + +## what stays unknown + +this is basic analysis of local facts, not a proof of the whole program. branches, loops, short-circuit operators, raw assembly, and nested compilation discard facts instead of merging uncertain paths. unknown callees invalidate facts about allocations passed to them. array mutations invalidate recorded lengths. pointer arithmetic, explicit casts, pointer-valued fields, stored aliases, and function return contracts are not inferred by this pass. + +an unknown fact does not produce a definite warning. runtime array checks still run. the pass may miss an error across one of these boundaries; silence is not a safety guarantee. the broader analysis in [BORROW.md](../BORROW.md) remains a design plan. + +## editor previews + +array and pointer hovers show the known element count and lifetime at that reference. a live stack allocation names its scope exit as its lifetime end. a live heap allocation ends when freed or released by its owner. a reference after a recorded end names that line. unavailable sizes and lifetimes say `unknown`. + +facts are copied into each reference's editor record while the compiler parses it. a later `free` therefore does not make an earlier hover claim the object was already dead. block comments and inferred type text remain part of the same markdown preview. + +## focused checks + +`node tests/drivers/storage_analysis_test.js bin/zclsp` checks known bounds, packed elements, direct aliases, free and scope lifetimes, hover metadata, and safe or uncertain neighboring cases. diff --git a/docs/design/struct-by-value.md b/docs/design/struct-by-value.md new file mode 100644 index 0000000..bbc8f26 --- /dev/null +++ b/docs/design/struct-by-value.md @@ -0,0 +1,9 @@ +# structs in native calls + +zc structs whose fields are one word each (`int`, `float` or pointers) can be passed by value to `extern` functions, and native functions can return structs. the interpreter, o3, llvm and jit paths support sysv x86-64 and linux arm64 aapcs64. apple arm64 is not verified. + +arguments are classified according to the host ABI. on sysv x86-64, structs up to 16 bytes use integer or sse registers when the whole value fits; otherwise they go on the stack. larger structs go on the stack. on aapcs64, homogeneous float structs of up to four words use v registers, integer structs of up to two words use x registers, and other arguments follow the platform ABI. + +returns are limited to seven words. the call stub allocates an owned zc object and passes its address through the call block; the native ABI determines how the result is filled. the llvm descriptor path does not handle grouped struct signatures, so these calls use the generic native-call path. + +see `tests/programs/structval.zc` and `tests/programs/structret.zc` for executable examples. platform-specific behavior beyond x86-64 sysv and linux arm64 aapcs64 remains unverified. diff --git a/docs/design/tiering.md b/docs/design/tiering.md new file mode 100644 index 0000000..21a74c9 --- /dev/null +++ b/docs/design/tiering.md @@ -0,0 +1,7 @@ +# automatic tiering + +automatic tiering was dropped. the `o3` keyword remains the explicit way to request an optimized native region. + +tiering would require runtime information the compiler currently records only for `o3` functions, including frame layout, address-taken slots, arrays and argument placement. `o3` also uses a different calling convention for dynamic arrays and enforces compile-time restrictions such as closure and gate-store limits. promoting an ordinary function would therefore need either a uniform calling convention, duplicate compiled versions with call-site switching, or equivalent runtime checks. + +keeping `o3` explicit avoids those changes. the existing optimization work—including direct `o3` calls, llvm inlining, global constant and copy propagation, loop-invariant code motion and cross-block common-subexpression elimination—remains available. diff --git a/docs/history/01-golf/notes.md b/docs/history/01-golf/notes.md new file mode 100644 index 0000000..f8c8b5d --- /dev/null +++ b/docs/history/01-golf/notes.md @@ -0,0 +1,10 @@ +# the golfed vm + +no code from this stage survives except where a code/ folder sits next to this file. these are the notes as they were written in the transcript. + +## message 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. diff --git a/docs/history/02-hardware/notes.md b/docs/history/02-hardware/notes.md new file mode 100644 index 0000000..e5ad911 --- /dev/null +++ b/docs/history/02-hardware/notes.md @@ -0,0 +1,46 @@ +# closer to hardware + +no code from this stage survives except where a code/ folder sits next to this file. these are the notes as they were written in the transcript. + +## message 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. + +## message 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 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. diff --git a/docs/history/05-hybrid/notes.md b/docs/history/05-hybrid/notes.md new file mode 100644 index 0000000..e111cec --- /dev/null +++ b/docs/history/05-hybrid/notes.md @@ -0,0 +1,9 @@ +# the assembler in assembly, and the hybrid compiler + +no code from this stage survives except where a code/ folder sits next to this file. these are the notes as they were written in the transcript. + +## message 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. diff --git a/docs/history/06-choosing/notes.md b/docs/history/06-choosing/notes.md new file mode 100644 index 0000000..1b9be6b --- /dev/null +++ b/docs/history/06-choosing/notes.md @@ -0,0 +1,10 @@ +# picking a favorite + +no code from this stage survives except where a code/ folder sits next to this file. these are the notes as they were written in the transcript. + +## message 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. diff --git a/docs/history/07-zygote/code/README.md b/docs/history/07-zygote/code/README.md new file mode 100644 index 0000000..924c48b --- /dev/null +++ b/docs/history/07-zygote/code/README.md @@ -0,0 +1,168 @@ +# 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 jit-compiles vm code to arm64, and the assembler lives in vm memory next to the program, where the program can modify it. + +this folder only has the latest code. earlier stages are described in the transcript below, but their code isn't included. + +## files + +`core.c` is the native core. it holds the arm64 jit, the stubs and the invalidation logic, and is the only native code in the system. `gen.s` is the genome header and boot loader, in vm assembly. `aslib.s` is the assembler, written in vm assembly. `mkgenome.c` is a build tool that assembles `gen.s` + `aslib.s` at address 48000 into `genome.h`, which is the generated result and is checked in. `repl.s` is a demo that mutates the resident assembler and repeatedly assembles and runs input chunks. `io_linux.c` is the `Q`/`G`/`J` test harness. `test.sh` builds for arm64 linux and runs everything under qemu. `examples/` has hello, a recursive factorial (prints in binary), echo, a self-patching test, and `asmain.s`, the standalone wrapper that turns `aslib.s` into a stdin-to-stdout assembler. + +## build + +``` +cc -o mkgenome mkgenome.c && cat gen.s aslib.s | ./mkgenome >genome.h # only after changing gen.s or aslib.s +cc -O2 core.c io.c -o zy # io.c provides char Q(void), void G(char), and J +./zy >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. the data stack grows down from 65000 and the return stack grows up from 60000. + +``` +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. + +assembler syntax uses whitespace-separated tokens. `:name` defines a label, a single op character is that opcode, `"text` emits raw characters, `#x` emits a raw number or label address, and anything else becomes a literal push of a number or label. when a label is defined twice, the last definition wins. a label nobody references emits nothing, so `:;like_this` works as a comment. + +## memory map and abi + +``` +0.. the program (assembled at origin 0 by the boot loader) +20000..44999 boot source buffer, one char per word (free after boot) +45000..47999 boot label table (free after boot) +48000 genome: 48000 boot, 48002 a.run (call with 48002 c), + 48004 &a.src 48005 &a.dst 48006 &a.org 48007 &a.lab 48008 &a.n 48009 &a.ops +60000 up return stack +65000 down data stack +``` + +to use the resident assembler, store a source address into `48004 @`, the destination into `48005 @`, the run-at origin into `48006 @` and a label scratch area into `48007 @`, then do `48002 c`. the word count ends up in `48008 @`. `48009 @` points to the mnemonic table `q@!$_~cjzr,?.+-*&|^><`, which you can rewrite. boot limits: the program has to fit in 20000 words and the source in 25000 chars. + +## 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 only. 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. + +differences from the golfed reference vm, which leaves all of these undefined: shift counts wrap at 32, stores outside memory are ignored, and jumping outside memory halts. + +## test results (linux arm64 via qemu) + +everything in `test.sh` passes: hello, factorial, echo after the backtick, self-patching that matches the golfed vm byte for byte, the self-hosted assembler running on the zygote and producing the same bytes as the c assembler, and the repl that prints `hi` and then `yo` from two chunks assembled into the same address. the trace shows the first chunk's translation being dropped. earlier in the session, `asm.s` running on the zygote reproduced the c assembler's output for its own source too. a 20 million iteration loop took 0.54 s on the zygote against 2.18 s for the golfed vm interpreter under the same qemu, and that 0.54 includes assembling the source at startup. + +## open ends + +- the llvm ir port was asked for and then dropped in favor of the zygote before any of it was written. +- the assembler library uses globals, so it isn't re-entrant. code that it assembles at runtime shouldn't call it while an outer `a.run` is still running. +- translations are only reclaimed by a full flush, and the hook rescans the block list on every store to a covered word. that's fine unless code rewrites itself in a hot loop. +- none of the later stages are golfed. the golf-sized code is the reference vm and assembler from stage 2. + +--- + +## 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 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. diff --git a/docs/history/07-zygote/code/aslib.s b/docs/history/07-zygote/code/aslib.s new file mode 100644 index 0000000..fc36df8 --- /dev/null +++ b/docs/history/07-zygote/code/aslib.s @@ -0,0 +1,67 @@ +:;assembler_library +:;in:_a.src_source_text_one_char_per_word_zero_terminated +:;in:_a.dst_output_address_a.org_address_the_code_will_run_at_a.lab_label_scratch +:;out:_a.n_words_written +:a.run 0 a.pass ! 0 a.nl ! +:a.p0 a.src @ a.q ! 0 a.n ! +:a.lp a.skip c a.q @ @ 0 $ a.c ! a.pd z + a.c @ 34 - a.str z + a.c @ 58 - a.lbl z + a.q @ 1 + @ a.end c a.ch z + a.c @ a.op c 0 $ -1 ~ < a.ch1 z + 2 * a.emit c a.q @ 1 + a.q ! a.lp j +:a.ch1 _ +:a.ch a.c @ 35 - a.raw z + a.q @ a.val c 2 * 1 + a.emit c a.tend c a.lp j +:a.raw a.q @ 1 + a.val c a.emit c a.tend c a.lp j +:a.str a.q @ 1 + a.q ! +:a.s1 a.q @ @ 0 $ a.end c a.s2 z _ a.lp j +:a.s2 a.emit c a.q @ 1 + a.q ! a.s1 j +:a.lbl a.pass @ a.l1 z a.tend c a.lp j +:a.l1 a.q @ 1 + a.lab @ a.nl @ 2 * + ! + a.org @ a.n @ + a.lab @ a.nl @ 2 * + 1 + ! + a.nl @ 1 + a.nl ! a.tend c a.lp j +:a.pd a.pass @ a.p1 z r +:a.p1 1 a.pass ! a.p0 j + +:;(c_--_f)_true_for_whitespace_and_the_terminator +:a.end 0 $ 33 < ~ -1 ~ < & r +:;skip_whitespace_at_a.q +:a.skip a.q @ @ 0 $ a.sk1 z a.end c a.sk2 z a.q @ 1 + a.q ! a.skip j +:a.sk1 _ +:a.sk2 r +:;move_a.q_to_the_end_of_the_token +:a.tend a.q @ @ a.end c a.te1 z r +:a.te1 a.q @ 1 + a.q ! a.tend j +:;(w_--) +:a.emit a.dst @ a.n @ + ! a.n @ 1 + a.n ! r +:;(x_y_--_f)_compare_two_tokens +:a.eq a.y ! a.x ! +:a.e1 a.x @ @ a.end c a.y @ @ a.end c 1 $ 1 $ & a.e2 z _ _ 1 r +:a.e2 | a.e3 z 0 r +:a.e3 a.x @ @ a.y @ @ - a.e4 z 0 r +:a.e4 a.x @ 1 + a.x ! a.y @ 1 + a.y ! a.e1 j +:;(c_--_index_or_-1) +:a.op a.c ! 0 a.j ! +:a.o1 a.ops a.j @ + @ 0 $ a.o2 z a.c @ - a.o3 z a.j @ 1 + a.j ! a.o1 j +:a.o2 _ -1 r +:a.o3 a.j @ r +:;(q_--_v)_last_matching_label_else_decimal +:a.val a.t ! a.nl @ a.j ! +:a.v1 a.j @ a.vn z a.j @ 1 - a.j ! + a.lab @ a.j @ 2 * + @ a.t @ a.eq c a.v1 z + a.lab @ a.j @ 2 * + 1 + @ r +:a.vn a.t @ a.num j +:;(q_--_v)_like_atoi +:a.num a.x ! 0 a.neg ! 0 a.v ! + a.x @ @ 45 - a.n1 z a.x @ @ 43 - a.n2 z a.n3 j +:a.n1 1 a.neg ! +:a.n2 a.x @ 1 + a.x ! +:a.n3 a.x @ @ 48 - 0 $ 10 < 1 $ -1 ~ < & a.n4 z + a.v @ 10 * + a.v ! a.x @ 1 + a.x ! a.n3 j +:a.n4 _ a.v @ a.neg @ a.n5 z 0 ~ - +:a.n5 r + +:a.src #0 :a.dst #0 :a.org #0 :a.lab #0 :a.n #0 :a.pass #0 :a.nl #0 :a.q #0 +:a.c #0 :a.j #0 :a.t #0 :a.v #0 :a.neg #0 :a.x #0 :a.y #0 +:a.ops "q@!$_~cjzr,?.+-*&|^>< #0 diff --git a/docs/history/07-zygote/code/core.c b/docs/history/07-zygote/code/core.c new file mode 100644 index 0000000..41930f4 --- /dev/null +++ b/docs/history/07-zygote/code/core.c @@ -0,0 +1,276 @@ +/* zygote core: puts the genome (boot loader + assembler, both vm code) into + memory and runs it. 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 assembler, just gets retranslated on the next visit. + arm64 only (darwin or linux). ZYTRACE=1 logs translations on stderr. */ +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#include +#endif +#include "genome.h" + +#ifndef JTYPE +#define JTYPE char +#endif +char Q(void); +void G(char); +extern JTYPE J; + +#define MW 65536 +#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 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, trace; +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(0x7140401f); /* cmp w0, #65536 */ + 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(0x7140413f); /* cmp w9, #65536 */ + 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; +} + +int main(void) +{ + int p = GORG; + union { unsigned *u; int (*f)(long *, void *); } enter; + trace = getenv("ZYTRACE") != 0; +#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); + memcpy(m + GORG, genome, sizeof genome); + S[0] = (long)m; S[1] = 65000; S[2] = 60000; 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); + } + return 0; +} diff --git a/docs/history/07-zygote/code/examples/asmain.s b/docs/history/07-zygote/code/examples/asmain.s new file mode 100644 index 0000000..96d9658 --- /dev/null +++ b/docs/history/07-zygote/code/examples/asmain.s @@ -0,0 +1,9 @@ +:;standalone:_source_on_Q,_binary_on_G +4000 a.q ! +:m.rd ? m.ch z 0 a.q @ ! m.go j +:m.ch , a.q @ ! a.q @ 1 + a.q ! m.rd j +:m.go 4000 a.src ! 40000 a.dst ! 0 a.org ! 50000 a.lab ! a.run c 0 a.j ! +:m.out a.j @ a.n @ < m.end z + 40000 a.j @ + @ 0 $ . 0 $ 8 > . 0 $ 16 > . 24 > . + a.j @ 1 + a.j ! m.out j +:m.end q diff --git a/docs/history/07-zygote/code/examples/echo.s b/docs/history/07-zygote/code/examples/echo.s new file mode 100644 index 0000000..002935d --- /dev/null +++ b/docs/history/07-zygote/code/examples/echo.s @@ -0,0 +1 @@ +:l ? x z q :x , . l j diff --git a/docs/history/07-zygote/code/examples/fact.s b/docs/history/07-zygote/code/examples/fact.s new file mode 100644 index 0000000..21f6e32 --- /dev/null +++ b/docs/history/07-zygote/code/examples/fact.s @@ -0,0 +1,3 @@ +10 fa c pb c 10 . q +:fa 0 $ 2 < fb z _ 1 r :fb 0 $ 1 - fa c * r +:pb 0 $ 1 > 0 $ p1 z pb c pd j :p1 _ :pd 1 & 48 + . r diff --git a/docs/history/07-zygote/code/examples/hello.s b/docs/history/07-zygote/code/examples/hello.s new file mode 100644 index 0000000..e5baf1a --- /dev/null +++ b/docs/history/07-zygote/code/examples/hello.s @@ -0,0 +1,2 @@ +s :l 0 $ @ 0 $ e z . 1 + l j :e q +:s "hello, #32 "world! #10 #0 diff --git a/docs/history/07-zygote/code/examples/sm.s b/docs/history/07-zygote/code/examples/sm.s new file mode 100644 index 0000000..954886e --- /dev/null +++ b/docs/history/07-zygote/code/examples/sm.s @@ -0,0 +1,3 @@ +133 x ! :x 65 . 10 . +fn c 133 fn ! fn c 131 fn ! fn c 10 . q +:fn 65 . r diff --git a/docs/history/07-zygote/code/gen.s b/docs/history/07-zygote/code/gen.s new file mode 100644 index 0000000..8ec6aa2 --- /dev/null +++ b/docs/history/07-zygote/code/gen.s @@ -0,0 +1,9 @@ +:;genome_header,_fixed_addresses_starting_at_48000 +:;48000_boot__48002_a.run__48004.._&a.src_&a.dst_&a.org_&a.lab_&a.n_&a.ops +z.boot j a.run j #a.src #a.dst #a.org #a.lab #a.n #a.ops +:;boot:_read_source_until_eof_or_backtick,_assemble_it_at_0,_become_it +:z.boot 20000 a.q ! +:z.rd ? z.ch z z.go j +:z.ch , 0 $ 96 - z.end z a.q @ ! a.q @ 1 + a.q ! z.rd j +:z.end _ +:z.go 0 a.q @ ! 20000 a.src ! 0 a.dst ! 0 a.org ! 45000 a.lab ! a.run c 0 j diff --git a/docs/history/07-zygote/code/genome.h b/docs/history/07-zygote/code/genome.h new file mode 100644 index 0000000..abf6072 --- /dev/null +++ b/docs/history/07-zygote/code/genome.h @@ -0,0 +1,39 @@ +#define GORG 48000 +#define GLEN 547 +static const int genome[] = { +96021,14,96115,14,48510,48511,48512,48513,48514,48525,40001,97035,4,22,96037,16, +96075,14,20,1,6,193,28,96073,16,97035,2,4,97035,2,3,26, +97035,4,96027,14,8,1,97035,2,4,40001,97021,4,1,97023,4,1, +97025,4,90001,97027,4,96115,12,1,14,1,97031,4,1,97033,4,97021, +2,97035,4,1,97029,4,96503,12,97035,2,2,1,6,97037,4,96463, +16,97037,2,69,28,96317,16,97037,2,117,28,96373,16,97035,2,3, +26,2,96483,12,96253,16,97037,2,96713,12,1,6,-1,10,40,96251, +16,5,30,96577,12,97035,2,3,26,97035,4,96141,14,8,97037,2, +71,28,96293,16,97035,2,96779,12,5,30,3,26,96577,12,96545,12, +96141,14,97035,2,3,26,96779,12,96577,12,96545,12,96141,14,97035,2, +3,26,97035,4,97035,2,2,1,6,96483,12,96353,16,8,96141,14, +96577,12,97035,2,3,26,97035,4,96329,14,97031,2,96389,16,96545,12, +96141,14,97035,2,3,26,97027,2,97033,2,5,30,26,4,97025,2, +97029,2,26,97027,2,97033,2,5,30,26,3,26,4,97033,2,3, +26,97033,4,96545,12,96141,14,97031,2,96473,16,18,3,97031,4,96127, +14,1,6,67,40,10,-1,10,40,32,18,97035,2,2,1,6, +96541,16,96483,12,96543,16,97035,2,3,26,97035,4,96503,14,8,18, +97035,2,2,96483,12,96561,16,18,97035,2,3,26,97035,4,96545,14, +97023,2,97029,2,26,4,97029,2,3,26,97029,4,18,97049,4,97047, +4,97047,2,2,96483,12,97049,2,2,96483,12,3,6,3,6,32, +96653,16,8,8,3,18,34,96663,16,1,18,97047,2,2,97049,2, +2,28,96685,16,1,18,97047,2,3,26,97047,4,97049,2,3,26, +97049,4,96611,14,97037,4,1,97039,4,97051,97039,2,26,2,1,6, +96767,16,97037,2,28,96773,16,97039,2,3,26,97039,4,96723,14,8, +-1,18,97039,2,18,97041,4,97033,2,97039,4,97039,2,96861,16,97039, +2,3,28,97039,4,97027,2,97039,2,5,30,26,2,97041,2,96603, +12,96791,16,97027,2,97039,2,5,30,26,3,26,2,18,97041,2, +96869,14,97047,4,1,97045,4,1,97043,4,97047,2,2,91,28,96917, +16,97047,2,2,87,28,96923,16,96935,14,3,97045,4,97047,2,3, +26,97047,4,97047,2,2,97,28,1,6,21,40,3,6,-1,10, +40,32,96999,16,97043,2,21,30,26,97043,4,97047,2,3,26,97047, +4,96935,14,8,97043,2,97045,2,97019,16,1,10,28,18,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,113,64,33, +36,95,126,99,106,122,114,44,63,46,43,45,42,38,124,94, +62,60,0 +}; diff --git a/docs/history/07-zygote/code/io_linux.c b/docs/history/07-zygote/code/io_linux.c new file mode 100644 index 0000000..7ea34e0 --- /dev/null +++ b/docs/history/07-zygote/code/io_linux.c @@ -0,0 +1,6 @@ +#include +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/07-zygote/code/mkgenome.c b/docs/history/07-zygote/code/mkgenome.c new file mode 100644 index 0000000..7d9f0bc --- /dev/null +++ b/docs/history/07-zygote/code/mkgenome.c @@ -0,0 +1,35 @@ +/* assembles the genome at a fixed origin and writes it as a c header */ +#include +#include +#include +#define ORG 48000 +static char tok[30000][99]; +static int lab[30000], nt, img[17536], n; +static char *ops = "q@!$_~cjzr,?.+-*&|^><"; +static int val(char *s) +{ + int j; char *e; long v; + for (j = nt; j--;) if (tok[j][0] == ':' && !strcmp(tok[j] + 1, s)) return lab[j]; + v = strtol(s, &e, 0); + if (!*s || *e) { fprintf(stderr, "unknown label %s\n", s); exit(1); } + return (int)v; +} +static void put(int w) { if (n >= 17536) exit(1); img[n++] = w; } +int main(void) +{ + int pass, i; char *q, *c; + while (nt < 30000 && scanf("%98s", tok[nt]) == 1) nt++; + for (pass = 0; pass < 2; pass++) + for (n = i = 0; i < nt; i++) { + q = tok[i]; + if (*q == '"') while (*++q) put(*q); + else if (*q == ':') lab[i] = ORG + n; + else if (!q[1] && (c = strchr(ops, *q))) put((c - ops) * 2); + else if (*q == '#') put(pass ? val(q + 1) : 0); + else put(pass ? val(q) * 2 + 1 : 1); + } + printf("#define GORG %d\n#define GLEN %d\nstatic const int genome[] = {", ORG, n); + for (i = 0; i < n; i++) printf("%s%d", !i ? "\n" : i % 16 ? "," : ",\n", img[i]); + printf("\n};\n"); + return 0; +} diff --git a/docs/history/07-zygote/code/repl.s b/docs/history/07-zygote/code/repl.s new file mode 100644 index 0000000..35ab7d4 --- /dev/null +++ b/docs/history/07-zygote/code/repl.s @@ -0,0 +1,11 @@ +:;teach_the_resident_assembler_that_p_means_out +112 48009 @ 12 + ! +:;each_backtick-separated_chunk_of_input_is_assembled_at_40000_and_called +:nx ? rd0 z q +:rd0 30000 ptr ! +:rd ? ch z go j +:ch , 0 $ 96 - eos z ptr @ ! ptr @ 1 + ptr ! rd j +:eos _ +:go 0 ptr @ ! 30000 48004 @ ! 40000 48005 @ ! 40000 48006 @ ! 41000 48007 @ ! 48002 c + 40000 c nx j +:ptr #0 diff --git a/docs/history/07-zygote/code/test.sh b/docs/history/07-zygote/code/test.sh new file mode 100755 index 0000000..add0379 --- /dev/null +++ b/docs/history/07-zygote/code/test.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# builds the zygote for arm64 linux and runs it under qemu. +# needs gcc, aarch64-linux-gnu-gcc and qemu-aarch64. on an arm64 mac or linux box, +# build natively instead and drop the qemu prefix. +cd "$(dirname "$0")"; T=$(mktemp -d); Q="timeout 60 qemu-aarch64" +chk(){ if [ "$1" = "$2" ]; then echo "ok $3"; else echo "FAIL $3: got [$1]"; fi; } +gcc -w mkgenome.c -o $T/mkg && cat gen.s aslib.s | $T/mkg >$T/g.h +cmp -s $T/g.h genome.h && echo "ok genome.h is up to date" || echo "FAIL genome.h is stale, regenerate it" +aarch64-linux-gnu-gcc -O2 -w -DJTYPE=int -static core.c io_linux.c -o $T/zy || exit 1 +chk "$($Q $T/zy $T/asm.s +(cat $T/asm.s; printf '`'; cat examples/hello.s) | $Q $T/zy >$T/a +chk "$(od -An -td4 $T/a | tr -s ' \n' ' ' | sed 's/^ //;s/ $//')" "29 1 6 2 1 6 27 16 24 3 26 3 14 0 104 101 108 108 111 44 32 119 111 114 108 100 33 10 0" "self-hosted assembler, running on the zygote, assembles hello" +chk "$( (cat repl.s; printf '`104 p 105 p 10 p r`121 p 111 p 10 p r') | $Q $T/zy | tr '\n' '/')" "hi/yo/" "repl with mutated assembler" +rm -rf $T diff --git a/docs/history/07-zygote/notes.md b/docs/history/07-zygote/notes.md new file mode 100644 index 0000000..a4f1089 --- /dev/null +++ b/docs/history/07-zygote/notes.md @@ -0,0 +1,10 @@ +# the zygote + +the code/ folder next to this file is the zygote exactly as it was packed in stage 8 and 9: the asm genome (gen.s, aslib.s), the arm64-only core, the repl and the .s examples. these are the notes as they were written in the transcript. + +## message 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. diff --git a/docs/history/08-packaging/notes.md b/docs/history/08-packaging/notes.md new file mode 100644 index 0000000..646dd89 --- /dev/null +++ b/docs/history/08-packaging/notes.md @@ -0,0 +1,17 @@ +# moving to cowork + +no code from this stage survives except where a code/ folder sits next to this file. these are the notes as they were written in the transcript. + +## message 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. + +## message 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. 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 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 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 +#include +#include +#if defined(__aarch64__) && !defined(ZYINTERP) +#define ZYJIT 1 +#include +#ifdef __APPLE__ +#include +#include +#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 +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 +#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 +#include +#include +#include + +#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, ""); 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; +} diff --git a/docs/history/10-zc/notes.md b/docs/history/10-zc/notes.md new file mode 100644 index 0000000..96baec2 --- /dev/null +++ b/docs/history/10-zc/notes.md @@ -0,0 +1,37 @@ +# zc: the c-like genome, u m d and the collector + +code/ next to this file is the tree as shipped at the end of this stage (tinyvm-zc.zip), with its own README. + +## message 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/`. + +## working notes + +before asking anything i restated the model so it could be corrected early: m is owned here, lent freely and freed at the scope end; d is a move to the first lower scope it touches; u is a return obligation that arrives as m above; recasts only go away from m. the answers settled scopes (every block), lending (borrow, no escape), containment (tags must match and children inherit), the collector (free lists plus mark-sweep), where the compiler lives (resident, bootstrapped from c), the homoiconic features (all four), how blocks hand u up (value and assignment) and the analyzer (on, with an off switch). + +calls made without asking: memory grew to 1m words; core.c gained a plain interpreter for non-arm64 hosts; the language is typeless like b; tags went on signatures (`m p`, `d p`, `-> u`) with `x as u` casts; storing into globals or untracked memory needs d and hands the object to the collector; unchecked code is collector-managed. + +the bootstrap went zc0 (c) -> g0 -> g1 -> g2 and g1 == g2 on the first self-compile. things the analyzer caught in its own runtime on the way: puts walking a borrowed pointer with s++, wcopy returning a borrowed pointer, and the whole compiler source getting cut short by a backtick inside an error message (the backtick ends the source). the first round of rejection tests found one real gap, an m object unused before an early return, fixed with a path-independent "owned but never used" check, and one wrong test, where touching a d object in an else block moved it into that block, exactly as the rules say. diff --git a/docs/history/11-types-enhancements/code/README.md b/docs/history/11-types-enhancements/code/README.md new file mode 100644 index 0000000..db3e378 --- /dev/null +++ b/docs/history/11-types-enhancements/code/README.md @@ -0,0 +1,389 @@ +# 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, compiled through llvm on other hosts if you build with it, or interpreted. 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, and 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. types are a compiler primitive, with structs, generics, reflection and an optional typechecker. a program can also wire up to 512 custom opcodes into the cpu (virtual enhancements), which the jits inline as native code. + +this folder has the latest code. `history/` is the scrapbook: notes for every stage, plus frozen code from the stages that still have it. + +## files + +`core.c` is the native core and the only native code at runtime: the arm64 jit, the llvm backend (behind `-DZYLLVM`), the portable interpreter, and the enhancement unit (recipe parser, vm-code lifter, optimizer and lowering). `src/rt.zc` is the runtime (i/o, the native division enhancements, 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` 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, an owning list, a repl, a typed program and an enhancement demo. `tests/` has feature tests, `tests/errors/` (programs the lifetime analyzer has to reject) and `tests/typeerrors/` (programs the typechecker has to reject). each of those starts with the message it expects, and `tests/runerr.sh` runs a folder of them. `test.sh` does the whole bootstrap and runs everything on all three backends. `history/` is the scrapbook. + +## build + +``` +cc -O2 core.c io_linux.c -o zy # io_linux.c provides Q, G and J +./zy `). `ZYNOLLVM=1` turns the llvm tier off. + +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, on every backend. + +## zc, the language + +it reads like c. underneath every value is a 32 bit word and memory is word addressed, so `p + 1` is the next word whatever `p` points at, and strings are one char per word with a 0 at the end. types are optional: untyped code is typed `word`, which goes with anything. + +``` +const N = 10; +[N]int table; // a global array +fn fib(int n) -> int { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +fn main() { + for (int i = 0; i < N; i++) table[i] = fib(i); + let sq = { let t = table[5]; t * t }; // a block is an expression too, its last line is its value + let x = asm { 2 3 + }; // raw vm code, leaves one value + putn(sq + x); putc(10); + return 0; +} +``` + +declarations are c-style, type first: `int a = 1, b;`, `*node p = new(node);`, `[4]char buf;`, `point origin;`. `let` declares without a type: it infers pointer, struct and function types from the initializer and keeps numbers as plain words, and `let a[10];` is an untyped array. statements are declarations, `if`/`else`, `while`, `for`, `break`, `continue`, `return`, `{ }` blocks, `asm { }` and expressions. operators are c's with c's precedence, plus `p.x` and `p->x` (the same thing: `.` goes through a pointer on its own), `e as T` to change a type without changing the bits, and the casts below. comparisons and `&& ||` give 0 or 1. `/`, `%` and `<<` compile to native enhancement opcodes. character literals, `0x` hex and the usual escapes are there. there's no `?:` and no `switch`. + +functions are called by name once declared, so mutual recursion works without prototypes, except that a function with tags has to be declared (a prototype is enough) before a checked call to it. `main` runs after the whole program has compiled. every function returns one word, 0 if it falls off the end. + +builtins from the runtime: `putc`, `getc`, `eof`, `puts`, `putn`, `halt`, `strlen`, `streq`, `wcopy`, `wfill`, `new`, `new_t`, `free`, `gc`, `isobj`, `osize`, `typeof_obj`, `live_objects`, `install`, `zdiv`, `zmod`, `zshl`. + +## memory model: u, m and d + +`new(n)` or `new(T)` gives back a fresh object. 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. a tag is written after the type, `*node.u p`, or alone, `.d x`. `u`, `m` and `d` are reserved words. + +**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, 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. the first time it's handed to a lower scope its life here is over: passing it to a `.d` parameter, 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. it has to leave this block for the one above, where it arrives as m. it leaves through `return` (the function's return type has to carry `.u`, like `-> *node.u` or just `-> .u`), as the value of a block expression, or by assignment to a variable of the directly enclosing block. letting it fall out of scope, or throwing away a u result, is an error. + +recasting is multiplication by the tag: `u*x`, `d*x`, `m*x`. it 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 declaration can carry a tag too, `.u r;`, and then whatever lands in it gets that tag. + +parameters: an untagged parameter is m from the caller's side, a lend, and the callee sees a plain word. `.m` makes it a checked borrow: the callee can read and write it but can't free it, return it, recast it or store it anywhere. `.d` hands the object over, and it arrives as m. + +``` +fn box(int v) -> *int.u { *int b = new(int); *b = v; return u*b; } +fn push(*list l, *int.d item) { l.items[l.len] = d*item; l.len++; return 0; } +``` + +containers own what you store in them. `p[i] = c` or `p.f = 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 counts as giving the child away, so it needs `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 `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. + +### 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 per rule. 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 what it allocates belongs to the collector, and checked variables can't be touched from inside an unchecked block. + +## types + +types are a compiler primitive. the compiler keeps them as records in a type area at 0x9C000, hash-consed so the same type is always the same pointer. they stay in memory after compiling, so programs and parse words can look at them. + +``` +struct point { int x, y; }; +struct list { int len; *T items; }; +type num = int; +fn first(*list l) -> T { return l.items[0]; } +fn mk(int cap) -> *list.u { *list l = new(list); l.items = new(T, cap); return u*l; } +... +*list<*point> ps = mk<*point>(8); // explicit type arguments, or inferred from the arguments +``` + +the kinds are `word`, `int`, `char`, `bool`, `void`, pointers `*T`, fixed arrays `[n]T`, function types `fn(int, *char) -> int`, structs, generic structs and generic functions. structs and arrays live in place (in a frame, a global or inside another struct), and their value is their address, so they're passed around by pointer. `sizeof` counts words. type arguments have to be one word (a number, a pointer or another parameter), so a generic function is compiled once and works for every instance. indexing scales by the element's size, while plain pointer arithmetic stays in words, like b. `new(T)` and `new(T, n)` stamp the type into the object's header. + +### reflection + +`typeof(e)` and `typeof(T)` give a type record and `sizeof(...)` its size. both work on any expression, which is compiled dry and never runs. at runtime: `tkind(t)` (one of the `TY_` constants), `tsize`, `tname`, `tlen`, `tnfields`, `tfname(t, i)`, `tftype`, `tfoff`, `tret`, `tnparams`, `tparam`, `tparamtag` (the u/m/d tag of a parameter), `tretu`, `tnargs` and `targ` for generic instances, and `tprint(t)`. `sigof(f)` gives the type of a function by address (untyped ones get a signature built from their arity and tags), `sigofs("name")` by name, and `typeof_obj(p)` reads the type stamped on a heap object. + +### the typechecker + +off by default. `typecheck on;` turns it on for what follows and `typecheck off;` turns it back off (a parse word can flip `tc_on`). it checks initializers, assignments, arguments (unifying generic parameters), return values, arithmetic, comparisons, dereferencing, indexing and calls. `word` matches anything, numbers mix with each other, a literal 0 is a null pointer, and arrays decay to pointers. it stops at the first error, printing what it expected and what it got. `tests/typeerrors/` has one per rule. some things are checked whatever the setting, because the compiler needs them to generate code: field names, and field access on something that isn't a struct. + +## virtual enhancements + +the cpu has room for 512 custom opcodes (22 to 533), and opcode 21 (`%` in asm) installs one at runtime. it's the closest a soft cpu gets to rewiring itself. an enhancement takes up to 8 inputs off the data stack and leaves up to 8 outputs, and it's written one of two ways: + +``` +enhance clamp(x, lo, hi) micro "x = max x lo; x = min x hi"; +enhance divmod(a, b) -> 2 micro "r2 = sdiv a b; r1 = srem a b; r0 = r2"; +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // can't be lifted (it does i/o), so calls use the fallback +``` + +a micro recipe works on registers `r0`..`r15`, which the inputs arrive in (also under the parameter names), and the outputs leave from `r0` up. the micro-ops are `li mov add sub mul sdiv udiv srem urem and or xor shl shr sar neg not lt ltu eq ne min max minu maxu mulhs mulhu clz abs sel ld st`. a `vm` body is straight-line vm code that gets lifted by running it symbolically. both turn into ssa, and the core's optimizer folds constants, simplifies algebra, removes common subexpressions and dead code, and turns division by a constant into a multiply-high sequence (`ZYTRACE=1` prints the result). the arm64 jit then inlines the code at every use with registers allocated, the llvm backend inlines it as ir, and the interpreter runs the optimized list. if something doesn't fit in registers, the jit calls the interpreter for that op. + +an enhancement is called like a function when it has one output, or by name from asm. `enhance` installs at compile time, so the wiring is there before `main` runs, and a parse word can use it right away. an image installs its own enhancements when it boots, from its symbol table. that's how `/`, `%` and `<<` work: `rt.zc` declares `idiv`, `imod` and `ishl` as one-instruction recipes. `install(desc)` is the raw interface, and its descriptor format is documented in `core.c`. stores done by an enhancement don't invalidate compiled code, so use them for data. + +this replaces my first plan for enhancements, which compiled c or llvm ir sources at runtime. part of that reply got stopped by a safety check, and once it turned out llvm was meant for portability, it moved into the backend below instead. + +## the llvm backend + +a tiered jit for hosts the arm64 backend doesn't cover. the interpreter counts how often each block start gets reached, and a hot block is translated to llvm ir using the same block rules as the arm64 jit: it ends at call, jump, ret or halt, keeps going past a jz, and literal targets are fused. the ir goes through the O2 pipeline and gets compiled by orc's lljit. stores into compiled words drop the blocks covering them, like on arm64. it pays off for long-running code: a loop-and-recursion benchmark runs about 3.3x faster than the interpreter. short bursty work like the self-compile is slower, since compile time dominates there. `ZYHOT=1` compiles every block, which is a good stress test, and the test suite runs that way too. + +## code as data + +the compiler is in memory with your program and every name in it is callable. + +`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, enhancement names emit their opcode, 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, and `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)` runs `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()`, `peek()`, `tk`/`tv` (current token kind and value), `expect`, `accept`, `expr()`, `stmt()`, `substmt()`, `ptype()`, `emit`, `lit`, `op`, `hole`/`setlit` for jumps, and `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` partway through a 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 both. `mnem` is the asm mnemonic table, `q@!$_~cjzr,?.+-*&|^><%`, and can be rewritten. + +## the bootstrap + +`zc0.c` compiles the subset `compiler.zc` uses (no analyzer, types, quote, parse words or block expressions, but it does lay out `enhance` declarations) into a first genome. that genome compiles `compiler.zc` again on the vm. that's where the real compiler, the analyzer and native division first meet their own source, and `compiler.zc` passes its own lifetime checks. the result compiles itself into identical words, on all three backends, and that's the `genome.h` that ships (57463 words). an image build (`build_image(org, dst)`) compiles with only the image's own names visible (plus keywords and builtin types), writes code meant for one address into another, and appends a symbol table so the booted genome knows its own names and enhancements. + +## the instruction set + +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 21 % install +2 ! store 7 j jump 12 . out (G) 17 | or 22..533 enhancements +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, `c` and `j` take their target from the stack, and `%` is `(descriptor -- status)`. there's still no div or mod in the base set, because a divider can't finish in one cycle in hardware. an enhancement can add one. + +## memory map and abi + +memory is 1m (1048576) words. it could grow until the host runs out (literals already reach 1g words), but that would mean reserving the jit tables with mmap instead of static arrays, and 1m is plenty for now. + +``` +0x00000.. the program: code, with globals between functions +0x40000..0x9BFFF heap +0x9C000..0x9FFFF type records +0xA0000 frame pointer word +0xA0100..0xBFFFF 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. heap objects have a 6 word header: size, size class, flags, a check word, owner, type. + +## 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, install hook, enhancement fallback). + +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 straight to it when it's already compiled. otherwise it returns to c, which compiles the block and re-enters. enhancements are inlined: inputs load from the data stack into w0..w15, the optimized micro-ops run in registers with x16 and x17 as scratch, and the outputs go back. an install calls into c and then returns to the loop, which flushes every translation, since code built before the install may have inlined the old version. + +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: the darwin path uses `MAP_JIT`, `pthread_jit_write_protect_np` and `sys_icache_invalidate`. linux uses rwx mmap and `__builtin___clear_cache`. only linux arm64 has actually been run, under qemu. the darwin path follows apple's documented recipe but hasn't been tested, and under the hardened runtime it also needs the allow-jit entitlement. every host shares the same semantics: shift counts wrap at 32, stores outside memory are ignored, loads outside memory read 0, and jumping outside memory or to an unwired opcode halts. + +## test results + +`test.sh` passes all 62 checks on x86-64 linux: the fixpoint, an up-to-date `genome.h`, and then every example and feature test on the interpreter, on the arm64 jit under qemu, and on the llvm backend, all with identical output. it also checks that all 23 programs in `tests/errors/` and all 10 in `tests/typeerrors/` get rejected with the expected message on each backend, that llvm agrees when it compiles every block, and that the self-compile matches byte for byte on all three. separately, 80000 random divisions through enhancements matched the software routine, covering divide by zero, INT_MIN/-1, negatives and the magic-number path for constants. + +## open ends + +the earlier gaps, in more detail: + +**branch and loop states must match exactly.** after a loop, the analyzer assumes every variable is back in the state it had when the loop started, and checks every `break` and `continue` against that. so a loop that gives something away and then always breaks is rejected, even though it's fine. the fix is to make the state after the loop the join of the break paths and the condition-false exit, and to check only the back-edges against the loop's start. + +**untracked aliases.** the analyzer only follows bare variable names. `let q = p + 0;` or `let c = list[1];` is a plain word pointing at an owned object, and nothing tracks it. when the owner is freed, the alias dangles. plain words are allowed into `.d` parameters, so you can even free through one. `free` checks the header, so freeing a dead block twice does nothing, but if that block has already been reused you free someone else's object. untagged parameters make this easier to hit now, since they accept lends while the callee sees a plain word. `examples/typed.zc` shows the safe way: `push` takes its item as `.d`. + +**the conservative collector.** the vm can't read its own stack pointer, so the collector scans the whole data stack region, stale values included. any word that happens to equal an object's address keeps that object alive. it never frees anything early, it just keeps garbage around longer. + +**free lists never merge.** each size class has its own list. freeing ten thousand small blocks doesn't help a big request, so the heap can run out while it's mostly free. the classes are powers of two, so a buddy allocator would be a small change. + +**coarse invalidation.** translations are only reclaimed by a full flush, and every store to a covered word rescans the block list. installing an enhancement flushes everything. the llvm backend never frees compiled code at all. + +**no stack overflow checks.** the frame stack is 64k words, the return stack 32k and the data stack 16k, and nothing checks them. deep recursion runs into the neighboring regions without a word. + +**generics are erased.** a generic function is compiled once, so the type stamped by `new(T)` inside it says `T`, and type arguments have to be one word. + +**the rest.** compile errors stop at the first one. a token list fed in by a macro reports the line where the macro was used. a declaration starting with `**` reads as an expression. `?:` and `switch` are still missing. the llvm backend compiles one module per block, so it's slow to warm up, and a background compile thread would fix that. stores done by enhancements don't invalidate compiled code. + +--- + +## 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 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/`. + +### 11 + +> progress report? +> add types please :) +> mostly as a compiler primitive though, plus type-inspection via reflection +> and a small optional typechecker (default off) +> oh and keep the stuff you write as a history scrapbook +> if it helps, add a path to the hardware which is called "virtual enhancements", and allows up to 512 custom operations to be compiled down via jit into hardware-level speeds and interoped directly into a fast path in the vm to become essentially custom wiring. useful for division and other stuff as a dynamic runtime path + +my answers to the clarifying questions, exactly: + +> types: words + structs + generics +> +> reflection: runtime type of heap objects, function signatures, typeof at compile time +> +> how an enhancement is defined: either actual C or llvm ir code or vm code or micro-ops passed through an optimizer. since for example, micro-ops and vm code are not sufficient for optimizing things like division +> +> scrapbook: notes + code snapshots + +**summary:** the progress report said the previous round was finished and shipped. i then laid out a plan where the core would compile c or llvm ir enhancement sources at runtime with the host toolchain and load the result. part of that reply was stopped by a safety check before it finished, so i stopped and checked in instead of building it. + +### 12 + +> also make the umd syntax like `type.u name`, and casting is multiplication `u*name` +> ideally i'd prefer memory to be unlimited words growing until system oom, but 1m is fine +> core.c plain interp is also nice +> zc0.c own file is fine +> i mentioned llvm for portability to non-arm targets +> yes, d object semantic that was intended +> u object hands up one block and becomes an m, that's fine. the code can make it a u or a d or whatever +> explain your gaps more +> +> wait why safety check? what's wrong with that + +my answers to the clarifying questions, exactly: + +> declarations: c-style, var -> let +> +> tags on untyped values and the names u, m, d: names reserved, bare .u allowed, untype is m by default +> +> llvm: llvm jit backend (Recommended) + +**summary:** on the safety check: nothing was wrong with the request. my best guess was that it tripped on the plan for a program inside the vm handing source text to the system compiler and loading the result into the running process, since that pattern also shows up in malware. with llvm meant for portability, that path wasn't needed. the gaps got the longer explanations that are now under open ends above. then the round itself: + +**syntax.** declarations are c-style (`int x`, `*node.m p`), `let` replaces `var` for untyped and inferred declarations, tags are `.u .m .d` after the type or on their own, recasts are `u*x` / `d*x` / `m*x`, `u m d` are reserved, and an untagged parameter counts as an m lend. + +**types.** a compiler primitive: hash-consed records with structs, generic structs and functions, fixed arrays, function types, `typeof`/`sizeof`, `as` casts and a reflection api, with object headers carrying their type. the typechecker is off by default and turned on with `typecheck on;`. + +**virtual enhancements.** opcode 21 installs, 22 to 533 are the slots. micro-op recipes and lifted vm code go through an optimizer in the core (folding, cse, dce, multiply-high division by constants) and get inlined by both jits. the language's own `/ % <<` now run on them. + +**backends.** a tiered llvm backend (`-DZYLLVM`) for non-arm hosts. + +**bootstrap and history.** it still reaches its fixpoint on all three backends. `history/` holds notes for every stage and code from stages 7, 10 and this one (in 11-types-enhancements). diff --git a/docs/history/11-types-enhancements/code/core.c b/docs/history/11-types-enhancements/code/core.c new file mode 100644 index 0000000..49cc6cc --- /dev/null +++ b/docs/history/11-types-enhancements/code/core.c @@ -0,0 +1,1157 @@ +/* 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 +#include +#include +#if defined(__aarch64__) && !defined(ZYINTERP) +#define ZYJIT 1 +#include +#ifdef __APPLE__ +#include +#include +#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; + +/* ---- virtual enhancements ---- + up to 512 custom opcodes (22 .. 533), wired in at runtime by the install + opcode (21). an enhancement is a short program over native micro-ops, + written either as a recipe (text) or as straight-line vm code that gets + lifted. both become ssa, go through the optimizer below, and then run in + the interpreter or get inlined by the jit as native code. */ +#define NENH 512 +#define XOP0 22 +enum { U_LI, U_MOV, U_ADD, U_SUB, U_MUL, U_SDIV, U_UDIV, U_SREM, U_UREM, U_AND, U_OR, U_XOR, + U_SHL, U_SHR, U_SAR, U_NEG, U_NOT, U_LT, U_LTU, U_EQ, U_NE, U_MIN, U_MAX, U_MINU, U_MAXU, + U_MULHS, U_MULHU, U_CLZ, U_ABS, U_SEL, U_LD, U_ST, U_N }; +static const char *unames[U_N] = { "li", "mov", "add", "sub", "mul", "sdiv", "udiv", "srem", "urem", + "and", "or", "xor", "shl", "shr", "sar", "neg", "not", "lt", "ltu", "eq", "ne", "min", "max", + "minu", "maxu", "mulhs", "mulhu", "clz", "abs", "sel", "ld", "st" }; +static const signed char uarity[U_N] = { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2 }; +typedef struct { int op, d, a, b, c, imm; } Uop; /* ssa: d is a fresh value, a b c are values */ +typedef struct { + int live, kind, nin, nout, n, nv, out[8]; + Uop *u; + signed char *reg; /* physical register per value, for the jit; 0 if it didn't fit */ +} Enh; +static Enh enh[NENH]; +static int need_flush; + +#define MAXUOP 4096 +static Uop ub[MAXUOP]; static int un, unv, uerr; /* the program being built */ +static int unew(int op, int a, int b, int c, int imm) +{ + Uop *u; + if (un >= MAXUOP) { uerr = -5; return 0; } + u = &ub[un++]; u->op = op; u->d = unv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + return u->d; +} +static int mread(int a) { return (unsigned)a < MW ? m[a] : 0; } + +/* recipe text: one statement per line or per ';' + r0 = sdiv r0 r1 dst = op operands, operands are rN, parameter names or numbers + r2 = r0 a copy, or a number + st r1 r0 memory[r1] = r0 + inputs arrive in r0.. (and under the parameter names), outputs leave from r0.. */ +static int parse_recipe(int src, int names, int nin, int nout, int *out) +{ + int cur[16], i, p = src, n, k, op, args[3], na, dst, isst; + char tok[8][32]; int nt; + for (i = 0; i < 16; i++) cur[i] = i < nin ? i : -1; + for (;;) { + /* read one statement into tokens */ + nt = 0; + for (;;) { + int c = mread(p); + while (c == ' ' || c == '\t' || c == '\r') c = mread(++p); + if (!c || c == '\n' || c == ';') break; + if (c == '=') { if (nt < 8) strcpy(tok[nt++], "="); p++; continue; } + n = 0; + while (c && c != ' ' && c != '\t' && c != '\n' && c != ';' && c != '=' && c != '\r') { if (n < 31) tok[nt < 8 ? nt : 7][n++] = (char)c; c = mread(++p); } + if (nt < 8) tok[nt++][n] = 0; + } + if (nt) { + isst = !strcmp(tok[0], "st"); + if (!isst && (nt < 3 || strcmp(tok[1], "="))) return -2; + /* destination register */ + dst = -1; + if (!isst) { + if (tok[0][0] == 'r' && tok[0][1] >= '0' && tok[0][1] <= '9') dst = atoi(tok[0] + 1); + else for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)tok[0][j]) j++; + if (!mread(s + j) && !tok[0][j]) dst = i; + } + if (dst < 0 || dst > 15) return -2; + } + k = isst ? 1 : 2; /* first token after "=" (or after st) */ + op = -1; + if (!isst && nt > 3) { for (i = 0; i < U_N; i++) if (!strcmp(tok[k], unames[i])) op = i; if (op < 0) return -2; k++; } + if (isst) op = U_ST; + na = 0; + for (; k < nt; k++) { + char *t = tok[k], *e; int v = -1; + if (na >= 3) return -2; + if (t[0] == 'r' && t[1] >= '0' && t[1] <= '9') { int r = atoi(t + 1); if (r > 15) return -2; if (cur[r] < 0) cur[r] = unew(U_LI, 0, 0, 0, 0); v = cur[r]; } + else if ((t[0] >= '0' && t[0] <= '9') || t[0] == '-') { long x = strtol(t, &e, 0); if (*e) return -2; v = unew(U_LI, 0, 0, 0, (int)x); } + else { + for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)t[j]) j++; + if (!mread(s + j) && !t[j]) v = cur[i] < 0 ? (cur[i] = unew(U_LI, 0, 0, 0, 0)) : cur[i]; + } + if (v < 0) return -2; + } + args[na++] = v; + } + if (op < 0) { /* x = y */ + if (na != 1) return -2; + cur[dst] = args[0]; + } else { + if (na != (op == U_LI ? 0 : uarity[op])) { + if (!(op == U_LI && na == 1)) return -2; + } + if (op == U_LI) cur[dst] = args[0]; + else if (op == U_ST) unew(U_ST, args[0], args[1], 0, 0); + else cur[dst] = unew(op, args[0], na > 1 ? args[1] : 0, na > 2 ? args[2] : 0, 0); + } + if (uerr) return uerr; + } + if (!mread(p)) break; + p++; + } + for (i = 0; i < nout; i++) { if (cur[i] < 0) cur[i] = unew(U_LI, 0, 0, 0, 0); out[i] = cur[i]; } + return uerr; +} + +/* straight-line vm code from addr up to its ret, run symbolically */ +static int lift_vm(int a, int len, int nin, int nout, int *out) +{ + int st[256], sp = 0, i, w, k, x, y; + for (i = 0; i < nin; i++) st[sp++] = i; + for (i = 0; i < len; i++) { + w = mread(a + i); + if (w & 1) { if (sp >= 256) return -4; st[sp++] = unew(U_LI, 0, 0, 0, w >> 1); continue; } + k = w / 2; + if (k == 9) break; + switch (k) { + case 1: if (sp < 1) return -4; st[sp - 1] = unew(U_LD, st[sp - 1], 0, 0, 0); break; + case 2: if (sp < 2) return -4; unew(U_ST, st[sp - 1], st[sp - 2], 0, 0); sp -= 2; break; + case 3: /* pick needs a constant index */ + if (sp < 1) return -4; + x = st[sp - 1]; + if (x < nin) return -4; + { int j; for (j = 0; j < un && ub[j].d != x; j++); if (j == un || ub[j].op != U_LI) return -4; y = ub[j].imm; } + if (y < 0 || y >= sp - 1) return -4; + st[sp - 1] = st[sp - 2 - y]; + break; + case 4: if (sp < 1) return -4; sp--; break; + case 5: if (sp < 2) return -4; x = st[sp - 1]; st[sp - 1] = st[sp - 2]; st[sp - 2] = x; break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: { + static const int map[] = { U_ADD, U_SUB, U_MUL, U_AND, U_OR, U_XOR, U_SAR, U_LT }; + if (sp < 2) return -4; + x = st[sp - 1]; y = st[sp - 2]; sp -= 2; + st[sp++] = unew(map[k - 13], y, x, 0, 0); + break; } + default: return -4; /* control flow, i/o and other enhancements don't lift */ + } + if (uerr) return uerr; + } + if (sp != nout) return -4; + for (i = 0; i < nout; i++) out[i] = st[i]; + return uerr; +} + +/* ---- the optimizer ---- + one forward pass of copy propagation, constant folding, algebraic + simplification, division by constants (the multiply-high trick) and + common subexpression elimination, then dead code removal. */ +static int ev(int op, int a, int b, int c) +{ + unsigned ua = (unsigned)a, ub_ = (unsigned)b; + switch (op) { + case U_ADD: return (int)(ua + ub_); + case U_SUB: return (int)(ua - ub_); + case U_MUL: return (int)(ua * ub_); + case U_SDIV: return b == 0 ? 0 : (a == (int)0x80000000 && b == -1) ? a : a / b; + case U_UDIV: return b == 0 ? 0 : (int)(ua / ub_); + case U_SREM: return b == 0 ? a : (a == (int)0x80000000 && b == -1) ? 0 : a % b; + case U_UREM: return b == 0 ? a : (int)(ua % ub_); + case U_AND: return a & b; + case U_OR: return a | b; + case U_XOR: return a ^ b; + case U_SHL: return (int)(ua << (b & 31)); + case U_SHR: return (int)(ua >> (b & 31)); + case U_SAR: return a >> (b & 31); + case U_NEG: return (int)(0u - ua); + case U_NOT: return ~a; + case U_LT: return a < b; + case U_LTU: return ua < ub_; + case U_EQ: return a == b; + case U_NE: return a != b; + case U_MIN: return a < b ? a : b; + case U_MAX: return a > b ? a : b; + case U_MINU: return ua < ub_ ? a : b; + case U_MAXU: return ua > ub_ ? a : b; + case U_MULHS: return (int)(((long long)a * (long long)b) >> 32); + case U_MULHU: return (int)(((unsigned long long)ua * ub_) >> 32); + case U_CLZ: { int n = 0; if (!ua) return 32; while (!(ua & 0x80000000u)) { ua <<= 1; n++; } return n; } + case U_ABS: return a < 0 ? (int)(0u - ua) : a; + case U_SEL: return a ? b : c; + } + return 0; +} +static void smagic(int d, int *mul, int *sh) /* hacker's delight, signed */ +{ + const unsigned two31 = 0x80000000u; + unsigned ad = d < 0 ? 0u - (unsigned)d : (unsigned)d, t = two31 + ((unsigned)d >> 31); + unsigned anc = t - 1 - t % ad, q1 = two31 / anc, r1 = two31 - q1 * anc, q2 = two31 / ad, r2 = two31 - q2 * ad, delta; + int p = 31; + do { + p++; + q1 *= 2; r1 *= 2; if (r1 >= anc) { q1++; r1 -= anc; } + q2 *= 2; r2 *= 2; if (r2 >= ad) { q2++; r2 -= ad; } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + *mul = (int)(q2 + 1); if (d < 0) *mul = -*mul; + *sh = p - 32; +} +static void umagic(unsigned d, unsigned *mul, int *add, int *sh) /* hacker's delight, unsigned */ +{ + unsigned nc = 0xFFFFFFFFu - (0u - d) % d, q1, r1, q2, r2, delta; + int p = 31; + *add = 0; + q1 = 0x80000000u / nc; r1 = 0x80000000u - q1 * nc; + q2 = 0x7FFFFFFFu / d; r2 = 0x7FFFFFFFu - q2 * d; + do { + p++; + if (r1 >= nc - r1) { q1 = 2 * q1 + 1; r1 = 2 * r1 - nc; } else { q1 = 2 * q1; r1 = 2 * r1; } + if (r2 + 1 >= d - r2) { if (q2 >= 0x7FFFFFFFu) *add = 1; q2 = 2 * q2 + 1; r2 = 2 * r2 + 1 - d; } + else { if (q2 >= 0x80000000u) *add = 1; q2 = 2 * q2; r2 = 2 * r2 + 1; } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + *mul = q2 + 1; *sh = p - 32; +} + +static Uop ob[MAXUOP]; static int on, onv; +static int *omap, *isk, *kv; /* old value -> new value; constness of new values */ +static int pure(int op) { return op != U_LD && op != U_ST; } +static int ispow2(unsigned x) { return x && !(x & (x - 1)); } +static int lg2(unsigned x) { int n = 0; while (x > 1) { x >>= 1; n++; } return n; } +static int oe(int op, int a, int b, int c, int imm); +static int K(int v) { return oe(U_LI, 0, 0, 0, v); } +static int raw(int op, int a, int b, int c, int imm) +{ + Uop *u; int i; + if (pure(op)) /* cse */ + for (i = 0; i < on; i++) { + u = &ob[i]; + if (u->op == op && u->a == a && u->b == b && u->c == c && u->imm == imm) return u->d; + } + if (on >= MAXUOP) { uerr = -5; return 0; } + u = &ob[on++]; u->op = op; u->d = onv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + isk[u->d] = op == U_LI; kv[u->d] = imm; + return u->d; +} +static int sdivk(int a, int d) /* a / d for a constant d, no divide instruction */ +{ + int mul, sh, q, t; + if (d == 1) return a; + if (d == -1) return oe(U_NEG, a, 0, 0, 0); + if (d == (int)0x80000000) return oe(U_EQ, a, K(d), 0, 0); + if (ispow2((unsigned)(d < 0 ? -d : d))) { + int k = lg2((unsigned)(d < 0 ? -d : d)); + t = oe(U_SAR, a, K(31), 0, 0); + t = oe(U_SHR, t, K(32 - k), 0, 0); + q = oe(U_SAR, oe(U_ADD, a, t, 0, 0), K(k), 0, 0); + return d < 0 ? oe(U_NEG, q, 0, 0, 0) : q; + } + smagic(d, &mul, &sh); + q = oe(U_MULHS, a, K(mul), 0, 0); + if (d > 0 && mul < 0) q = oe(U_ADD, q, a, 0, 0); + if (d < 0 && mul > 0) q = oe(U_SUB, q, a, 0, 0); + if (sh) q = oe(U_SAR, q, K(sh), 0, 0); + return oe(U_ADD, q, oe(U_SHR, q, K(31), 0, 0), 0, 0); +} +static int udivk(int a, unsigned d) +{ + unsigned mul; int add, sh, t; + if (d == 1) return a; + if (ispow2(d)) return oe(U_SHR, a, K(lg2(d)), 0, 0); + if (d > 0x80000000u) return oe(U_XOR, oe(U_LTU, a, K((int)d), 0, 0), K(1), 0, 0); /* a >= d */ + umagic(d, &mul, &add, &sh); + t = oe(U_MULHU, a, K((int)mul), 0, 0); + if (!add) return sh ? oe(U_SHR, t, K(sh), 0, 0) : t; + t = oe(U_ADD, oe(U_SHR, oe(U_SUB, a, t, 0, 0), K(1), 0, 0), t, 0, 0); + return sh > 1 ? oe(U_SHR, t, K(sh - 1), 0, 0) : t; +} +static int oe(int op, int a, int b, int c, int imm) +{ + int ka, kb, A, B; + if (op == U_LI) return raw(U_LI, 0, 0, 0, imm); + if (op == U_MOV) return a; + if (op == U_LD || op == U_ST) return raw(op, a, b, 0, 0); + ka = isk[a]; kb = uarity[op] > 1 && isk[b]; + A = kv[a]; B = kv[b]; + /* everything constant: fold */ + if (ka && (uarity[op] < 2 || kb) && (uarity[op] < 3 || isk[c])) return K(ev(op, A, B, kv[c])); + /* constants go right for commutative ops */ + if (ka && !kb && (op == U_ADD || op == U_MUL || op == U_AND || op == U_OR || op == U_XOR || op == U_EQ || op == U_NE || + op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU || op == U_MULHS || op == U_MULHU)) { + int t = a; a = b; b = t; kb = 1; B = A; ka = 0; + } + if (op == U_SEL && ka) return A ? b : c; + if (op == U_SEL && b == c) return b; + if (kb) switch (op) { + case U_ADD: case U_SUB: case U_OR: case U_XOR: case U_SHL: case U_SHR: case U_SAR: + if (!B || (op >= U_SHL && op <= U_SAR && !(B & 31))) return a; + break; + case U_MUL: + if (B == 0) return K(0); + if (B == 1) return a; + if (B == -1) return oe(U_NEG, a, 0, 0, 0); + if (ispow2((unsigned)B)) return oe(U_SHL, a, K(lg2((unsigned)B)), 0, 0); + break; + case U_AND: if (B == 0) return K(0); if (B == -1) return a; break; + case U_SDIV: if (B == 0) return K(0); return sdivk(a, B); + case U_SREM: if (B == 0) return a; if (B == 1 || B == -1) return K(0); + return oe(U_SUB, a, oe(U_MUL, sdivk(a, B), b, 0, 0), 0, 0); + case U_UDIV: if (B == 0) return K(0); return udivk(a, (unsigned)B); + case U_UREM: if (B == 0) return a; + if (ispow2((unsigned)B)) return oe(U_AND, a, K(B - 1), 0, 0); + return oe(U_SUB, a, oe(U_MUL, udivk(a, (unsigned)B), b, 0, 0), 0, 0); + } + if (a == b && uarity[op] == 2) { + if (op == U_SUB || op == U_XOR || op == U_LT || op == U_LTU || op == U_NE) return K(0); + if (op == U_AND || op == U_OR || op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU) return a; + if (op == U_EQ) return K(1); + } + return raw(op, a, b, c, 0); +} +/* runs the optimizer over ub[0..un) with nin inputs; leaves the result in e */ +static int optimize(Enh *e, int nin, int *out, int nout) +{ + int i, *live, n = 0; + static int omap_[MAXUOP + 16], isk_[MAXUOP * 4], kv_[MAXUOP * 4]; + omap = omap_; isk = isk_; kv = kv_; + on = 0; onv = nin; + for (i = 0; i < nin; i++) { omap[i] = i; isk[i] = 0; } + for (i = 0; i < un && !uerr; i++) { + Uop *u = &ub[i]; + int a = uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD ? omap[u->a] : 0; + int b = uarity[u->op] > 1 || u->op == U_ST ? omap[u->b] : 0; + int c = uarity[u->op] > 2 ? omap[u->c] : 0; + if (u->op == U_ST) oe(U_ST, a, b, 0, 0); + else omap[u->d] = oe(u->op, a, b, c, u->imm); + } + if (uerr) return uerr; + /* dead code: outputs and stores are live */ + live = calloc(onv + 1, sizeof *live); + for (i = 0; i < nout; i++) { e->out[i] = omap[out[i]]; live[e->out[i]] = 1; } + for (i = on; i--;) { + Uop *u = &ob[i]; + if (u->op != U_ST && !live[u->d]) { u->op = -1; continue; } + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) live[u->a] = 1; + if (uarity[u->op] > 1 || u->op == U_ST) live[u->b] = 1; + if (uarity[u->op] > 2) live[u->c] = 1; + } + free(live); + e->u = malloc((on + 1) * sizeof(Uop)); + for (i = 0; i < on; i++) if (ob[i].op >= 0) e->u[n++] = ob[i]; + e->n = n; e->nv = onv; e->nin = nin; e->nout = nout; + return 0; +} +/* run an installed enhancement on a downward-growing stack; returns the new top */ +static int *xexec(Enh *e, int *sp) +{ + int vb[256], *v = e->nv <= 256 ? vb : malloc(e->nv * sizeof(int)), i, j; + for (j = 0; j < e->nin; j++) v[j] = sp[e->nin - 1 - j]; + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + switch (u->op) { + case U_LI: v[u->d] = u->imm; break; + case U_LD: v[u->d] = mread(v[u->a]); break; + case U_ST: if ((unsigned)v[u->a] < MW) m[v[u->a]] = v[u->b]; break; + default: v[u->d] = ev(u->op, v[u->a], v[u->b], v[u->c]); + } + } + sp += e->nin - e->nout; + for (j = 0; j < e->nout; j++) sp[e->nout - 1 - j] = v[e->out[j]]; + if (v != vb) free(v); + return sp; +} +static void xdump(int slot, Enh *e) +{ + int i; + fprintf(stderr, "enh %d: %d in, %d out, %d ops\n", slot, e->nin, e->nout, e->n); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (u->op == U_ST) fprintf(stderr, " st v%d v%d\n", u->a, u->b); + else if (u->op == U_LI) fprintf(stderr, " v%d = %d\n", u->d, u->imm); + else { fprintf(stderr, " v%d = %s v%d", u->d, unames[u->op], u->a); if (uarity[u->op] > 1) fprintf(stderr, " v%d", u->b); if (uarity[u->op] > 2) fprintf(stderr, " v%d", u->c); fprintf(stderr, "\n"); } + } + for (i = 0; i < e->nout; i++) fprintf(stderr, " out%d = v%d\n", i, e->out[i]); +} +/* registers for the jit: values live in w0..w15, straight-line linear scan. + if they don't fit, reg stays 0 and the jit calls the interpreter instead. */ +static void regalloc(Enh *e) +{ + int *last = malloc(e->nv * sizeof(int)), i, j, k, fr = 0xffff; + signed char *r = malloc(e->nv); + for (i = 0; i < e->nv; i++) { last[i] = -2; r[i] = -1; } + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) last[u->a] = i; + if (uarity[u->op] > 1 || u->op == U_ST) last[u->b] = i; + if (uarity[u->op] > 2) last[u->c] = i; + } + for (i = 0; i < e->nout; i++) last[e->out[i]] = e->n; +#define TAKE(v) do { for (k = 0; k < 16 && !(fr >> k & 1); k++); if (k == 16) goto fail; fr &= ~(1 << k); r[v] = (signed char)k; } while (0) + for (j = 0; j < e->nin; j++) if (last[j] >= -1 && last[j] != -2) TAKE(j); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; int ops[3], no = 0; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) ops[no++] = u->a; + if (uarity[u->op] > 1 || u->op == U_ST) ops[no++] = u->b; + if (uarity[u->op] > 2) ops[no++] = u->c; + for (j = 0; j < no; j++) if (last[ops[j]] == i && r[ops[j]] >= 0 && (fr >> r[ops[j]] & 1) == 0) fr |= 1 << r[ops[j]]; + if (u->op != U_ST) TAKE(u->d); + if (u->op != U_ST && last[u->d] == -2) fr |= 1 << r[u->d]; /* never used */ + } +#undef TAKE + free(last); e->reg = r; return; +fail: + free(last); free(r); e->reg = 0; +} +/* the install opcode. descriptor: slot, kind (0 recipe, 1 vm code), inputs, + outputs, payload address, payload length, parameter names (or 0). + returns 0, or -1 bad descriptor, -2 recipe syntax, -4 code doesn't lift, + -5 too big. */ +static int install(int d) +{ + int slot = mread(d), kind = mread(d + 1), nin = mread(d + 2), nout = mread(d + 3); + int pay = mread(d + 4), len = mread(d + 5), names = mread(d + 6), out[8], r; + Enh ne; + if ((unsigned)slot >= NENH || (unsigned)nin > 8 || (unsigned)nout > 8 || (kind != 0 && kind != 1)) return -1; + un = 0; unv = nin; uerr = 0; + r = kind == 0 ? parse_recipe(pay, names, nin, nout, out) : lift_vm(pay, len, nin, nout, out); + if (r) { if (trace) fprintf(stderr, "enh %d: install failed (%d)\n", slot, r); return r; } + memset(&ne, 0, sizeof ne); + if ((r = optimize(&ne, nin, out, nout))) return r; + ne.kind = kind; ne.live = 1; + regalloc(&ne); + if (enh[slot].live) { free(enh[slot].u); free(enh[slot].reg); } + enh[slot] = ne; + need_flush = 1; + if (trace) xdump(slot, &enh[slot]); + return 0; +} +#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[11]; /* m, s, r, tab, cov, Q, G, &J, store hook, install, enhancement fallback */ + +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); +} + +/* an enhancement, inlined: inputs from the data stack into w0..w15, the + optimized micro-ops, outputs back. x16 and x17 are scratch. */ +static void emit_enh(int s) +{ + Enh *e = &enh[s]; + signed char *r = e->reg; + int i, j, delta; + if (!r) { /* didn't fit in registers: x0 = data stack, w1 = slot, call the interpreter */ + E(0xaa1403e0); li(W1, s); ldrx_u(X11, ST, 80); blr(X11); E(0xaa0003f4); + return; + } + for (j = 0; j < e->nin; j++) if (r[j] >= 0) ldr_u(r[j], SP, 4 * (e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + int d = u->op == U_ST ? 0 : r[u->d], a = r[u->a], b = r[u->b], c = r[u->c]; + switch (u->op) { + case U_LI: li(d, u->imm); break; + case U_ADD: op3(0x0b000000, d, a, b); break; + case U_SUB: op3(0x4b000000, d, a, b); break; + case U_MUL: op3(0x1b007c00, d, a, b); break; + case U_SDIV: op3(0x1ac00c00, d, a, b); break; + case U_UDIV: op3(0x1ac00800, d, a, b); break; + case U_SREM: op3(0x1ac00c00, 16, a, b); E(0x1b008000 | b << 16 | a << 10 | 16 << 5 | d); break; /* msub */ + case U_UREM: op3(0x1ac00800, 16, a, b); E(0x1b008000 | b << 16 | a << 10 | 16 << 5 | d); break; + case U_AND: op3(0x0a000000, d, a, b); break; + case U_OR: op3(0x2a000000, d, a, b); break; + case U_XOR: op3(0x4a000000, d, a, b); break; + case U_SHL: op3(0x1ac02000, d, a, b); break; + case U_SHR: op3(0x1ac02400, d, a, b); break; + case U_SAR: op3(0x1ac02800, d, a, b); break; + case U_NEG: E(0x4b0003e0 | a << 16 | d); break; + case U_NOT: E(0x2a2003e0 | a << 16 | d); break; + case U_LT: E(0x6b00001f | b << 16 | a << 5); E(0x1a9fa7e0 | d); break; /* cmp; cset lt */ + case U_LTU: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f27e0 | d); break; /* cset lo */ + case U_EQ: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f17e0 | d); break; + case U_NE: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f07e0 | d); break; + case U_MIN: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 11 << 12 | a << 5 | d); break; + case U_MAX: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 12 << 12 | a << 5 | d); break; + case U_MINU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 3 << 12 | a << 5 | d); break; + case U_MAXU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 8 << 12 | a << 5 | d); break; + case U_MULHS: E(0x9b207c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; /* smull; lsr #32 */ + case U_MULHU: E(0x9ba07c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; + case U_CLZ: E(0x5ac01000 | a << 5 | d); break; + case U_ABS: E(0x7100001f | a << 5); E(0x5a800400 | a << 16 | 10 << 12 | a << 5 | d); break; /* cmp #0; cneg */ + case U_SEL: E(0x7100001f | a << 5); E(0x1a800000 | c << 16 | 1 << 12 | b << 5 | d); break; /* csel ne */ + case U_LD: /* out of range reads 0, like the interpreter */ + E(0x52800011); E(0x7144001f | a << 5); E(0x54000042); ldr_rr(17, M, a, UXTW); movw(d, 17); + break; + case U_ST: E(0x7144001f | a << 5); E(0x54000042); str_rr(b, M, a, UXTW); break; + } + } + delta = 4 * (e->nin - e->nout); + if (delta > 0) E(0x91000294 | delta << 10); + if (delta < 0) E(0xd1000294 | (-delta) << 10); + for (j = 0; j < e->nout; j++) str_u(r[e->out[j]], SP, 4 * (e->nout - 1 - j)); +} +static int inst_hook(int d) { return install(d); } +static long xrun(long sp, int slot) { return (long)xexec(&enh[slot], (int *)sp); } + +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; } + if (k == 21) { /* install: call into c, then return to it so it can flush */ + ldr_u(W0, SP, 0); ldrx_u(X11, ST, 72); blr(X11); str_u(W0, SP, 0); + li(W0, i + 1); b_to(x_exit); i++; break; + } + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { emit_enh(k - XOP0); i++; continue; } + if (k > 20) { E(0x12800000); b_to(x_exit); i++; break; } /* not wired: halt */ + 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). */ +#ifdef ZYLLVM +/* ---- llvm backend ---- + a tiered jit for hosts the arm64 backend doesn't cover. the interpreter + counts how often each block start is reached; a hot block is translated to + llvm ir (same block rules as the arm64 jit: it ends at call, jump, ret or + halt, and keeps going past a jz), optimized at O2 and compiled with orc. + enhancements are inlined as ir. stores into compiled words drop the blocks + that cover them, so self-modifying code still works. */ +#include +#include +#include +#include +#include +#include +static int HOT = 5000; /* runs before a block gets compiled: ZYHOT */ +static const char *lpasses = "default"; /* ZYPASSES */ +#define LMAXB 65536 +typedef int (*Blk)(int *mem, int *regs); +static Blk lt[MW]; /* address -> compiled block */ +static unsigned short hot[MW]; +static unsigned char lcov[MW]; /* 1 if a compiled block covers the word */ +static struct { int a, b; } lbl[LMAXB]; +static int nlbl, llvm_ok, nblocks; +static LLVMOrcLLJITRef jit; +static LLVMOrcThreadSafeContextRef tsc; +static LLVMContextRef ctx; +static LLVMTypeRef i8t, i32t, i64t, ptrt, i1t; +static LLVMBuilderRef bd; +static LLVMValueRef fn_, vm_, vregs, vs, vr; /* function, memory, regs, s and r slots */ +static LLVMModuleRef mod_; + +static void ldrop_all(void) +{ + memset(lt, 0, sizeof lt); memset(lcov, 0, sizeof lcov); memset(hot, 0, sizeof hot); nlbl = 0; + if (trace) fprintf(stderr, "llvm: dropped every block\n"); +} +/* a store to a word some block covers: write it, drop those blocks */ +static int lhook(int a, int v) +{ + int j, x, hit = 0; + if (m[a] == v) return 0; + m[a] = v; + for (j = 0; j < nlbl; j++) + if (lbl[j].a >= 0 && lbl[j].a <= a && a < lbl[j].b) { + lt[lbl[j].a] = 0; hot[lbl[j].a] = 0; + if (trace) fprintf(stderr, "llvm: dropped %d..%d\n", lbl[j].a, lbl[j].b - 1); + lbl[j].a = -1; hit = 1; + } + if (hit) { + memset(lcov, 0, sizeof lcov); + for (j = 0; j < nlbl; j++) if (lbl[j].a >= 0) for (x = lbl[j].a; x < lbl[j].b; x++) lcov[x] = 1; + } + return hit; +} +static int linstall(int d) { return install(d); } + +static LLVMValueRef K32(int v) { return LLVMConstInt(i32t, (unsigned)v, 0); } +static LLVMValueRef cptr(void *p) { return LLVMConstIntToPtr(LLVMConstInt(i64t, (unsigned long long)(size_t)p, 0), ptrt); } +static LLVMValueRef mslot(LLVMValueRef idx) { return LLVMBuildGEP2(bd, i32t, vm_, &idx, 1, ""); } +static LLVMValueRef ld(LLVMValueRef idx) { return LLVMBuildLoad2(bd, i32t, mslot(idx), ""); } +static void st(LLVMValueRef idx, LLVMValueRef v) { LLVMBuildStore(bd, v, mslot(idx)); } +static LLVMValueRef gets(void) { return LLVMBuildLoad2(bd, i32t, vs, ""); } +static void sets(LLVMValueRef v) { LLVMBuildStore(bd, v, vs); } +static LLVMValueRef add(LLVMValueRef a, int k) { return LLVMBuildAdd(bd, a, K32(k), ""); } +/* a load that reads 0 outside memory */ +static LLVMValueRef safeld(LLVMValueRef a) +{ + LLVMValueRef in = LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""); + LLVMValueRef v = ld(LLVMBuildSelect(bd, in, a, K32(0), "")); + return LLVMBuildSelect(bd, in, v, K32(0), ""); +} +static void push(LLVMValueRef v) { LLVMValueRef s = add(gets(), -1); sets(s); st(s, v); } +/* leave the block: write s and r back, return the next vm address */ +static void leave(LLVMValueRef next) +{ + LLVMValueRef r0 = K32(0), r1 = K32(1); + LLVMBuildStore(bd, gets(), LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, vr, ""), LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, "")); + LLVMBuildRet(bd, next); +} +static LLVMBasicBlockRef newbb(void) { return LLVMAppendBasicBlockInContext(ctx, fn_, ""); } +static LLVMValueRef callp(void *f, LLVMTypeRef ret, LLVMTypeRef *at, int n, LLVMValueRef *args) +{ + LLVMTypeRef ft = LLVMFunctionType(ret, at, (unsigned)n, 0); + return LLVMBuildCall2(bd, ft, cptr(f), args, (unsigned)n, ""); +} +/* an enhancement as ir: the same semantics as ev() */ +static void ir_enh(Enh *e) +{ + LLVMValueRef *v = calloc(e->nv + 1, sizeof *v), s = gets(), z = K32(0), q, d, t, c1, c2; + int i, j; + LLVMTypeRef i64 = i64t; + for (j = 0; j < e->nin; j++) v[j] = ld(add(s, e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + LLVMValueRef a = u->op == U_LI ? 0 : v[u->a], b = uarity[u->op] > 1 || u->op == U_ST ? v[u->b] : 0, c = uarity[u->op] > 2 ? v[u->c] : 0, r = 0; + switch (u->op) { + case U_LI: r = K32(u->imm); break; + case U_ADD: r = LLVMBuildAdd(bd, a, b, ""); break; + case U_SUB: r = LLVMBuildSub(bd, a, b, ""); break; + case U_MUL: r = LLVMBuildMul(bd, a, b, ""); break; + case U_SDIV: case U_SREM: /* /0 and INT_MIN/-1 are defined, like the cpu */ + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + c2 = LLVMBuildAnd(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32((int)0x80000000), ""), LLVMBuildICmp(bd, LLVMIntEQ, b, K32(-1), ""), ""); + d = LLVMBuildSelect(bd, LLVMBuildOr(bd, c1, c2, ""), K32(1), b, ""); + if (u->op == U_SDIV) { q = LLVMBuildSDiv(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, z, q, ""); } + else { q = LLVMBuildSRem(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, a, LLVMBuildSelect(bd, c2, z, q, ""), ""); } + break; + case U_UDIV: case U_UREM: + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + d = LLVMBuildSelect(bd, c1, K32(1), b, ""); + if (u->op == U_UDIV) r = LLVMBuildSelect(bd, c1, z, LLVMBuildUDiv(bd, a, d, ""), ""); + else r = LLVMBuildSelect(bd, c1, a, LLVMBuildURem(bd, a, d, ""), ""); + break; + case U_AND: r = LLVMBuildAnd(bd, a, b, ""); break; + case U_OR: r = LLVMBuildOr(bd, a, b, ""); break; + case U_XOR: r = LLVMBuildXor(bd, a, b, ""); break; + case U_SHL: r = LLVMBuildShl(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SHR: r = LLVMBuildLShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SAR: r = LLVMBuildAShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_NEG: r = LLVMBuildSub(bd, z, a, ""); break; + case U_NOT: r = LLVMBuildNot(bd, a, ""); break; + case U_LT: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), i32t, ""); break; + case U_LTU: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), i32t, ""); break; + case U_EQ: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, b, ""), i32t, ""); break; + case U_NE: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntNE, a, b, ""), i32t, ""); break; + case U_MIN: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), a, b, ""); break; + case U_MAX: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSGT, a, b, ""), a, b, ""); break; + case U_MINU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), a, b, ""); break; + case U_MAXU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntUGT, a, b, ""), a, b, ""); break; + case U_MULHS: case U_MULHU: { + LLVMValueRef x = u->op == U_MULHS ? LLVMBuildSExt(bd, a, i64, "") : LLVMBuildZExt(bd, a, i64, ""); + LLVMValueRef y = u->op == U_MULHS ? LLVMBuildSExt(bd, b, i64, "") : LLVMBuildZExt(bd, b, i64, ""); + r = LLVMBuildTrunc(bd, LLVMBuildLShr(bd, LLVMBuildMul(bd, x, y, ""), LLVMConstInt(i64, 32, 0), ""), i32t, ""); + break; } + case U_CLZ: { + unsigned id = LLVMLookupIntrinsicID("llvm.ctlz", 9); + LLVMValueRef f = LLVMGetIntrinsicDeclaration(mod_, id, &i32t, 1), args[2]; + args[0] = a; args[1] = LLVMConstInt(i1t, 0, 0); + r = LLVMBuildCall2(bd, LLVMIntrinsicGetType(ctx, id, &i32t, 1), f, args, 2, ""); + break; } + case U_ABS: t = LLVMBuildICmp(bd, LLVMIntSLT, a, z, ""); r = LLVMBuildSelect(bd, t, LLVMBuildSub(bd, z, a, ""), a, ""); break; + case U_SEL: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntNE, a, z, ""), b, c, ""); break; + case U_LD: r = safeld(a); break; + case U_ST: { + LLVMBasicBlockRef yes = newbb(), done = newbb(); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), yes, done); + LLVMPositionBuilderAtEnd(bd, yes); st(a, b); LLVMBuildBr(bd, done); + LLVMPositionBuilderAtEnd(bd, done); + break; } + } + if (u->op != U_ST) v[u->d] = r; + } + s = add(s, e->nin - e->nout); sets(s); + for (j = 0; j < e->nout; j++) st(add(s, e->nout - 1 - j), v[e->out[j]]); + free(v); +} +static void llvm_init(void) +{ + LLVMErrorRef err; + if (getenv("ZYHOT")) HOT = atoi(getenv("ZYHOT")); + if (HOT < 1) HOT = 1; + if (HOT > 65000) HOT = 65000; + if (getenv("ZYPASSES")) lpasses = getenv("ZYPASSES"); + LLVMInitializeNativeTarget(); LLVMInitializeNativeAsmPrinter(); + if ((err = LLVMOrcCreateLLJIT(&jit, 0))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return; } + tsc = LLVMOrcCreateNewThreadSafeContext(); + ctx = LLVMOrcThreadSafeContextGetContext(tsc); + i1t = LLVMInt1TypeInContext(ctx); i8t = LLVMInt8TypeInContext(ctx); i32t = LLVMInt32TypeInContext(ctx); + i64t = LLVMInt64TypeInContext(ctx); ptrt = LLVMPointerTypeInContext(ctx, 0); + bd = LLVMCreateBuilderInContext(ctx); + llvm_ok = 1; +} +/* compile the block at p; 0 if it couldn't be */ +static Blk lcompile(int p) +{ + char name[32]; LLVMTypeRef pt[2], ft; LLVMValueRef s, a, b, v, r, args[2]; LLVMTypeRef at[2]; + LLVMOrcExecutorAddress addr; LLVMErrorRef err; LLVMPassBuilderOptionsRef po; + int i = p, n = 0, w, k, t, done = 0; + if (!llvm_ok || nlbl >= LMAXB) return 0; + sprintf(name, "b%d_%d", p, nblocks++); + mod_ = LLVMModuleCreateWithNameInContext(name, ctx); + pt[0] = ptrt; pt[1] = ptrt; + ft = LLVMFunctionType(i32t, pt, 2, 0); + fn_ = LLVMAddFunction(mod_, name, ft); + vm_ = LLVMGetParam(fn_, 0); vregs = LLVMGetParam(fn_, 1); + LLVMPositionBuilderAtEnd(bd, newbb()); + vs = LLVMBuildAlloca(bd, i32t, "s"); vr = LLVMBuildAlloca(bd, i32t, "r"); + { LLVMValueRef r0 = K32(0), r1 = K32(1); + sets(LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, ""), "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, ""), ""), vr); } + while (!done) { + if (i >= MW) { leave(K32(MW)); break; } + if (n++ >= 1024) { leave(K32(i)); break; } + w = m[i]; + lcov[i] = 1; + if (w & 1) { + /* a literal followed by call, jump or jz: a known target */ + if (i + 1 < MW && !(m[i + 1] & 1) && (k = m[i + 1] / 2) >= 6 && k <= 8) { + t = w >> 1; lcov[i + 1] = 1; + if (k == 8) { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + s = gets(); a = ld(s); sets(add(s, 1)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(K32(t)); + LLVMPositionBuilderAtEnd(bd, go); + i += 2; continue; + } + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 2)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(K32(t)); i += 2; break; + } + push(K32(w >> 1)); i++; continue; + } + k = w / 2; + s = gets(); + switch (k) { + case 0: leave(K32(MW)); done = 1; break; + case 1: st(s, safeld(ld(s))); break; + case 2: { + LLVMBasicBlockRef in = newbb(), cv = newbb(), plain = newbb(), out = newbb(), quit = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), in, out); + LLVMPositionBuilderAtEnd(bd, in); + v = LLVMBuildLoad2(bd, i8t, LLVMBuildGEP2(bd, i8t, cptr(lcov), &a, 1, ""), ""); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, LLVMConstInt(i8t, 0, 0), ""), cv, plain); + LLVMPositionBuilderAtEnd(bd, plain); st(a, b); LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, cv); + at[0] = i32t; at[1] = i32t; args[0] = a; args[1] = b; + v = callp((void *)lhook, i32t, at, 2, args); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, K32(0), ""), quit, out); + LLVMPositionBuilderAtEnd(bd, quit); leave(K32(i + 1)); /* a block died: back to the loop */ + LLVMPositionBuilderAtEnd(bd, out); + break; } + case 3: a = ld(s); st(s, safeld(LLVMBuildAdd(bd, add(s, 1), a, ""))); break; + case 4: sets(add(s, 1)); break; + case 5: a = ld(s); b = ld(add(s, 1)); st(s, b); st(add(s, 1), a); break; + case 6: case 7: + a = ld(s); sets(add(s, 1)); + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 1)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(a); done = 1; break; + case 8: { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, b, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(a); + LLVMPositionBuilderAtEnd(bd, go); + break; } + case 9: + r = add(LLVMBuildLoad2(bd, i32t, vr, ""), -1); LLVMBuildStore(bd, r, vr); + leave(ld(r)); done = 1; break; + case 10: v = callp((void *)Q, i8t, 0, 0, 0); push(LLVMBuildSExt(bd, v, i32t, "")); break; + case 11: + if (sizeof J == 1) push(LLVMBuildZExt(bd, LLVMBuildLoad2(bd, i8t, cptr(&J), ""), i32t, "")); + else push(LLVMBuildLoad2(bd, i32t, cptr(&J), "")); + break; + case 12: at[0] = i8t; args[0] = LLVMBuildTrunc(bd, ld(s), i8t, ""); callp((void *)G, LLVMVoidTypeInContext(ctx), at, 1, args); sets(add(s, 1)); break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + a = ld(s); b = ld(add(s, 1)); s = add(s, 1); sets(s); + switch (k) { + case 13: v = LLVMBuildAdd(bd, b, a, ""); break; + case 14: v = LLVMBuildSub(bd, b, a, ""); break; + case 15: v = LLVMBuildMul(bd, b, a, ""); break; + case 16: v = LLVMBuildAnd(bd, b, a, ""); break; + case 17: v = LLVMBuildOr(bd, b, a, ""); break; + case 18: v = LLVMBuildXor(bd, b, a, ""); break; + case 19: v = LLVMBuildAShr(bd, b, LLVMBuildAnd(bd, a, K32(31), ""), ""); break; + default: v = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, b, a, ""), i32t, ""); + } + st(s, v); break; + case 21: /* install: then back to the loop, which drops every block */ + at[0] = i32t; args[0] = ld(s); + st(s, callp((void *)linstall, i32t, at, 1, args)); + leave(K32(i + 1)); done = 1; break; + default: + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { ir_enh(&enh[k - XOP0]); break; } + leave(K32(MW)); done = 1; /* not wired: halt */ + } + i++; + } + lbl[nlbl].a = p; lbl[nlbl++].b = i; + po = LLVMCreatePassBuilderOptions(); + if ((err = LLVMRunPasses(mod_, lpasses, 0, po))) { LLVMConsumeError(err); } + LLVMDisposePassBuilderOptions(po); + if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, LLVMOrcLLJITGetMainJITDylib(jit), LLVMOrcCreateNewThreadSafeModule(mod_, tsc)))) { + char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; + } + if ((err = LLVMOrcLLJITLookup(jit, &addr, name))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; } + if (trace) fprintf(stderr, "llvm: %d..%d compiled\n", p, i - 1); + return (Blk)(size_t)addr; +} +#endif +#define LD(x) ((unsigned)(x) < MW ? m[x] : 0) +static void run(int p) +{ + int s = DS0, r = RS0, w, a, b, xfer = 1; + unsigned long long steps = 0; +#ifdef ZYLLVM + int regs[2]; + if (!getenv("ZYNOLLVM")) llvm_init(); +#endif + while ((unsigned)p < MW) { +#ifdef ZYLLVM + if (xfer && llvm_ok) { /* at a block start: run it compiled, or count it */ + xfer = 0; + if (!lt[p] && hot[p] < 65535 && ++hot[p] == HOT && !(lt[p] = lcompile(p))) hot[p] = 65535; + if (lt[p]) { + regs[0] = s; regs[1] = r; + p = lt[p](m, regs); + s = regs[0]; r = regs[1]; + if (need_flush) { need_flush = 0; ldrop_all(); } + xfer = 1; + continue; + } + } +#endif + 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) { +#ifdef ZYLLVM + if (lcov[a]) lhook(a, b); else +#endif + 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++; xfer = 1; break; + case 7: p = a; s++; xfer = 1; break; + case 8: if (!b) { p = a; xfer = 1; } s += 2; break; + case 9: p = m[--r]; xfer = 1; 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; + case 21: + m[s] = install(a); +#ifdef ZYLLVM + if (need_flush) { need_flush = 0; ldrop_all(); } +#endif + break; + default: + if (w / 2 >= XOP0 && w / 2 < XOP0 + NENH && enh[w / 2 - XOP0].live) s = (int)(xexec(&enh[w / 2 - XOP0], m + s) - m); + else p = MW; /* halt: unwired opcodes and the reserved negative ones */ + } + } + 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; + S[9] = (long)inst_hook; S[10] = (long)xrun; + 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); + if (need_flush) { need_flush = 0; jitwrite(1); flush(); jitwrite(0); } + } + } +#else + run(GORG); +#endif + return 0; +} diff --git a/docs/history/11-types-enhancements/code/examples/echo.zc b/docs/history/11-types-enhancements/code/examples/echo.zc new file mode 100644 index 0000000..01f28b0 --- /dev/null +++ b/docs/history/11-types-enhancements/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/11-types-enhancements/code/examples/fact.zc b/docs/history/11-types-enhancements/code/examples/fact.zc new file mode 100644 index 0000000..2a218b2 --- /dev/null +++ b/docs/history/11-types-enhancements/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/11-types-enhancements/code/examples/hello.zc b/docs/history/11-types-enhancements/code/examples/hello.zc new file mode 100644 index 0000000..f36a810 --- /dev/null +++ b/docs/history/11-types-enhancements/code/examples/hello.zc @@ -0,0 +1 @@ +fn main() { puts("hello, world!\n"); return 0; } diff --git a/docs/history/11-types-enhancements/code/examples/lists.zc b/docs/history/11-types-enhancements/code/examples/lists.zc new file mode 100644 index 0000000..6ac276e --- /dev/null +++ b/docs/history/11-types-enhancements/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 { let b = new(1); b[0] = v; return u*b; } +fn mklist(cap) -> .u { let l = new(cap + 1); l[0] = 0; return u*l; } +// item m*arrives (it was given down), and goes d*on into the borrowed list +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn show(.m l) +{ + let i = 1; + putc('['); + while (i <= l[0]) { if (i > 1) putc(' '); putn(l[i][0]); i++; } + putc(']'); + return 0; +} +fn squares(n) -> .u +{ + let l = mklist(n), i = 0; + while (i < n) { + let b = box(i * i); + push(l, d*b); + i++; + } + return u*l; +} +fn main() +{ + let before = live_objects(); + { + let 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/11-types-enhancements/code/examples/repl.zc b/docs/history/11-types-enhancements/code/examples/repl.zc new file mode 100644 index 0000000..b7b81b8 --- /dev/null +++ b/docs/history/11-types-enhancements/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. +let buf[4000]; +fn readchunk() +{ + let 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() +{ + let 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(d*q); + } + return 0; +} diff --git a/docs/history/11-types-enhancements/code/examples/selfpatch.zc b/docs/history/11-types-enhancements/code/examples/selfpatch.zc new file mode 100644 index 0000000..074ccec --- /dev/null +++ b/docs/history/11-types-enhancements/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() +{ + let 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/11-types-enhancements/code/examples/typed.zc b/docs/history/11-types-enhancements/code/examples/typed.zc new file mode 100644 index 0000000..d91fe6a --- /dev/null +++ b/docs/history/11-types-enhancements/code/examples/typed.zc @@ -0,0 +1,47 @@ +// types: structs, a generic container, and looking at it all through reflection +typecheck on; +struct point { int x, y; }; +struct vec { int len, cap; *T items; }; + +fn mkvec(int cap) -> *vec.u +{ + *vec v = new(vec); + v.cap = cap; + v.items = new(T, cap); + return u*v; +} +// x is given away (.d): the vector's memory holds it from now on, and the +// collector looks after it +fn push(*vec v, T.d x) -> bool +{ + if (v.len == v.cap) { free(d*x); return 0; } + v.items[v.len] = d*x; + v.len++; + return 1; +} +fn show(word t) +{ + let i = 0; + tprint(t); puts(" is "); putn(tsize(t)); puts(" words: "); + while (i < tnfields(t)) { if (i) puts(", "); puts(tfname(t, i)); puts(" "); tprint(tftype(t, i)); i++; } + putc(10); + return 0; +} +fn main() -> int +{ + *vec<*point> v = mkvec<*point>(4); + int i = 0; + while (i < 3) { + *point p = new(point); + p.x = i; p.y = i * i; + push(v, d*p); + i++; + } + puts("last: "); putn(v.items[2].y); putc(10); + show(typeof(point)); + show(typeof(*v)); + puts("push is "); tprint(sigof(push)); putc(10); + // generic code is compiled once, so what mkvec stamped is vec + puts("the heap says v is a "); tprint(typeof_obj(v)); puts(", and v.items[0] is a "); tprint(typeof_obj(v.items[0])); putc(10); + return 0; +} diff --git a/docs/history/11-types-enhancements/code/examples/wiring.zc b/docs/history/11-types-enhancements/code/examples/wiring.zc new file mode 100644 index 0000000..ed30935 --- /dev/null +++ b/docs/history/11-types-enhancements/code/examples/wiring.zc @@ -0,0 +1,19 @@ +// virtual enhancements: custom opcodes wired into the cpu while compiling. +// the recipes run through the core's optimizer; the jit inlines the result. +enhance popcount(x) micro + "r1 = shr x 1; r1 = and r1 0x55555555; x = sub x r1" + "; r1 = shr x 2; r1 = and r1 0x33333333; x = and x 0x33333333; x = add x r1" + "; r1 = shr x 4; x = add x r1; x = and x 0x0f0f0f0f; x = mul x 0x01010101; x = shr x 24"; +enhance div10(x) micro "x = udiv x 10"; // becomes a multiply-high, no divide +enhance hypot2(a, b) vm { 0 $ * ~ 0 $ * + }; // lifted from vm code +enhance minmax(a, b) -> 2 micro "r2 = min a b; r1 = max a b; r0 = r2"; +let lo, hi; +fn main() +{ + putn(popcount(0xff00ff)); putc(' '); + putn(div10(12345)); putc(' '); + putn(hypot2(3, 4)); putc(' '); + asm { 9 4 minmax hi ! lo ! } + putn(lo); putc('/'); putn(hi); putc(10); + return 0; +} diff --git a/docs/history/11-types-enhancements/code/genome.h b/docs/history/11-types-enhancements/code/genome.h new file mode 100644 index 0000000..26cf3dd --- /dev/null +++ b/docs/history/11-types-enhancements/code/genome.h @@ -0,0 +1,3596 @@ +#define GORG 786432 +static const int genome[] = { +1966081,1310721,4,1677827,14,839142,843895,1310721,2,3,28,1310721,4,1310721,2,4, +1310721,2,2,42,1572911,14,1,1310721,2,3,26,1310721,4,18,0,0, +2,1,786475,0,786469,786471,786473,97,0,98,0,97,32,61,32,115, +100,105,118,32,97,32,98,0,1,0,2,1,786501,0,786495,786497, +786499,97,0,98,0,97,32,61,32,115,114,101,109,32,97,32, +98,0,2,0,2,1,786527,0,786521,786523,786525,97,0,98,0,97, +32,61,32,115,104,108,32,97,32,98,0,1310721,2,3,28,1310721, +4,1310721,2,4,1310721,2,2,24,1,1573113,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,1,28,1310721,4,20,1573147,14,1,1310721,2,1, +26,1310721,4,18,1310721,2,1,28,1310721,4,22,1573181,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,0,1,1573217,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, +1573349,16,1310721,2,2,1310721,2,3,26,2,26,2,1573079,12,8,1310721, +2,3,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1573261,14,1,1573357,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,1573449,16,91,1573079,12,8,1310721,2,1,1310721,2,2,28,10,3, +6,10,4,8,1310721,2,2,1,40,1573503,16,1573489,14,50,49,52, +55,52,56,51,54,52,56,0,1573467,1573231,12,8,1,1573717,14,3, +1573641,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,46,26,10,3, +6,10,4,8,1310721,2,1310721,2,2,21,44,10,3,6,10,4, +8,1310721,2,2,1,6,1,10,28,34,63,38,3,26,1573637,16, +1573641,14,1573503,14,1310721,2,27,26,2,1573709,16,1310721,2,3,26,1310721, +2,27,26,1,6,2,-1,26,1,6,5,6,4,10,8,26, +2,1573079,12,8,1573641,14,1,1573717,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,1573823,16,1310721,2,3,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1573761,14,1310721, +2,3,26,2,1573839,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,1574009,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,1574011,14,1,1574053,16,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1573893,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,1574125,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,1574307,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,1574189, +14,1,1574315,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, +1574483,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,1574379,14,1,1574491,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,1574683,16, +1574569,1310721,2,2,10,3,6,10,4,8,1,1574997,14,1310721,2,9, +26,2,1,40,3,36,1574957,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,1574919,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,1574683,14,1574569,1310721,2,7,26,2,10,3,6,10, +4,8,1310721,2,5,26,2,1574997,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,1575115,16,1574569,1310721,2,2,10,3,6,10, +4,8,1,1575351,14,1310721,2,2,1,40,1575177,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,1575263,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,1574571,12,10,3,6, +10,4,8,1310721,2,5,26,2,1575335,16,1,1310721,2,7,26,2, +28,1575351,14,1310721,2,7,26,2,1575351,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,3,26,2,1, +28,1,6,1,10,28,34,63,38,3,26,1575461,16,1310721,2,2, +1575519,14,1310721,2,2,1310721,2,3,26,2,1575011,12,8,1310721,2,5, +26,2,1575509,16,1,1574569,2,28,1575519,14,1574569,2,1575519,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,1574505,1310721,2,3,26,2,63,32,26, +2,30,1575595,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,1574505,1,26,3,10,3, +6,10,4,8,1310721,2,2,65,40,1575825,16,1574505,1310721,2,2,26, +1574505,1310721,2,2,3,28,26,2,1574505,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,1575721,14,1575609,524289,10,3,6,10,4,8, +1575611,1,65,1574329,12,8,1,1575861,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,524289,13,26, +40,3,36,1575953,16,1310721,2,2,1575609,2,40,1,6,1,10,28, +34,63,38,1,10,28,1575955,14,1,1576035,16,1310721,2,2,7,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,1576037, +14,1,1576089,16,1310721,2,2,9,1,10,28,26,2,3,32,1, +6,1,10,28,34,63,38,1,10,28,1576091,14,1,1576097,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721,4,1576175,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,1576127,1573231,12,8,1573195,12,8,1,1576197, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,13,26,1310721,2,5,26, +4,7,1310721,2,7,26,4,17,1310721,2,9,26,4,1,1310721,2, +11,26,4,1310721,2,2,1,40,1576331,16,1310721,2,5,26,13,10, +3,6,10,4,8,1310721,2,9,26,2,1310721,2,5,26,2,40, +1576437,16,1310721,2,9,26,1310721,2,9,26,2,1310721,2,9,26,2, +26,10,3,6,10,4,8,1310721,2,7,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1576331,14,1575611,1310721,2,7,26,2, +26,2,1576539,16,1310721,2,11,26,1575611,1310721,2,7,26,2,26,2, +10,3,6,10,4,8,1575611,1310721,2,7,26,2,26,1310721,2,11, +26,2,13,26,2,10,3,6,10,4,8,1576837,14,1575609,2,1310721, +2,9,26,2,26,1310721,10,40,3,36,1576627,16,1310721,2,11,26, +1575609,2,10,3,6,10,4,8,1575609,1575609,2,1310721,2,9,26,2, +26,10,3,6,10,4,8,1576837,14,1575679,2,1576641,16,1578563,12,8, +1575611,1310721,2,7,26,2,26,2,1576743,16,1310721,2,11,26,1575611,1310721, +2,7,26,2,26,2,10,3,6,10,4,8,1575611,1310721,2,7, +26,2,26,1310721,2,11,26,2,13,26,2,10,3,6,10,4, +8,1576837,14,1575609,2,1310721,2,9,26,2,26,1310721,10,40,3,36, +1576831,16,1310721,2,11,26,1575609,2,10,3,6,10,4,8,1575609,1575609, +2,1310721,2,9,26,2,26,10,3,6,10,4,8,1576837,14,1576111, +12,8,1310721,2,13,26,1310721,2,11,26,2,13,26,10,3,6, +10,4,8,1310721,2,11,26,2,1,26,1310721,2,9,26,2,10, +3,6,10,4,8,1310721,2,11,26,2,3,26,1310721,2,7,26, +2,10,3,6,10,4,8,1310721,2,11,26,2,5,26,3,10, +3,6,10,4,8,1310721,2,11,26,2,7,26,1310721,2,13,26, +2,1459366445,36,10,3,6,10,4,8,1310721,2,11,26,2,9,26, +1,10,3,6,10,4,8,1310721,2,11,26,2,11,26,1310721,2, +3,26,2,10,3,6,10,4,8,1310721,2,13,26,2,1,1310721, +2,9,26,2,13,28,1574329,12,8,1310721,2,13,26,2,1577123,14, +1,1310721,2,15,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +4,1310721,2,2,1,1576211,12,1577173,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,1575875,12,1, +6,1,10,28,34,63,38,3,26,1577245,16,1,1577273,14,1310721,2, +2,13,1,10,28,26,2,13,28,1577273,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,1575875, +12,1,6,1,10,28,34,63,38,3,26,1577345,16,1,1577369,14, +1310721,2,2,3,1,10,28,26,2,1577369,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,4,1310721,2,2,13, +28,1310721,2,3,26,4,1310721,2,3,26,2,1,26,2,13,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,1577711,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,1575875, +12,1577651,16,1310721,2,9,26,2,5,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,1577653,14,1,1577673,16,1310721,2,9,26, +2,1577383,12,8,1310721,2,7,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1577491,14,1310721,2,3,26,2,9,26,1,10, +3,6,10,4,8,1310721,2,3,26,2,13,26,1575611,1310721,2,3, +26,2,3,26,2,26,2,10,3,6,10,4,8,1575611,1310721,2, +3,26,2,3,26,2,26,1310721,2,3,26,2,10,3,6,10, +4,8,1,1577837,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,4,1310721,2,2,1575875,12,1577895,16,1310721,2,2, +1577383,12,8,1,1577903,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,1575875, +12,1577997,16,1310721,2,2,5,1,10,28,26,1310721,2,3,26,2, +10,3,6,10,4,8,1310721,2,2,1578009,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,1575875,12,1,6,1,10,28,34,63,38,3,26,1578089, +16,3,1578133,14,1310721,2,2,9,1,10,28,26,2,5,32,1, +6,1,10,28,34,63,38,1,10,28,1578143,16,1,1578287,14,1310721, +2,2,9,1,10,28,26,1310721,2,2,9,1,10,28,26,2, +5,34,10,3,6,10,4,8,1578023,2,32769,40,1578263,16,2031617,1578023, +2,26,1310721,2,2,10,3,6,10,4,8,1578023,1,6,2,1, +6,3,26,5,6,4,10,8,8,1578279,14,1578025,3,10,3,6, +10,4,8,1,1578287,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,1578399,16,1310721,2,2,2,1578031,12,8,1310721,2, +1,6,2,1,6,3,26,5,6,4,10,8,8,1578329,14,1, +1578407,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4, +1578023,2,1578541,16,1578023,1,6,2,1,6,-1,26,5,6,4,10, +8,8,1310721,2,2031617,1578023,2,26,2,10,3,6,10,4,8,1310721, +2,2,1310721,2,2,1310721,2,2,13,1,10,28,26,2,26,13, +28,1578301,12,8,1578433,14,1,1578549,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,7,28,1310721,4,1,1310721,2,5,26,4,1578023,1,10, +3,6,10,4,8,1578025,1,10,3,6,10,4,8,1674931,12,8, +1578421,12,8,1578025,2,1578815,16,1578025,1,10,3,6,10,4,8,1310721, +2,524289,10,3,6,10,4,8,1310721,2,2,1575609,2,40,1578811,16, +1310721,2,2,5,26,2,7,28,1,6,1,10,28,34,63,38, +3,26,1578765,16,1310721,2,2,13,26,1310721,2,2,1310721,2,2,1, +26,2,26,1578301,12,8,1310721,2,1310721,2,2,1310721,2,2,1,26, +2,26,10,3,6,10,4,8,1578421,12,8,1578673,14,1578631,14,1310721, +2,524289,10,3,6,10,4,8,1310721,2,2,1575609,2,40,1579183,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,1579081,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,13, +26,1575611,1310721,2,2,3,26,2,26,2,10,3,6,10,4,8, +1575611,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,1579145,14,1310721,2,2,5,26,2,7,28,1,6,1,10, +28,34,63,38,3,26,1579145,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,1578833,14,1575675,1,6,2,1,6,3,26,5, +6,4,10,8,8,1575677,1575677,2,1310721,2,5,26,2,26,10,3, +6,10,4,8,1310721,2,5,26,2,1579257,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,1575609,2,40,1579413,16,1310721,2,2,5,26, +2,3,32,1579373,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,1579303,14,1310721,2,3,26,2,1579429, +14,1,1310721,2,5,26,1310721,4,18,0,0,0,0,0,0,0, +0,0,0,0,0,789734,113,64,33,36,95,126,99,106,122,114, +44,63,46,43,45,42,38,124,94,62,60,37,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,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,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,1582033,14,122,99, +58,32,108,105,110,101,32,0,1582013,1573231,12,8,1579523,2,1573371,12, +8,1582061,14,58,32,0,1582055,1573231,12,8,1310721,2,2,1573231,12,8, +21,1573079,12,8,1573195,12,8,1,1582103,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,3,26,4,1310721,2,4, +1582169,14,122,99,58,32,108,105,110,101,32,0,1582149,1573231,12,8, +1579523,2,1573371,12,8,1582197,14,58,32,0,1582191,1573231,12,8,1310721,2, +2,1573231,12,8,1582227,14,58,32,0,1582221,1573231,12,8,1310721,2,3, +26,2,1573231,12,8,21,1573079,12,8,1573195,12,8,1,1582273,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4, +1581763,2,1582343,16,1581767,2,1,6,1,10,28,34,63,38,1,10, +28,1582345,14,1,1582361,16,1310721,2,2,1581991,12,8,1,1582369,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3, +26,4,1310721,2,4,1581763,2,1582449,16,1581767,2,1,6,1,10,28, +34,63,38,1,10,28,1582451,14,1,1582483,16,1466881,1310721,2,2,26, +2,1310721,2,3,26,2,1582117,12,8,1,1582491,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,1582625,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,1582535,14, +1310721,2,3,26,2,16385,3,28,32,1582649,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,4,1310721,2,2,1582505, +12,1310721,2,3,26,4,3,1582865,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,1582781,16,1582865,14,1310721,2, +5,26,2,1310721,2,2,1573853,12,1582819,16,1310721,2,5,26,2,1583145, +14,1310721,2,3,26,1310721,2,3,26,2,3,26,16385,3,28,32, +10,3,6,10,4,8,1582701,14,1310721,2,7,26,1310721,2,2,1573731, +12,10,3,6,10,4,8,1579445,2,1310721,2,7,26,2,26,5, +26,1409025,40,3,36,1582973,16,1582965,14,115,116,114,105,110,103,32, +112,111,111,108,32,102,117,108,108,0,1582931,1581991,12,8,1579445,2, +1,26,1,10,3,6,10,4,8,1310721,2,5,26,1579445,2,3, +26,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,2,1310721, +2,7,26,2,3,26,1574139,12,8,1579445,1579445,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,1583145,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,1579447,2, +1310721,2,7,26,4,1579447,2,8193,40,3,36,1583275,16,1583267,14,115, +121,109,98,111,108,32,116,97,98,108,101,32,102,117,108,108, +0,1583231,1581991,12,8,1579447,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,1559041,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,1583621, +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,1583933,16,1310721,2,3, +26,2,1579451,2,40,3,36,1583737,16,3,1583799,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,1583809,16,3,1583871,14, +1417729,1310721,2,3,26,2,26,2,15,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1583889, +16,1310721,2,3,26,2,1583947,14,1310721,2,3,26,1458689,1310721,2,3, +26,2,26,2,3,28,10,3,6,10,4,8,1583685,14,3,1, +10,28,1583947,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1579447,2,1310721,2,2,10,40,1584071,16,1579447,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1409537,1579447,2,26, +2,3,1,10,28,26,1458689,1579447,2,26,2,10,3,6,10,4, +8,1583979,14,1,1584079,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,4,1310721,2,2,1582663,12,1583635,12,1584131,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2, +3,26,4,1310721,2,4,1579455,2,1310721,2,5,26,4,1310721,2,5, +26,2,1584235,16,1579455,1491457,1310721,2,5,26,2,26,2,10,3,6, +10,4,8,1584377,14,1579453,1,6,2,1,6,3,26,5,6,4, +10,8,8,1310721,2,5,26,1579453,2,10,3,6,10,4,8,1310721, +2,5,26,2,16385,40,3,36,1584377,16,1584369,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,1584313,1581991,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,1584461,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,1584649,16, +1475073,1310721,2,2,26,2,1310721,2,3,26,2,1584967,12,8,1310721,2, +5,26,1491457,1310721,2,2,26,2,10,3,6,10,4,8,1491457,1310721, +2,2,26,1579455,2,10,3,6,10,4,8,1579455,1310721,2,2,10, +3,6,10,4,8,1310721,2,1310721,2,5,26,2,10,3,6,10, +4,8,1584503,14,1,1584657,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,4,1581893,2,1584703,16,1,1584829,14,1581747, +2,1581751,2,40,3,36,1584765,16,1584757,14,112,114,111,103,114,97, +109,32,116,111,111,32,98,105,103,0,1584725,1581991,12,8,1581747,2, +1581749,2,26,1310721,2,2,10,3,6,10,4,8,1581747,1,6,2, +1,6,3,26,5,6,4,10,8,8,1,1584829,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,1584671,12,8,1,1584893,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,1584671,12,8,1,1584953,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3,26,4,1310721,2, +4,1581893,2,1585009,16,1,1585067,14,1310721,2,2,1581749,2,26,1310721,2, +3,26,2,1310721,2,3,26,2,26,3,26,10,3,6,10,4, +8,1,1585067,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1310721,2,2,1584843,12,8,15,1584907,12,8,1, +1585127,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1581747,2,1310721,2,4,2097153,3,28,1584843,12,8,1310721,2,2,1585187,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +4,1310721,2,2,3,1,1583159,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, +1585287,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,1585363,16,1425921,1310721,2, +2,26,2,1584843,12,8,1,1585439,14,1581893,2,1585377,16,1,1585439,14, +1450497,1310721,2,2,26,1581747,2,1450497,1310721,2,2,26,2,1584145,12,10, +3,6,10,4,8,2097153,3,28,1584843,12,8,1,1585439,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1310721, +2,2,1583635,12,1310721,2,3,26,4,1310721,2,3,26,2,1,40, +1585539,16,1310721,2,3,26,1310721,2,2,1585201,12,10,3,6,10,4, +8,1310721,2,3,26,2,1585301,12,8,13,1584907,12,8,1,1585571,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +4,1310721,1584843,12,8,3,1584907,12,8,1310721,2,2,1585649,16,1310721,2, +2,1584843,12,8,27,1584907,12,8,1,1585657,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,4,1585141,12,1310721,2, +3,26,4,15,1584907,12,8,1310721,2,5,26,1581747,2,10,3,6, +10,4,8,1310721,2,2,2,1585795,16,1310721,2,2,2,1584671,12,8, +1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8,1585735, +14,1,1584671,12,8,1310721,2,3,26,2,1581747,2,1584967,12,8,1310721, +2,5,26,2,1584843,12,8,1,1585847,14,1,1310721,2,7,26,1310721, +4,18,1310721,2,1,28,1310721,4,1579529,2,1,28,1,6,1,10, +28,34,63,38,3,26,1586075,16,1579533,2,1585919,16,3,1585945,14,1573161, +12,1,6,1,10,28,34,63,38,1,10,28,1585977,16,1579527,3, +1,10,28,10,3,6,10,4,8,1,1586225,14,1579527,1573127,12,10, +3,6,10,4,8,1579527,2,193,28,1,6,1,10,28,34,63, +38,3,26,1586071,16,1579533,3,10,3,6,10,4,8,1579527,3,1, +10,28,10,3,6,10,4,8,1,1586225,14,1586157,14,1579527,1579531,2, +2,10,3,6,10,4,8,1579527,2,1586135,16,1579531,1,6,2,1, +6,3,26,5,6,4,10,8,8,1586157,14,1579527,3,1,10,28, +10,3,6,10,4,8,1579527,2,21,28,1,6,1,10,28,34, +63,38,3,26,1586217,16,1579525,1,6,2,1,6,3,26,5,6, +4,10,8,8,1,1586225,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,1579535,1,6,2,1,6,3,26,5, +6,4,10,8,8,1579535,2,65,40,3,36,1586395,16,1586387,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,1586335,1581991,12,8,1310721,2,9, +26,1540609,1579535,2,33,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,1579517,2,10,3,6,10,4,8,1310721,2, +9,26,2,13,26,1579519,2,10,3,6,10,4,8,1310721,2,9, +26,2,15,26,1579521,2,10,3,6,10,4,8,1310721,2,9,26, +2,17,26,1579527,2,10,3,6,10,4,8,1310721,2,9,26,2, +19,26,1579529,2,10,3,6,10,4,8,1310721,2,9,26,2,21, +26,1579531,2,10,3,6,10,4,8,1310721,2,9,26,2,25,26, +1581737,2,10,3,6,10,4,8,1310721,2,9,26,2,27,26,1581739, +2,10,3,6,10,4,8,1310721,2,9,26,2,29,26,1581741,2, +10,3,6,10,4,8,1310721,2,9,26,2,31,26,1581743,2,10, +3,6,10,4,8,1581737,1,10,3,6,10,4,8,1310721,2,2, +3,28,1,6,1,10,28,34,63,38,3,26,1587015,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,1587087,16,1579529,1,10,3,6,10,4,8,1579533,1,10,3, +6,10,4,8,1585861,12,8,1310721,2,2,5,28,1,6,1,10, +28,34,63,38,3,26,1587167,16,1579529,5,10,3,6,10,4,8, +1579531,1310721,2,3,26,2,10,3,6,10,4,8,1585861,12,8,1, +1587175,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28,1310721,4, +1540609,1579535,2,33,30,26,1310721,2,4,1579517,1310721,2,2,11,26,2, +10,3,6,10,4,8,1579519,1310721,2,2,13,26,2,10,3,6, +10,4,8,1579521,1310721,2,2,15,26,2,10,3,6,10,4,8, +1579527,1310721,2,2,17,26,2,10,3,6,10,4,8,1579529,1310721,2, +2,19,26,2,10,3,6,10,4,8,1579531,1310721,2,2,21,26, +2,10,3,6,10,4,8,1581737,1310721,2,2,25,26,2,10,3, +6,10,4,8,1581739,1310721,2,2,27,26,2,10,3,6,10,4, +8,1581741,1310721,2,2,29,26,2,10,3,6,10,4,8,1581743,1310721, +2,2,31,26,2,10,3,6,10,4,8,1581745,1579523,2,10,3, +6,10,4,8,1579535,1,6,2,1,6,-1,26,5,6,4,10, +8,8,1310721,2,2,23,26,2,1587559,16,1310721,2,2,3,26,2, +1577851,12,8,1,1587567,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,4,1587643,14,43,45,42,47,37,61,60, +62,33,38,124,94,126,63,58,46,64,35,36,0,1587603,1310721,2, +3,26,4,1310721,2,3,26,2,2,1587759,16,1310721,2,3,26,2, +2,1310721,2,2,28,1,6,1,10,28,34,63,38,3,26,1587721, +16,3,1587767,14,1310721,2,3,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1587655,14,1,1587767,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,1579463,2,40,1588223,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,1588009,16,1310721,2,7,26,2,1310721,2,9, +26,2,26,2,1579537,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,1588011,14,1,1588053,16,1310721,2,9,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1587899,14,1310721,2,9,26,2,1310721, +2,2,28,1,6,1,10,28,34,63,38,3,26,1588173,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,1588175,14,1,1588185,16,3,1588231,14,1310721,2,5,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1587821,14,1, +1588231,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,1588323,16,1310721,2,2,115, +10,40,3,36,1,6,1,10,28,34,63,38,1,10,28,1588325, +14,1,1588331,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,1588423,16,1310721,2, +2,245,10,40,3,36,1,6,1,10,28,34,63,38,1,10, +28,1588425,14,1,1588435,16,3,1588519,14,1310721,2,2,131,40,3,36, +1588495,16,1310721,2,2,181,10,40,3,36,1,6,1,10,28,34, +63,38,1,10,28,1588497,14,1,1,6,1,10,28,34,63,38, +1,10,28,1588529,16,3,1588581,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,1588587,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1310721,2,2,1588245,12,1588647,16,1310721,2,2,97, +28,1588829,14,1310721,2,2,195,40,3,36,1588707,16,1310721,2,2,205, +10,40,3,36,1,6,1,10,28,34,63,38,1,10,28,1588709, +14,1,1588731,16,1310721,2,2,195,28,21,26,1588829,14,1310721,2,2, +131,40,3,36,1588791,16,1310721,2,2,141,10,40,3,36,1,6, +1,10,28,34,63,38,1,10,28,1588793,14,1,1588815,16,1310721,2, +2,131,28,21,26,1588829,14,3,1,10,28,1588829,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1579527,2,1310721,2,4, +1585861,12,8,1310721,2,2,185,28,1,6,1,10,28,34,63,38, +1,10,28,1588917,16,1310721,2,2,1589155,14,1310721,2,1579527,2,10,3, +6,10,4,8,1585861,12,8,1310721,2,2,221,28,1,6,1,10, +28,34,63,38,3,26,1588983,16,21,1589155,14,1310721,2,2,233,28, +1,6,1,10,28,34,63,38,3,26,1589023,16,19,1589155,14,1310721, +2,2,229,28,1,6,1,10,28,34,63,38,3,26,1589063,16, +27,1589155,14,1310721,2,2,97,28,1,6,1,10,28,34,63,38, +3,26,1589103,16,1,1589155,14,1310721,2,2,203,28,1,6,1,10, +28,34,63,38,3,26,1589143,16,55,1589155,14,1310721,2,2,1589155,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +4,1579527,2,1,40,3,36,1589237,16,1579527,2,1587581,12,1,6,1, +10,28,34,63,38,1,10,28,1589239,14,1,1589283,16,1310721,2,2, +1579527,2,1587781,12,1,6,1,10,28,34,63,38,1,10,28,1589285, +14,1,1589355,16,1579537,1310721,2,2,26,1579527,2,10,3,6,10,4, +8,1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8, +1585861,12,8,1589187,14,1579537,1310721,2,2,26,1,10,3,6,10,4, +8,1579517,9,10,3,6,10,4,8,1579519,1579537,1582663,12,10,3,6, +10,4,8,1,1589423,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +7,28,1310721,4,1,1310721,2,4,1579521,3,10,3,6,10,4,8, +3,1590125,16,1579527,2,65,28,1,6,1,10,28,34,63,38,3, +26,1589517,16,3,1589567,14,1579527,2,19,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1589577, +16,3,1589627,14,1579527,2,21,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1589637,16,3, +1589687,14,1579527,2,27,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1589717,16,1585861,12,8, +1579521,1,10,3,6,10,4,8,1589479,14,1579527,2,95,28,1,6, +1,10,28,34,63,38,1,10,28,1589755,16,1590125,14,1585861,12,8, +1579527,2,95,28,1,6,1,10,28,34,63,38,3,26,1589901,16, +1579527,2,1,40,3,36,1589865,16,1579527,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,1589867,14,1,1589881,16,1585861,12,8,1589793,14,1579521,1,10,3, +6,10,4,8,1589473,14,1579527,2,85,28,1,6,1,10,28,34, +63,38,3,26,1590069,16,1585861,12,8,1579527,2,1,40,3,36,1590043, +16,1579527,2,85,28,1,6,1,10,28,34,63,38,3,26,1590033, +16,1585861,12,8,1579527,2,95,28,1,6,1,10,28,34,63,38, +3,26,1590029,16,1590043,14,1590039,14,1585861,12,8,1589939,14,1585861,12,8, +1579521,1,10,3,6,10,4,8,1589473,14,1579523,1579525,2,10,3,6, +10,4,8,1579537,1,26,95,10,3,6,10,4,8,3,1589169,12, +8,1,1591409,14,1589473,14,1579523,1579525,2,10,3,6,10,4,8,1579527, +2,1,40,1590193,16,1579517,1,10,3,6,10,4,8,1579519,1,10, +3,6,10,4,8,1,1591409,14,1579527,2,1588245,12,1590615,16,1310721,2, +3,26,1,10,3,6,10,4,8,1579527,2,97,28,1,6,1, +10,28,34,63,38,3,26,1590503,16,1585861,12,8,1579527,2,241,28, +1,6,1,10,28,34,63,38,3,26,1590303,16,3,1590353,14,1579527, +2,177,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1590503,16,1585861,12,8,1310721,2,5, +26,1579527,2,1588601,12,10,3,6,10,4,1,40,3,36,1590457,16, +1310721,2,3,26,1310721,2,3,26,2,33,30,1310721,2,5,26,2, +26,10,3,6,10,4,8,1585861,12,8,1590363,14,1579517,3,10,3, +6,10,4,8,1579519,1310721,2,3,26,2,10,3,6,10,4,8, +1,1591409,14,1579527,2,1588245,12,1590569,16,1310721,2,3,26,1310721,2,3, +26,2,21,30,1579527,2,26,97,28,10,3,6,10,4,8,1585861, +12,8,1590503,14,1579517,3,10,3,6,10,4,8,1579519,1310721,2,3, +26,2,10,3,6,10,4,8,1,1591409,14,1579527,2,1588345,12,1590825, +16,1579527,2,1588345,12,1590645,16,3,1590675,14,1579527,2,1588245,12,1,6, +1,10,28,34,63,38,1,10,28,1590759,16,1310721,2,2,2001,40, +1590749,16,1579537,1310721,2,2,26,1579527,2,10,3,6,10,4,8,1310721, +2,1,6,2,1,6,3,26,5,6,4,10,8,8,1585861,12, +8,1590627,14,1579537,1310721,2,2,26,1,10,3,6,10,4,8,1579517, +5,10,3,6,10,4,8,1579519,1579537,1582663,12,10,3,6,10,4, +8,1,1591409,14,1579527,2,79,28,1,6,1,10,28,34,63,38, +3,26,1590999,16,1585861,12,8,1579519,1588843,12,10,3,6,10,4,8, +1579527,2,79,28,1,6,1,10,28,34,63,38,1,10,28,1590971, +16,1590963,14,98,97,100,32,99,104,97,114,97,99,116,101,114, +32,108,105,116,101,114,97,108,0,1590919,1581991,12,8,1585861,12,8, +1579517,3,10,3,6,10,4,8,1,1591409,14,1579527,2,69,28,1, +6,1,10,28,34,63,38,3,26,1591291,16,1585861,12,8,1579527,2, +1,40,3,36,1591109,16,1579527,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, +1591111,14,1,1591219,16,1310721,2,3,26,1588843,12,10,3,6,10,4, +8,1310721,2,2,2001,40,1591215,16,1579537,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,1591037,14,1585861,12,8,1579537,1310721,2,2, +26,1,10,3,6,10,4,8,1579517,7,10,3,6,10,4,8, +1579519,1579537,1582663,12,10,3,6,10,4,8,1,1591409,14,1579537,1,26, +1579527,2,10,3,6,10,4,8,1585861,12,8,1579537,1,26,2,1587581, +12,1591345,16,3,1589169,12,1591409,14,1579537,3,26,1,10,3,6,10, +4,8,1579517,9,10,3,6,10,4,8,1579519,1579537,1582663,12,10,3, +6,10,4,8,1,1591409,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,1,28,1310721,4,1581737,2,1591537,16,1579517,1581739,2,10,3,6,10, +4,8,1579519,1581741,2,10,3,6,10,4,8,1579521,1581743,2,10,3, +6,10,4,8,1579523,1581745,2,10,3,6,10,4,8,1581737,1,10, +3,6,10,4,8,1,1591547,14,1591887,12,1591547,14,1,1310721,2,1, +26,1310721,4,18,1310721,2,9,28,1310721,4,1581737,2,1591587,16,1,1591873, +14,1310721,2,1579517,2,10,3,6,10,4,8,1310721,2,3,26,1579519, +2,10,3,6,10,4,8,1310721,2,5,26,1579521,2,10,3,6, +10,4,8,1310721,2,7,26,1579523,2,10,3,6,10,4,8,1591887, +12,8,1581739,1579517,2,10,3,6,10,4,8,1581741,1579519,2,10,3, +6,10,4,8,1581743,1579521,2,10,3,6,10,4,8,1581745,1579523,2, +10,3,6,10,4,8,1581737,3,10,3,6,10,4,8,1579517,1310721, +2,2,10,3,6,10,4,8,1579519,1310721,2,3,26,2,10,3, +6,10,4,8,1579521,1310721,2,5,26,2,10,3,6,10,4,8, +1579523,1310721,2,7,26,2,10,3,6,10,4,8,1,1591873,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1540609, +1579535,2,33,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,1591981,16, +1589437,12,8,1,1592327,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,1592239,16,1310721,2,3,26,1310721,2,2,3,26,2,10,3, +6,10,4,8,1579517,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,1579519, +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,1579521,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,1592327,14,1310721,2,2,9,26,2,1,6,1, +10,28,34,63,38,3,26,1592313,16,1579517,1,10,3,6,10,4, +8,1579519,1,10,3,6,10,4,8,1,1592327,14,1587189,12,8,1, +1592327,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,4,1579517,2,9,28,1,6,1,10,28,34,63,38,3, +26,1592449,16,1579519,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,1592451,14, +1,1592457,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,4,1579517,2,5,28,1,6,1,10,28,34,63,38, +3,26,1592579,16,1579519,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,1592581, +14,1,1592587,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1579517,2,9,28,1,6,1,10,28,34,63, +38,3,26,1592657,16,3,1592707,14,1579517,2,5,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1592769,16,1579519,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,1592771,14, +1,1592787,16,1591423,12,8,3,1592795,14,1,1592795,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2, +1592601,12,1,6,1,10,28,34,63,38,3,26,1592965,16,1592885,14, +122,99,58,32,108,105,110,101,32,0,1592865,1573231,12,8,1579523,2, +1573371,12,8,1592931,14,58,32,101,120,112,101,99,116,101,100,32, +0,1592907,1573231,12,8,1310721,2,2,1573231,12,8,21,1573079,12,8,1573195, +12,8,1,1592973,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1579519,2,1310721,2,4,1579517,2,5,28,1,6,1,10, +28,34,63,38,1,10,28,1593087,16,1593079,14,101,120,112,101,99, +116,101,100,32,97,32,110,97,109,101,0,1593047,1581991,12,8,1591423, +12,8,1310721,2,2,1593105,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,15,28,1310721,4,1310721,2,4,1579465,2,1310721,2,3,26,4,3, +1594205,16,1310721,2,2,2,65,28,1,6,1,10,28,34,63,38, +3,26,1593227,16,1310721,2,1,6,2,1,6,3,26,5,6,4, +10,8,8,1593157,14,1310721,2,2,2,1,6,1,10,28,34,63, +38,3,26,1593263,16,1594205,14,1310721,2,5,26,1,10,3,6,10, +4,8,1310721,2,2,1310721,2,5,26,2,26,2,1593381,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, +1593383,14,1,1593471,16,1579537,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,1593285,14,1579537, +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,1579537,1,26,2,91,28,1,6,1,10,28,34,63,38, +3,26,1593615,16,1579537,3,26,2,1588245,12,1,6,1,10,28,34, +63,38,1,10,28,1593617,14,1,10,3,6,10,4,8,1579537,1310721, +2,7,26,2,26,2,1588245,12,1593945,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,1579537,1310721,2,11,26,2,26,2,1593819,16,1310721,2, +9,26,1310721,2,9,26,2,21,30,1579537,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,1593705,14,1310721,2,7, +26,2,1593867,16,1310721,2,9,26,1,1310721,2,9,26,2,28,10, +3,6,10,4,8,1542657,1579465,2,26,1310721,2,9,26,2,1310721,2, +9,26,2,26,3,26,10,3,6,10,4,8,1579465,1,6,2, +1,6,3,26,5,6,4,10,8,8,1594201,14,1310721,2,5,26, +2,3,28,1,6,1,10,28,34,63,38,3,26,1594047,16,1310721, +2,13,26,1579537,1,26,2,1594235,12,10,3,6,10,4,1,40, +3,36,1,6,1,10,28,34,63,38,1,10,28,1594049,14,1, +1594127,16,1542657,1579465,2,26,1310721,2,13,26,2,1310721,2,13,26,2, +26,10,3,6,10,4,8,1579465,1,6,2,1,6,3,26,5, +6,4,10,8,8,1594201,14,1542657,1579465,2,26,-3,10,3,6,10, +4,8,1542657,1579465,2,3,26,26,1579537,1582663,12,10,3,6,10,4, +8,1579465,1579465,2,5,26,10,3,6,10,4,8,1593151,14,1310721,2, +3,26,2,1594221,14,1,1310721,2,15,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,4,1,1310721,2,3,26,4,1579467,2,1310721,2, +3,26,2,26,2,1594389,16,1579467,2,1310721,2,3,26,2,26,2, +1310721,2,2,28,1,6,1,10,28,34,63,38,3,26,1594351,16, +1310721,2,3,26,2,1594403,14,1310721,2,3,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1594265,14,3,1,10,28,1594403,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,1594875,16,1542657, +1310721,2,2,26,2,-3,28,1,6,1,10,28,34,63,38,3, +26,1594823,16,1310721,2,7,26,1542657,1310721,2,2,3,26,26,2,1583635, +12,10,3,6,10,4,8,1310721,2,7,26,2,1,40,1594633,16, +1310721,2,7,26,1542657,1310721,2,2,3,26,26,2,1585201,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,1594697,16,1310721,2,7,26,2,1585301, +12,8,1594793,14,1417729,1310721,2,7,26,2,26,2,13,28,1,6, +1,10,28,34,63,38,3,26,1594771,16,45,1425921,1310721,2,7,26, +2,26,2,26,1584907,12,8,1594793,14,1425921,1310721,2,7,26,2,26, +2,1584843,12,8,1310721,2,1310721,2,2,5,26,10,3,6,10,4, +8,1594871,14,1542657,1310721,2,2,26,2,1584671,12,8,1310721,2,1,6, +2,1,6,3,26,5,6,4,10,8,8,1594473,14,1,1594883,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,1579463,2,40,1595039, +16,1547777,1310721,2,3,26,2,26,2,1310721,2,2,28,1,6,1, +10,28,34,63,38,3,26,1595001,16,1,1595101,14,1310721,2,3,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1594927,14,1547777, +1579463,2,26,1310721,2,2,10,3,6,10,4,8,1579463,1,6,2, +1,6,3,26,5,6,4,10,8,8,1,1595101,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1579457,2, +1310721,2,3,26,4,1310721,2,3,26,2,1595261,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,1595257,16,1310721,2,3,26,2,1595275,14,1595147,14,3,1, +10,28,1595275,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,4,1579459,2,1310721,2,3,26,4,1310721,2,3,26, +2,1595435,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,1595431,16,1310721,2,3,26, +2,1595449,14,1595321,14,3,1,10,28,1595449,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1579461,2,1310721,2, +3,26,4,1310721,2,3,26,2,1595609,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,1595605,16,1310721,2,3,26,2,1595623,14,1595495,14,3,1,10,28, +1595623,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, +1582663,12,1310721,2,7,26,4,1310721,2,7,26,2,1595115,12,1310721,2, +9,26,4,1310721,2,9,26,2,1,40,1595789,16,1310721,2,9,26, +1579457,2,10,3,6,10,4,8,1579457,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,1596013,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,1594897,12,8,1310721, +2,9,26,2,1596641,14,1547009,1310721,2,9,26,2,26,1310721,2,5, +26,2,1593119,12,10,3,6,10,4,8,1547137,1310721,2,9,26,2, +26,1579465,2,1547009,1310721,2,9,26,2,26,2,28,10,3,6,10, +4,8,1310721,2,7,26,2,1594897,12,8,1310721,2,13,26,1310721,2, +2,1573731,12,10,3,6,10,4,8,1579537,2001,26,1310721,2,2,1310721, +2,13,26,2,1574139,12,8,1579537,2001,1310721,2,13,26,2,26,26, +123,10,3,6,10,4,8,1579537,2003,1310721,2,13,26,2,26,26, +1,10,3,6,10,4,8,1310721,2,11,26,1579537,2001,26,1582663,12, +10,3,6,10,4,8,1310721,2,3,26,2,17,40,3,36,1596297, +16,3,1596353,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, +1596363,16,3,1596419,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,1596429,16,3,1596485,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,1596625,16,1310721,2,11,26,2,1595463,12,1,40,1596569,16,1547457, +1579461,2,26,1310721,2,11,26,2,10,3,6,10,4,8,1579461,1, +6,2,1,6,3,26,5,6,4,10,8,8,1547585,1310721,2,11, +26,2,1595463,12,26,1310721,2,9,26,2,10,3,6,10,4,8, +1310721,2,11,26,2,1594897,12,8,1310721,2,9,26,2,1596641,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,1582663,12,1310721,2,5,26,4,1310721, +2,5,26,2,1595289,12,1310721,2,7,26,4,1310721,2,7,26,2, +1,40,1596797,16,1310721,2,7,26,1579459,2,10,3,6,10,4,8, +1579459,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,1593119,12,10,3, +6,10,4,8,1547393,1310721,2,7,26,2,26,1579465,2,1547329,1310721,2, +7,26,2,26,2,28,10,3,6,10,4,8,1310721,2,5,26, +2,1594897,12,8,1310721,2,7,26,2,1596953,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,1582663,12,11,1310721,2,3,26, +2,1583159,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,1597097,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,4,1581755,2,1310721,2,3,26,4,1310721,2,3,26,2, +1581757,2,10,40,1597265,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,1597261,16,1310721, +2,3,26,2,1597279,14,1597143,14,3,1,10,28,1597279,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1581755, +2,1310721,2,3,26,4,1581755,2,1025,40,3,36,1597385,16,1597377,14, +116,111,111,32,109,97,110,121,32,108,111,99,97,108,115,0, +1597345,1581991,12,8,1581755,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,1581761,2,10,3,6,10,4, +8,1468929,1310721,2,3,26,2,26,1581759,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,1556993,1310721,2,3,26,2,26,1581877,2,10, +3,6,10,4,8,1558017,1310721,2,3,26,2,26,1,10,3,6, +10,4,8,1310721,2,3,26,2,1597719,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,1597823,16,1310721, +2,1470977,1310721,2,2,26,2,10,3,6,10,4,8,1597751,14,1310721, +2,2,1597835,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,1597911,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,1581763,2,1,6,1,10,28,34,63, +38,3,26,1598001,16,1,1598377,14,1310721,2,3,26,1310721,2,2,1597733, +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,1598185,16,1310721,2,2,1598171,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,1598113,1582383,12, +8,1,1598377,14,1469953,1310721,2,3,26,2,26,2,7,28,1,6, +1,10,28,34,63,38,3,26,1598277,16,1468929,1310721,2,3,26,2, +26,2,1581759,2,40,1,6,1,10,28,34,63,38,1,10,28, +1598279,14,1,1598369,16,1468929,1310721,2,3,26,2,26,1581759,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,1598377,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,1598593,16,1598585,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,1598447,1582287,12,8, +1310721,2,2,5,40,3,36,1598627,16,1310721,2,2,5,28,1597925,12, +8,1,1598635,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1467905,1310721,2,2,26,2,1585585,12,8,3,1584907, +12,8,1581861,2,1585453,12,8,9,1584907,12,8,1,1598719,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,3,26, +4,1310721,2,4,1581755,2,1310721,2,5,26,4,1581763,2,1,6,1, +10,28,34,63,38,3,26,1598809,16,3,1598855,14,1581767,2,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1598865,16,1,1599425,14,1310721,2,5,26,2,1581757,2,10, +40,1599417,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, +1598953,16,1598865,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,1599047,16,1310721,2,5,26,2,1598649,12, +8,1599413,14,1310721,2,7,26,2,5,28,1,6,1,10,28,34, +63,38,3,26,1599293,16,1310721,2,5,26,2,1599281,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,1599099,1582383,12,8,1599413,14,1310721,2, +7,26,2,7,28,1,6,1,10,28,34,63,38,3,26,1599413, +16,1310721,2,5,26,2,1599405,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,1599345,1582383,12,8,1598865,14,1,1599425,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4, +1310721,2,2,1581755,2,40,1599693,16,1581763,2,1599519,16,1474049,1310721,2,2, +26,2,1,6,1,10,28,34,63,38,1,10,28,1599521,14,1, +1599583,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,1599585,14,1, +1599659,16,1466881,1310721,2,2,26,2,1599651,14,109,32,111,98,106,101, +99,116,32,105,115,32,110,101,118,101,114,32,117,115,101,100, +0,1599605,1582117,12,8,1310721,2,1,6,2,1,6,3,26,5,6, +4,10,8,8,1599457,14,1,1599701,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,4,1581757,2,1310721,2,3,26, +4,1310721,2,2,1599439,12,8,1581759,2,3,1598733,12,8,1310721,2,3, +26,2,1310721,2,2,40,1599923,16,1468929,1310721,2,3,26,2,26,2, +1581759,2,40,3,36,1599885,16,1469953,1310721,2,3,26,2,26,9,10, +3,6,10,4,8,1468929,1310721,2,3,26,2,26,1581759,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,1599771,14,1581755,1310721,2,2,10,3,6, +10,4,8,1,1599951,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +7,28,1310721,4,1581783,2,1310721,2,4,1581757,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,1581757,2,10,3,6,10,4,8,1310721,2, +5,26,2,3,26,1581755,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,1581755,2,40,1600343,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,1600125,14,1581783,1310721,2,5,26, +2,1507841,28,10,3,6,10,4,8,1581783,2,16001,40,3,36,1600467, +16,1600459,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,1600391,1581991,12,8,1310721,2,2,1600479,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1581783, +1310721,2,2,10,3,6,10,4,8,1,1600539,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,1581755,2,10,40,1600689,16,1310721,2,7,26, +1581755,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,1600947,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,1600723,14,1,1600955,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,1601027,16,3,1601079, +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,1601085,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,1581755,2,10,40,1601235,16,1310721,2,7, +26,1581755,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,1601859,16,1310721,2,9,26,1469953,1310721,2,5,26, +2,26,2,10,3,6,10,4,8,1310721,2,9,26,2,1600969,12, +1601395,16,1310721,2,3,26,2,1,26,2,1600969,12,1,6,1,10, +28,34,63,38,1,10,28,1601397,14,1,1601477,16,1310721,2,3,26, +2,1,26,2,9,28,1,6,1,10,28,34,63,38,3,26, +1601473,16,1469953,1310721,2,5,26,2,26,9,10,3,6,10,4,8, +1601787,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,1601537,16,3,1601615,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,1601625,16,3,1601769,14,1310721,2,9,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1601745,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,1601747,14,1,1,6,1,10,28,34,63, +38,1,10,28,1601787,16,1310721,2,5,26,2,1601873,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,1601269, +14,3,1,10,28,1601873,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,1601961,16,1601955,14,101,109,112,116,121, +0,1601943,1602287,14,1310721,2,2,3,28,1,6,1,10,28,34,63, +38,3,26,1602009,16,1602003,14,109,0,1601999,1602287,14,1310721,2,2,5, +28,1,6,1,10,28,34,63,38,3,26,1602057,16,1602051,14,117, +0,1602047,1602287,14,1310721,2,2,7,28,1,6,1,10,28,34,63, +38,3,26,1602105,16,1602099,14,100,0,1602095,1602287,14,1310721,2,2,9, +28,1,6,1,10,28,34,63,38,3,26,1602171,16,1602165,14,103, +105,118,101,110,32,97,119,97,121,0,1602143,1602287,14,1310721,2,2, +11,28,1,6,1,10,28,34,63,38,3,26,1602257,16,1602251,14, +111,119,110,101,100,32,98,121,32,97,32,99,111,110,116,97, +105,110,101,114,0,1602209,1602287,14,1602279,14,98,111,114,114,111,119, +101,100,0,1602261,1602287,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,1581763,2,1,6,1,10,28,34,63,38,3,26,1602373,16,1, +1602649,14,1602397,14,122,99,58,32,108,105,110,101,32,0,1602377,1573231, +12,8,1579523,2,1573371,12,8,1602425,14,58,32,0,1602419,1573231,12,8, +1466881,1310721,2,2,26,2,1573231,12,8,1602461,14,58,32,0,1602455,1573231, +12,8,1310721,2,5,26,2,1573231,12,8,1602533,14,32,40,111,110, +101,32,112,97,116,104,32,108,101,97,118,101,115,32,105,116, +32,0,1602489,1573231,12,8,1310721,2,3,26,2,1601887,12,1573231,12,8, +1602587,14,44,32,97,110,111,116,104,101,114,32,0,1602565,1573231,12, +8,1469953,1310721,2,2,26,2,1601887,12,1573231,12,8,1602627,14,41,10, +0,1602621,1573231,12,8,1573195,12,8,1,1602649,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, +1602731,16,1,1603049,14,1581767,2,1,6,1,10,28,34,63,38,3, +26,1602793,16,1310721,2,2,1600553,12,8,1581767,3,10,3,6,10,4, +8,1,1603049,14,1310721,2,5,26,1310721,2,2,1601099,12,10,3,6, +10,4,8,1310721,2,5,26,2,1,40,3,36,1603041,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,1603033,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,1602939,1602301,12,8, +1,1603049,14,1,1310721,2,9,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,4,1581763,2,1,6,1,10,28,34,63,38,3,26, +1603115,16,3,1603161,14,1581767,2,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1603171,16,1,1603473, +14,1310721,2,3,26,1310721,2,2,1601099,12,10,3,6,10,4,8, +1310721,2,3,26,2,1,40,3,36,1603465,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,1603457,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, +1603317,1602301,12,8,1,1603473,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,9,28,1310721,4,1310721,2,3,26,4,1310721,2,4,1581763,2,1, +6,1,10,28,34,63,38,3,26,1603553,16,1310721,2,2,1604523,14, +1310721,2,2,5,40,1603669,16,1603651,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,1603571,1582287,12,8,1310721,2,2,1604523,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,1603933,16,1310721,2,5,26, +2,1603921,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,1603815,1582383,12,8,1604511,14,1310721,2, +7,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1604061, +16,1310721,2,5,26,2,1604049,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,1603985,1582383,12,8,1604511,14,1310721,2, +7,26,2,1,28,1,6,1,10,28,34,63,38,3,26,1604169, +16,1310721,2,5,26,2,1604157,14,105,115,110,39,116,32,97,110, +32,111,119,110,101,100,32,111,98,106,101,99,116,0,1604113,1582383, +12,8,1604511,14,1310721,2,7,26,2,9,28,1,6,1,10,28, +34,63,38,3,26,1604291,16,1310721,2,5,26,2,1604279,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,1604221,1582383,12,8,1604511, +14,1310721,2,3,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1604391,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,1604393,14,1,1604475,16,1310721,2,5,26,2,1604463,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,1604411,1582383,12,8,1604511,14,1469953,1310721,2, +5,26,2,26,1310721,2,3,26,2,10,3,6,10,4,8,1310721, +2,2,1604523,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28, +1310721,4,1310721,2,3,26,4,1310721,2,4,1581763,2,1,6,1,10, +28,34,63,38,3,26,1604599,16,1,1606033,14,1310721,2,2,3,28, +1,6,1,10,28,34,63,38,3,26,1604843,16,1310721,2,3,26, +2,5,28,1,6,1,10,28,34,63,38,1,10,28,1604837,16, +1604829,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,1604677,1582287, +12,8,1,1606033,14,1310721,2,2,5,40,1604863,16,3,1604919,14,1310721, +2,2,5,28,1597849,12,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1604929,16,1,1606033,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,1597733,12,26,2,9,28,1,6,1, +10,28,34,63,38,3,26,1605129,16,1310721,2,5,26,2,1605115,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,1605057,1582383,12, +8,1,1606033,14,1310721,2,3,26,2,3,10,40,3,36,1605357,16, +1310721,2,7,26,2,7,28,1,6,1,10,28,34,63,38,3, +26,1605335,16,1310721,2,5,26,2,1605321,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,1605205,1582383,12,8,1,1606033,14,1310721,2,5,26,2, +1597925,12,8,1,1606033,14,1310721,2,7,26,2,7,28,1,6,1, +10,28,34,63,38,3,26,1605457,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,1606033,14,1310721,2,7,26,2,3,28,1, +6,1,10,28,34,63,38,3,26,1605585,16,1310721,2,5,26,2, +1605573,14,105,115,32,109,59,32,119,114,105,116,101,32,100,42, +120,32,116,111,32,103,105,118,101,32,105,116,32,97,119,97, +121,0,1605509,1582383,12,8,1606025,14,1310721,2,7,26,2,5,28,1, +6,1,10,28,34,63,38,3,26,1605761,16,1310721,2,5,26,2, +1605749,14,105,115,32,117,59,32,119,114,105,116,101,32,100,42, +120,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,1605637,1582383,12,8,1606025,14, +1310721,2,7,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1605931,16,1310721,2,5,26,2,1605919,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,1605813, +1582383,12,8,1606025,14,1310721,2,5,26,2,1606017,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, +1605945,1582383,12,8,1,1606033,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,4,1467905,1310721,2,2,26,2,1585585,12, +8,3,1584907,12,8,1581863,2,1585453,12,8,1,1606109,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,1581763,2,1,6,1,10,28,34, +63,38,3,26,1606195,16,1,1609571,14,1310721,2,9,26,3,1,10, +28,10,3,6,10,4,8,1310721,2,5,26,2,5,40,3,36, +1606289,16,1310721,2,5,26,2,5,28,1597849,12,1,6,1,10,28, +34,63,38,1,10,28,1606291,14,1,1606329,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,1606421,16,1469953,1310721,2,9,26,2,1597733,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,1606423,14,1,1606513,16,1310721,2,9, +26,2,1606499,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,1606441,1582383,12,8,1,1609571,14,1310721,2,2,3,28,1,6,1, +10,28,34,63,38,3,26,1607969,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,1606663,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,1606665,14,1,1606869,16,1310721,2,7,26,2,1600969,12,1,6,1, +10,28,34,63,38,3,26,1606835,16,1310721,2,3,26,2,1606823,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,1606721,1582383,12,8,1606863,14,1469953,1310721,2,3,26,2,26, +1,10,3,6,10,4,8,1,1609571,14,1310721,2,7,26,2,1600969, +12,1,6,1,10,28,34,63,38,3,26,1607037,16,1310721,2,3, +26,2,1607023,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,1606921,1582383,12,8,1,1609571,14,1310721,2, +5,26,2,3,28,1,6,1,10,28,34,63,38,3,26,1607227, +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,1558017,1310721,2,3,26, +2,26,2,1607221,16,1469953,1310721,2,3,26,2,26,1558017,1310721,2,3, +26,2,26,2,10,3,6,10,4,8,1,1609571,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, +1607385,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,1607387,14,1,1607599,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,1558017,1310721,2,3,26,2,26,2,1607593,16,1469953, +1310721,2,3,26,2,26,1558017,1310721,2,3,26,2,26,2,10,3, +6,10,4,8,1,1609571,14,1310721,2,13,26,2,5,28,1,6, +1,10,28,34,63,38,3,26,1607819,16,1310721,2,9,26,2,1607807, +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,1607651, +1582383,12,8,1607963,14,1310721,2,9,26,2,1607955,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,1607833,1582383,12,8,1,1609571,14, +1310721,2,2,7,28,1,6,1,10,28,34,63,38,3,26,1609239, +16,1310721,2,11,26,1310721,2,3,26,2,1597733,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,1597925,12,8,1310721,2,5,26, +2,3,28,1,6,1,10,28,34,63,38,3,26,1608149,16,1310721, +2,3,26,2,1606047,12,8,1,1609571,14,1310721,2,9,26,2,1, +40,1608173,16,1,1609571,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,1608335,16,1310721,2,9,26,2, +1608323,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,1608261,1582383,12,8,1609233,14,1310721,2,13,26,2,13,28,1,6, +1,10,28,34,63,38,3,26,1608463,16,1310721,2,9,26,2,1608451, +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,1608387,1582383,12,8,1609233,14,1310721,2,7,26,2,13,28,1,6, +1,10,28,34,63,38,3,26,1608735,16,1310721,2,13,26,2,7, +28,1,6,1,10,28,34,63,38,1,10,28,1608659,16,1310721,2, +9,26,2,1608647,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,1608555,1582383,12,8,1608731,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,1606047,12,8,1609233,14,1310721, +2,13,26,2,1310721,2,7,26,2,28,1,6,1,10,28,34, +63,38,1,10,28,1608941,16,1310721,2,9,26,2,1608929,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, +1608797,1582383,12,8,1609233,14,1468929,1310721,2,9,26,2,26,2,1468929,1310721, +2,11,26,2,26,2,40,1609125,16,1310721,2,9,26,2,1609113,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,1608993,1582383,12,8, +1609233,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,1606047,12,8,1,1609571,14,1310721,2,9,26,2, +1,40,3,36,1609563,16,1469953,1310721,2,9,26,2,26,2,7,28, +1,6,1,10,28,34,63,38,3,26,1609365,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,1609563,14,1310721,2,9,26,2,1609555, +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,1609379,1582383,12,8,1,1609571,14, +1,1310721,2,15,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +4,1581763,2,1,6,1,10,28,34,63,38,3,26,1609637,16,1, +1610531,14,1310721,2,3,26,3,1,10,28,10,3,6,10,4,8, +1310721,2,2,5,40,3,36,1609723,16,1310721,2,2,5,28,1597849,12, +1,6,1,10,28,34,63,38,1,10,28,1609725,14,1,1609759,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,1609851,16,1469953,1310721,2,3,26,2, +1597733,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,1609853,14,1,1609943,16, +1310721,2,3,26,2,1609929,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,1609871,1582383,12,8,1,1610531,14,1581765,2,1610199,16,1310721, +2,3,26,2,1,40,3,36,1610193,16,1469953,1310721,2,3,26,2, +26,2,5,28,1,6,1,10,28,34,63,38,3,26,1610077,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,1610193,14,1310721,2, +3,26,2,1610185,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,117, +42,120,39,0,1610091,1582383,12,8,1,1610531,14,1310721,2,2,3,28, +1,6,1,10,28,34,63,38,3,26,1610357,16,1610345,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,46,117,0,1610237,1582287,12,8,1610523,14,1310721,2,3,26,2,1, +40,3,36,1610523,16,1310721,2,3,26,2,1610515,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,46,117,0,1610393,1582383,12,8,1,1610531,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +4,1581763,2,1,6,1,10,28,34,63,38,3,26,1610597,16,1, +1611225,14,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3, +26,1610637,16,3,1611225,14,1310721,2,2,5,40,1610657,16,3,1610713,14, +1310721,2,2,5,28,1597849,12,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1610723,16,1,1611225, +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,1610865,16,1468929,1310721,2,3,26,2,26,2,1581759,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1610867,14,1,1610933,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,1611225,14,1469953,1310721,2,3,26,2, +26,2,5,28,1,6,1,10,28,34,63,38,3,26,1611097,16, +1310721,2,3,26,2,1611085,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,1610991,1582383,12,8,1611217,14,1310721,2,3,26, +2,1611209,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,1611111,1582383,12,8,1,1611225,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,1611407,16,1611395,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,1611295,1582287,12,8,1611441,14,1310721,2,2,5,40,3,36,1611441,16, +1310721,2,2,5,28,1597925,12,8,1,1611449,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1581873,2,1310721,2, +3,26,4,1581873,2,1310721,2,2,26,1310721,40,3,36,1611575,16,1611567, +14,116,104,101,32,116,121,112,101,32,97,114,101,97,32,105, +115,32,102,117,108,108,0,1611523,1581991,12,8,1581873,1581873,2,1310721,2, +2,26,10,3,6,10,4,8,1310721,2,3,26,2,1,1310721,2, +2,1574329,12,8,1310721,2,3,26,2,1611641,14,1,1310721,2,5,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,15,1310721,2,7,26, +2,26,1611463,12,1310721,2,9,26,4,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,1310721,2,5,26,2,10,3,6,10,4,8,1581875,2,2049, +40,3,36,1611893,16,1611885,14,116,111,111,32,109,97,110,121,32, +116,121,112,101,115,0,1611855,1581991,12,8,1277953,1581875,2,26,1310721,2, +9,26,2,10,3,6,10,4,8,1581875,1,6,2,1,6,3, +26,5,6,4,10,8,8,1310721,2,9,26,2,1611967,14,1,1310721, +2,11,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,4,1, +1310721,2,3,26,4,1310721,2,3,26,2,1581875,2,40,1612239,16,1310721, +2,5,26,1277953,1310721,2,3,26,2,26,2,10,3,6,10,4, +8,1310721,2,5,26,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1612181,16,1310721,2,5,26,2,9,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,1612183,14,1,1612201,16,1310721,2,5, +26,2,1612319,14,1310721,2,3,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1612011,14,1310721,2,5,26,11,3,1,1,1611655, +12,10,3,6,10,4,8,1310721,2,5,26,2,9,26,1310721,2, +2,10,3,6,10,4,8,1310721,2,5,26,2,1612319,14,1,1310721, +2,7,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,5,26,2,1581875, +2,40,1612681,16,1310721,2,7,26,1277953,1310721,2,5,26,2,26,2, +10,3,6,10,4,8,1310721,2,7,26,2,1,26,2,13,28, +1,6,1,10,28,34,63,38,3,26,1612543,16,1310721,2,7,26, +2,9,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,1612545,14,1, +1612623,16,1310721,2,7,26,2,7,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,1612625,14,1,1612643,16,1310721,2,7,26,2,1612817, +14,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1612373,14,1310721,2,7,26,13,1310721,2,3,26,2,1310721,2, +2,1615957,12,30,1,1,1611655,12,10,3,6,10,4,8,1310721,2, +7,26,2,9,26,1310721,2,2,10,3,6,10,4,8,1310721,2, +7,26,2,7,26,1310721,2,3,26,2,10,3,6,10,4,8, +1310721,2,7,26,2,1612817,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,15,28,1310721,4,1310721,2,7,26,4,1310721,2,5,26,4,1310721, +2,3,26,4,1310721,2,4,1,1310721,2,9,26,4,1310721,2,9, +26,2,1581875,2,40,1613517,16,1310721,2,13,26,1277953,1310721,2,9,26, +2,26,2,10,3,6,10,4,8,1310721,2,13,26,2,1,26, +2,15,28,1,6,1,10,28,34,63,38,3,26,1613061,16,1310721, +2,13,26,2,9,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, +1613063,14,1,1613141,16,1310721,2,13,26,2,7,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,1613143,14,1,1613221,16,1310721,2,13, +26,2,11,26,2,1310721,2,7,26,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1613223,14,1,1613479,16,1310721,2,11,26,1,10,3,6,10,4,8, +1310721,2,11,26,2,1310721,2,3,26,2,40,1613375,16,1310721,2,13, +26,2,15,1310721,2,11,26,2,26,26,2,1310721,2,5,26,2, +1310721,2,11,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,1613377,14,1, +1613419,16,1310721,2,11,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1613249,14,1310721,2,11,26,2,1310721,2,3,26,2,28, +1,6,1,10,28,34,63,38,3,26,1613479,16,1310721,2,13,26, +2,1613717,14,1310721,2,9,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1612891,14,1310721,2,13,26,15,3,1,1310721,2,3, +26,2,1611655,12,10,3,6,10,4,8,1310721,2,13,26,2,9, +26,1310721,2,2,10,3,6,10,4,8,1310721,2,13,26,2,7, +26,1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,13,26, +2,11,26,1310721,2,7,26,2,10,3,6,10,4,8,1310721,2, +13,26,2,15,26,1310721,2,5,26,2,1310721,2,3,26,2,1574139, +12,8,1310721,2,13,26,2,1613717,14,1,1310721,2,15,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,5,26,2,1581875,2,40,1613999,16,1310721, +2,7,26,1277953,1310721,2,5,26,2,26,2,10,3,6,10,4, +8,1310721,2,7,26,2,1,26,2,19,28,1,6,1,10,28, +34,63,38,3,26,1613941,16,1310721,2,7,26,2,7,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,1613943,14,1,1613961,16,1310721,2,7, +26,2,1614087,14,1310721,2,5,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1613771,14,1310721,2,7,26,19,3,1310721,2,3, +26,2,1,1611655,12,10,3,6,10,4,8,1310721,2,7,26,2, +7,26,1310721,2,2,10,3,6,10,4,8,1310721,2,7,26,2, +1614087,14,1,1310721,2,9,26,1310721,4,18,1310721,2,15,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,1581875,2,40,1614653,16,1310721,2,11, +26,1277953,1310721,2,7,26,2,26,2,10,3,6,10,4,8,1310721, +2,11,26,2,1,26,2,17,28,1,6,1,10,28,34,63, +38,3,26,1614321,16,1310721,2,11,26,2,11,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,1614323,14,1,1614615,16,1310721,2,13,26,1310721, +2,11,26,2,13,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,5, +26,2,40,1614511,16,1310721,2,13,26,2,3,1310721,2,9,26,2, +26,26,2,1310721,2,3,26,2,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,1614513,14,1,1614555,16,1310721,2,9,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1614385,14,1310721,2,9, +26,2,1310721,2,5,26,2,28,1,6,1,10,28,34,63,38, +3,26,1614615,16,1310721,2,11,26,2,1614927,14,1310721,2,7,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1614151,14,1310721,2, +13,26,1310721,2,5,26,2,3,26,1611463,12,10,3,6,10,4, +8,1310721,2,13,26,2,1,26,1310721,2,5,26,2,10,3,6, +10,4,8,1310721,2,13,26,2,3,26,1310721,2,3,26,2,1310721, +2,5,26,2,1574139,12,8,1310721,2,11,26,17,1,1310721,2,2, +5,26,2,1,1611655,12,10,3,6,10,4,8,1310721,2,11,26, +2,7,26,3,1,10,28,10,3,6,10,4,8,1310721,2,11, +26,2,11,26,1310721,2,2,10,3,6,10,4,8,1310721,2,11, +26,2,13,26,1310721,2,13,26,2,10,3,6,10,4,8,1310721, +2,11,26,2,1614927,14,1,1310721,2,15,26,1310721,4,18,1310721,2, +33,28,1310721,4,1310721,2,4,1,1310721,2,13,26,4,1310721,2,2, +1,26,2,17,28,1,6,1,10,28,34,63,38,1,10,28, +1615019,16,3,1615061,14,1310721,2,2,7,26,2,1,40,3,36,1, +6,1,10,28,34,63,38,1,10,28,1615075,16,1310721,2,2,1615943, +14,1310721,2,2,7,26,2,5,1,10,28,28,1,6,1,10, +28,34,63,38,3,26,1615211,16,1615203,14,97,32,115,116,114,117, +99,116,32,99,97,110,39,116,32,99,111,110,116,97,105,110, +32,105,116,115,101,108,102,32,98,121,32,118,97,108,117,101, +0,1615125,1581991,12,8,1310721,2,2,7,26,5,1,10,28,10,3, +6,10,4,8,1310721,2,3,26,1310721,2,2,11,26,2,10,3, +6,10,4,8,1310721,2,7,26,1310721,2,3,26,2,11,26,2, +10,3,6,10,4,8,1310721,2,5,26,1310721,2,3,26,2,9, +26,2,10,3,6,10,4,8,1310721,2,17,26,1,17,1574329,12, +8,1310721,2,17,26,1310721,2,2,13,26,2,3,26,1310721,2,2, +13,26,2,1,26,2,1574139,12,8,1310721,2,11,26,1310721,2,7, +26,2,7,30,3,26,1611463,12,10,3,6,10,4,8,1310721,2, +9,26,1,10,3,6,10,4,8,1310721,2,9,26,2,1310721,2, +7,26,2,40,1615835,16,1310721,2,15,26,1310721,2,5,26,2,1310721, +2,9,26,2,1310721,2,9,26,2,26,3,26,26,2,1310721,2, +17,26,1616107,12,10,3,6,10,4,8,1310721,2,11,26,2,1310721, +2,9,26,2,7,30,26,1310721,2,5,26,2,1310721,2,9,26, +2,1310721,2,9,26,2,26,26,2,10,3,6,10,4,8,1310721, +2,11,26,2,1310721,2,9,26,2,7,30,3,26,26,1310721,2, +15,26,2,10,3,6,10,4,8,1310721,2,11,26,2,1310721,2, +9,26,2,7,30,5,26,26,1310721,2,13,26,2,10,3,6, +10,4,8,1310721,2,13,26,1310721,2,13,26,2,1310721,2,15,26, +2,1615957,12,26,10,3,6,10,4,8,1310721,2,9,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1615475,14,1310721,2,2, +9,26,1310721,2,11,26,2,10,3,6,10,4,8,1310721,2,2, +3,26,1310721,2,13,26,2,10,3,6,10,4,8,1310721,2,2, +7,26,1310721,2,7,26,2,10,3,6,10,4,8,1310721,2,2, +1615943,14,1,1310721,2,33,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,4,1310721,2,2,1,26,2,17,28,1,6,1,10,28, +34,63,38,3,26,1616057,16,1310721,2,2,7,26,2,1,40,1, +6,1,10,28,34,63,38,1,10,28,1616059,14,1,1616075,16,1310721, +2,2,1614941,12,8,1310721,2,2,3,26,2,1616093,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,61,28,1310721,4,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,1,26,2,1310721,2,5,26,4,1310721,2, +5,26,2,19,28,1,6,1,10,28,34,63,38,3,26,1616263, +16,1310721,2,3,26,2,1310721,2,2,7,26,2,26,2,1616255,16, +1310721,2,3,26,2,1310721,2,2,7,26,2,26,2,1617069,14,1581877, +2,1617069,14,1310721,2,5,26,2,11,28,1,6,1,10,28,34, +63,38,3,26,1616335,16,1310721,2,2,9,26,2,1310721,2,3,26, +2,1616107,12,1611981,12,1617069,14,1310721,2,5,26,2,13,28,1,6, +1,10,28,34,63,38,3,26,1616419,16,1310721,2,2,9,26,2, +1310721,2,3,26,2,1616107,12,1310721,2,2,7,26,2,1612333,12,1617069, +14,1310721,2,5,26,2,15,28,1,6,1,10,28,34,63,38, +3,26,1616709,16,1310721,2,9,26,1310721,2,2,7,26,2,10,3, +6,10,4,8,1310721,2,7,26,1,10,3,6,10,4,8,1310721, +2,7,26,2,1310721,2,9,26,2,40,1616645,16,1310721,2,11,26, +1310721,2,7,26,2,26,1310721,2,2,15,1310721,2,7,26,2,26, +26,2,1310721,2,3,26,2,1616107,12,10,3,6,10,4,8,1310721, +2,7,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1616511,14,1310721,2,2,9,26,2,1310721,2,3,26,2,1616107,12,1310721, +2,9,26,2,1310721,2,11,26,1310721,2,2,11,26,2,1612831,12, +1617069,14,1310721,2,5,26,2,17,28,1,6,1,10,28,34,63, +38,3,26,1616785,16,1310721,2,2,11,26,2,1,6,1,10,28, +34,63,38,1,10,28,1616787,14,1,1617057,16,1310721,2,59,26,1310721, +2,2,13,26,2,10,3,6,10,4,8,1310721,2,9,26,1310721, +2,59,26,2,1,26,2,10,3,6,10,4,8,1310721,2,7, +26,1,10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,9, +26,2,40,1617019,16,1310721,2,11,26,1310721,2,7,26,2,26,1310721, +2,59,26,2,3,1310721,2,7,26,2,26,26,2,1310721,2,3, +26,2,1616107,12,10,3,6,10,4,8,1310721,2,7,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1616881,14,1310721,2,2, +11,26,2,1310721,2,11,26,1310721,2,9,26,2,1614101,12,1617069,14, +1310721,2,2,1617069,14,1,1310721,2,61,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,4,1310721,2,2,1,26,2,3,28,1,6, +1,10,28,34,63,38,3,26,1617147,16,3,1617205,14,1310721,2,2, +1,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,1617215,16,3,1617273,14,1310721, +2,2,1,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,1617279,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721, +2,2,1,26,2,13,28,1,6,1,10,28,34,63,38,3, +26,1617357,16,3,1617415,14,1310721,2,2,1,26,2,17,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1617421,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,4,1310721,2,2,1,26,2,11,28,1,6, +1,10,28,34,63,38,3,26,1617499,16,3,1617557,14,1310721,2,2, +1,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1617563,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2, +1,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1617655, +16,1310721,2,2,9,26,2,1611981,12,1617667,14,1310721,2,2,1617667,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +4,1310721,2,2,1,26,2,11,28,1,6,1,10,28,34,63, +38,3,26,1617745,16,3,1617803,14,1310721,2,2,1,26,2,13,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1617823,16,1310721,2,2,9,26,2,1617833,14,1581877, +2,1617833,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,28,1,6,1,10,28,34,63,38,3,26,1617923,16,3,1617977, +14,1310721,2,2,1581877,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1617987,16,3,1618045, +14,1310721,2,3,26,2,1581877,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1618055,16, +3,1618781,14,1310721,2,2,1617083,12,1618109,16,1310721,2,3,26,2,1617083, +12,1,6,1,10,28,34,63,38,1,10,28,1618111,14,1,1618121, +16,3,1618781,14,1310721,2,3,26,1310721,2,3,26,2,1617577,12,10, +3,6,10,4,8,1310721,2,2,1,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1618261,16,1310721,2,3,26,2,1,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,1618263,14,1,1618587,16,1310721,2,2, +9,26,2,1581877,2,28,1,6,1,10,28,34,63,38,3,26, +1618315,16,3,1618379,14,1310721,2,3,26,2,9,26,2,1581877,2,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1618389,16,3,1618449,14,1310721,2,2,9,26,2, +1581885,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1618459,16,3,1618523,14,1310721,2,3, +26,2,9,26,2,1581885,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1618533,16,3, +1618781,14,1310721,2,2,9,26,2,1310721,2,3,26,2,9,26,2, +28,1,6,1,10,28,34,63,38,3,26,1618781,14,1310721,2,2, +1,26,2,11,28,1,6,1,10,28,34,63,38,3,26,1618633, +16,3,1618691,14,1310721,2,2,1,26,2,15,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1618725,16,1581891,2,1,6,1,10,28,34,63,38,1,10,28, +1618727,14,1,1618737,16,3,1618781,14,1310721,2,2,1310721,2,3,26,2, +28,1,6,1,10,28,34,63,38,3,26,1618781,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,1,26,2,19,28, +1,6,1,10,28,34,63,38,3,26,1619045,16,1310721,2,7,26, +1310721,2,2,7,26,2,10,3,6,10,4,8,1310721,2,5,26, +2,1310721,2,7,26,2,26,2,1,6,1,10,28,34,63,38, +3,26,1619003,16,1310721,2,5,26,2,1310721,2,7,26,2,26,1310721, +2,3,26,2,10,3,6,10,4,8,3,1619849,14,1310721,2,5, +26,2,1310721,2,7,26,2,26,2,1310721,2,3,26,2,1617847,12, +1619849,14,1310721,2,3,26,1310721,2,3,26,2,1617577,12,10,3,6, +10,4,8,1310721,2,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1619185,16,1310721,2,3,26,2,1,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,1619187,14,1,1619289,16,1310721,2,3,26,2, +9,26,2,1581877,2,28,1,6,1,10,28,34,63,38,3,26, +1619243,16,3,1619849,14,1310721,2,2,9,26,2,1310721,2,3,26,2, +9,26,2,1310721,2,5,26,2,1618795,12,1619849,14,1310721,2,2,1, +26,2,17,28,1,6,1,10,28,34,63,38,3,26,1619367,16, +1310721,2,2,11,26,2,1,6,1,10,28,34,63,38,1,10, +28,1619369,14,1,1619439,16,1310721,2,3,26,2,1,26,2,17,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1619441,14,1,1619521,16,1310721,2,3,26,2,11, +26,2,1310721,2,2,11,26,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1619523,14, +1,1619823,16,1310721,2,11,26,1310721,2,2,13,26,2,10,3,6, +10,4,8,1310721,2,13,26,1310721,2,3,26,2,13,26,2,10, +3,6,10,4,8,1310721,2,9,26,1310721,2,11,26,2,1,26, +2,10,3,6,10,4,8,1310721,2,7,26,1,10,3,6,10, +4,8,1310721,2,7,26,2,1310721,2,9,26,2,40,1619817,16,1310721, +2,11,26,2,3,1310721,2,7,26,2,26,26,2,1310721,2,13, +26,2,3,1310721,2,7,26,2,26,26,2,1310721,2,5,26,2, +1618795,12,1,6,1,10,28,34,63,38,3,26,1619779,16,1,1619849, +14,1310721,2,7,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1619653,14,3,1619849,14,1310721,2,2,1310721,2,3,26,2,1617847, +12,1619849,14,1,1310721,2,15,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,4,1310721,2,2,1,26,2,1310721,2,3,26,4,1310721, +2,3,26,2,11,28,1,6,1,10,28,34,63,38,3,26, +1619969,16,85,1573079,12,8,1310721,2,2,9,26,2,1619863,12,1621071,14, +1310721,2,3,26,2,13,28,1,6,1,10,28,34,63,38,3, +26,1620061,16,183,1573079,12,8,1310721,2,2,7,26,2,1573371,12,8, +187,1573079,12,8,1310721,2,2,9,26,2,1619863,12,1621071,14,1310721,2, +3,26,2,15,28,1,6,1,10,28,34,63,38,3,26,1620721, +16,1620111,14,102,110,40,0,1620103,1573231,12,8,1310721,2,5,26,1, +10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,2,7,26, +2,40,1620493,16,1310721,2,5,26,2,1620201,16,1620193,14,44,32,0, +1620187,1573231,12,8,1310721,2,2,15,1310721,2,5,26,2,26,26,2, +1619863,12,8,1310721,2,5,26,2,25,40,1620319,16,1310721,2,2,1310721, +2,5,26,2,1632761,12,3,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1620321,14,1, +1620343,16,1620335,14,46,109,0,1620329,1573231,12,8,1310721,2,5,26,2, +25,40,1620431,16,1310721,2,2,1310721,2,5,26,2,1632761,12,5,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1620433,14,1,1620455,16,1620447,14,46,100,0,1620441, +1573231,12,8,1310721,2,5,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1620141,14,83,1573079,12,8,1310721,2,2,9,26,2, +1581877,2,28,1,6,1,10,28,34,63,38,1,10,28,1620551,16, +3,1620589,14,1310721,2,2,11,26,2,3,32,1,6,1,10,28, +34,63,38,1,10,28,1620715,16,1620607,14,32,45,62,32,0,1620597, +1573231,12,8,1310721,2,2,9,26,2,1581877,2,28,1,6,1,10, +28,34,63,38,1,10,28,1620677,16,1310721,2,2,9,26,2,1619863, +12,8,1310721,2,2,11,26,2,3,32,1620715,16,1620707,14,46,117, +0,1620701,1573231,12,8,1,1621071,14,1310721,2,2,5,26,2,1620759,16, +1310721,2,2,5,26,2,1573231,12,8,1620775,14,1620767,14,63,0,1620763, +1573231,12,8,1310721,2,3,26,2,17,28,1,6,1,10,28,34, +63,38,3,26,1620851,16,1310721,2,2,11,26,2,1,6,1,10, +28,34,63,38,1,10,28,1620853,14,1,1621063,16,1310721,2,7,26, +1310721,2,2,13,26,2,10,3,6,10,4,8,121,1573079,12,8, +1310721,2,5,26,1,10,3,6,10,4,8,1310721,2,5,26,2, +1310721,2,7,26,2,1,26,2,40,1621055,16,1310721,2,5,26,2, +1620983,16,1620975,14,44,32,0,1620969,1573231,12,8,1310721,2,7,26,2, +3,1310721,2,5,26,2,26,26,2,1619863,12,8,1310721,2,5,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1620919,14,125, +1573079,12,8,1,1621071,14,1,1310721,2,9,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2, +4,1581887,2,1,6,1,10,28,34,63,38,3,26,1621157,16,3, +1621203,14,1581767,2,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1621213,16,3,1621239,14,1581893,2, +1,6,1,10,28,34,63,38,1,10,28,1621249,16,1,1621461,14, +1621273,14,122,99,58,32,108,105,110,101,32,0,1621253,1573231,12,8, +1579523,2,1573371,12,8,1621325,14,58,32,116,121,112,101,32,101,114, +114,111,114,58,32,0,1621295,1573231,12,8,1310721,2,2,1573231,12,8, +1621373,14,58,32,101,120,112,101,99,116,101,100,32,0,1621349,1573231, +12,8,1310721,2,3,26,2,1619863,12,8,1621415,14,44,32,103,111, +116,32,0,1621401,1573231,12,8,1310721,2,5,26,2,1619863,12,8,21, +1573079,12,8,1573195,12,8,1,1621461,14,1,1310721,2,7,26,1310721,4, +18,1310721,2,7,28,1310721,4,1310721,2,5,26,4,1310721,2,3,26, +4,1310721,2,4,1310721,2,2,1621529,16,3,1621575,14,1581887,2,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1621585,16,3,1621631,14,1581767,2,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1621641, +16,3,1621667,14,1581893,2,1,6,1,10,28,34,63,38,1,10, +28,1621677,16,1,1621841,14,1621701,14,122,99,58,32,108,105,110,101, +32,0,1621681,1573231,12,8,1579523,2,1573371,12,8,1621753,14,58,32,116, +121,112,101,32,101,114,114,111,114,58,32,0,1621723,1573231,12,8, +1310721,2,3,26,2,1573231,12,8,1621795,14,44,32,103,111,116,32, +0,1621781,1573231,12,8,1310721,2,5,26,2,1619863,12,8,21,1573079,12, +8,1573195,12,8,1,1621841,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,4,1581911,2,1310721,2,3,26,4,1310721, +2,3,26,2,1622001,16,1310721,2,3,26,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1581895,1310721,2,3,26,2,26,2,1310721, +2,2,28,1,6,1,10,28,34,63,38,3,26,1621997,16,1310721, +2,3,26,2,1622015,14,1621887,14,3,1,10,28,1622015,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,4,1310721, +2,2,1621855,12,1,40,3,36,1622075,16,3,1622229,14,1310721,2,2, +1597111,12,1,40,3,36,1622103,16,1,1622229,14,1310721,2,3,26,1310721, +2,2,1583635,12,10,3,6,10,4,8,1310721,2,3,26,2,1, +40,3,36,1622221,16,1417729,1310721,2,3,26,2,26,2,15,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1622223,14,1,1622229,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,1,28,1310721,4,1581921,2,1592341,12,1622291,16,1579519,1581919,2, +10,3,6,10,4,8,1,1622309,14,1581919,2,1592809,12,8,1,1622309, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,79,28,1310721,4,1, +1310721,2,7,26,4,1,1310721,2,75,26,4,1581821,2,1592601,12,1622383, +16,1622323,12,1611981,12,1624165,14,1581805,2,1592601,12,1622547,16,1310721,2,1649967, +12,10,3,6,10,4,8,1581807,2,1592809,12,8,1310721,2,5,26, +1622323,12,10,3,6,10,4,8,1310721,2,2,1,40,1622523,16,1622515, +14,97,32,110,101,103,97,116,105,118,101,32,97,114,114,97, +121,32,108,101,110,103,116,104,0,1622467,1581991,12,8,1310721,2,5, +26,2,1310721,2,2,1612333,12,1624165,14,1581837,2,1592471,12,1623117,16,1591423, +12,8,1581797,2,1592809,12,8,1581799,2,1592341,12,1,6,1,10,28, +34,63,38,3,26,1622797,16,3,1622797,16,1310721,2,7,26,2,49, +40,3,36,1622687,16,1622679,14,116,111,111,32,109,97,110,121,32, +112,97,114,97,109,101,116,101,114,115,0,1622639,1581991,12,8,1310721, +2,9,26,1310721,2,7,26,2,26,1622323,12,10,3,6,10,4, +8,1310721,2,7,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1581809,2,1592601,12,1,6,1,10,28,34,63,38,3,26, +1622793,16,1622797,14,1622607,14,1581799,2,1592809,12,8,1310721,2,57,26,1581877, +2,10,3,6,10,4,8,1310721,2,77,26,1,10,3,6,10, +4,8,1581815,2,1592601,12,1623047,16,1581835,2,1592341,12,1,6,1,10, +28,34,63,38,3,26,1622921,16,1310721,2,57,26,1622323,12,10,3, +6,10,4,8,1581835,2,1592601,12,1623047,16,1581855,2,1592471,12,1,6, +1,10,28,34,63,38,3,26,1623019,16,1623011,14,116,104,101,32, +114,101,116,117,114,110,32,116,97,103,32,105,115,32,46,117, +0,1622969,1581991,12,8,1591423,12,8,1310721,2,77,26,3,10,3,6, +10,4,8,1310721,2,57,26,2,1310721,2,7,26,2,1310721,2,9, +26,1310721,2,77,26,2,1310721,2,7,26,2,26,1310721,2,7,26, +2,26,1612831,12,1624165,14,1579517,2,5,28,1,6,1,10,28,34, +63,38,1,10,28,1623195,16,1623187,14,101,120,112,101,99,116,101, +100,32,97,32,116,121,112,101,0,1623155,1581991,12,8,1310721,2,1579519, +2,10,3,6,10,4,8,1310721,2,77,26,1310721,2,2,1621855,12, +10,3,6,10,4,8,1310721,2,77,26,2,1,40,3,36,1623297, +16,1591423,12,8,1310721,2,77,26,2,1310721,2,2,1613731,12,1624165,14, +1310721,2,3,26,1310721,2,2,1583635,12,10,3,6,10,4,8,1310721, +2,3,26,2,1,40,1623351,16,3,1623415,14,1417729,1310721,2,3,26, +2,26,2,15,28,1,6,1,10,28,34,63,38,1,10,28, +1,6,1,10,28,34,63,38,1,10,28,1623463,16,1310721,2,2, +1623455,14,105,115,110,39,116,32,97,32,116,121,112,101,0,1623429, +1582117,12,8,1591423,12,8,1310721,2,5,26,1425921,1310721,2,3,26,2, +26,2,10,3,6,10,4,8,1310721,2,5,26,2,1,26,2, +21,28,1,6,1,10,28,34,63,38,1,10,28,1623565,16,1310721, +2,5,26,2,1624165,14,1581917,2,1592809,12,8,3,1623987,16,1310721,2, +75,26,2,17,40,3,36,1623663,16,1623655,14,116,111,111,32,109, +97,110,121,32,116,121,112,101,32,97,114,103,117,109,101,110, +116,115,0,1623607,1581991,12,8,1310721,2,59,26,1310721,2,75,26,2, +26,1622323,12,10,3,6,10,4,8,1310721,2,59,26,1310721,2,75, +26,2,26,2,1615957,12,3,28,1,6,1,10,28,34,63,38, +1,10,28,1623913,16,1623905,14,116,121,112,101,32,97,114,103,117, +109,101,110,116,115,32,104,97,118,101,32,116,111,32,98,101, +32,111,110,101,32,119,111,114,100,32,40,97,32,112,111,105, +110,116,101,114,44,32,97,32,110,117,109,98,101,114,44,32, +111,114,32,97,32,112,97,114,97,109,101,116,101,114,41,0, +1623759,1581991,12,8,1310721,2,75,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1581809,2,1592601,12,1,6,1,10,28,34,63, +38,3,26,1623983,16,1623987,14,1623575,14,1622243,12,8,1310721,2,75,26, +2,1310721,2,5,26,2,7,26,2,28,1,6,1,10,28,34, +63,38,1,10,28,1624127,16,1310721,2,2,1624119,14,119,114,111,110, +103,32,110,117,109,98,101,114,32,111,102,32,116,121,112,101, +32,97,114,103,117,109,101,110,116,115,0,1624057,1582117,12,8,1310721, +2,5,26,2,1310721,2,59,26,1310721,2,75,26,2,1614101,12,1624165, +14,1,1310721,2,79,26,1310721,4,18,1310721,2,1,28,1310721,4,1579517, +2,9,28,1,6,1,10,28,34,63,38,3,26,1624627,16,1579519, +2,1581805,2,28,1,6,1,10,28,34,63,38,3,26,1624263,16, +3,1624315,14,1579519,2,1581835,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1624325,16,3, +1624743,14,1579519,2,1581821,2,28,1,6,1,10,28,34,63,38,3, +26,1624621,16,1591561,12,8,1581739,2,5,28,1,6,1,10,28,34, +63,38,3,26,1624493,16,1581741,2,1622029,12,1624415,16,3,1624467,14,1581741, +2,1581837,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,1624495,14,1,1624505,16,3,1624617,14,1581739,2,9,28, +1,6,1,10,28,34,63,38,3,26,1624593,16,1581741,2,1581805,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1624595,14,1,1,6,1,10,28,34,63, +38,1,10,28,1624743,14,1,1624743,14,1579517,2,5,28,1,6,1, +10,28,34,63,38,1,10,28,1624667,16,1,1624743,14,1579519,2,1581837, +2,28,1,6,1,10,28,34,63,38,3,26,1624707,16,3,1624737, +14,1579519,2,1622029,12,1,6,1,10,28,34,63,38,1,10,28, +1624743,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4, +1581913,1,10,3,6,10,4,8,1581915,1,10,3,6,10,4,8, +1581835,2,1592341,12,1,6,1,10,28,34,63,38,3,26,1624851,16, +1581913,1622323,12,10,3,6,10,4,8,1581835,2,1592601,12,1625087,16,1579519, +2,1581851,2,28,1,6,1,10,28,34,63,38,3,26,1624917,16, +1581915,3,10,3,6,10,4,8,1625081,14,1579519,2,1581855,2,28,1, +6,1,10,28,34,63,38,3,26,1624971,16,1581915,5,10,3,6, +10,4,8,1625081,14,1579519,2,1581853,2,28,1,6,1,10,28,34, +63,38,3,26,1625025,16,1581915,7,10,3,6,10,4,8,1625081,14, +1625073,14,97,32,116,97,103,32,105,115,32,46,117,44,32,46, +109,32,111,114,32,46,100,0,1625029,1581991,12,8,1591423,12,8,1, +1625095,14,1,1310721,2,1,26,1310721,4,18,1310721,2,21,28,1310721,4, +1,1310721,2,7,26,4,1524225,1310721,2,9,26,4,1,1310721,2,15, +26,4,1,1310721,2,17,26,4,1591423,12,8,1310721,2,1592987,12,10, +3,6,10,4,8,1581917,2,1592341,12,1625589,16,1591423,12,8,1581911,1, +10,3,6,10,4,8,3,1625405,16,1581911,2,17,40,3,36,1625313, +16,1625305,14,116,111,111,32,109,97,110,121,32,116,121,112,101, +32,112,97,114,97,109,101,116,101,114,115,0,1625255,1581991,12,8, +1581895,1581911,2,26,1592987,12,10,3,6,10,4,8,1581911,1,6,2, +1,6,3,26,5,6,4,10,8,8,1581809,2,1592601,12,1,6, +1,10,28,34,63,38,3,26,1625401,16,1625405,14,1625229,14,1622243,12, +8,1310721,2,17,26,3,10,3,6,10,4,8,1310721,2,3,26, +21,1,1310721,2,2,1,1611655,12,10,3,6,10,4,8,1310721,2, +3,26,2,7,26,1581911,2,10,3,6,10,4,8,1310721,2,13, +26,1581911,2,1611463,12,10,3,6,10,4,8,1310721,2,13,26,2, +1581895,1581911,2,1574139,12,8,1310721,2,3,26,2,13,26,1310721,2,13, +26,2,10,3,6,10,4,8,1625659,14,1310721,2,3,26,17,1, +1310721,2,2,1,1611655,12,10,3,6,10,4,8,1310721,2,3,26, +2,7,26,5,1,10,28,10,3,6,10,4,8,1310721,2,5, +26,1310721,2,2,15,1310721,2,3,26,2,1583159,12,10,3,6,10, +4,8,1581801,2,1592809,12,8,1581803,2,1592341,12,1,6,1,10,28, +34,63,38,3,26,1626037,16,1310721,2,19,26,1622323,12,10,3,6, +10,4,8,3,1626023,16,1310721,2,7,26,2,2001,40,3,36,1625839, +16,1625831,14,116,111,111,32,109,97,110,121,32,102,105,101,108, +100,115,0,1625799,1581991,12,8,1310721,2,9,26,2,1310721,2,7,26, +2,1310721,2,7,26,2,26,26,1592987,12,10,3,6,10,4,8, +1310721,2,9,26,2,1310721,2,7,26,2,1310721,2,7,26,2,26, +3,26,26,1310721,2,19,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,1581809, +2,1592601,12,1,6,1,10,28,34,63,38,3,26,1626019,16,1626023, +14,1625767,14,1581811,2,1592809,12,8,1625711,14,1591423,12,8,1310721,2,17, +26,2,1626243,16,1310721,2,13,26,1310721,2,7,26,2,1310721,2,7, +26,2,26,1611463,12,10,3,6,10,4,8,1310721,2,13,26,2, +1310721,2,9,26,2,1310721,2,7,26,2,1310721,2,7,26,2,26, +1574139,12,8,1310721,2,3,26,2,9,26,1310721,2,13,26,2,10, +3,6,10,4,8,1310721,2,3,26,2,11,26,1310721,2,7,26, +2,10,3,6,10,4,8,1581911,1,10,3,6,10,4,8,1626929, +14,1310721,2,13,26,1310721,2,7,26,2,7,30,3,26,1611463,12, +10,3,6,10,4,8,1310721,2,11,26,1,10,3,6,10,4, +8,1310721,2,11,26,2,1310721,2,7,26,2,40,1626821,16,1310721,2, +19,26,1310721,2,9,26,2,1310721,2,11,26,2,1310721,2,11,26, +2,26,3,26,26,2,10,3,6,10,4,8,1310721,2,19,26, +2,1310721,2,3,26,2,28,1,6,1,10,28,34,63,38,3, +26,1626559,16,1626551,14,97,32,115,116,114,117,99,116,32,99,97, +110,39,116,32,99,111,110,116,97,105,110,32,105,116,115,101, +108,102,32,98,121,32,118,97,108,117,101,59,32,117,115,101, +32,97,32,112,111,105,110,116,101,114,0,1626443,1581991,12,8,1310721, +2,13,26,2,1310721,2,11,26,2,7,30,26,1310721,2,9,26, +2,1310721,2,11,26,2,1310721,2,11,26,2,26,26,2,10,3, +6,10,4,8,1310721,2,13,26,2,1310721,2,11,26,2,7,30, +3,26,26,1310721,2,19,26,2,10,3,6,10,4,8,1310721,2, +13,26,2,1310721,2,11,26,2,7,30,5,26,26,1310721,2,15, +26,2,10,3,6,10,4,8,1310721,2,15,26,1310721,2,15,26, +2,1310721,2,19,26,2,1615957,12,26,10,3,6,10,4,8,1310721, +2,11,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1626307,14,1310721,2,3,26,2,9,26,1310721,2,13,26,2,10,3, +6,10,4,8,1310721,2,3,26,2,3,26,1310721,2,15,26,2, +10,3,6,10,4,8,1310721,2,3,26,2,7,26,1310721,2,7, +26,2,10,3,6,10,4,8,1581811,2,1592601,12,8,1310721,2,5, +26,2,1626955,14,1,1310721,2,21,26,1310721,4,18,1310721,2,3,28, +1310721,4,1591423,12,8,1310721,2,1592987,12,10,3,6,10,4,8,1581813, +2,1592809,12,8,1310721,2,2,15,1622323,12,1583159,12,8,1581811,2,1592809, +12,8,1,1627053,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1, +28,1310721,4,1591423,12,8,1581939,2,1592471,12,1627117,16,1581887,3,10,3, +6,10,4,8,1627221,14,1581941,2,1592471,12,1627149,16,1581887,1,10,3, +6,10,4,8,1627221,14,1627213,14,116,121,112,101,99,104,101,99, +107,32,111,110,32,111,114,32,116,121,112,101,99,104,101,99, +107,32,111,102,102,0,1627153,1581991,12,8,1591423,12,8,1581811,2,1592809, +12,8,1,1627245,14,1,1310721,2,1,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,1614941,12,8,1310721,2,5,26,2,1310721,2,2,7, +26,2,40,1627457,16,1310721,2,2,9,26,2,1310721,2,5,26,2, +7,30,26,2,1310721,2,3,26,2,28,1,6,1,10,28,34, +63,38,3,26,1627419,16,1310721,2,5,26,2,1627471,14,1310721,2,5, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1627311,14, +3,1,10,28,1627471,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +7,28,1310721,4,1581797,2,1592809,12,8,1624179,12,1627569,16,1581835,2,1592341, +12,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1627571,14,1,1627599,16,1310721,2,1622323,12,10, +3,6,10,4,8,1627761,14,1310721,2,3,26,1599965,12,10,3,6, +10,4,8,1581893,1,6,2,1,6,3,26,5,6,4,10,8, +8,1310721,2,5,26,1646495,12,10,3,6,10,4,8,1633929,12,8, +1310721,2,1581889,2,10,3,6,10,4,8,1581893,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1310721,2,3,26,2,1600553,12,8, +1310721,2,3,26,2,1600493,12,8,1581799,2,1592809,12,8,1310721,2,2, +1627783,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4, +1591423,12,8,1310721,2,1627485,12,10,3,6,10,4,8,1310721,2,2, +1615957,12,1584843,12,8,1581889,1581879,2,10,3,6,10,4,8,1,1627877, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1591423, +12,8,1310721,2,1627485,12,10,3,6,10,4,8,1310721,2,2,1584843, +12,8,1581889,1581877,2,10,3,6,10,4,8,1,1627967,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,1,28,1310721,4,1581873,1277953,2049,26, +10,3,6,10,4,8,1581875,1,10,3,6,10,4,8,1581877,1, +3,1628049,14,119,111,114,100,0,1628039,1582663,12,1,1611655,12,10,3, +6,10,4,8,1581879,3,3,1628091,14,105,110,116,0,1628083,1582663,12, +1,1611655,12,10,3,6,10,4,8,1581881,5,3,1628135,14,99,104, +97,114,0,1628125,1582663,12,1,1611655,12,10,3,6,10,4,8,1581883, +7,3,1628179,14,98,111,111,108,0,1628169,1582663,12,1,1611655,12,10, +3,6,10,4,8,1581885,9,1,1628223,14,118,111,105,100,0,1628213, +1582663,12,1,1611655,12,10,3,6,10,4,8,1581877,2,5,26,2, +15,1581877,2,1583159,12,8,1581879,2,5,26,2,15,1581879,2,1583159,12, +8,1581881,2,5,26,2,15,1581881,2,1583159,12,8,1581883,2,5,26, +2,15,1581883,2,1583159,12,8,1581885,2,5,26,2,15,1581885,2,1583159, +12,8,1581917,1628367,14,60,0,1628363,1582663,12,10,3,6,10,4,8, +1581919,1628395,14,62,0,1628391,1582663,12,10,3,6,10,4,8,1581921,1628425, +14,62,62,0,1628419,1582663,12,10,3,6,10,4,8,1581923,1628455,14, +60,61,0,1628449,1582663,12,10,3,6,10,4,8,1581925,1628485,14,62, +61,0,1628479,1582663,12,10,3,6,10,4,8,1581927,1628515,14,61,61, +0,1628509,1582663,12,10,3,6,10,4,8,1581929,1628545,14,33,61,0, +1628539,1582663,12,10,3,6,10,4,8,1581931,1628573,14,43,0,1628569,1582663, +12,10,3,6,10,4,8,1581933,1628611,14,115,116,114,117,99,116, +0,1628597,1582663,12,10,3,6,10,4,8,1581935,1628645,14,116,121,112, +101,0,1628635,1582663,12,10,3,6,10,4,8,1581937,1628689,14,116,121, +112,101,99,104,101,99,107,0,1628669,1582663,12,10,3,6,10,4, +8,1581939,1628719,14,111,110,0,1628713,1582663,12,10,3,6,10,4,8, +1581941,1628751,14,111,102,102,0,1628743,1582663,12,10,3,6,10,4,8, +1581943,1628783,14,110,101,119,0,1628775,1582663,12,10,3,6,10,4,8, +1581945,1628819,14,110,101,119,95,116,0,1628807,1582663,12,10,3,6,10, +4,8,1581947,1,26,1628851,14,42,0,1628847,1582663,12,10,3,6,10, +4,8,1581947,3,26,1628883,14,47,0,1628879,1582663,12,10,3,6,10, +4,8,1581947,5,26,1628915,14,37,0,1628911,1582663,12,10,3,6,10, +4,8,1581947,7,26,1628947,14,38,0,1628943,1582663,12,10,3,6,10, +4,8,1581947,9,26,1628979,14,124,0,1628975,1582663,12,10,3,6,10, +4,8,1581947,11,26,1629011,14,94,0,1629007,1582663,12,10,3,6,10, +4,8,1581947,13,26,1629045,14,60,60,0,1629039,1582663,12,10,3,6, +10,4,8,1581947,15,26,1581921,2,10,3,6,10,4,8,1581971,17, +10,3,6,10,4,8,1,1629109,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,3,26,2,1581971,2,40,1629265,16,1581947,1310721,2,3,26,2, +26,2,1310721,2,2,28,1,6,1,10,28,34,63,38,3,26, +1629227,16,3,1629273,14,1310721,2,3,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1629153,14,1,1629273,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,5,26,4,1310721,2, +3,26,4,1310721,2,4,1546753,1310721,2,2,26,2,1310721,2,7,26, +4,1310721,2,3,26,1310721,2,3,26,2,1617577,12,10,3,6,10, +4,8,1310721,2,5,26,1310721,2,5,26,2,1617577,12,10,3,6, +10,4,8,1547137,1310721,2,2,26,2,1,40,1629611,16,1310721,2,3, +26,2,1617293,12,1,6,1,10,28,34,63,38,3,26,1629533,16, +1310721,2,5,26,2,1617293,12,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1629535,14,1,1629585, +14,38,38,32,97,110,100,32,124,124,32,110,101,101,100,32, +115,99,97,108,97,114,115,0,1629539,1310721,2,3,26,2,1621475,12, +8,1581883,2,1632037,14,1310721,2,7,26,2,1581927,2,28,1,6,1, +10,28,34,63,38,3,26,1629657,16,3,1629715,14,1310721,2,7,26, +2,1581929,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1629905,16,1310721,2,3,26,2, +1310721,2,5,26,2,1617847,12,1,6,1,10,28,34,63,38,3, +26,1629837,16,1310721,2,5,26,2,1310721,2,3,26,2,1617847,12,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1629839,14,1,1629897,16,1629869,14,99,111,109,112,97, +114,105,115,111,110,0,1629847,1310721,2,3,26,2,1310721,2,5,26, +2,1621085,12,8,1581883,2,1632037,14,1310721,2,7,26,2,1581917,2,28, +1,6,1,10,28,34,63,38,3,26,1629951,16,3,1630009,14,1310721, +2,7,26,2,1581919,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1630019,16,3,1630077, +14,1310721,2,7,26,2,1581923,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1630087,16, +3,1630145,14,1310721,2,7,26,2,1581925,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1630575,16,1310721,2,3,26,2,1581877,2,28,1,6,1,10,28,34, +63,38,3,26,1630195,16,3,1630253,14,1310721,2,5,26,2,1581877,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1630263,16,3,1630345,14,1310721,2,3,26,2, +1617083,12,1630321,16,1310721,2,5,26,2,1617083,12,1,6,1,10,28, +34,63,38,1,10,28,1630323,14,1,1,6,1,10,28,34,63, +38,1,10,28,1630355,16,3,1630489,14,1310721,2,3,26,2,1,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1630465,16,1310721, +2,5,26,2,1,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,1630467,14, +1,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,3,26,1630567,16,1630539,14,99,111,109,112,97,114, +105,115,111,110,0,1630517,1310721,2,3,26,2,1310721,2,5,26,2, +1621085,12,8,1581883,2,1632037,14,1310721,2,7,26,2,1581931,2,28,1, +6,1,10,28,34,63,38,3,26,1631123,16,1310721,2,3,26,2, +1,26,2,11,28,1,6,1,10,28,34,63,38,3,26,1630767, +16,1310721,2,5,26,2,1617083,12,1630683,16,3,1630741,14,1310721,2,5, +26,2,1581877,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,1630769,14,1,1630787,16,1310721,2,3,26,2,1632037, +14,1310721,2,5,26,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1630871,16,1310721,2,3,26,2,1617083,12,1,6, +1,10,28,34,63,38,1,10,28,1630873,14,1,1630891,16,1310721,2, +5,26,2,1632037,14,1310721,2,3,26,2,1581877,2,28,1,6,1, +10,28,34,63,38,3,26,1630937,16,3,1630995,14,1310721,2,5,26, +2,1581877,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1631007,16,1581877,2,1632037,14,1310721, +2,3,26,2,1617083,12,1631065,16,1310721,2,5,26,2,1617083,12,1, +6,1,10,28,34,63,38,1,10,28,1631067,14,1,1631079,16,1581879, +2,1632037,14,1631087,14,43,0,1631083,1310721,2,3,26,2,1310721,2,5, +26,2,1621085,12,8,1581877,2,1632037,14,1310721,2,7,26,2,1581829,2, +28,1,6,1,10,28,34,63,38,3,26,1631691,16,1310721,2,3, +26,2,1,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1631273,16,1310721,2,5,26,2,1,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,1631275,14,1,1631287,16,1581879,2,1632037,14,1310721,2,3,26,2, +1,26,2,11,28,1,6,1,10,28,34,63,38,3,26,1631439, +16,1310721,2,5,26,2,1617083,12,1631355,16,3,1631413,14,1310721,2,5, +26,2,1581877,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,1631441,14,1,1631459,16,1310721,2,3,26,2,1632037, +14,1310721,2,3,26,2,1581877,2,28,1,6,1,10,28,34,63, +38,3,26,1631505,16,3,1631563,14,1310721,2,5,26,2,1581877,2,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1631575,16,1581877,2,1632037,14,1310721,2,3,26,2, +1617083,12,1631633,16,1310721,2,5,26,2,1617083,12,1,6,1,10,28, +34,63,38,1,10,28,1631635,14,1,1631647,16,1581879,2,1632037,14,1631655, +14,45,0,1631651,1310721,2,3,26,2,1310721,2,5,26,2,1621085,12, +8,1581877,2,1632037,14,1310721,2,7,26,2,1629123,12,1632027,16,1310721,2, +3,26,2,1581877,2,28,1,6,1,10,28,34,63,38,3,26, +1631755,16,3,1631813,14,1310721,2,5,26,2,1581877,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1631825,16,1581877,2,1632037,14,1310721,2,3,26,2,1617083,12,1631883, +16,1310721,2,5,26,2,1617083,12,1,6,1,10,28,34,63,38, +1,10,28,1631885,14,1,1631897,16,1581879,2,1632037,14,1310721,2,3,26, +2,1617083,12,1631945,16,1310721,2,3,26,1310721,2,5,26,2,10,3, +6,10,4,8,1,1632001,14,97,114,105,116,104,109,101,116,105, +99,32,110,101,101,100,115,32,110,117,109,98,101,114,115,0, +1631951,1310721,2,3,26,2,1621475,12,8,1581877,2,1632037,14,1581877,2,1632037, +14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,4,1310721,2,2,1,26,2,1632087,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,1615957,12, +1632135,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,4,1310721,2,2,5,26,2,1632185,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2,2,7, +26,2,1632235,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1310721,2,2,1614941,12,8,1310721,2,2,7,26, +2,1632297,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,1614941,12,8,1310721, +2,2,9,26,2,1310721,2,3,26,2,7,30,26,2,1632387,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +3,26,4,1310721,2,4,1310721,2,2,1614941,12,8,1310721,2,2,9, +26,2,1310721,2,3,26,2,7,30,3,26,26,2,1632481,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3, +26,4,1310721,2,4,1310721,2,2,1614941,12,8,1310721,2,2,9,26, +2,1310721,2,3,26,2,7,30,5,26,26,2,1632575,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721, +2,2,9,26,2,1632625,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,4,1310721,2,2,7,26,2,1632675,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,15,1310721,2,3,26,2,26, +26,2,1632747,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,3,26,4,1310721,2,4,1310721,2,2,11,26,2, +13,38,1310721,2,3,26,2,1310721,2,3,26,2,26,38,7,32, +1632839,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,4,1310721,2,2,11,26,2,3,32,1632893,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2, +2,1,26,2,17,28,1,6,1,10,28,34,63,38,1,10, +28,1632973,16,3,1633027,14,1310721,2,2,11,26,2,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1633037,16,1,1633061,14,1310721,2,2,13,26,2,1,26,2,1633061, +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,13,26,2,3,1310721,2, +3,26,2,26,26,2,1633139,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,59,28,1310721,4,1310721,2,4,1579447,2,1310721,2,3,26,4, +3,1,10,28,1310721,2,5,26,4,1310721,2,3,26,2,1633461,16, +1310721,2,3,26,1,6,2,1,6,-1,26,5,6,4,10,8, +8,1417729,1310721,2,3,26,2,26,2,3,28,1,6,1,10,28, +34,63,38,3,26,1633365,16,1425921,1310721,2,3,26,2,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,1633367,14,1,1633417,16,1442305,1310721,2, +3,26,2,26,2,3,32,1,6,1,10,28,34,63,38,1, +10,28,1633419,14,1,1633457,16,1310721,2,5,26,1310721,2,3,26,2, +10,3,6,10,4,8,1633461,14,1633203,14,1310721,2,5,26,2,1, +40,1633485,16,1,1633739,14,1559041,1310721,2,5,26,2,26,2,1633525,16, +1559041,1310721,2,5,26,2,26,2,1633739,14,1310721,2,55,26,1434113,1310721, +2,5,26,2,26,2,3,38,63,32,10,3,6,10,4,8, +1310721,2,57,26,1,10,3,6,10,4,8,1310721,2,57,26,2, +1310721,2,55,26,2,40,1633691,16,1310721,2,7,26,1310721,2,57,26, +2,26,1581877,2,10,3,6,10,4,8,1310721,2,57,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1633591,14,1581877,2,1310721, +2,55,26,2,1310721,2,7,26,1434113,1310721,2,5,26,2,26,2, +1612831,12,1633739,14,1,1310721,2,59,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,4,1310721,2,2,1584093,12,1310721,2,3,26,4,1310721, +2,3,26,2,1,40,1633815,16,3,1633879,14,1417729,1310721,2,3,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,1633889,16,1,1633915,14, +1425921,1310721,2,3,26,2,26,2,1633153,12,1633915,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,1,28,1310721,4,1581785,2,1634005,16,1581889,2, +1617293,12,1,6,1,10,28,34,63,38,3,26,1633989,16,3,1584907, +12,8,1581785,1,10,3,6,10,4,8,1,1634013,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,1581791,2, +1310721,2,7,26,4,1581791,1310721,2,3,26,2,10,3,6,10,4, +8,1581793,1,10,3,6,10,4,8,1581889,1581877,2,10,3,6,10, +4,8,1581891,1,10,3,6,10,4,8,1310721,2,5,26,2,1, +6,12,10,8,8,1581791,1310721,2,7,26,2,10,3,6,10,4, +8,1310721,2,9,26,1581793,2,10,3,6,10,4,8,1581785,1,10, +3,6,10,4,8,1581787,1,10,3,6,10,4,8,1310721,2,9, +26,2,1634283,14,1,1310721,2,11,26,1310721,4,18,1310721,2,1,28, +1310721,4,1581791,2,1634409,16,1634401,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, +1634321,1581991,12,8,1,1634417,14,1,1310721,2,1,26,1310721,4,18,1310721, +2,13,28,1310721,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721, +2,4,1,1310721,2,7,26,4,1581797,2,1592809,12,8,1581799,2,1592341, +12,1,6,1,10,28,34,63,38,3,26,1634915,16,3,1634915,16, +1310721,2,9,26,1646495,12,10,3,6,10,4,8,1633929,12,8,1310721, +2,9,26,2,1310721,2,2,1310721,2,7,26,2,1310721,2,7,26, +2,26,38,7,32,1604537,12,8,1310721,2,3,26,2,1634677,16,1310721, +2,7,26,2,1310721,2,3,26,2,7,26,2,40,1,6,1, +10,28,34,63,38,1,10,28,1634679,14,1,1634841,16,1310721,2,11, +26,1310721,2,3,26,2,15,1310721,2,7,26,2,26,26,2,10, +3,6,10,4,8,1310721,2,11,26,2,1581889,2,1310721,2,5,26, +2,1618795,12,1,6,1,10,28,34,63,38,3,26,1634841,16,1634805, +14,97,114,103,117,109,101,110,116,0,1634787,1310721,2,11,26,2, +1310721,2,5,26,2,1616107,12,1581889,2,1621085,12,8,1310721,2,7,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1581809,2,1592601, +12,1,6,1,10,28,34,63,38,3,26,1634911,16,1634915,14,1634523, +14,1581799,2,1592809,12,8,1310721,2,7,26,2,1634941,14,1,1310721,2, +13,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1622323,12,10, +3,6,10,4,8,1581809,2,1592601,12,1635131,16,1310721,2,3,26,1646495, +12,10,3,6,10,4,8,1633929,12,8,1310721,2,3,26,2,1598391, +12,8,1310721,2,2,1615957,12,3,28,1,6,1,10,28,34,63, +38,1,10,28,1635109,16,1310721,2,2,1615957,12,1584843,12,8,31,1584907, +12,8,1310721,2,2,1,1612333,12,1584843,12,8,1635159,14,1310721,2,2, +1615957,12,1584843,12,8,1310721,2,2,1584843,12,8,1581799,2,1592809,12,8, +1581945,2,1585453,12,8,1581785,1,10,3,6,10,4,8,1581787,1,10, +3,6,10,4,8,1581889,1310721,2,2,1611981,12,10,3,6,10,4, +8,1581891,1,10,3,6,10,4,8,3,1635259,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,27,28,1310721,4,1310721,2,4,1,1310721,2, +5,26,4,1,1310721,2,7,26,4,1559041,1310721,2,2,26,2,1310721, +2,9,26,4,1409537,1310721,2,2,26,2,1581943,2,28,1,6,1, +10,28,34,63,38,3,26,1635441,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,1635443,14,1,1635771,16,1591561,12,8,1581739,2, +9,28,1,6,1,10,28,34,63,38,3,26,1635603,16,1581741,2, +1581821,2,28,1,6,1,10,28,34,63,38,3,26,1635525,16,3, +1635577,14,1581741,2,1581805,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,1635605,14,1,1635623,16,1591423,12,8,1634955, +12,1636371,14,1581739,2,5,28,1,6,1,10,28,34,63,38,3, +26,1635751,16,1581741,2,1622029,12,1635673,16,3,1635725,14,1581741,2,1581837,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,1635753,14,1,1635771,16,1591423,12,8,1634955,12,1636371,14,1442305,1310721,2, +2,26,2,5,32,1635867,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,1635905,14,1442305,1310721,2, +2,26,1442305,1310721,2,2,26,2,9,34,10,3,6,10,4,8, +1310721,2,11,26,1,17,1574329,12,8,1581989,2,1635967,16,1310721,2,11, +26,1581973,1581989,2,1574139,12,8,1581989,1,10,3,6,10,4,8,1310721, +2,3,26,1310721,2,5,26,2,1310721,2,9,26,2,1310721,2,11, +26,1634431,12,10,3,6,10,4,8,1442305,1310721,2,2,26,2,5, +32,1636119,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,1636121,14,1,1636201,16,1409537,1310721, +2,2,26,2,1636193,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, +1636141,1582117,12,8,1310721,2,2,1585301,12,8,13,1584907,12,8,1581785,1, +10,3,6,10,4,8,1581787,1,10,3,6,10,4,8,1581891,1, +10,3,6,10,4,8,1581889,1581877,2,10,3,6,10,4,8,1310721, +2,9,26,2,1636343,16,1581889,1310721,2,9,26,2,9,26,2,1310721, +2,11,26,1616107,12,10,3,6,10,4,8,1310721,2,7,26,2, +1636363,16,3,1636371,14,1,1636371,14,1,1310721,2,27,26,1310721,4,18, +1310721,2,11,28,1310721,4,1310721,2,4,1434113,1310721,2,2,26,2,31, +32,1310721,2,3,26,4,1434113,1310721,2,2,26,2,9,38,31,32, +1310721,2,5,26,4,1,1310721,2,7,26,4,1581797,2,1592809,12,8, +1581799,2,1592341,12,1,6,1,10,28,34,63,38,3,26,1636639,16, +3,1636639,16,1310721,2,9,26,1646495,12,10,3,6,10,4,8,1633929, +12,8,1310721,2,9,26,2,1598391,12,8,1310721,2,7,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1581809,2,1592601,12,1, +6,1,10,28,34,63,38,3,26,1636635,16,1636639,14,1636513,14,1581799, +2,1592809,12,8,1310721,2,7,26,2,1310721,2,3,26,2,28,1, +6,1,10,28,34,63,38,1,10,28,1636767,16,1409537,1310721,2,2, +26,2,1636759,14,119,114,111,110,103,32,110,117,109,98,101,114, +32,111,102,32,105,110,112,117,116,115,0,1636713,1582117,12,8,1581785, +1,10,3,6,10,4,8,1581787,1,10,3,6,10,4,8,1581889, +1581877,2,10,3,6,10,4,8,1581891,1,10,3,6,10,4,8, +1442305,1310721,2,2,26,2,129,32,1636889,16,1450497,1310721,2,2,26,2, +3,28,1585301,12,8,13,1584907,12,8,1,1637087,14,45,1425921,1310721,2, +2,26,2,26,1584907,12,8,1310721,2,5,26,2,1,28,1,6, +1,10,28,34,63,38,3,26,1636957,16,1,1584843,12,8,1310721,2, +5,26,2,3,10,40,1637079,16,1409537,1310721,2,2,26,2,1637071,14, +108,101,97,118,101,115,32,115,101,118,101,114,97,108,32,118, +97,108,117,101,115,59,32,117,115,101,32,105,116,32,102,114, +111,109,32,97,115,109,0,1636993,1582117,12,8,1,1637087,14,1,1310721, +2,11,26,1310721,4,18,1310721,2,9,28,1310721,4,1581785,1,10,3, +6,10,4,8,1581787,1,10,3,6,10,4,8,1581891,1,10,3, +6,10,4,8,1579517,2,3,28,1,6,1,10,28,34,63,38, +3,26,1637275,16,1579519,2,1584843,12,8,1581891,1579519,2,1,28,1,6, +1,10,28,34,63,38,3,26,10,3,6,10,4,8,1581889,1581879, +2,10,3,6,10,4,8,1591423,12,8,1,1639809,14,1579517,2,7, +28,1,6,1,10,28,34,63,38,3,26,1637351,16,1579519,2,1585671, +12,8,1591423,12,8,1581889,1581881,2,1611981,12,10,3,6,10,4,8, +1,1639809,14,1579517,2,9,28,1,6,1,10,28,34,63,38,3, +26,1637571,16,1579519,2,1581797,2,28,1,6,1,10,28,34,63,38, +3,26,1637471,16,1591423,12,8,1310721,2,7,26,1646495,12,10,3,6, +10,4,8,1581799,2,1592809,12,8,1310721,2,7,26,2,1639809,14,1579519, +2,1581801,2,28,1,6,1,10,28,34,63,38,3,26,1637513,16, +1648443,12,1639809,14,1637563,14,101,120,112,101,99,116,101,100,32,97, +110,32,101,120,112,114,101,115,115,105,111,110,0,1637517,1581991,12, +8,1579517,2,5,28,1,6,1,10,28,34,63,38,1,10,28, +1637663,16,1637655,14,101,120,112,101,99,116,101,100,32,97,110,32, +101,120,112,114,101,115,115,105,111,110,0,1637609,1581991,12,8,1310721, +2,1579519,2,10,3,6,10,4,8,1310721,2,3,26,1310721,2,2, +1597111,12,10,3,6,10,4,8,1310721,2,3,26,2,1,40,3, +36,1638135,16,1591423,12,8,1581763,2,1,6,1,10,28,34,63,38, +3,26,1637809,16,1310721,2,3,26,2,1597849,12,1,6,1,10,28, +34,63,38,1,10,28,1637811,14,1,1637959,16,1310721,2,2,1637951,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,1637825, +1582117,12,8,1467905,1310721,2,3,26,2,26,2,1585585,12,8,1581889,1556993, +1310721,2,3,26,2,26,2,10,3,6,10,4,8,1473025,1310721,2, +3,26,2,26,2,1638037,16,1,1639809,14,1581785,3,10,3,6,10, +4,8,1581787,3,10,3,6,10,4,8,1581789,1310721,2,3,26,2, +10,3,6,10,4,8,1310721,2,3,26,2,1597849,12,1638129,16,5, +1310721,2,3,26,2,26,1639809,14,1,1639809,14,1310721,2,5,26,1310721, +2,2,1583635,12,10,3,6,10,4,8,1310721,2,5,26,2,1, +40,3,36,1638253,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,1638255,14,1,1638411,16,1442305,1310721,2,5,26,2,26, +2,33,32,1,6,1,10,28,34,63,38,3,26,1638391,16,1310721, +2,2,1638383,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,1638313,1582117,12,8,1310721,2,5,26,2, +3,1634027,12,1639809,14,1310721,2,5,26,2,1,40,3,36,1638499,16, +1417729,1310721,2,5,26,2,26,2,15,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1638501, +14,1,1638569,16,1310721,2,2,1638561,14,105,115,32,97,32,116,121, +112,101,44,32,110,111,116,32,97,32,118,97,108,117,101,0, +1638515,1582117,12,8,1591423,12,8,1581889,1581877,2,10,3,6,10,4,8, +1310721,2,5,26,2,1,40,3,36,1638681,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,1638683,14,1,1638787,16,1425921, +1310721,2,5,26,2,26,2,1584843,12,8,1581889,1581879,2,10,3,6, +10,4,8,1581891,1425921,1310721,2,5,26,2,26,2,1,28,1,6, +1,10,28,34,63,38,3,26,10,3,6,10,4,8,1,1639809, +14,1310721,2,5,26,2,1,40,3,36,1638875,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,1638877,14,1,1638991,16, +1425921,1310721,2,5,26,2,26,2,1584843,12,8,1559041,1310721,2,5,26, +2,26,2,1638953,16,1581889,1559041,1310721,2,5,26,2,26,2,10,3, +6,10,4,8,1581785,3,10,3,6,10,4,8,1581787,5,10,3, +6,10,4,8,1,1639809,14,1310721,2,5,26,2,1,40,3,36, +1639079,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,1639081,14,1,1639163,16,1425921,1310721,2,5,26,2,26,2,1584843,12, +8,1559041,1310721,2,5,26,2,26,2,1639157,16,1581889,1559041,1310721,2,5, +26,2,26,2,10,3,6,10,4,8,1,1639809,14,1310721,2,5, +26,2,1,40,3,36,1639251,16,1417729,1310721,2,5,26,2,26,2, +13,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1639253,14,1,1639275,16,1310721,2,5,26, +2,1636385,12,1639809,14,1310721,2,5,26,2,1,40,1639323,16,1310721,2, +5,26,1310721,2,2,1585201,12,10,3,6,10,4,8,1581917,2,1592341, +12,1639381,16,1442305,1310721,2,5,26,2,26,2,257,32,1,6,1, +10,28,34,63,38,1,10,28,1639383,14,1,1639705,16,1591423,12,8, +1581989,1,10,3,6,10,4,8,3,1639583,16,1581989,2,17,40,3, +36,1639491,16,1639483,14,116,111,111,32,109,97,110,121,32,116,121, +112,101,32,97,114,103,117,109,101,110,116,115,0,1639435,1581991,12, +8,1581973,1581989,2,26,1622323,12,10,3,6,10,4,8,1581989,1,6, +2,1,6,3,26,5,6,4,10,8,8,1581809,2,1592601,12,1, +6,1,10,28,34,63,38,3,26,1639579,16,1639583,14,1639409,14,1622243, +12,8,1581797,2,1592341,12,1,6,1,10,28,34,63,38,3,26, +1639705,16,1639697,14,101,120,112,101,99,116,101,100,32,40,32,97, +102,116,101,114,32,116,104,101,32,116,121,112,101,32,97,114, +103,117,109,101,110,116,115,0,1639625,1581991,12,8,1581797,2,1592341,12, +1639735,16,1310721,2,5,26,2,1635273,12,1639809,14,1310721,2,5,26,2, +1585301,12,8,1559041,1310721,2,5,26,2,26,2,1639801,16,1581889,1559041,1310721, +2,5,26,2,26,2,10,3,6,10,4,8,1,1639809,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,3, +26,4,1310721,2,4,1581785,2,1,6,1,10,28,34,63,38,3, +26,1639967,16,1639959,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,1639883,1581991,12,8,1581787, +2,3,28,1,6,1,10,28,34,63,38,3,26,1640029,16,1581763, +2,1,6,1,10,28,34,63,38,1,10,28,1640031,14,1,1640069, +16,1581789,2,1597849,12,1,6,1,10,28,34,63,38,1,10,28, +1640071,14,1,1640171,16,1581789,2,1640163,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,1640083,1582383,12,8,1581889,2,1617083,12,1640189,16,3,1640245,14,1581889,2, +1,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,1640255,16,3,1640307,14,1581889, +2,1581877,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1640385,14,43,43,32,97,110, +100,32,45,45,32,110,101,101,100,32,97,32,110,117,109,98, +101,114,32,111,114,32,97,32,112,111,105,110,116,101,114,0, +1640311,1581889,2,1621475,12,8,1581785,1,10,3,6,10,4,8,1581787,1, +10,3,6,10,4,8,1581891,1,10,3,6,10,4,8,1,1584843, +12,8,7,1584907,12,8,3,1584907,12,8,1310721,2,2,1640547,16,1, +1584843,12,8,7,1584907,12,8,1310721,2,3,26,2,1584843,12,8,27, +1584907,12,8,5,1584843,12,8,7,1584907,12,8,5,1584907,12,8,1640611, +14,1310721,2,3,26,2,1584843,12,8,27,1584907,12,8,1,1584843,12, +8,7,1584907,12,8,5,1584843,12,8,7,1584907,12,8,5,1584907,12, +8,11,1584907,12,8,9,1584907,12,8,1,1640635,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,4,3,1,10, +28,1310721,2,9,26,4,1591423,12,8,1310721,2,3,26,1592987,12,10, +3,6,10,4,8,1633929,12,8,1310721,2,2,3,28,1,6,1, +10,28,34,63,38,3,26,1640891,16,1640879,14,117,115,101,32,97, +32,102,105,101,108,100,32,111,102,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,1640759,1582287,12,8,1640955,14,1310721,2,2, +5,40,3,36,1640955,16,1310721,2,2,5,28,1597925,12,8,1310721,2, +9,26,1310721,2,2,5,28,10,3,6,10,4,8,1310721,2,5, +26,1581889,2,10,3,6,10,4,8,1310721,2,5,26,2,1,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1641059,16,1310721, +2,5,26,1310721,2,5,26,2,9,26,2,10,3,6,10,4, +8,1310721,2,5,26,2,1,26,2,17,28,1,6,1,10,28, +34,63,38,1,10,28,1641319,16,1641129,14,122,99,58,32,108,105, +110,101,32,0,1641109,1573231,12,8,1579523,2,1573371,12,8,1641159,14,58, +32,46,0,1641151,1573231,12,8,1310721,2,3,26,2,1573231,12,8,1641211, +14,58,32,116,104,97,116,39,115,32,97,32,0,1641187,1573231,12, +8,1581889,2,1619863,12,8,1641305,14,44,32,110,111,116,32,97,32, +115,116,114,117,99,116,32,111,114,32,97,32,112,111,105,110, +116,101,114,32,116,111,32,111,110,101,10,0,1641233,1573231,12,8, +1573195,12,8,1310721,2,7,26,1310721,2,5,26,2,1310721,2,3,26, +2,1627259,12,10,3,6,10,4,8,1310721,2,7,26,2,1,40, +1641529,16,1641405,14,122,99,58,32,108,105,110,101,32,0,1641385,1573231, +12,8,1579523,2,1573371,12,8,1641433,14,58,32,0,1641427,1573231,12,8, +1310721,2,5,26,2,1619863,12,8,1641491,14,32,104,97,115,32,110, +111,32,102,105,101,108,100,32,0,1641461,1573231,12,8,1310721,2,3, +26,2,1573231,12,8,21,1573079,12,8,1573195,12,8,1310721,2,5,26, +2,9,26,2,1310721,2,7,26,2,7,30,5,26,26,2,1641623, +16,1310721,2,5,26,2,9,26,2,1310721,2,7,26,2,7,30, +5,26,26,2,1584843,12,8,27,1584907,12,8,1581889,1310721,2,5,26, +2,9,26,2,1310721,2,7,26,2,7,30,3,26,26,2,10, +3,6,10,4,8,1581785,3,10,3,6,10,4,8,1581891,1,10, +3,6,10,4,8,1310721,2,9,26,2,1,40,3,36,1641773,16, +1581787,7,10,3,6,10,4,8,1581789,1310721,2,9,26,2,10,3, +6,10,4,8,1641789,14,1581787,9,10,3,6,10,4,8,1,1641797, +14,1,1310721,2,11,26,1310721,4,18,1310721,2,29,28,1310721,4,1637101, +12,1310721,2,4,3,1643751,16,1579517,2,5,28,1,6,1,10,28, +34,63,38,3,26,1641927,16,1579519,2,1581845,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1641929,14,1,1642013,16,1591423,12,8,1310721,2,7,26,1622323,12,10, +3,6,10,4,8,1633929,12,8,1581889,1310721,2,7,26,2,10,3, +6,10,4,8,1581787,1,10,3,6,10,4,8,1641833,14,1579517,2, +9,28,1,6,1,10,28,34,63,38,1,10,28,1642057,16,1310721, +2,2,1643763,14,1579519,2,1581805,2,28,1,6,1,10,28,34,63, +38,3,26,1642971,16,1591423,12,8,1633929,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,1642283,16,1642271,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,1642169, +1582287,12,8,1642347,14,1310721,2,2,5,40,3,36,1642347,16,1310721,2, +2,5,28,1597925,12,8,1310721,2,3,26,1310721,2,2,5,28,10, +3,6,10,4,8,1581889,2,1617435,12,1642365,16,3,1642417,14,1581889,2, +1581877,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1642501,14,111,110,108,121,32,112, +111,105,110,116,101,114,115,32,97,110,100,32,97,114,114,97, +121,115,32,99,97,110,32,98,101,32,105,110,100,101,120,101, +100,0,1642421,1581889,2,1621475,12,8,1310721,2,9,26,1581889,2,1617681,12, +10,3,6,10,4,8,1310721,2,1646495,12,10,3,6,10,4,8, +1633929,12,8,1310721,2,2,1598391,12,8,1581889,2,1617083,12,1642597,16,3, +1642649,14,1581889,2,1581877,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1642709,14,97,110, +32,105,110,100,101,120,32,104,97,115,32,116,111,32,98,101, +32,97,32,110,117,109,98,101,114,0,1642653,1581889,2,1621475,12,8, +1581807,2,1592809,12,8,1310721,2,9,26,2,1615957,12,3,28,1,6, +1,10,28,34,63,38,1,10,28,1642803,16,1310721,2,9,26,2, +1615957,12,1584843,12,8,31,1584907,12,8,27,1584907,12,8,1581785,3,10, +3,6,10,4,8,1581889,1310721,2,9,26,2,10,3,6,10,4, +8,1581891,1,10,3,6,10,4,8,1310721,2,3,26,2,1,40, +3,36,1642933,16,1581787,7,10,3,6,10,4,8,1581789,1310721,2,3, +26,2,10,3,6,10,4,8,1642949,14,1581787,9,10,3,6,10, +4,8,1310721,2,1,10,3,6,10,4,8,1641833,14,1579519,2,1581835, +2,28,1,6,1,10,28,34,63,38,3,26,1643011,16,3,1643063, +14,1579519,2,1581815,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1643097,16,1310721,2,1310721, +2,2,1640649,12,10,3,6,10,4,8,1641833,14,1579519,2,1581797,2, +28,1,6,1,10,28,34,63,38,3,26,1643595,16,1633929,12,8, +1310721,2,2,1598391,12,8,1310721,2,11,26,1,10,3,6,10,4, +8,1581889,2,1,26,2,15,28,1,6,1,10,28,34,63,38, +3,26,1643237,16,1310721,2,11,26,1581889,2,10,3,6,10,4,8, +1643341,14,1581889,2,1581877,2,28,1,6,1,10,28,34,63,38,3, +26,1643329,14,111,110,108,121,32,102,117,110,99,116,105,111,110, +115,32,99,97,110,32,98,101,32,99,97,108,108,101,100,0, +1643271,1581889,2,1621475,12,8,1310721,2,13,26,1,17,1574329,12,8,1310721, +2,5,26,1,1310721,2,11,26,2,1310721,2,13,26,1634431,12,10, +3,6,10,4,8,1310721,2,5,26,2,1584843,12,8,7,1584907,12, +8,13,1584907,12,8,11,1584907,12,8,9,1584907,12,8,1581785,1,10, +3,6,10,4,8,1581787,1,10,3,6,10,4,8,1310721,2,1, +10,3,6,10,4,8,1581891,1,10,3,6,10,4,8,1581889,1581877, +2,10,3,6,10,4,8,1310721,2,11,26,2,1643591,16,1581889,1310721, +2,11,26,2,9,26,2,1310721,2,13,26,1616107,12,10,3,6, +10,4,8,1641833,14,1579519,2,1581817,2,28,1,6,1,10,28,34, +63,38,3,26,1643663,16,1591423,12,8,1310721,2,3,3,1639823,12,10, +3,6,10,4,8,1641833,14,1579519,2,1581819,2,28,1,6,1,10, +28,34,63,38,3,26,1643737,16,1591423,12,8,1310721,2,3,3,1, +10,28,1639823,12,10,3,6,10,4,8,1641833,14,1310721,2,2,1643763, +14,1641833,14,1310721,2,2,1643763,14,1,1310721,2,29,26,1310721,4,18, +1310721,2,7,28,1310721,4,1579517,2,5,28,1,6,1,10,28,34, +63,38,3,26,1644001,16,1579519,2,1581855,2,28,1,6,1,10,28, +34,63,38,3,26,1643861,16,3,1643913,14,1579519,2,1581851,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1643923,16,3,1643975,14,1579519,2,1581853,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,1644003,14, +1,1644223,16,1310721,2,5,26,3,10,3,6,10,4,8,1579519,2, +1581855,2,28,1,6,1,10,28,34,63,38,3,26,1644085,16,1310721, +2,5,26,5,10,3,6,10,4,8,1579519,2,1581853,2,28,1, +6,1,10,28,34,63,38,3,26,1644141,16,1310721,2,5,26,7, +10,3,6,10,4,8,1591423,12,8,1581821,2,1592809,12,8,1310721,2, +1643777,12,10,3,6,10,4,8,1633929,12,8,1581787,1,10,3,6, +10,4,8,1310721,2,2,1310721,2,5,26,2,1603487,12,1645419,14,1579517, +2,9,28,1,6,1,10,28,34,63,38,3,26,1645409,16,1579519, +2,1581821,2,28,1,6,1,10,28,34,63,38,3,26,1644589,16, +1591423,12,8,1310721,2,1643777,12,10,3,6,10,4,8,1633929,12,8, +1310721,2,2,1598391,12,8,1581889,2,1,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1644377,16,3,1644429,14,1581889,2,1581877,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1644501,14,111,110,108,121,32,112,111,105, +110,116,101,114,115,32,99,97,110,32,98,101,32,100,101,114, +101,102,101,114,101,110,99,101,100,0,1644433,1581889,2,1621475,12,8, +1581889,1581889,2,1617681,12,10,3,6,10,4,8,1581785,3,10,3,6, +10,4,8,1581787,9,10,3,6,10,4,8,1581891,1,10,3,6, +10,4,8,1,1645419,14,1579519,2,1581823,2,28,1,6,1,10,28, +34,63,38,3,26,1644919,16,1591423,12,8,1310721,2,1643777,12,10,3, +6,10,4,8,1581785,2,1,6,1,10,28,34,63,38,3,26, +1644731,16,1581889,2,1617293,12,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1644733,14,1,1644809,16, +1644801,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, +1644741,1581991,12,8,1310721,2,2,5,40,3,36,1644843,16,1310721,2,2, +5,28,1597925,12,8,1581785,1,10,3,6,10,4,8,1581787,1,10, +3,6,10,4,8,1581891,1,10,3,6,10,4,8,1581889,1581889,2, +1611981,12,10,3,6,10,4,8,1,1645419,14,1579519,2,1581817,2,28, +1,6,1,10,28,34,63,38,3,26,1644977,16,1591423,12,8,1643777, +12,8,1,3,1639823,12,1645419,14,1579519,2,1581819,2,28,1,6,1, +10,28,34,63,38,3,26,1645041,16,1591423,12,8,1643777,12,8,1, +3,1,10,28,1639823,12,1645419,14,1310721,2,3,26,1579519,2,1595289,12, +10,3,6,10,4,8,1310721,2,3,26,2,1,40,3,36,1645409, +16,1591423,12,8,1310721,2,1643777,12,10,3,6,10,4,8,1633929,12, +8,1310721,2,2,1598391,12,8,1547329,1310721,2,3,26,2,26,2,1547393, +1310721,2,3,26,2,26,2,1594417,12,8,1310721,2,3,26,2,3, +10,40,3,36,1645219,16,1581889,1581883,2,10,3,6,10,4,8,1645355, +14,1581889,2,1581877,2,28,1,6,1,10,28,34,63,38,1,10, +28,1645355,16,1581889,2,1617083,12,1645325,14,116,104,105,115,32,111,112, +101,114,97,116,111,114,32,110,101,101,100,115,32,97,32,110, +117,109,98,101,114,0,1645267,1581889,2,1621475,12,8,1581889,1581879,2,10, +3,6,10,4,8,1581785,1,10,3,6,10,4,8,1581787,1,10, +3,6,10,4,8,1581891,1,10,3,6,10,4,8,1,1645419,14, +1641811,12,1645419,14,1,1310721,2,7,26,1310721,4,18,1310721,2,15,28, +1310721,4,1310721,2,4,1643777,12,1310721,2,3,26,4,1579517,2,9,28, +1,6,1,10,28,34,63,38,3,26,1646391,16,1310721,2,5,26, +1579519,2,1595115,12,10,3,6,10,4,8,1310721,2,5,26,2,1, +40,1645557,16,1310721,2,3,26,2,1646407,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,1645629,16,1310721,2,3,26,2,1646407,14,1591423,12, +8,1633929,12,8,1310721,2,3,26,2,1598391,12,8,1310721,2,13,26, +1581889,2,10,3,6,10,4,8,1547137,1310721,2,5,26,2,26,2, +3,1,10,28,28,1,6,1,10,28,34,63,38,3,26,1645929, +16,1310721,2,9,26,1585141,12,10,3,6,10,4,8,17,1584907,12, +8,1310721,2,3,26,1310721,2,7,26,2,3,26,1645433,12,10,3, +6,10,4,8,1633929,12,8,1310721,2,3,26,2,1598391,12,8,1547329, +3,26,2,1547393,3,26,2,1594417,12,8,1310721,2,11,26,1585141,12, +10,3,6,10,4,8,15,1584907,12,8,1310721,2,9,26,2,1581747, +2,1584967,12,8,1,1584843,12,8,1310721,2,11,26,2,1581747,2,1584967, +12,8,1646275,14,1547137,1310721,2,5,26,2,26,2,5,1,10,28, +28,1,6,1,10,28,34,63,38,3,26,1646177,16,1310721,2,9, +26,1585141,12,10,3,6,10,4,8,17,1584907,12,8,3,1584843,12, +8,1310721,2,11,26,1585141,12,10,3,6,10,4,8,15,1584907,12, +8,1310721,2,9,26,2,1581747,2,1584967,12,8,1310721,2,3,26,1310721, +2,7,26,2,3,26,1645433,12,10,3,6,10,4,8,1633929,12, +8,1310721,2,3,26,2,1598391,12,8,1547329,3,26,2,1547393,3,26, +2,1594417,12,8,1310721,2,11,26,2,1581747,2,1584967,12,8,1646275,14, +1310721,2,3,26,1310721,2,7,26,2,3,26,1645433,12,10,3,6, +10,4,8,1633929,12,8,1310721,2,3,26,2,1598391,12,8,1547009,1310721, +2,5,26,2,26,2,1547137,1310721,2,5,26,2,26,2,1594417,12, +8,1581889,1310721,2,5,26,2,1310721,2,13,26,2,1581889,2,1629287,12, +10,3,6,10,4,8,1581785,1,10,3,6,10,4,8,1581787,1, +10,3,6,10,4,8,1310721,2,3,26,1,10,3,6,10,4, +8,1581891,1,10,3,6,10,4,8,1645465,14,1310721,2,3,26,2, +1646407,14,1,1310721,2,15,26,1310721,4,18,1310721,2,1,28,1310721,4, +11,1584907,12,8,3,1584843,12,8,7,1584907,12,8,11,1584907,12,8, +5,1584907,12,8,1,1646481,14,1,1310721,2,1,26,1310721,4,18,1310721, +2,13,28,1310721,4,3,1645433,12,1310721,2,4,1579517,2,9,28,1, +6,1,10,28,34,63,38,1,10,28,1646563,16,1310721,2,2,1647957, +14,1579519,2,1581813,2,28,1,6,1,10,28,34,63,38,3,26, +1647155,16,1581785,2,1,6,1,10,28,34,63,38,3,26,1646689,16, +1646681,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,1646629,1581991,12,8, +1310721,2,3,26,1581787,2,10,3,6,10,4,8,1310721,2,5,26, +1581789,2,10,3,6,10,4,8,1310721,2,11,26,1581889,2,10,3, +6,10,4,8,1310721,2,11,26,2,1617293,12,1646913,16,1646905,14,97, +32,119,104,111,108,101,32,115,116,114,117,99,116,32,111,114, +32,97,114,114,97,121,32,99,97,110,39,116,32,98,101,32, +97,115,115,105,103,110,101,100,59,32,97,115,115,105,103,110, +32,105,116,115,32,102,105,101,108,100,115,0,1646783,1581991,12,8, +1591423,12,8,1310721,2,9,26,1646495,12,10,3,6,10,4,8,1633929, +12,8,1310721,2,11,26,2,1581889,2,1617847,12,1,6,1,10,28, +34,63,38,3,26,1647039,16,1647017,14,97,115,115,105,103,110,109, +101,110,116,0,1646995,1310721,2,11,26,2,1581889,2,1621085,12,8,1646421, +12,8,1581785,1,10,3,6,10,4,8,1581787,1,10,3,6,10, +4,8,1581889,1310721,2,11,26,2,10,3,6,10,4,8,1581891,1, +10,3,6,10,4,8,1310721,2,3,26,2,1310721,2,5,26,2, +1310721,2,9,26,2,1606123,12,1647957,14,1310721,2,7,26,1579519,2,1595463, +12,10,3,6,10,4,8,1310721,2,7,26,2,1,40,3,36, +1647945,16,1581785,2,1,6,1,10,28,34,63,38,3,26,1647297,16, +1647289,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,1647237,1581991,12,8, +1581787,2,3,28,1,6,1,10,28,34,63,38,3,26,1647359,16, +1581763,2,1,6,1,10,28,34,63,38,1,10,28,1647361,14,1, +1647399,16,1581789,2,1597849,12,1,6,1,10,28,34,63,38,1,10, +28,1647401,14,1,1647521,16,1581789,2,1647513,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,1647413,1582383,12,8, +1310721,2,11,26,1581889,2,10,3,6,10,4,8,1591423,12,8,1, +1584843,12,8,7,1584907,12,8,3,1584907,12,8,1581785,1,10,3,6, +10,4,8,1310721,2,9,26,1646495,12,10,3,6,10,4,8,1633929, +12,8,1310721,2,9,26,2,1598391,12,8,1547009,1547585,1310721,2,7,26, +2,26,2,26,2,1547137,1547585,1310721,2,7,26,2,26,2,26,2, +1594417,12,8,1310721,2,3,26,1547585,1310721,2,7,26,2,26,2,1310721, +2,11,26,2,1581889,2,1629287,12,10,3,6,10,4,8,1310721,2, +11,26,2,1310721,2,3,26,2,1617847,12,1,6,1,10,28,34, +63,38,3,26,1647861,16,1647833,14,99,111,109,112,111,117,110,100, +32,97,115,115,105,103,110,109,101,110,116,0,1647793,1310721,2,11, +26,2,1310721,2,3,26,2,1621085,12,8,1646421,12,8,1581785,1,10, +3,6,10,4,8,1581787,1,10,3,6,10,4,8,1581889,1310721,2, +11,26,2,10,3,6,10,4,8,1581891,1,10,3,6,10,4, +8,1,1647957,14,1310721,2,2,1647957,14,1,1310721,2,13,26,1310721,4, +18,1310721,2,3,28,1310721,4,1579517,2,9,28,1,6,1,10,28, +34,63,38,3,26,1648147,16,1579519,2,1581811,2,28,1,6,1,10, +28,34,63,38,3,26,1648055,16,3,1648107,14,1579519,2,1581801,2,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1648117,16,3,1648143,14,1624179,12,1,6,1,10, +28,34,63,38,1,10,28,1648429,14,1579517,2,5,28,1,6,1, +10,28,34,63,38,1,10,28,1648187,16,3,1648225,14,1579519,2,1597111, +12,1,40,3,36,1,6,1,10,28,34,63,38,1,10,28, +1648235,16,1,1648429,14,1624179,12,1648249,16,3,1648429,14,1310721,2,1579519,2, +1583635,12,10,3,6,10,4,8,1310721,2,2,1,40,3,36,1648353, +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,1648355,14, +1,1648421,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, +1648423,14,1,1648429,14,1,1310721,2,3,26,1310721,4,18,1310721,2,9, +28,1310721,4,1581755,2,1310721,2,4,1,1310721,2,3,26,4,1,1310721, +2,5,26,4,1581879,2,1310721,2,7,26,4,1591423,12,8,1581759,1, +6,2,1,6,3,26,5,6,4,10,8,8,1581769,1,6,2, +1,6,3,26,5,6,4,10,8,8,1581803,2,1592341,12,1,6, +1,10,28,34,63,38,3,26,1648937,16,1579517,2,1,28,1,6, +1,10,28,34,63,38,3,26,1648661,16,1648653,14,109,105,115,115, +105,110,103,32,125,0,1648633,1581991,12,8,1647971,12,1648679,16,1650659,12, +8,1648565,14,1310721,2,3,26,1646495,12,10,3,6,10,4,8,1633929, +12,8,1581811,2,1592601,12,1648771,16,9,1584907,12,8,1310721,2,3,26, +2,1611239,12,8,1310721,2,3,26,1,10,3,6,10,4,8,1648565, +14,1581803,2,1592341,12,1,6,1,10,28,34,63,38,3,26,1648887, +16,1648879,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,1648807,1581991,12,8,1310721,2,5,26,3, +10,3,6,10,4,8,1310721,2,7,26,1581889,2,10,3,6,10, +4,8,1648565,14,1591423,12,8,1310721,2,5,26,2,1648995,16,1310721,2, +3,26,1310721,2,3,26,2,1610545,12,10,3,6,10,4,8,1649003, +14,1,1584843,12,8,1310721,2,2,1599715,12,8,1581759,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1581769,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1581785,1,10,3,6,10,4,8,1581787, +1,10,3,6,10,4,8,1581889,1310721,2,7,26,2,10,3,6, +10,4,8,1581891,1,10,3,6,10,4,8,1310721,2,3,26,2, +1649159,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5,28,1310721,4, +1579517,2,3,28,1,6,1,10,28,34,63,38,3,26,1649253,16, +1310721,2,1579519,2,10,3,6,10,4,8,1591423,12,8,1310721,2,2, +1649953,14,1581829,2,1592601,12,1649277,16,1,1649173,12,28,1649953,14,1579517,2, +9,28,1,6,1,10,28,34,63,38,3,26,1649369,16,1579519,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,1649371,14,1,1649393,16,1591423, +12,8,1649173,12,-1,36,1649953,14,1581797,2,1592601,12,1649445,16,1310721,2, +1649967,12,10,3,6,10,4,8,1581799,2,1592809,12,8,1310721,2,2, +1649953,14,1579517,2,5,28,1,6,1,10,28,34,63,38,3,26, +1649893,16,1310721,2,3,26,1579519,2,1583635,12,10,3,6,10,4,8, +1310721,2,3,26,2,1,40,3,36,1649861,16,1417729,1310721,2,3,26, +2,26,2,9,28,1,6,1,10,28,34,63,38,3,26,1649577, +16,3,1649639,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,1649649,16,3,1649763,14,1417729,1310721,2,3,26,2,26,2, +3,28,1,6,1,10,28,34,63,38,3,26,1649739,16,1442305,1310721, +2,3,26,2,26,2,3,32,1,6,1,10,28,34,63,38, +1,10,28,1649741,14,1,1,6,1,10,28,34,63,38,1,10, +28,1649773,16,3,1649835,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, +1649863,14,1,1649893,16,1591423,12,8,1425921,1310721,2,3,26,2,26,2, +1649953,14,1649937,14,101,120,112,101,99,116,101,100,32,97,32,99, +111,110,115,116,97,110,116,0,1649897,1581991,12,8,1,1649953,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1649173,12,1310721, +2,4,1579517,2,9,28,1,6,1,10,28,34,63,38,3,26, +1650633,16,1310721,2,3,26,1579519,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,1650127,16,1591423,12,8,1310721,2,1310721,2,2,1649173,12,26,10, +3,6,10,4,8,1650629,14,1310721,2,3,26,2,1546753,9,26,2, +28,1,6,1,10,28,34,63,38,3,26,1650209,16,1591423,12,8, +1310721,2,1310721,2,2,1649173,12,28,10,3,6,10,4,8,1650629,14, +1310721,2,3,26,2,1546753,1,26,2,28,1,6,1,10,28,34, +63,38,3,26,1650291,16,1591423,12,8,1310721,2,1310721,2,2,1649173,12, +30,10,3,6,10,4,8,1650629,14,1310721,2,3,26,2,1546753,31, +26,2,28,1,6,1,10,28,34,63,38,3,26,1650373,16,1591423, +12,8,1310721,2,1310721,2,2,1649173,12,34,10,3,6,10,4,8, +1650629,14,1310721,2,3,26,2,1546753,27,26,2,28,1,6,1,10, +28,34,63,38,3,26,1650455,16,1591423,12,8,1310721,2,1310721,2,2, +1649173,12,32,10,3,6,10,4,8,1650629,14,1310721,2,3,26,2, +1546753,11,26,2,28,1,6,1,10,28,34,63,38,3,26,1650537, +16,1591423,12,8,1310721,2,1310721,2,2,1649173,12,48,10,3,6,10, +4,8,1650629,14,1310721,2,3,26,2,1546753,13,26,2,28,1,6, +1,10,28,34,63,38,3,26,1650619,16,1591423,12,8,1310721,2,1310721, +2,2,1649173,12,38,10,3,6,10,4,8,1650629,14,1310721,2,2, +1650645,14,1649989,14,1310721,2,2,1650645,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,5,28,1310721,4,1579517,2,5,28,1,6,1,10,28, +34,63,38,3,26,1650741,16,1579519,2,1597111,12,1,40,1,6,1, +10,28,34,63,38,1,10,28,1650743,14,1,1650925,16,1310721,2,1579519, +2,1583635,12,10,3,6,10,4,8,1310721,2,2,1,40,3,36, +1650851,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,1650853, +14,1,1650899,16,1442305,1310721,2,2,26,2,17,32,1,6,1,10, +28,34,63,38,1,10,28,1650901,14,1,1650925,16,1310721,2,2,1, +1634027,12,8,1,1651143,14,1624179,12,1650947,16,3,1651529,12,8,1,1651143, +14,1579517,2,9,28,1,6,1,10,28,34,63,38,3,26,1651071, +16,1579519,2,1581811,2,28,1,6,1,10,28,34,63,38,3,26, +1651025,16,1591423,12,8,1,1651143,14,1579519,2,1581801,2,28,1,6,1, +10,28,34,63,38,3,26,1651071,16,1651157,12,8,1,1651143,14,1310721, +2,3,26,1646495,12,10,3,6,10,4,8,1633929,12,8,9,1584907, +12,8,1581811,2,1592809,12,8,1310721,2,3,26,2,1611239,12,8,1, +1651143,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4, +1581755,2,1310721,2,4,1581801,2,1592809,12,8,1581759,1,6,2,1,6, +3,26,5,6,4,10,8,8,1581803,2,1592341,12,1,6,1,10, +28,34,63,38,3,26,1651323,16,1579517,2,1,28,1,6,1,10, +28,34,63,38,3,26,1651313,16,1651305,14,109,105,115,115,105,110, +103,32,125,0,1651285,1581991,12,8,1650659,12,8,1651217,14,1591423,12,8, +1310721,2,2,1599715,12,8,1581759,1,6,2,1,6,-1,26,5,6, +4,10,8,8,1,1651377,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1581755,2,1310721,2,4,1581801,2,1592341,12,1651433,16, +1651157,12,1651515,14,1581759,1,6,2,1,6,3,26,5,6,4,10, +8,8,1650659,12,8,1310721,2,2,1599715,12,8,1581759,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1,1651515,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,4,1,1310721,2, +11,26,4,1,1310721,2,13,26,4,1310721,2,2,1651737,16,1624757,12, +8,1310721,2,11,26,1581913,2,10,3,6,10,4,8,1310721,2,13, +26,1581915,2,10,3,6,10,4,8,1310721,2,11,26,2,1581885,2, +28,1,6,1,10,28,34,63,38,3,26,1651737,16,1651729,14,97, +32,118,97,114,105,97,98,108,101,32,99,97,110,39,116,32, +98,101,32,118,111,105,100,0,1651679,1581991,12,8,3,1652745,16,1310721, +2,3,26,1592987,12,10,3,6,10,4,8,1310721,2,5,26,1310721, +2,3,26,2,1597293,12,10,3,6,10,4,8,1558017,1310721,2,5, +26,2,26,1310721,2,13,26,2,10,3,6,10,4,8,1581805,2, +1592601,12,1652063,16,1310721,2,9,26,1649967,12,10,3,6,10,4,8, +1581807,2,1592809,12,8,1310721,2,11,26,2,1,6,1,10,28,34, +63,38,3,26,1651941,16,1310721,2,11,26,1581877,2,10,3,6,10, +4,8,1473025,1310721,2,5,26,2,26,3,10,3,6,10,4,8, +1556993,1310721,2,5,26,2,26,1310721,2,11,26,2,1310721,2,9,26, +2,1612333,12,10,3,6,10,4,8,1581761,1581761,2,1556993,1310721,2,5, +26,2,26,2,1615957,12,26,10,3,6,10,4,8,1652303,14,1310721, +2,11,26,2,1652117,16,1310721,2,11,26,2,1617293,12,1,6,1, +10,28,34,63,38,1,10,28,1652119,14,1,1652225,16,1473025,1310721,2, +5,26,2,26,3,10,3,6,10,4,8,1556993,1310721,2,5,26, +2,26,1310721,2,11,26,2,10,3,6,10,4,8,1581761,1581761,2, +1310721,2,11,26,2,1615957,12,26,10,3,6,10,4,8,1652303,14, +1581761,1,6,2,1,6,3,26,5,6,4,10,8,8,1310721,2, +11,26,2,1652303,16,1556993,1310721,2,5,26,2,26,1310721,2,11,26, +2,10,3,6,10,4,8,1581813,2,1592601,12,1652705,16,1473025,1310721,2, +5,26,2,26,2,1652445,16,1652437,14,97,110,32,97,114,114,97, +121,32,111,114,32,97,32,115,116,114,117,99,116,32,99,97, +110,39,116,32,98,101,32,105,110,105,116,105,97,108,105,122, +101,100,32,119,105,116,104,32,61,0,1652339,1581991,12,8,1310721,2, +7,26,1646495,12,10,3,6,10,4,8,1633929,12,8,1467905,1310721,2, +5,26,2,26,2,1585585,12,8,5,1584907,12,8,1310721,2,11,26, +2,1652615,16,1310721,2,11,26,2,1581889,2,1617847,12,1,6,1,10, +28,34,63,38,3,26,1652611,16,1652589,14,105,110,105,116,105,97, +108,105,122,101,114,0,1652565,1310721,2,11,26,2,1581889,2,1621085,12, +8,1652677,14,1581889,2,1617083,12,1,6,1,10,28,34,63,38,3, +26,1652677,16,1556993,1310721,2,5,26,2,26,1581889,2,10,3,6,10, +4,8,3,1310721,2,5,26,2,1310721,2,7,26,2,1606123,12,8, +1581809,2,1592601,12,1,6,1,10,28,34,63,38,3,26,1652741,16, +1652745,14,1651737,14,1581811,2,1592809,12,8,1,1652763,14,1,1310721,2,15, +26,1310721,4,18,1310721,2,1,28,1310721,4,1634297,12,8,1591423,12,8, +1,1651529,12,1652813,14,1,1310721,2,1,26,1310721,4,18,1310721,2,15, +28,1310721,4,1634297,12,8,1591423,12,8,1581797,2,1592809,12,8,1310721,2, +5,26,1646495,12,10,3,6,10,4,8,1633929,12,8,1310721,2,5, +26,2,1598391,12,8,1581799,2,1592809,12,8,1310721,2,1585141,12,10,3, +6,10,4,8,17,1584907,12,8,1310721,2,11,26,1581767,2,10,3, +6,10,4,8,1310721,2,7,26,1599965,12,10,3,6,10,4,8, +1651391,12,8,1310721,2,13,26,1581767,2,10,3,6,10,4,8,1310721, +2,9,26,1599965,12,10,3,6,10,4,8,1581843,2,1592471,12,1653183, +16,1591423,12,8,1310721,2,3,26,1585141,12,10,3,6,10,4,8, +15,1584907,12,8,1310721,2,2,1581747,2,1584967,12,8,1310721,2,7,26, +2,1600553,12,8,1581767,1310721,2,11,26,2,10,3,6,10,4,8, +1651391,12,8,1310721,2,3,26,2,1581747,2,1584967,12,8,1653239,14,1310721, +2,2,1581747,2,1584967,12,8,1310721,2,7,26,2,1600553,12,8,1581767, +1310721,2,11,26,2,10,3,6,10,4,8,1310721,2,9,26,2, +1310721,2,13,26,2,1602663,12,8,1310721,2,7,26,2,1600493,12,8, +1,1653289,14,1,1310721,2,15,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,3,26,4,1310721,2,4,1552897,1581777,2,13,30,26,1310721, +2,5,26,4,1581777,2,121,40,3,36,1653429,16,1653421,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,1653373,1581991,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,1581759, +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, +1581769,2,10,3,6,10,4,8,1581777,1,6,2,1,6,3,26, +5,6,4,10,8,8,1,1653621,14,1,1310721,2,7,26,1310721,4, +18,1310721,2,1,28,1310721,4,1581777,1,6,2,1,6,-1,26,5, +6,4,10,8,8,1552897,1581777,2,13,30,3,26,26,2,1581747,2, +1584475,12,8,1,1653711,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +9,28,1310721,4,1581747,2,1310721,2,4,1634297,12,8,1591423,12,8,1310721, +2,5,26,1599965,12,10,3,6,10,4,8,1581797,2,1592809,12,8, +1310721,2,7,26,1646495,12,10,3,6,10,4,8,1633929,12,8,1310721, +2,7,26,2,1598391,12,8,1581799,2,1592809,12,8,1310721,2,3,26, +1585141,12,10,3,6,10,4,8,17,1584907,12,8,1310721,2,2,1310721, +2,5,26,2,1653303,12,8,1651391,12,8,1310721,2,5,26,2,1603063, +12,8,1310721,2,2,1585081,12,8,1310721,2,3,26,2,1581747,2,1584967, +12,8,1653635,12,8,1310721,2,5,26,2,1600553,12,8,1581767,3,10, +3,6,10,4,8,1310721,2,5,26,2,1600493,12,8,1,1654019,14, +1,1310721,2,9,26,1310721,4,18,1310721,2,15,28,1310721,4,1581755,2, +1310721,2,4,1634297,12,8,1591423,12,8,1581797,2,1592809,12,8,1581759,1, +6,2,1,6,3,26,5,6,4,10,8,8,1581839,2,1592471,12, +1654127,16,1652777,12,8,1654243,14,1624179,12,1654147,16,3,1651529,12,8,1654243, +14,1581811,2,1592341,12,1,6,1,10,28,34,63,38,3,26,1654233, +16,1310721,2,13,26,1646495,12,10,3,6,10,4,8,1633929,12,8, +9,1584907,12,8,1310721,2,13,26,2,1611239,12,8,1581811,2,1592809,12, +8,1310721,2,3,26,1599965,12,10,3,6,10,4,8,1310721,2,5, +26,1581747,2,10,3,6,10,4,8,1581811,2,1592341,12,1,6,1, +10,28,34,63,38,3,26,1654373,16,1310721,2,13,26,1646495,12,10, +3,6,10,4,8,1633929,12,8,1310721,2,13,26,2,1598391,12,8, +1654381,14,3,1584843,12,8,1581811,2,1592809,12,8,1310721,2,7,26,1585141, +12,10,3,6,10,4,8,17,1584907,12,8,1310721,2,9,26,1585141, +12,10,3,6,10,4,8,15,1584907,12,8,1310721,2,11,26,1581747, +2,10,3,6,10,4,8,1581799,2,1592341,12,1,6,1,10,28, +34,63,38,3,26,1654565,16,1310721,2,13,26,1646495,12,10,3,6, +10,4,8,1633929,12,8,9,1584907,12,8,1310721,2,13,26,2,1611239, +12,8,1581799,2,1592809,12,8,1310721,2,5,26,2,1585081,12,8,1310721, +2,9,26,2,1581747,2,1584967,12,8,1310721,2,11,26,2,1310721,2, +3,26,2,1653303,12,8,1651391,12,8,1310721,2,3,26,2,1603063,12, +8,1310721,2,11,26,2,1585081,12,8,1310721,2,7,26,2,1581747,2, +1584967,12,8,1653635,12,8,1310721,2,3,26,2,1600553,12,8,1581767,3, +10,3,6,10,4,8,1310721,2,3,26,2,1600493,12,8,1310721,2, +2,1599715,12,8,1581759,1,6,2,1,6,-1,26,5,6,4,10, +8,8,1,1654797,14,1,1310721,2,15,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,4,1581777,2,1581779,2,10,40,3,36,1654927,16, +1654919,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,1654853,1581991,12,8,1310721,2,2,9,26,2,1581769,2,28, +1,6,1,10,28,34,63,38,1,10,28,1655083,16,1655075,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,1654975,1581991,12,8,1310721,2,2,7,26,2,1603063,12,8,1310721,2, +2,5,26,2,3,26,1,1598733,12,8,1,1655133,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1552897,1581777,2,3,28, +13,30,26,1310721,2,4,1634297,12,8,1591423,12,8,1581811,2,1592809,12, +8,1310721,2,2,1654811,12,8,1310721,2,2,3,26,1581747,2,1310721,2, +2,3,26,2,1584145,12,10,3,6,10,4,8,2097153,3,28,1584843, +12,8,15,1584907,12,8,1581767,1,10,3,6,10,4,8,1,1655301, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1552897, +1581777,2,3,28,13,30,26,1310721,2,4,1634297,12,8,1591423,12,8, +1581811,2,1592809,12,8,1310721,2,2,1654811,12,8,1310721,2,2,1,26, +2,1585081,12,8,1581767,1,10,3,6,10,4,8,1,1655425,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1634297,12,8, +1591423,12,8,1581775,2,1,6,1,10,28,34,63,38,3,26,1655555, +16,1655547,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,1655495,1581991,12, +8,1581769,2,1655651,16,1655643,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,1655567,1581991,12, +8,1581811,2,1592341,12,1655693,16,1,1584843,12,8,1310721,2,1,10,3, +6,10,4,8,1655921,14,1310721,2,1646495,12,10,3,6,10,4,8, +1633929,12,8,1581795,2,1581885,2,28,1,6,1,10,28,34,63,38, +3,26,1655803,16,1655783,14,114,101,116,117,114,110,32,118,97,108, +117,101,0,1655757,1581885,2,1581889,2,1621085,12,8,1655921,14,1581795,2,1655869, +16,1581795,2,1581889,2,1617847,12,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1655871,14,1,1655921, +16,1655905,14,114,101,116,117,114,110,32,118,97,108,117,101,0, +1655879,1581795,2,1581889,2,1621085,12,8,1581811,2,1592809,12,8,1310721,2,2, +1609585,12,8,3,1,1598733,12,8,1581771,1581747,2,1581771,2,1584145,12,10, +3,6,10,4,8,2097153,3,28,1584843,12,8,15,1584907,12,8,1581767, +1,10,3,6,10,4,8,1,1656023,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,3,28,1310721,4,1581763,2,1310721,2,4,1634297,12,8, +1591423,12,8,1581763,1,10,3,6,10,4,8,1651391,12,8,1581763,1310721, +2,2,10,3,6,10,4,8,1,1656121,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,1581801,2,1592809,12,8,1581803,2,1592341,12,1,6,1,10,28,34, +63,38,3,26,1658207,16,1579517,2,1,28,1,6,1,10,28,34, +63,38,3,26,1656359,16,1656351,14,117,110,116,101,114,109,105,110, +97,116,101,100,32,97,115,109,32,98,108,111,99,107,0,1656305, +1581991,12,8,1579517,2,3,28,1,6,1,10,28,34,63,38,3, +26,1656411,16,1579519,2,1584843,12,8,1591423,12,8,1656237,14,1579517,2,7, +28,1,6,1,10,28,34,63,38,3,26,1656463,16,1579519,2,1585671, +12,8,1591423,12,8,1656237,14,1581827,2,1592341,12,1656581,16,1591423,12,8, +1579517,2,3,28,1,6,1,10,28,34,63,38,1,10,28,1656561, +16,1656553,14,35,32,110,101,101,100,115,32,97,32,110,117,109, +98,101,114,0,1656519,1581991,12,8,1579519,2,1584671,12,8,1591423,12,8, +1656237,14,1581829,2,1592341,12,1656703,16,1591423,12,8,1579517,2,3,28,1, +6,1,10,28,34,63,38,3,26,1656661,16,1579521,2,1,6,1, +10,28,34,63,38,1,10,28,1656663,14,1,1656691,16,1,1579519,2, +28,1584843,12,8,1591423,12,8,1656699,14,29,1584907,12,8,1656237,14,1581825, +2,1592341,12,1656893,16,1591423,12,8,1310721,2,2,129,40,3,36,1656791, +16,1656783,14,116,111,111,32,109,97,110,121,32,97,115,109,32, +108,97,98,101,108,115,0,1656743,1581991,12,8,1310721,2,13,26,2, +1310721,2,2,26,1592987,12,10,3,6,10,4,8,1310721,2,15,26, +2,1310721,2,2,26,1581747,2,10,3,6,10,4,8,1310721,2,1, +6,2,1,6,3,26,5,6,4,10,8,8,1656237,14,1579519,2, +1,26,2,1656963,16,1579519,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,1656965, +14,1,1657035,16,1310721,2,9,26,1579519,2,1,26,2,1594235,12,10, +3,6,10,4,1,40,3,36,1,6,1,10,28,34,63,38, +1,10,28,1657037,14,1,1657067,16,1310721,2,9,26,2,1584907,12,8, +1591423,12,8,1656237,14,1579517,2,5,28,1,6,1,10,28,34,63, +38,1,10,28,1657147,16,1657139,14,98,97,100,32,116,111,107,101, +110,32,105,110,32,97,115,109,0,1657105,1581991,12,8,1310721,2,5, +26,1579519,2,1597111,12,10,3,6,10,4,8,1310721,2,5,26,2, +1,40,3,36,1657257,16,1472001,1310721,2,5,26,2,26,3,10,3, +6,10,4,8,1467905,1310721,2,5,26,2,26,2,1585585,12,8,1591423, +12,8,1656237,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,1657451,16,1310721,2,13,26,2,1310721,2,5, +26,2,26,2,1579519,2,28,1,6,1,10,28,34,63,38,3, +26,1657413,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,1657307,14,1310721,2,7,26,2,1,40,3,36,1657513,16, +1310721,2,15,26,2,1310721,2,7,26,2,26,2,1584843,12,8,1591423, +12,8,1656237,14,1310721,2,11,26,1579519,2,1583635,12,10,3,6,10, +4,8,1310721,2,11,26,2,1,40,3,36,1657629,16,1417729,1310721,2, +11,26,2,26,2,13,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1657631,14,1,1657671, +16,45,1425921,1310721,2,11,26,2,26,2,26,1584907,12,8,1591423,12, +8,1656237,14,1310721,2,11,26,2,1,40,3,36,1657761,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,1657763,14, +1,1657835,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,1657837,14,1,1657873,16,1425921,1310721,2,11,26,2,26,2, +1584843,12,8,1591423,12,8,1656237,14,1310721,2,11,26,2,1,40,3, +36,1657961,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,1657963,14,1,1657993,16,1310721,2,11,26,2,1585301,12,8,1591423, +12,8,1656237,14,1310721,2,3,26,2,501,40,3,36,1658087,16,1658079, +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,1658019, +1581991,12,8,1310721,2,17,26,2,1310721,2,3,26,2,26,1579519,2, +10,3,6,10,4,8,1310721,2,19,26,2,1310721,2,3,26,2, +26,1585141,12,10,3,6,10,4,8,1310721,2,3,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1591423,12,8,1656237,14,1591423, +12,8,1310721,2,5,26,1,10,3,6,10,4,8,1310721,2,5, +26,2,1310721,2,3,26,2,40,1658661,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,1658475,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,1658437,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,1658311,14,1310721,2,7,26,2,1,40,1658569,16,1310721,2, +17,26,2,1310721,2,5,26,2,26,2,1658561,14,117,110,107,110, +111,119,110,32,110,97,109,101,32,105,110,32,97,115,109,0, +1658521,1582117,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,1584967,12,8,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1658235,14,1,1658669,14,1,1310721,2,21,26,1310721,4,18,1310721,2,1, +28,1310721,4,1591423,12,8,1656135,12,8,1581793,1,10,3,6,10,4, +8,1,1658731,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,1581801,2,1592341,12, +1,6,1,10,28,34,63,38,3,26,1658843,16,1658835,14,101,120, +112,101,99,116,101,100,32,123,0,1658813,1581991,12,8,1591423,12,8, +3,1659239,16,1579517,2,1,28,1,6,1,10,28,34,63,38,3, +26,1658937,16,1658929,14,117,110,116,101,114,109,105,110,97,116,101, +100,32,113,117,111,116,101,0,1658891,1581991,12,8,1581801,2,1592341,12, +1658983,16,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1581803,2,1592341,12,1659067,16,1310721,2,3,26,2,1,6, +1,10,28,34,63,38,3,26,1659033,16,1659239,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,1659127,16,1659119,14,113,117,111,116,101,32,116,111, +111,32,108,111,110,103,0,1659089,1581991,12,8,1524225,1310721,2,2,1310721, +2,2,26,26,1579517,2,10,3,6,10,4,8,1524225,1310721,2,2, +1310721,2,2,26,3,26,26,1579519,2,10,3,6,10,4,8,1310721, +2,1,6,2,1,6,3,26,5,6,4,10,8,8,1591423,12, +8,1658849,14,1591423,12,8,1310721,2,5,26,1310721,2,2,1310721,2,2, +26,3,26,1577137,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,1574139,12,8,1310721,2,5, +26,2,1659371,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,1577137,12,1310721,2,5,26,4, +1310721,2,5,26,2,1310721,2,2,1310721,2,3,26,2,1574139,12,8, +1310721,2,5,26,2,1659505,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,1577137,12,1310721,2, +5,26,4,1310721,2,5,26,2,1310721,2,2,1310721,2,3,26,2, +1574139,12,8,1310721,2,5,26,2,1659639,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,1659783,16,1310721,2,2,1310721,2,5,26,2,26,2,1584671,12,8, +1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1659693,14,1,1659791,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +9,28,1310721,4,1591423,12,8,1310721,2,1658745,12,10,3,6,10,4, +8,1310721,2,3,26,1585141,12,10,3,6,10,4,8,15,1584907,12, +8,1310721,2,5,26,1581747,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,1659653,12,8,1310721,2,2,1577851, +12,8,1310721,2,3,26,2,1581747,2,1584967,12,8,1310721,2,5,26, +2,1584843,12,8,1581865,2,1585453,12,8,1581793,3,10,3,6,10,4, +8,1,1660043,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,1586239,12,8,1591423,12,8,1579517,2,1,28,1,6,1,10,28, +34,63,38,1,10,28,1660343,16,1310721,2,3,26,2,8001,40,3, +36,1660211,16,1660203,14,116,111,111,32,109,97,110,121,32,116,111, +107,101,110,115,0,1660171,1581991,12,8,1524225,1310721,2,3,26,2,1310721, +2,3,26,2,26,26,1579517,2,10,3,6,10,4,8,1524225,1310721, +2,3,26,2,1310721,2,3,26,2,26,3,26,26,1579519,2,10, +3,6,10,4,8,1310721,2,3,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1591423,12,8,1660111,14,1587189,12,8,1310721,2, +5,26,1310721,2,3,26,2,1310721,2,3,26,2,26,3,26,1577137, +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,1574139,12,8,1310721, +2,5,26,2,1660495,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,4,3,1310721,2,2,3,3,1586239,12,8, +1591423,12,8,1,1660559,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +3,28,1310721,4,1548801,1581781,2,49,30,26,1310721,2,4,1581781,2,61, +40,3,36,1660685,16,1660677,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,1660623,1581991,12,8,1581781,1,6,2,1,6,3,26,5,6, +4,10,8,8,1310721,2,2,1,26,1581755,2,10,3,6,10,4, +8,1310721,2,2,3,26,1581757,2,10,3,6,10,4,8,1310721,2, +2,5,26,1581759,2,10,3,6,10,4,8,1310721,2,2,7,26, +1581761,2,10,3,6,10,4,8,1310721,2,2,9,26,1581763,2,10, +3,6,10,4,8,1310721,2,2,11,26,1581765,2,10,3,6,10, +4,8,1310721,2,2,13,26,1581767,2,10,3,6,10,4,8,1310721, +2,2,15,26,1581769,2,10,3,6,10,4,8,1310721,2,2,17, +26,1581771,2,10,3,6,10,4,8,1310721,2,2,19,26,1581773,2, +10,3,6,10,4,8,1310721,2,2,21,26,1581775,2,10,3,6, +10,4,8,1310721,2,2,23,26,1581777,2,10,3,6,10,4,8, +1310721,2,2,25,26,1581779,2,10,3,6,10,4,8,1310721,2,2, +27,26,1581785,2,10,3,6,10,4,8,1310721,2,2,29,26,1581787, +2,10,3,6,10,4,8,1310721,2,2,31,26,1581789,2,10,3, +6,10,4,8,1310721,2,2,33,26,1581791,2,10,3,6,10,4, +8,1310721,2,2,35,26,1581793,2,10,3,6,10,4,8,1310721,2, +2,37,26,1581783,2,10,3,6,10,4,8,1310721,2,2,39,26, +1581795,2,10,3,6,10,4,8,1310721,2,2,41,26,1581911,2,10, +3,6,10,4,8,1310721,2,2,43,26,1581889,2,10,3,6,10, +4,8,1310721,2,2,45,26,1581895,5,1574139,12,8,1,1661313,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1581781,1,6, +2,1,6,-1,26,5,6,4,10,8,8,1310721,2,1548801,1581781,2, +49,30,26,10,3,6,10,4,8,1581755,1310721,2,2,1,26,2, +10,3,6,10,4,8,1581757,1310721,2,2,3,26,2,10,3,6, +10,4,8,1581759,1310721,2,2,5,26,2,10,3,6,10,4,8, +1581761,1310721,2,2,7,26,2,10,3,6,10,4,8,1581763,1310721,2, +2,9,26,2,10,3,6,10,4,8,1581765,1310721,2,2,11,26, +2,10,3,6,10,4,8,1581767,1310721,2,2,13,26,2,10,3, +6,10,4,8,1581769,1310721,2,2,15,26,2,10,3,6,10,4, +8,1581771,1310721,2,2,17,26,2,10,3,6,10,4,8,1581773,1310721, +2,2,19,26,2,10,3,6,10,4,8,1581775,1310721,2,2,21, +26,2,10,3,6,10,4,8,1581777,1310721,2,2,23,26,2,10, +3,6,10,4,8,1581779,1310721,2,2,25,26,2,10,3,6,10, +4,8,1581785,1310721,2,2,27,26,2,10,3,6,10,4,8,1581787, +1310721,2,2,29,26,2,10,3,6,10,4,8,1581789,1310721,2,2, +31,26,2,10,3,6,10,4,8,1581791,1310721,2,2,33,26,2, +10,3,6,10,4,8,1581793,1310721,2,2,35,26,2,10,3,6, +10,4,8,1581783,1310721,2,2,37,26,2,10,3,6,10,4,8, +1581795,1310721,2,2,39,26,2,10,3,6,10,4,8,1581911,1310721,2, +2,41,26,2,10,3,6,10,4,8,1581889,1310721,2,2,43,26, +2,10,3,6,10,4,8,1581895,1310721,2,2,45,26,5,1574139,12, +8,1,1661995,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,3,26,4,1310721,2,4,1581757,1581755,2,10,3,6, +10,4,8,1581759,3,10,3,6,10,4,8,1581761,1,10,3,6, +10,4,8,1581763,1310721,2,2,1662129,16,1579515,2,1,6,1,10,28, +34,63,38,1,10,28,1662131,14,1,10,3,6,10,4,8,1581765, +1310721,2,3,26,2,10,3,6,10,4,8,1581795,1,10,3,6, +10,4,8,1581767,3,10,3,6,10,4,8,1581769,1,10,3,6, +10,4,8,1581771,1,10,3,6,10,4,8,1581775,3,10,3,6, +10,4,8,1581779,1581777,2,10,3,6,10,4,8,1581785,1,10,3, +6,10,4,8,1581787,1,10,3,6,10,4,8,1,1662305,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,1584843,12, +8,3,1584907,12,8,1581773,1585141,12,10,3,6,10,4,8,29,1584907, +12,8,1310721,1584843,12,8,5,1584907,12,8,1,1662397,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1,1584843,12,8,1581771, +2,1581747,2,1584475,12,8,1310721,1584843,12,8,3,1584907,12,8,1581761,2, +1584843,12,8,27,1584907,12,8,1310721,1584843,12,8,5,1584907,12,8,19, +1584907,12,8,1581773,2,1581761,2,1584967,12,8,1581775,1,10,3,6,10, +4,8,1581755,1581757,2,10,3,6,10,4,8,1,1662559,14,1,1310721, +2,1,26,1310721,4,18,1310721,2,1,28,1310721,4,1581801,2,1592809,12, +8,1581803,2,1592341,12,1,6,1,10,28,34,63,38,3,26,1662751, +16,1579517,2,1,28,1,6,1,10,28,34,63,38,3,26,1662741, +16,1662733,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,1662663,1581991,12,8,1650659,12,8,1662595,14,1591423, +12,8,1581757,2,1599439,12,8,1581763,2,1662805,16,1581767,2,1,6,1, +10,28,34,63,38,1,10,28,1662807,14,1,1662925,16,3,3,1598733, +12,8,1581765,2,1662925,16,1662917,14,97,32,45,62,32,46,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,1662833,1582287,12,8,1,1662933,14,1,1310721,2,1,26,1310721,4, +18,1310721,2,169,28,1310721,4,1310721,2,4,1,1310721,2,7,26,4, +1,1310721,2,9,26,4,1,1310721,2,13,26,4,1,1310721,2,163, +26,4,1,1310721,2,165,26,4,1591423,12,8,1310721,2,3,26,1592987, +12,10,3,6,10,4,8,1581911,1,10,3,6,10,4,8,1581917, +2,1592341,12,1663293,16,1591423,12,8,3,1663265,16,1581911,2,17,40,3, +36,1663173,16,1663165,14,116,111,111,32,109,97,110,121,32,116,121, +112,101,32,112,97,114,97,109,101,116,101,114,115,0,1663115,1581991, +12,8,1581895,1581911,2,26,1592987,12,10,3,6,10,4,8,1581911,1, +6,2,1,6,3,26,5,6,4,10,8,8,1581809,2,1592601,12, +1,6,1,10,28,34,63,38,3,26,1663261,16,1663265,14,1663089,14, +1622243,12,8,1310721,2,165,26,3,10,3,6,10,4,8,1310721,2, +5,26,1310721,2,3,26,2,1583635,12,10,3,6,10,4,8,1310721, +2,5,26,2,1,40,1663351,16,3,1663389,14,1310721,2,5,26,2, +1579449,2,40,1,6,1,10,28,34,63,38,1,10,28,1663399,16, +3,1663463,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,1663473,16,3,1663515,14,1442305,1310721,2,5,26,2,26,2, +3,32,1,6,1,10,28,34,63,38,1,10,28,1663585,16,1310721, +2,5,26,1310721,2,3,26,2,3,1,1583159,12,10,3,6,10, +4,8,1442305,1310721,2,5,26,2,26,1,10,3,6,10,4,8, +1581797,2,1592809,12,8,1581799,2,1592341,12,1,6,1,10,28,34,63, +38,3,26,1664929,16,3,1664929,16,1310721,2,11,26,1,10,3,6, +10,4,8,1310721,2,115,26,1310721,2,7,26,2,26,1581877,2,10, +3,6,10,4,8,1581835,2,1592341,12,1,6,1,10,28,34,63, +38,3,26,1664063,16,1579517,2,9,28,1,6,1,10,28,34,63, +38,3,26,1663873,16,1579519,2,1581821,2,28,1,6,1,10,28,34, +63,38,3,26,1663795,16,3,1663847,14,1579519,2,1581805,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,1663875,14, +1,1663885,16,3,1664037,14,1579517,2,5,28,1,6,1,10,28,34, +63,38,3,26,1664013,16,1579519,2,1581837,2,28,1,6,1,10,28, +34,63,38,3,26,1663957,16,3,1663987,14,1579519,2,1622029,12,1,6, +1,10,28,34,63,38,1,10,28,1,6,1,10,28,34,63, +38,1,10,28,1664015,14,1,1,6,1,10,28,34,63,38,1, +10,28,1,6,1,10,28,34,63,38,1,10,28,1664065,14,1, +1664251,16,1310721,2,115,26,1310721,2,7,26,2,26,1622323,12,10,3, +6,10,4,8,1310721,2,165,26,3,10,3,6,10,4,8,1310721, +2,115,26,1310721,2,7,26,2,26,2,1617293,12,1664251,16,1664243,14, +115,116,114,117,99,116,115,32,97,110,100,32,97,114,114,97, +121,115,32,97,114,101,32,112,97,115,115,101,100,32,98,121, +32,112,111,105,110,116,101,114,0,1664161,1581991,12,8,1581835,2,1592601, +12,1664457,16,1579519,2,1581851,2,28,1,6,1,10,28,34,63,38, +3,26,1664323,16,1310721,2,11,26,3,10,3,6,10,4,8,1664451, +14,1579519,2,1581853,2,28,1,6,1,10,28,34,63,38,3,26, +1664383,16,1310721,2,11,26,5,10,3,6,10,4,8,1664451,14,1664443, +14,97,32,112,97,114,97,109,101,116,101,114,32,116,97,103, +32,105,115,32,46,109,32,111,114,32,46,100,0,1664387,1581991,12, +8,1591423,12,8,1310721,2,19,26,1310721,2,7,26,2,26,1592987,12, +10,3,6,10,4,8,1310721,2,7,26,2,25,40,3,36,1664551, +16,1310721,2,11,26,2,1,6,1,10,28,34,63,38,1,10, +28,1664553,14,1,1664655,16,1664647,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,1664561,1581991,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,1664781,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,48,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, +1664889,16,1664881,14,116,111,111,32,109,97,110,121,32,112,97,114, +97,109,101,116,101,114,115,0,1664841,1581991,12,8,1581809,2,1592601,12, +1,6,1,10,28,34,63,38,3,26,1664925,16,1664929,14,1663627,14, +1581799,2,1592809,12,8,1581815,2,1592601,12,1665155,16,1581835,2,1592341,12,1, +6,1,10,28,34,63,38,3,26,1665029,16,1310721,2,163,26,1622323, +12,10,3,6,10,4,8,1310721,2,165,26,3,10,3,6,10, +4,8,1581835,2,1592601,12,1665155,16,1581855,2,1592471,12,1,6,1,10, +28,34,63,38,3,26,1665127,16,1665119,14,116,104,101,32,114,101, +116,117,114,110,32,116,97,103,32,105,115,32,46,117,0,1665077, +1581991,12,8,1591423,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,1665405,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,1665401,16,1310721,2,3,26,2, +1665393,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,1665317,1582117,12,8,1665693,14,1442305,1310721, +2,5,26,2,26,2,9,32,1665507,16,1310721,2,9,26,2,1665449, +16,3,1665481,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,1665509, +14,1,1665693,16,1310721,2,3,26,2,1665685,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,1665527,1582117,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,1581911,2,1665829,16,1442305,1310721,2,5,26, +2,26,1442305,1310721,2,5,26,2,26,2,257,34,10,3,6,10, +4,8,1310721,2,165,26,2,1666199,16,1310721,2,163,26,2,1,6, +1,10,28,34,63,38,3,26,1665901,16,1310721,2,163,26,1581877,2, +10,3,6,10,4,8,1310721,2,167,26,1310721,2,163,26,2,1310721, +2,7,26,2,1310721,2,115,26,1310721,2,15,26,2,1612831,12,10, +3,6,10,4,8,1559041,1310721,2,5,26,2,26,2,1666059,16,1559041, +1310721,2,5,26,2,26,2,1310721,2,167,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,1666061,14,1,1666163,16,1310721,2,3,26,2,1666155,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,1666079,1582117,12,8,1559041,1310721,2,5,26,2,26, +1310721,2,167,26,2,10,3,6,10,4,8,1581811,2,1592601,12,1666241, +16,1581911,1,10,3,6,10,4,8,1310721,2,5,26,2,1667131,14, +1442305,1310721,2,5,26,2,26,2,3,32,1666321,16,1310721,2,3,26, +2,1666313,14,105,115,32,100,101,102,105,110,101,100,32,116,119, +105,99,101,0,1666279,1582117,12,8,1425921,1310721,2,5,26,2,26,1581747, +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,1581747,2,1584475,12,8,1450497,1310721,2,5,26, +2,26,1,10,3,6,10,4,8,1310721,2,2,1310721,2,13,26, +2,1662009,12,8,1310721,2,165,26,2,1666511,16,1581795,1310721,2,163,26, +2,10,3,6,10,4,8,1662319,12,8,1310721,2,17,26,1,10, +3,6,10,4,8,1310721,2,17,26,2,1310721,2,7,26,2,40, +1666981,16,1310721,2,11,26,1310721,2,19,26,1310721,2,17,26,2,26, +2,1597293,12,10,3,6,10,4,8,1581761,1,6,2,1,6,3, +26,5,6,4,10,8,8,1556993,1310721,2,11,26,2,26,1310721,2, +115,26,1310721,2,17,26,2,26,2,10,3,6,10,4,8,1581763, +2,1666767,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,1666769,14,1,1666801,16,1469953,1310721,2,11,26,2, +26,13,10,3,6,10,4,8,1581763,2,1666881,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,1666883,14, +1,1666943,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, +1666539,14,1310721,2,17,26,1310721,2,7,26,2,10,3,6,10,4, +8,1310721,2,17,26,2,1667087,16,1310721,2,17,26,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1310721,2,17,26,2,1585585,12, +8,5,1584907,12,8,1667011,14,1662573,12,8,1662411,12,8,1581911,1,10, +3,6,10,4,8,1310721,2,5,26,2,1667131,14,1,1310721,2,169, +26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,4,1,1310721,2, +9,26,4,1310721,2,2,1667433,16,1624757,12,8,1310721,2,9,26,1581913, +2,10,3,6,10,4,8,1581915,2,1667327,16,1667319,14,116,97,103, +115,32,103,111,32,111,110,32,108,111,99,97,108,115,32,97, +110,100,32,112,97,114,97,109,101,116,101,114,115,44,32,110, +111,116,32,103,108,111,98,97,108,115,0,1667227,1581991,12,8,1310721, +2,9,26,2,1581885,2,28,1,6,1,10,28,34,63,38,3, +26,1667429,16,1667421,14,97,32,118,97,114,105,97,98,108,101,32, +99,97,110,39,116,32,98,101,32,118,111,105,100,0,1667371,1581991, +12,8,1667439,14,1591423,12,8,3,1668391,16,1310721,2,3,26,1592987,12, +10,3,6,10,4,8,1581805,2,1592601,12,1667767,16,1310721,2,7,26, +1649967,12,10,3,6,10,4,8,1581807,2,1592809,12,8,1310721,2,11, +26,1310721,2,3,26,2,7,1581747,2,1583159,12,10,3,6,10,4, +8,1310721,2,9,26,2,1,6,1,10,28,34,63,38,3,26, +1667613,16,1310721,2,9,26,1581877,2,10,3,6,10,4,8,1559041,1310721, +2,11,26,2,26,1310721,2,9,26,2,1310721,2,7,26,2,1612333, +12,10,3,6,10,4,8,1310721,2,7,26,1559041,1310721,2,11,26, +2,26,2,1615957,12,10,3,6,10,4,8,1310721,2,7,26,2, +1667763,16,1,1584671,12,8,1310721,2,7,26,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1667703,14,1668351,14,1310721,2,9,26,2, +1667821,16,1310721,2,9,26,2,1617293,12,1,6,1,10,28,34,63, +38,1,10,28,1667823,14,1,1668001,16,1310721,2,11,26,1310721,2,3, +26,2,7,1581747,2,1583159,12,10,3,6,10,4,8,1559041,1310721,2, +11,26,2,26,1310721,2,9,26,2,10,3,6,10,4,8,1310721, +2,7,26,1310721,2,9,26,2,1615957,12,10,3,6,10,4,8, +1310721,2,7,26,2,1667997,16,1,1584671,12,8,1310721,2,7,26,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1667937,14,1668351,14, +1310721,2,5,26,1581747,2,10,3,6,10,4,8,1310721,2,11,26, +1310721,2,3,26,2,5,1310721,2,5,26,2,1583159,12,10,3,6, +10,4,8,1310721,2,9,26,2,1668121,16,1559041,1310721,2,11,26,2, +26,1310721,2,9,26,2,10,3,6,10,4,8,1,1584671,12,8, +1581813,2,1592601,12,1668351,16,1579517,2,7,28,1,6,1,10,28,34, +63,38,3,26,1668319,16,1310721,2,5,26,2,1581749,2,26,1581747,2, +10,3,6,10,4,8,1310721,2,7,26,1579519,2,10,3,6,10, +4,8,1310721,2,7,26,2,2,1668301,16,1310721,2,7,26,2,2, +1584671,12,8,1310721,2,7,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1668229,14,1,1584671,12,8,1591423,12,8,1668351,14,1310721, +2,5,26,2,1581749,2,26,1649967,12,10,3,6,10,4,8,1581809, +2,1592601,12,1,6,1,10,28,34,63,38,3,26,1668387,16,1668391, +14,1667439,14,1581811,2,1592809,12,8,1,1668409,14,1,1310721,2,13,26, +1310721,4,18,1310721,2,3,28,1310721,4,1591423,12,8,3,1668535,16,1310721, +2,1592987,12,10,3,6,10,4,8,1581813,2,1592809,12,8,1310721,2, +2,9,1649967,12,1583159,12,8,1581809,2,1592601,12,1,6,1,10,28, +34,63,38,3,26,1668531,16,1668535,14,1668441,14,1581811,2,1592809,12,8, +1,1668553,14,1,1310721,2,3,26,1310721,4,18,1310721,2,43,28,1310721, +4,1,1310721,2,3,26,4,3,1310721,2,5,26,4,1,1310721,2, +13,26,4,1,1310721,2,15,26,4,1591423,12,8,1310721,2,1592987,12, +10,3,6,10,4,8,1581797,2,1592809,12,8,1581799,2,1592341,12,1, +6,1,10,28,34,63,38,3,26,1668937,16,3,1668937,16,1310721,2, +3,26,2,17,28,1,6,1,10,28,34,63,38,3,26,1668827, +16,1668819,14,97,110,32,101,110,104,97,110,99,101,109,101,110, +116,32,116,97,107,101,115,32,97,116,32,109,111,115,116,32, +56,32,105,110,112,117,116,115,0,1668743,1581991,12,8,1310721,2,27, +26,1310721,2,3,26,2,26,1592987,12,10,3,6,10,4,8,1310721, +2,3,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1581809,2,1592601,12,1,6,1,10,28,34,63,38,3,26,1668933,16, +1668937,14,1668695,14,1581799,2,1592809,12,8,1581815,2,1592601,12,1669179,16,1579517, +2,3,28,1,6,1,10,28,34,63,38,1,10,28,1668999,16, +3,1669029,14,1579519,2,1,40,1,6,1,10,28,34,63,38,1, +10,28,1669039,16,3,1669071,14,1579519,2,17,10,40,1,6,1,10, +28,34,63,38,1,10,28,1669149,16,1669141,14,101,120,112,101,99, +116,101,100,32,116,104,101,32,110,117,109,98,101,114,32,111, +102,32,111,117,116,112,117,116,115,0,1669079,1581991,12,8,1310721,2, +5,26,1579519,2,10,3,6,10,4,8,1591423,12,8,1310721,2,7, +26,1581747,2,10,3,6,10,4,8,1310721,2,17,26,1,10,3, +6,10,4,8,1310721,2,17,26,2,15,40,1669289,16,1,1584671,12, +8,1310721,2,17,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1669225,14,1310721,2,9,26,1581747,2,10,3,6,10,4,8, +1310721,2,17,26,1,10,3,6,10,4,8,1310721,2,17,26,2, +1310721,2,3,26,2,40,1669407,16,1,1584671,12,8,1310721,2,17,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1669335,14,1310721, +2,17,26,1,10,3,6,10,4,8,1310721,2,17,26,2,1310721, +2,3,26,2,40,1669659,16,1310721,2,9,26,2,1310721,2,17,26, +2,26,1581749,2,26,1581747,2,10,3,6,10,4,8,1310721,2,19, +26,1310721,2,27,26,1310721,2,17,26,2,26,2,10,3,6,10, +4,8,1310721,2,19,26,2,2,1669613,16,1310721,2,19,26,2,2, +1584671,12,8,1310721,2,19,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1669541,14,1,1584671,12,8,1310721,2,17,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1669429,14,1581869,2,1592601, +12,1669955,16,1310721,2,11,26,1581747,2,10,3,6,10,4,8,1579517, +2,7,28,1,6,1,10,28,34,63,38,1,10,28,1669805,16, +1669797,14,101,120,112,101,99,116,101,100,32,116,104,101,32,114, +101,99,105,112,101,32,97,115,32,97,32,115,116,114,105,110, +103,0,1669733,1581991,12,8,1579517,2,7,28,1,6,1,10,28,34, +63,38,3,26,1669943,16,1310721,2,19,26,1579519,2,10,3,6,10, +4,8,1310721,2,19,26,2,2,1669933,16,1310721,2,19,26,2,2, +1584671,12,8,1310721,2,19,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1669861,14,1591423,12,8,1669805,14,1,1584671,12,8,1670121, +14,1581871,2,1592601,12,1670067,16,1310721,2,11,26,1581747,2,10,3,6, +10,4,8,1656135,12,8,19,1584907,12,8,1310721,2,13,26,1581747,2, +1310721,2,11,26,2,28,10,3,6,10,4,8,1310721,2,15,26, +3,10,3,6,10,4,8,1670121,14,1670113,14,101,120,112,101,99, +116,101,100,32,109,105,99,114,111,32,111,114,32,118,109,0, +1670071,1581991,12,8,1310721,2,23,26,1579443,2,10,3,6,10,4,8, +1310721,2,23,26,2,1025,40,3,36,1670251,16,1670243,14,97,108,108, +32,53,49,50,32,101,110,104,97,110,99,101,109,101,110,116, +32,115,108,111,116,115,32,97,114,101,32,116,97,107,101,110, +0,1670171,1581991,12,8,1579443,1,6,2,1,6,3,26,5,6,4, +10,8,8,1310721,2,19,26,1310721,2,7,26,2,1581749,2,26,10, +3,6,10,4,8,1310721,2,19,26,2,1,26,1310721,2,23,26, +2,10,3,6,10,4,8,1310721,2,19,26,2,3,26,1310721,2, +15,26,2,10,3,6,10,4,8,1310721,2,19,26,2,5,26, +1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,19,26,2, +7,26,1310721,2,5,26,2,10,3,6,10,4,8,1310721,2,19, +26,2,9,26,1310721,2,11,26,2,10,3,6,10,4,8,1310721, +2,19,26,2,11,26,1310721,2,13,26,2,10,3,6,10,4, +8,1310721,2,19,26,2,13,26,1310721,2,9,26,2,10,3,6, +10,4,8,1310721,2,21,26,1310721,2,2,13,1310721,2,23,26,2, +1583159,12,10,3,6,10,4,8,1434113,1310721,2,21,26,2,26,1310721, +2,3,26,2,1310721,2,5,26,2,33,30,26,1310721,2,7,26, +2,513,30,26,10,3,6,10,4,8,1581843,2,1592601,12,1670809,16, +1310721,2,25,26,1579519,2,1583635,12,10,3,6,10,4,8,1310721,2, +25,26,2,1,40,1670763,16,1310721,2,25,26,1579519,2,1585201,12,10, +3,6,10,4,8,1591423,12,8,1450497,1310721,2,21,26,2,26,1310721, +2,25,26,2,3,26,10,3,6,10,4,8,1581811,2,1592809,12, +8,1581749,2,1,6,1,10,28,34,63,38,3,26,1671179,16,1310721, +2,25,26,1310721,2,7,26,2,1572879,12,10,3,6,10,4,8, +1310721,2,25,26,2,1,40,1671179,16,1450497,1310721,2,21,26,2,26, +2,1,6,1,10,28,34,63,38,3,26,1671133,16,1670963,14,122, +99,58,32,108,105,110,101,32,0,1670943,1573231,12,8,1579523,2,1573371, +12,8,1670991,14,58,32,0,1670985,1573231,12,8,1310721,2,2,1573231,12, +8,1671085,14,58,32,116,104,101,32,101,110,104,97,110,99,101, +109,101,110,116,32,100,105,100,110,39,116,32,105,110,115,116, +97,108,108,32,40,0,1671015,1573231,12,8,1310721,2,25,26,2,1573371, +12,8,1671119,14,41,10,0,1671113,1573231,12,8,1573195,12,8,1442305,1310721, +2,21,26,2,26,1442305,1310721,2,21,26,2,26,2,129,34,10, +3,6,10,4,8,1,1671187,14,1,1310721,2,43,26,1310721,4,18, +1310721,2,9,28,1310721,4,3,1310721,2,4,1,1310721,2,3,26,4, +1581847,2,1592471,12,1671303,16,1591423,12,8,1581811,2,1592601,12,1671285,16,1579515, +1,10,3,6,10,4,8,1,1672241,14,1310721,2,1,10,3,6, +10,4,8,1581849,2,1592471,12,1671343,16,1591423,12,8,1310721,2,3,26, +3,10,3,6,10,4,8,1581837,2,1592471,12,1671629,16,1310721,2,5, +26,1310721,2,2,1662947,12,10,3,6,10,4,8,1310721,2,3,26, +2,1671623,16,1581749,2,1671525,16,1671517,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,1671411,1581991, +12,8,1310721,2,7,26,1409537,1310721,2,5,26,2,26,2,11,1425921, +1310721,2,5,26,2,26,2,1583159,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,1672241,14,1310721,2,2,1,6,1,10,28,34,63, +38,3,26,1671665,16,3,1671697,14,1310721,2,3,26,2,1,6,1, +10,28,34,63,38,1,10,28,1671737,16,1671729,14,101,120,112,101, +99,116,101,100,32,102,110,0,1671705,1581991,12,8,1581839,2,1592471,12, +1671759,16,1,1667145,12,1672241,14,1581933,2,1592471,12,1671783,16,1625109,12,8, +1,1672241,14,1581935,2,1592471,12,1671803,16,1626969,12,1672241,14,1581937,2,1592471, +12,1671823,16,1627067,12,1672241,14,1581867,2,1592471,12,1671843,16,1668567,12,1672241, +14,1581841,2,1592471,12,1671863,16,1668423,12,1672241,14,1579517,2,5,28,1, +6,1,10,28,34,63,38,3,26,1672093,16,1310721,2,5,26,1579519, +2,1583635,12,10,3,6,10,4,8,1310721,2,5,26,2,1,40, +3,36,1672011,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,1672013,14,1,1672063,16,1442305,1310721,2,5,26,2,26,2, +65,32,1,6,1,10,28,34,63,38,1,10,28,1672065,14,1, +1672093,16,1310721,2,5,26,2,1,1634027,12,8,1,1672241,14,1624179,12, +1672111,16,3,1667145,12,1672241,14,1672225,14,101,120,112,101,99,116,101, +100,32,102,110,44,32,108,101,116,44,32,99,111,110,115,116, +44,32,115,116,114,117,99,116,44,32,116,121,112,101,32,111, +114,32,97,32,100,101,99,108,97,114,97,116,105,111,110,0, +1672115,1581991,12,8,1,1672241,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,1,28,1310721,4,1579517,2,1,28,1,6,1,10,28,34,63, +38,1,10,28,1672311,16,1671201,12,8,1672267,14,1,1672319,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,1579447,2,40,1672669, +16,1417729,1310721,2,3,26,2,26,2,3,28,1,6,1,10,28, +34,63,38,3,26,1672497,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,1672499,14,1,1672545,16,1450497,1310721,2,3,26, +2,26,2,1,6,1,10,28,34,63,38,1,10,28,1672547,14, +1,1672631,16,1409537,1310721,2,3,26,2,26,2,1672623,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,1672571,1582117,12,8,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1672367,14,1,1672677, +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,1579447,2,1310721,2,9,26,4,1660573,12,8, +1581775,2,1672809,16,1310721,2,5,26,1585141,12,10,3,6,10,4,8, +15,1584907,12,8,3,1310721,2,2,1,1,1586239,12,8,1591423,12,8, +1310721,2,3,26,2,1672857,16,1672255,12,8,1673011,14,1310721,2,7,26, +1581747,2,10,3,6,10,4,8,3,1,1662009,12,8,1662319,12,8, +1579517,2,1,28,1,6,1,10,28,34,63,38,1,10,28,1672941, +16,1650659,12,8,1672897,14,1581757,2,1599439,12,8,1581763,2,1672989,16,1581767, +2,1,6,1,10,28,34,63,38,1,10,28,1672991,14,1,1673005, +16,3,3,1598733,12,8,1662411,12,8,1587189,12,8,1310721,2,9,26, +2,1672333,12,8,1310721,2,5,26,2,1,40,3,36,1673075,16,1310721, +2,5,26,2,1581747,2,1584967,12,8,1581747,2,1581753,2,10,40,1673109, +16,1581753,1581747,2,10,3,6,10,4,8,1661327,12,8,1310721,2,7, +26,2,1673131,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,4,1310721,2,2,1,1672691,12,1673181,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,4,1310721,2, +2,3,1672691,12,8,1,1673235,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,4,1310721,2,2,1,1672691,12,1310721, +2,3,26,4,1310721,2,3,26,2,1,6,12,10,8,1673315,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2, +4,1310721,2,2,1660057,12,1310721,2,3,26,4,1310721,2,3,26,2, +1673249,12,1310721,2,5,26,4,1310721,2,3,26,2,1577851,12,8,1310721, +2,5,26,2,1673423,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,1579447,2,40,1673869,16,1417729,1310721,2,3,26,2,26, +2,3,40,3,36,1673571,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,1673573, +14,1,1673583,16,3,1673645,14,1417729,1310721,2,3,26,2,26,2,13, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1673831,16,1417729,1310721,2,3,26,2,26,2, +1584671,12,8,1425921,1310721,2,3,26,2,26,2,1584671,12,8,1434113,1310721, +2,3,26,2,26,2,1584671,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,1673823,16,1310721,2,5,26,2,2,1584671,12,8,1310721,2,5,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1673751,14,1, +1584671,12,8,1310721,2,3,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1673471,14,1,1584671,12,8,1,1673885,14,1,1310721,2, +7,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,4,1310721,2, +2,2,1674259,16,1310721,2,5,26,1310721,2,2,7,26,1582663,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,1583159,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,2,1,26,2,13,28,1,6,1, +10,28,34,63,38,3,26,1674209,16,1310721,2,2,3,26,2,1579443, +2,40,3,36,1674187,16,1579443,1310721,2,2,3,26,2,3,26,10, +3,6,10,4,8,1310721,2,2,5,26,2,17,38,1572879,12,8, +1310721,2,1310721,2,2,7,26,1310721,2,2,7,26,1573731,12,26,3, +26,10,3,6,10,4,8,1673917,14,1,1674267,14,1,1310721,2,7, +26,1310721,4,18,1310721,2,21,28,1310721,4,1310721,2,3,26,4,1310721, +2,4,1581747,2,1310721,2,5,26,4,1581749,2,1310721,2,7,26,4, +1581751,2,1310721,2,9,26,4,1579449,2,1310721,2,11,26,4,1579451,2, +1310721,2,13,26,4,1579447,2,1310721,2,15,26,4,1579443,2,1310721,2, +17,26,4,1579449,1579447,2,10,3,6,10,4,8,1579451,1579447,2,10, +3,6,10,4,8,1579443,1,10,3,6,10,4,8,1581747,1310721,2, +2,10,3,6,10,4,8,1581749,1310721,2,3,26,2,1310721,2,2, +28,10,3,6,10,4,8,1581751,1310721,2,2,393217,26,10,3,6, +10,4,8,1966081,1584843,12,8,1310721,1584843,12,8,5,1584907,12,8,1581857, +2,1585201,12,1585301,12,8,15,1584907,12,8,1,1584671,12,8,1,1584671, +12,8,1,1,1,1,1586239,12,8,1591423,12,8,1672255,12,8,1579449, +2,1672333,12,8,1587189,12,8,1310721,2,3,26,2,11,26,1581747,2, +10,3,6,10,4,8,1579449,2,1673437,12,8,1310721,2,3,26,2, +13,26,1581747,2,10,3,6,10,4,8,1310721,2,19,26,1581747,2, +1310721,2,2,28,10,3,6,10,4,8,1310721,2,15,26,2,1583961, +12,8,1579449,1310721,2,11,26,2,10,3,6,10,4,8,1579451,1310721, +2,13,26,2,10,3,6,10,4,8,1581747,1310721,2,5,26,2, +10,3,6,10,4,8,1581749,1310721,2,7,26,2,10,3,6,10, +4,8,1581751,1310721,2,9,26,2,10,3,6,10,4,8,1579443,1310721, +2,17,26,2,10,3,6,10,4,8,1310721,2,19,26,2,1674917, +14,1,1310721,2,21,26,1310721,4,18,1310721,2,1,28,1310721,4,1, +1581753,2,1578301,12,8,1581749,2,1,6,1,10,28,34,63,38,3, +26,1675021,16,1581747,2,1581753,2,10,40,1,6,1,10,28,34,63, +38,1,10,28,1675023,14,1,1675041,16,1581753,2,1581747,2,1578301,12,8, +1572865,1572865,13,26,2,1578301,12,8,1540609,1540609,1025,26,1578301,12,8,1310721, +2,1966081,1578301,12,8,2064385,2097121,1578301,12,8,1,1675101,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1579445,1327617,10,3,6, +10,4,8,1311233,1,16385,1574329,12,8,1579447,1,10,3,6,10,4, +8,1579453,1,10,3,6,10,4,8,1579455,1,10,3,6,10,4, +8,1579457,1,10,3,6,10,4,8,1579459,1,10,3,6,10,4, +8,1579461,1,10,3,6,10,4,8,1579463,1,10,3,6,10,4, +8,1579465,1,10,3,6,10,4,8,1581777,1,10,3,6,10,4, +8,1581781,1,10,3,6,10,4,8,1581783,1,10,3,6,10,4, +8,1581755,1,10,3,6,10,4,8,1581757,1,10,3,6,10,4, +8,1581797,1675373,14,40,0,1675369,1582663,12,10,3,6,10,4,8,1581799, +1675401,14,41,0,1675397,1582663,12,10,3,6,10,4,8,1581801,1675429,14, +123,0,1675425,1582663,12,10,3,6,10,4,8,1581803,1675457,14,125,0, +1675453,1582663,12,10,3,6,10,4,8,1581805,1675485,14,91,0,1675481,1582663, +12,10,3,6,10,4,8,1581807,1675513,14,93,0,1675509,1582663,12,10, +3,6,10,4,8,1581809,1675541,14,44,0,1675537,1582663,12,10,3,6, +10,4,8,1581811,1675569,14,59,0,1675565,1582663,12,10,3,6,10,4, +8,1581813,1675597,14,61,0,1675593,1582663,12,10,3,6,10,4,8,1581815, +1675627,14,45,62,0,1675621,1582663,12,10,3,6,10,4,8,1581817,1675657, +14,43,43,0,1675651,1582663,12,10,3,6,10,4,8,1581819,1675687,14, +45,45,0,1675681,1582663,12,10,3,6,10,4,8,1581821,1675715,14,42, +0,1675711,1582663,12,10,3,6,10,4,8,1581823,1675743,14,38,0,1675739, +1582663,12,10,3,6,10,4,8,1581825,1675771,14,58,0,1675767,1582663,12, +10,3,6,10,4,8,1581827,1675799,14,35,0,1675795,1582663,12,10,3, +6,10,4,8,1581829,1675827,14,45,0,1675823,1582663,12,10,3,6,10, +4,8,1581835,1675855,14,46,0,1675851,1582663,12,10,3,6,10,4,8, +1581831,1675885,14,38,38,0,1675879,1582663,12,10,3,6,10,4,8,1581833, +1675915,14,124,124,0,1675909,1582663,12,10,3,6,10,4,8,1581837,1675945, +14,102,110,0,1675939,1582663,12,10,3,6,10,4,8,1581839,1675977,14, +108,101,116,0,1675969,1582663,12,10,3,6,10,4,8,1581841,1676013,14, +99,111,110,115,116,0,1676001,1582663,12,10,3,6,10,4,8,1581843, +1676047,14,101,108,115,101,0,1676037,1582663,12,10,3,6,10,4,8, +1581845,1676077,14,97,115,0,1676071,1582663,12,10,3,6,10,4,8,1581847, +1676121,14,117,110,99,104,101,99,107,101,100,0,1676101,1582663,12,10, +3,6,10,4,8,1581849,1676165,14,105,109,109,101,100,105,97,116, +101,0,1676145,1582663,12,10,3,6,10,4,8,1581851,1676193,14,109,0, +1676189,1582663,12,10,3,6,10,4,8,1581853,1676221,14,100,0,1676217,1582663, +12,10,3,6,10,4,8,1581855,1676249,14,117,0,1676245,1582663,12,10, +3,6,10,4,8,1581857,1676285,14,115,116,97,114,116,0,1676273,1582663, +12,10,3,6,10,4,8,1581859,1676319,14,109,97,105,110,0,1676309, +1582663,12,10,3,6,10,4,8,1581861,1676353,14,102,114,101,101,0, +1676343,1582663,12,10,3,6,10,4,8,1581863,1676385,14,111,119,110,0, +1676377,1582663,12,10,3,6,10,4,8,1581865,1676419,14,113,110,101,119, +0,1676409,1582663,12,10,3,6,10,4,8,1581867,1676459,14,101,110,104, +97,110,99,101,0,1676443,1582663,12,10,3,6,10,4,8,1581869,1676495, +14,109,105,99,114,111,0,1676483,1582663,12,10,3,6,10,4,8, +1581871,1676525,14,118,109,0,1676519,1582663,12,10,3,6,10,4,8,1, +1676551,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4, +1676585,14,33,0,1676581,1676633,14,48,32,36,32,48,32,126,32,45, +32,124,32,51,49,32,62,32,49,32,43,0,1676591,1596655,12,8, +1676651,14,33,33,0,1676645,1676703,14,48,32,36,32,48,32,126,32, +45,32,124,32,51,49,32,62,32,48,32,126,32,45,0,1676657, +1596655,12,8,1676719,14,126,0,1676715,1676735,14,45,49,32,94,0,1676725, +1596655,12,8,1676751,14,45,0,1676747,1676769,14,48,32,126,32,45,0, +1676757,1596655,12,8,1676785,14,42,0,1676781,21,1676797,14,42,0,1676793,1595637, +12,8,1676813,14,47,0,1676809,21,1676831,14,105,100,105,118,0,1676821, +1595637,12,8,1676847,14,37,0,1676843,21,1676865,14,105,109,111,100,0, +1676855,1595637,12,8,1676881,14,43,0,1676877,19,1676893,14,43,0,1676889,1595637, +12,8,1676909,14,45,0,1676905,19,1676921,14,45,0,1676917,1595637,12,8, +1676939,14,60,60,0,1676933,17,1676957,14,105,115,104,108,0,1676947,1595637, +12,8,1676975,14,62,62,0,1676969,17,1676987,14,62,0,1676983,1595637,12, +8,1677003,14,60,0,1676999,15,1677015,14,60,0,1677011,1595637,12,8,1677031, +14,62,0,1677027,15,1677047,14,126,32,60,0,1677039,1595637,12,8,1677065, +14,60,61,0,1677059,15,1677089,14,126,32,60,32,49,32,94,0, +1677073,1595637,12,8,1677107,14,62,61,0,1677101,15,1677127,14,60,32,49, +32,94,0,1677115,1595637,12,8,1677145,14,61,61,0,1677139,13,1677199,14, +45,32,48,32,36,32,48,32,126,32,45,32,124,32,51,49, +32,62,32,49,32,43,0,1677153,1595637,12,8,1677217,14,33,61,0, +1677211,13,1677275,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,1677225,1595637,12, +8,1677291,14,38,0,1677287,11,1677303,14,38,0,1677299,1595637,12,8,1677319, +14,94,0,1677315,9,1677331,14,94,0,1677327,1595637,12,8,1677347,14,124, +0,1677343,7,1677359,14,124,0,1677355,1595637,12,8,1677377,14,38,38,0, +1677371,3,1,10,28,1,1595637,12,8,1677405,14,124,124,0,1677399,5, +1,10,28,1,1595637,12,8,1581813,2,1594897,12,8,1581815,2,1594897,12, +8,1581817,2,1594897,12,8,1581819,2,1594897,12,8,1677475,14,108,101,116, +0,1677467,1652777,17,1596967,12,8,1677497,14,105,102,0,1677491,1652827,17,1596967, +12,8,1677525,14,119,104,105,108,101,0,1677513,1653725,17,1596967,12,8, +1677549,14,102,111,114,0,1677541,1654033,17,1596967,12,8,1677577,14,98,114, +101,97,107,0,1677565,1655147,17,1596967,12,8,1677611,14,99,111,110,116, +105,110,117,101,0,1677593,1655315,17,1596967,12,8,1677641,14,114,101,116, +117,114,110,0,1677627,1655439,17,1596967,12,8,1677677,14,117,110,99,104, +101,99,107,101,100,0,1677657,1656037,17,1596967,12,8,1677701,14,97,115, +109,0,1677693,1658683,17,33,34,1596967,12,8,1677733,14,113,117,111,116, +101,0,1677721,1659805,33,1596967,12,8,1677763,14,115,105,122,101,111,102, +0,1677749,1627797,33,1596967,12,8,1677793,14,116,121,112,101,111,102,0, +1677779,1627891,33,1596967,12,8,1,1677813,14,1,1310721,2,1,26,1310721,4, +18,1310721,2,5,28,1310721,4,1575681,12,8,1675115,12,8,1572865,11,26, +2,1673899,12,8,1676565,12,8,1627981,12,8,1581747,1,10,3,6,10, +4,8,1581749,1,10,3,6,10,4,8,1581751,524289,10,3,6,10, +4,8,1581753,1,10,3,6,10,4,8,1579449,1579447,2,10,3,6, +10,4,8,1579451,1,10,3,6,10,4,8,1,1,1,1,1586239, +12,8,1591423,12,8,1672255,12,8,1579449,2,1672333,12,8,1581747,2,1581753, +2,10,40,1678045,16,1581753,1581747,2,10,3,6,10,4,8,1310721,2, +1581859,2,1583635,12,10,3,6,10,4,8,1310721,2,2,1,40,3, +36,1678149,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, +1678151,14,1,1678197,16,1442305,1310721,2,2,26,2,3,32,1,6,1, +10,28,34,63,38,1,10,28,1678199,14,1,1678257,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,1573195,12,8,1,1678271,14,1,1310721, +2,5,26,1310721,4,18,1,838913,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,105, +110,115,116,97,108,108,0,6,0,201334290,105,100,105,118,0,6, +1,201340946,105,109,111,100,0,6,2,201347602,105,115,104,108,0,1, +786539,2,112,117,116,99,0,1,786563,0,103,101,116,99,0,1, +786580,0,101,111,102,0,1,786597,0,104,97,108,116,0,1,786615, +2,112,117,116,115,0,1,786685,2,112,117,116,110,0,1,786865, +2,115,116,114,108,101,110,0,1,786926,4,115,116,114,101,113, +0,1,787069,6,119,99,111,112,121,0,1,787164,6,119,102,105, +108,108,0,3,787252,0,112,111,119,50,0,2,787284,0,122,114, +101,109,0,1,787285,4,122,117,100,105,118,0,1,787505,4,122, +100,105,118,0,1,787682,4,122,109,111,100,0,1,787766,4,122, +115,104,108,0,4,6,0,72,68,82,0,2,787804,0,104,98, +117,109,112,0,3,787805,0,102,114,101,101,108,0,2,787837,0, +103,99,95,114,117,110,115,0,2,787838,0,103,99,95,102,114, +101,101,100,0,2,787839,0,103,99,95,97,117,116,111,0,1, +787840,0,104,101,97,112,95,105,110,105,116,0,1,787937,2,105, +115,111,98,106,0,1,788055,0,111,111,109,0,1,788105,5,110, +101,119,95,116,0,1,789281,0,103,99,0,1,788568,3,110,101, +119,0,1,788593,2,111,115,105,122,101,0,1,788643,2,116,121, +112,101,111,102,95,111,98,106,0,1,788691,2,114,101,108,101, +97,115,101,0,1,788925,130,102,114,101,101,0,1,788958,4,111, +119,110,0,2,789011,0,109,115,95,116,111,112,0,2,789012,0, +109,115,95,111,118,101,114,0,2,789013,0,103,99,95,108,111, +0,2,789014,0,103,99,95,104,105,0,1,789015,2,109,97,114, +107,0,1,789150,4,109,97,114,107,114,97,110,103,101,0,1, +789210,0,100,114,97,105,110,0,1,837465,0,103,99,95,114,111, +111,116,115,0,1,789635,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,6,0,75,95, +69,78,72,0,4,7,0,75,95,84,89,80,69,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,64,0,70,95,70, +65,76,76,66,65,67,75,0,4,128,0,70,95,71,69,78, +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,22,0,88,79,80,48,0,4, +-2,0,83,69,81,82,69,70,0,2,789721,0,110,101,110,104, +0,2,789722,0,112,111,111,108,116,111,112,0,2,789723,0,110, +115,121,109,0,2,789724,0,117,98,97,115,101,0,2,789725,0, +118,105,115,108,111,0,2,789726,0,110,102,105,120,117,0,2, +789727,0,102,105,120,102,114,101,101,0,2,789728,0,110,98,105, +110,0,2,789729,0,110,117,110,0,2,789730,0,110,97,115,103, +0,2,789731,0,110,107,111,112,0,2,789732,0,115,101,113,116, +111,112,0,2,789733,0,109,110,101,109,0,2,789757,0,99,104, +101,99,107,95,111,110,0,2,789758,0,116,107,0,2,789759,0, +116,118,0,2,789760,0,116,103,108,117,101,0,2,789761,0,116, +108,105,110,101,0,2,789762,0,108,105,110,101,0,2,789763,0, +99,104,0,2,789764,0,99,104,107,105,110,100,0,2,789765,0, +99,104,112,116,114,0,2,789766,0,113,100,111,110,101,0,2, +789767,0,105,115,112,0,3,789768,0,116,98,117,102,0,2,790868, +0,112,107,95,104,97,115,0,2,790869,0,112,107,95,116,107, +0,2,790870,0,112,107,95,116,118,0,2,790871,0,112,107,95, +103,108,117,101,0,2,790872,0,112,107,95,108,105,110,101,0, +2,790873,0,104,101,114,101,0,2,790874,0,104,100,101,108,116, +97,0,2,790875,0,104,108,105,109,105,116,0,2,790876,0,112, +116,111,112,0,2,790877,0,110,108,111,99,0,2,790878,0,108, +98,97,115,101,0,2,790879,0,102,100,101,112,116,104,0,2, +790880,0,102,115,108,111,116,115,0,2,790881,0,102,99,104,107, +0,2,790882,0,102,114,101,116,0,2,790883,0,108,105,118,101, +0,2,790884,0,98,120,100,101,112,116,104,0,2,790885,0,101, +112,105,99,104,97,105,110,0,2,790886,0,102,102,114,97,109, +101,0,2,790887,0,105,110,102,110,0,2,790888,0,108,115,112, +0,2,790889,0,108,111,111,112,98,97,115,101,0,2,790890,0, +99,116,120,115,112,0,2,790891,0,115,110,97,112,116,111,112, +0,2,790892,0,108,118,0,2,790893,0,108,118,107,0,2,790894, +0,108,118,105,0,2,790895,0,107,119,95,101,120,112,114,0, +2,790896,0,120,99,108,115,0,2,790897,0,102,116,121,0,2, +790898,0,115,95,108,112,0,2,790899,0,115,95,114,112,0,2, +790900,0,115,95,108,98,0,2,790901,0,115,95,114,98,0,2, +790902,0,115,95,108,107,0,2,790903,0,115,95,114,107,0,2, +790904,0,115,95,99,111,109,109,97,0,2,790905,0,115,95,115, +101,109,105,0,2,790906,0,115,95,101,113,0,2,790907,0,115, +95,97,114,114,111,119,0,2,790908,0,115,95,105,110,99,0, +2,790909,0,115,95,100,101,99,0,2,790910,0,115,95,115,116, +97,114,0,2,790911,0,115,95,97,109,112,0,2,790912,0,115, +95,99,111,108,111,110,0,2,790913,0,115,95,104,97,115,104, +0,2,790914,0,115,95,109,105,110,117,115,0,2,790915,0,115, +95,97,110,100,97,110,100,0,2,790916,0,115,95,111,114,111, +114,0,2,790917,0,115,95,100,111,116,0,2,790918,0,115,95, +102,110,0,2,790919,0,115,95,118,97,114,0,2,790920,0,115, +95,99,111,110,115,116,0,2,790921,0,115,95,101,108,115,101, +0,2,790922,0,115,95,97,115,0,2,790923,0,115,95,117,110, +99,104,101,99,107,101,100,0,2,790924,0,115,95,105,109,109, +101,100,105,97,116,101,0,2,790925,0,115,95,109,0,2,790926, +0,115,95,100,0,2,790927,0,115,95,117,0,2,790928,0,115, +95,115,116,97,114,116,0,2,790929,0,115,95,109,97,105,110, +0,2,790930,0,115,95,102,114,101,101,0,2,790931,0,115,95, +111,119,110,0,2,790932,0,115,95,113,110,101,119,0,2,790933, +0,115,95,101,110,104,97,110,99,101,0,2,790934,0,115,95, +109,105,99,114,111,0,2,790935,0,115,95,118,109,0,4,0, +0,84,89,95,87,79,82,68,0,4,1,0,84,89,95,73, +78,84,0,4,2,0,84,89,95,67,72,65,82,0,4,3, +0,84,89,95,66,79,79,76,0,4,4,0,84,89,95,86, +79,73,68,0,4,5,0,84,89,95,80,84,82,0,4,6, +0,84,89,95,65,82,82,0,4,7,0,84,89,95,70,78, +0,4,8,0,84,89,95,83,84,82,85,67,84,0,4,9, +0,84,89,95,86,65,82,0,4,10,0,84,89,95,71,69, +78,0,4,638976,0,82,95,84,89,0,4,655360,0,82,95,84, +89,69,78,68,0,4,1024,0,78,84,76,0,4,778496,0,108, +116,121,112,101,0,4,779008,0,108,116,97,103,0,4,779520,0, +115,116,121,112,101,0,2,790936,0,116,121,116,111,112,0,2, +790937,0,110,116,108,0,2,790938,0,116,119,111,114,100,0,2, +790939,0,116,105,110,116,0,2,790940,0,116,99,104,97,114,0, +2,790941,0,116,98,111,111,108,0,2,790942,0,116,118,111,105, +100,0,2,790943,0,116,99,95,111,110,0,2,790944,0,120,116, +121,0,2,790945,0,120,122,101,114,111,0,2,790946,0,100,114, +121,0,3,790947,0,116,112,110,0,2,790955,0,110,116,112,0, +2,790956,0,100,116,121,0,2,790957,0,100,116,97,103,0,2, +790958,0,115,95,108,116,0,2,790959,0,115,95,103,116,0,2, +790960,0,115,95,115,104,114,0,2,790961,0,115,95,108,101,0, +2,790962,0,115,95,103,101,0,2,790963,0,115,95,101,113,101, +113,0,2,790964,0,115,95,110,101,0,2,790965,0,115,95,112, +108,117,115,0,2,790966,0,115,95,115,116,114,117,99,116,0, +2,790967,0,115,95,116,121,112,101,0,2,790968,0,115,95,116, +121,112,101,99,104,101,99,107,0,2,790969,0,115,95,111,110, +0,2,790970,0,115,95,111,102,102,0,2,790971,0,115,95,110, +101,119,0,2,790972,0,115,95,110,101,119,95,116,0,3,790973, +0,110,117,109,111,112,115,0,2,790985,0,110,110,117,109,111, +112,115,0,3,790986,0,103,98,105,110,100,0,2,790994,0,110, +103,98,105,110,100,0,1,790995,2,100,105,101,0,1,791058,4, +100,105,101,110,0,1,791143,2,99,101,114,114,0,1,791191,4, +99,101,114,114,110,0,1,791252,2,104,97,115,104,115,0,1, +791331,2,105,110,116,101,114,110,0,1,791579,6,97,100,100,115, +121,109,0,1,791817,2,108,111,111,107,117,112,0,1,791980,2, +112,111,112,115,121,109,115,0,1,792046,2,108,111,111,107,117, +112,115,0,1,792072,4,102,105,120,110,101,119,0,1,792237,4, +102,105,120,97,108,108,0,1,792483,4,115,101,116,108,105,116, +0,1,792335,2,101,109,105,116,0,1,792421,2,108,105,116,0, +1,792453,2,111,112,0,1,792540,2,106,109,112,0,1,792570,0, +104,111,108,101,0,1,792600,2,102,119,100,102,110,0,1,792650, +2,102,110,114,101,102,0,1,792726,2,99,97,108,108,110,97, +109,101,0,1,792792,2,108,97,100,100,114,0,1,792835,2,115, +116,114,108,105,116,0,1,792930,0,110,101,120,116,99,104,0, +1,793119,8,115,114,99,95,112,117,115,104,0,1,793594,0,115, +114,99,95,112,111,112,0,1,793790,2,105,115,111,112,99,104, +0,1,793890,4,111,112,112,114,101,102,105,120,0,1,794122,2, +105,115,100,105,103,0,1,794172,2,105,115,97,108,0,1,794300, +2,104,101,120,118,0,1,794421,0,101,115,99,99,104,0,1, +794584,2,111,112,108,101,120,0,1,794718,0,108,101,120,0,1, +795711,0,110,101,120,116,0,1,795943,0,110,101,120,116,48,0, +1,795780,0,112,101,101,107,0,1,796170,2,105,115,95,111,112, +0,1,796235,2,105,115,95,105,100,0,1,796300,2,97,99,99, +101,112,116,0,1,796404,2,101,120,112,101,99,116,0,1,796493, +0,110,97,109,101,0,1,796559,2,115,101,113,97,115,109,0, +1,797117,2,109,110,101,109,105,100,120,0,1,797208,4,101,109, +105,116,115,101,113,0,1,797448,2,97,100,100,107,111,112,0, +1,797557,2,98,105,110,102,105,110,100,0,1,797644,2,117,110, +102,105,110,100,0,1,797731,2,97,115,103,102,105,110,100,0, +1,797818,6,97,100,100,95,98,105,110,111,112,0,1,798327,4, +97,100,100,95,117,110,111,112,0,1,798483,6,97,100,100,95, +107,119,0,1,798555,2,102,105,110,100,108,111,99,0,1,798646, +2,110,101,119,108,111,99,0,1,798866,2,108,114,111,111,116, +0,1,798924,2,116,114,97,99,107,101,100,0,1,798962,2,116, +111,117,99,104,0,1,799195,2,112,108,97,105,110,117,115,101, +0,1,799324,2,102,114,101,101,118,97,114,0,1,799366,4,101, +120,105,116,95,118,97,114,115,0,1,799719,2,117,110,117,115, +101,100,95,99,104,101,99,107,0,1,799857,2,98,108,111,99, +107,95,99,108,111,115,101,0,1,799982,0,115,110,97,112,95, +112,117,115,104,0,1,800246,2,115,110,97,112,95,112,111,112, +0,1,800276,2,115,110,97,112,95,114,101,115,116,111,114,101, +0,1,800484,2,101,109,112,116,121,0,1,800549,2,115,110,97, +112,95,99,109,112,0,1,800943,2,115,116,97,116,101,110,97, +109,101,0,1,801150,6,109,101,114,103,101,95,101,114,114,0, +1,801331,4,109,101,114,103,101,0,1,801531,2,108,111,111,112, +99,104,101,99,107,0,1,801743,4,114,101,99,97,115,116,0, +1,802268,4,97,114,103,99,104,101,99,107,0,1,803023,2,101, +109,105,116,111,119,110,0,1,803061,6,97,115,115,105,103,110, +99,104,101,99,107,0,1,804792,2,114,101,116,99,104,101,99, +107,0,1,805272,2,104,97,110,100,117,112,0,1,805619,2,100, +105,115,99,97,114,100,0,1,805731,2,116,97,108,108,111,99, +0,1,805827,8,116,110,101,119,0,1,805990,2,116,112,116,114, +0,1,806166,4,116,97,114,114,0,1,807978,2,116,115,122,0, +1,806415,8,116,102,110,0,1,806865,4,116,118,97,114,0,1, +807050,6,116,105,110,115,116,0,1,807470,2,116,114,101,115,111, +108,118,101,0,1,808053,4,115,117,98,115,116,0,1,808541,2, +105,115,110,117,109,0,1,808646,2,105,115,97,103,103,0,1, +808717,2,105,115,112,116,114,0,1,808788,2,100,101,99,97,121, +0,1,808840,2,116,101,108,101,109,0,1,808923,4,99,111,109, +112,97,116,0,1,809397,6,117,110,105,102,121,0,1,809931,2, +116,112,114,105,110,116,0,1,816380,4,116,112,97,114,97,109, +116,97,103,0,1,810542,6,116,99,101,114,114,0,1,810737,6, +116,99,110,101,101,100,0,1,810927,2,116,112,102,105,110,100, +0,1,811014,2,105,115,116,121,112,101,110,97,109,101,0,1, +811121,0,99,108,111,115,101,97,110,103,108,101,0,1,811161,0, +112,116,121,112,101,0,1,824983,0,99,101,120,112,114,0,1, +812089,0,116,115,116,97,114,116,0,1,812378,0,100,116,121,112, +101,0,1,812554,0,107,119,95,115,116,114,117,99,116,0,1, +813484,0,107,119,95,116,121,112,101,0,1,813533,0,107,119,95, +116,121,112,101,99,104,101,99,107,0,1,813629,4,116,102,105, +110,100,102,105,101,108,100,0,1,813742,0,116,121,112,101,97, +114,103,0,1,823247,0,101,120,112,114,0,1,816964,0,114,118, +97,108,0,1,813898,0,107,119,95,115,105,122,101,111,102,0, +1,813945,0,107,119,95,116,121,112,101,111,102,0,1,813990,0, +116,121,112,101,115,95,105,110,105,116,0,1,814561,2,105,115, +110,117,109,111,112,0,1,814643,6,98,105,110,116,121,112,101, +0,1,816025,2,116,107,105,110,100,0,1,816050,2,116,115,105, +122,101,0,1,816074,2,116,110,97,109,101,0,1,816099,2,116, +108,101,110,0,1,816124,2,116,110,102,105,101,108,100,115,0, +1,816155,4,116,102,110,97,109,101,0,1,816200,4,116,102,116, +121,112,101,0,1,816247,4,116,102,111,102,102,0,1,816294,2, +116,114,101,116,0,1,816319,2,116,110,112,97,114,97,109,115, +0,1,816344,4,116,112,97,114,97,109,0,1,816426,2,116,114, +101,116,117,0,1,816453,2,116,110,97,114,103,115,0,1,816537, +4,116,97,114,103,0,1,816576,2,115,105,103,111,102,0,1, +816876,2,115,105,103,111,102,115,0,1,817013,4,107,119,99,97, +108,108,0,1,817148,0,115,116,109,116,111,110,108,121,0,1, +817215,6,97,114,103,115,0,1,817477,0,110,101,119,116,121,112, +101,100,0,1,817636,2,99,97,108,108,0,1,818192,2,101,110, +104,99,97,108,108,0,1,818550,0,112,114,105,109,97,114,121, +0,1,824221,0,98,108,111,99,107,101,120,112,114,0,1,819911, +4,105,110,99,100,101,99,0,1,820324,2,102,105,101,108,100, +0,1,820905,0,112,111,115,116,102,105,120,0,1,821888,0,117, +110,97,114,121,0,1,822716,2,98,105,110,0,1,823210,0,115, +116,111,114,101,107,101,101,112,0,1,823985,0,115,116,109,116, +115,116,97,114,116,0,1,825329,0,115,116,109,116,0,1,824586, +0,99,112,114,105,109,0,1,825764,2,108,111,99,97,108,100, +101,99,108,0,1,825578,0,98,108,111,99,107,0,1,825695,0, +115,117,98,115,116,109,116,0,1,826388,0,107,119,95,118,97, +114,0,1,826413,0,107,119,95,105,102,0,1,826651,4,108,111, +111,112,95,112,117,115,104,0,1,826817,0,108,111,111,112,95, +112,111,112,0,1,826862,0,107,119,95,119,104,105,108,101,0, +1,827016,0,107,119,95,102,111,114,0,1,827405,2,108,111,111, +112,101,120,105,116,0,1,827573,0,107,119,95,98,114,101,97, +107,0,1,827657,0,107,119,95,99,111,110,116,105,110,117,101, +0,1,827719,0,107,119,95,114,101,116,117,114,110,0,1,828018, +0,107,119,95,117,110,99,104,101,99,107,101,100,0,1,828067, +0,97,115,109,98,108,111,99,107,0,1,829341,0,107,119,95, +97,115,109,0,1,829372,1,103,114,97,98,0,1,829692,3,113, +110,101,119,0,1,829759,67,113,100,117,112,0,1,829826,68,119, +99,111,112,121,116,111,0,1,829902,0,107,119,95,113,117,111, +116,101,0,1,830028,3,116,111,107,101,110,115,0,1,830254,130, +102,101,101,100,0,1,830286,0,99,116,120,95,112,117,115,104, +0,1,830663,0,99,116,120,95,112,111,112,0,1,831004,4,102, +110,95,98,101,103,105,110,0,1,831159,0,112,114,111,108,111, +103,117,101,0,1,831205,0,101,112,105,108,111,103,117,101,0, +1,831286,0,98,111,100,121,0,1,831473,2,102,110,100,101,102, +0,1,833572,2,103,100,101,99,108,0,1,834211,0,103,99,111, +110,115,116,0,1,834283,0,101,110,104,100,101,102,0,1,835600, +0,116,111,112,105,116,101,109,0,1,836127,0,117,110,105,116, +95,116,111,112,0,1,836166,2,117,110,105,116,95,101,110,100, +0,1,836345,4,99,111,109,112,105,108,101,95,108,105,115,116, +0,1,836572,2,99,111,109,112,105,108,101,0,1,836597,2,108, +111,97,100,0,1,836624,2,101,118,97,108,0,1,836664,2,101, +118,97,108,115,0,1,836718,2,98,108,111,98,95,101,109,105, +116,0,1,836949,2,98,108,111,98,95,108,111,97,100,0,1, +837140,4,98,117,105,108,100,95,105,109,97,103,101,0,1,837557, +0,122,99,95,105,110,105,116,0,1,838282,0,122,99,95,116, +97,98,108,101,115,0,0 +}; +#define GLEN 57463 diff --git a/docs/history/11-types-enhancements/code/io_linux.c b/docs/history/11-types-enhancements/code/io_linux.c new file mode 100644 index 0000000..7ea34e0 --- /dev/null +++ b/docs/history/11-types-enhancements/code/io_linux.c @@ -0,0 +1,6 @@ +#include +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/11-types-enhancements/code/mkgenome.c b/docs/history/11-types-enhancements/code/mkgenome.c new file mode 100644 index 0000000..8fb2cc5 --- /dev/null +++ b/docs/history/11-types-enhancements/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 +#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/11-types-enhancements/code/src/compiler.zc b/docs/history/11-types-enhancements/code/src/compiler.zc new file mode 100644 index 0000000..7e86b07 --- /dev/null +++ b/docs/history/11-types-enhancements/code/src/compiler.zc @@ -0,0 +1,2253 @@ +// ============================================================================ +// 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, K_ENH = 6, K_TYPE = 7; +const F_DEF = 1, F_SIG = 2, F_UNTYPED = 4, F_STMT = 8, F_EXPR = 16, F_TOP = 32, F_FALLBACK = 64, F_GEN = 128; +// 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 XOP0 = 22; // first enhancement opcode +const SEQREF = -2; // in an operator sequence: the next word names a symbol + +// ---- state ---- +let nenh, pooltop, nsym, ubase, vislo, nfixu, fixfree; +let nbin, nun, nasg, nkop, seqtop; +let mnem = "q@!$_~cjzr,?.+-*&|^><%"; +let check_on = 1; // set to 0 to switch the analyzer off for what follows +let tk, tv, tglue, tline, line = 1, ch, chkind, chptr, qdone, isp = -1; +let tbuf[1100]; +let pk_has, pk_tk, pk_tv, pk_glue, pk_line; // a peeked token +let here, hdelta, hlimit, ptop; +let nloc, lbase, fdepth, fslots, fchk, fret, live, bxdepth, epichain, fframe, infn; +let lsp, loopbase, ctxsp, snaptop; +let lv, lvk, lvi, kw_expr, xcls, fty; +// interned spellings the parser compares against +let s_lp, s_rp, s_lb, s_rb, s_lk, s_rk, s_comma, s_semi, s_eq, s_arrow, s_inc, s_dec; +let s_star, s_amp, s_colon, s_hash, s_minus, s_andand, s_oror; +let s_dot, s_fn, s_var, s_const, s_else, s_as, s_unchecked, s_immediate, s_m, s_d, s_u; +let s_start, s_main, s_free, s_own, s_qnew, s_enhance, s_micro, s_vm; + +// ---- types: kinds, tables and parser state (see the types section) ---- +const TY_WORD = 0, TY_INT = 1, TY_CHAR = 2, TY_BOOL = 3, TY_VOID = 4, TY_PTR = 5, TY_ARR = 6; +const TY_FN = 7, TY_STRUCT = 8, TY_VAR = 9, TY_GEN = 10; +const R_TY = 0x9C000, R_TYEND = 0xA0000, NTL = 1024; // the first NTL words list every record +const ltype = 0xBE100, ltag = 0xBE300, stype = 0xBE500; // type per local, declared tag per local, type per symbol +let tytop, ntl, tword, tint, tchar, tbool, tvoid; +let tc_on; // the optional typechecker, off unless a program says typecheck on; +let xty, xzero, dry; // type of the last expression, was it a literal 0, and dry runs (typeof) +let tpn[8], ntp; // type parameters in scope +let dty, dtag; // result of dtype() +let s_lt, s_gt, s_shr, s_le, s_ge, s_eqeq, s_ne, s_plus, s_struct, s_type, s_typecheck, s_on, s_off, s_new, s_new_t; +let numops[12], nnumops; +let gbind[8], ngbind; // explicit type arguments for the next call: f(...) + +// ---- 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) { let h = 0; while (*s) { h = h * 31 + *s; s++; } return h & (IHN - 1); } +fn intern(s) +{ + let 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) +{ + let 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; stype[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) +{ + let i = name[-1] - 1; + while (i >= 0) { + if (i >= vislo || skind[i] == K_KW || skind[i] == K_TYPE) 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) +{ + let 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) +{ + let 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 (dry) return 0; 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) { if (dry) return 0; *(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() { let a = here; lit(MW - 1); return a; } +fn fwdfn(name) { let s = addsym(name, K_FN, 0); sflag[s] = 0; return s; } +fn fnref(s) +{ + if (sflag[s] & F_DEF) { lit(sval[s]); return 0; } + if (dry) 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) { let 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) +{ + let 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 12..15 saved lookahead +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) +{ + let f; + isp++; + if (isp >= 32) die("sources nested too deeply"); + f = R_SRC + isp * 16; + 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; + f[12] = pk_has; f[13] = pk_tk; f[14] = pk_tv; f[15] = pk_glue; pk_has = 0; + 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() +{ + let f = R_SRC + isp * 16; + tk = f[5]; tv = f[6]; tglue = f[7]; ch = f[8]; chkind = f[9]; chptr = f[10]; + pk_has = f[12]; pk_tk = f[13]; pk_tv = f[14]; pk_glue = f[15]; pk_line = tline; + isp--; + if (f[11]) free(f[1]); + return 0; +} +fn isopch(c) +{ + let 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) +{ + let 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() +{ + let 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() +{ + let n = 0, v, dg; + 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 ((dg = hexv(ch)) >= 0) { v = v * 16 + dg; 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; +} +// one token of lookahead: peek() fills pk_*, next() takes it first +fn next() +{ + if (pk_has) { tk = pk_tk; tv = pk_tv; tglue = pk_glue; tline = pk_line; pk_has = 0; return 0; } + return next0(); +} +fn peek() +{ + let a, b, c, e; + if (pk_has) return 0; + a = tk; b = tv; c = tglue; e = tline; + next0(); + pk_tk = tk; pk_tv = tv; pk_glue = tglue; pk_line = tline; pk_has = 1; + tk = a; tv = b; tglue = c; tline = e; + return 0; +} +fn next0() +{ + let f, q, i; + f = R_SRC + isp * 16; + 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() +{ + let 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) +{ + let 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) { let i = 0; while (mnem[i]) { if (mnem[i] == c) return i; i++; } return -1; } +fn emitseq(a, n) +{ + let 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 if (skind[s] == K_ENH) op(XOP0 + sval[s]); else lit(sval[s]); + a = a + 2; + } else { emit(R_SEQ[a]); a++; } + } + return 0; +} +fn addkop(p) { let i = 0; while (i < nkop) { if (kops[i] == p) return 0; i++; } kops[nkop] = p; nkop++; return 0; } +fn binfind(p) { let i = nbin; while (i) { i--; if (bname[i] == p) return i; } return -1; } +fn unfind(p) { let i = nun; while (i) { i--; if (uname[i] == p) return i; } return -1; } +fn asgfind(p) { let 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) +{ + let 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) +{ + let 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) { let 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) { let i = nloc; while (i > lbase) { i--; if (lname[i] == n) return i; } return -1; } +fn newloc(n) +{ + let 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; ltype[i] = tword; ltag[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) +{ + let 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) +{ + let 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) +{ + let 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() +{ + let 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) +{ + let 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) +{ + let 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) +{ + let 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) +{ + let 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) +{ + let 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) +{ + let 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 <= 1) { // untagged parameters are m: a lend + 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 d*x to give it away"); + else if (st == S_U) cerrn(i, "is u; write d*x 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) +{ + let 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; if (ltag[i]) lstate[i] = ltag[i]; 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; if (ltag[i]) lstate[i] = ltag[i]; + 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) +{ + let 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 u*x'"); + } + 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) +{ + let 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; +} + +// ---- types ---- +// types are a compiler primitive: records in the type area, hash-consed so +// the same type is always the same pointer and comparing types is comparing +// words. untyped code is typed word, which goes with anything. the records +// stay in memory after compiling, so programs can inspect them. +// t[0] kind t[1] size in words t[2] name t[3] n t[4] a t[5] b t[6] c t[7..] extra +// ptr: a = element arr: a = element, n = length +// fn: a = return type, n = parameter count, b = signature (u m d tags), extra = parameter types +// struct: n = field count (-1 until laid out), a = fields (name, type, offset), +// b = generic template, c = type arguments [n, t1, t2 ...] +// var: a type parameter, n = its index +// gen: a generic struct: n = parameter count, a = fields (name, type), b = field count, c = parameter names + + +fn talloc(n) { let p = tytop; if (tytop + n >= R_TYEND) die("the type area is full"); tytop = tytop + n; wfill(p, 0, n); return p; } +fn tnew(kind, size, nm, extra) +{ + let t = talloc(7 + extra); + t[0] = kind; t[1] = size; t[2] = nm; + if (ntl >= NTL) die("too many types"); + R_TY[ntl] = t; ntl++; + return t; +} +fn tptr(e) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_PTR && t[4] == e) return t; i++; } + t = tnew(TY_PTR, 1, 0, 0); t[4] = e; + return t; +} +fn tarr(e, n) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_ARR && t[4] == e && t[3] == n) return t; i++; } + t = tnew(TY_ARR, n * tsz(e), 0, 0); t[4] = e; t[3] = n; + return t; +} +fn tfn(ret, np, ps, sig) +{ + let i = 0, j, t; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_FN && t[4] == ret && t[3] == np && t[5] == sig) { + j = 0; while (j < np && t[7 + j] == ps[j]) j++; + if (j == np) return t; + } + i++; + } + t = tnew(TY_FN, 1, 0, np); t[4] = ret; t[3] = np; t[5] = sig; + wcopy(t + 7, ps, np); + return t; +} +fn tvar(i, nm) +{ + let k = 0, t; + while (k < ntl) { t = R_TY[k]; if (t[0] == TY_VAR && t[3] == i) return t; k++; } + t = tnew(TY_VAR, 1, nm, 0); t[3] = i; + return t; +} +fn tinst(g, args, n) +{ + let i = 0, j, t, v; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_STRUCT && t[5] == g) { + v = t[6]; j = 0; while (j < n && v[1 + j] == args[j]) j++; + if (j == n) return t; + } + i++; + } + v = talloc(n + 1); v[0] = n; wcopy(v + 1, args, n); + t = tnew(TY_STRUCT, 0, g[2], 0); t[3] = -1; t[5] = g; t[6] = v; + return t; +} +// lay out a generic instance on first use +fn tresolve(t) +{ + let g, f, n, i, fs, off = 0, ft, bs[8]; + if (t[0] != TY_STRUCT || t[3] >= 0) return t; + if (t[3] == -2) die("a struct can't contain itself by value"); + t[3] = -2; + g = t[5]; n = g[5]; f = g[4]; + wfill(bs, 0, 8); wcopy(bs, t[6] + 1, t[6][0]); + fs = talloc(n * 3 + 1); + i = 0; + while (i < n) { + ft = subst(f[i + i + 1], bs); + fs[i * 3] = f[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = n; + return t; +} +fn tsz(t) { if (t[0] == TY_STRUCT && t[3] < 0) tresolve(t); return t[1]; } +// replace type parameters with what they were bound to (unbound ones become word) +fn subst(t, bs) +{ + let k = t[0], i, n, v[24], vec; + if (k == TY_VAR) { if (bs[t[3]]) return bs[t[3]]; return tword; } + if (k == TY_PTR) return tptr(subst(t[4], bs)); + if (k == TY_ARR) return tarr(subst(t[4], bs), t[3]); + if (k == TY_FN) { n = t[3]; i = 0; while (i < n) { v[i] = subst(t[7 + i], bs); i++; } return tfn(subst(t[4], bs), n, v, t[5]); } + if (k == TY_STRUCT && t[5]) { vec = t[6]; n = vec[0]; i = 0; while (i < n) { v[i] = subst(vec[1 + i], bs); i++; } return tinst(t[5], v, n); } + return t; +} +fn isnum(t) { return t[0] == TY_INT || t[0] == TY_CHAR || t[0] == TY_BOOL; } +fn isagg(t) { return t[0] == TY_ARR || t[0] == TY_STRUCT; } +fn isptr(t) { return t[0] == TY_PTR || t[0] == TY_ARR; } +fn decay(t) { if (t[0] == TY_ARR) return tptr(t[4]); return t; } +fn telem(t) { if (t[0] == TY_PTR || t[0] == TY_ARR) return t[4]; return tword; } +// can a value of type src go where dst is expected? +fn compat(dst, src) +{ + if (dst == src || dst == tword || src == tword) return 1; + if (isnum(dst) && isnum(src)) return 1; + src = decay(src); + if (dst[0] == TY_PTR && src[0] == TY_PTR) { + if (dst[4] == tword || src[4] == tword || dst[4] == tvoid || src[4] == tvoid) return 1; + return dst[4] == src[4]; + } + if ((dst[0] == TY_PTR || dst[0] == TY_FN) && xzero) return 1; // a literal 0 is a null pointer + return dst == src; +} +fn unify(p, a, bs) +{ + let i, n, pv, av; + if (p[0] == TY_VAR) { i = p[3]; if (!bs[i]) { bs[i] = a; return 1; } return compat(bs[i], a); } + a = decay(a); + if (p[0] == TY_PTR && a[0] == TY_PTR) { if (a[4] == tword) return 1; return unify(p[4], a[4], bs); } + if (p[0] == TY_STRUCT && p[5] && a[0] == TY_STRUCT && a[5] == p[5]) { + pv = p[6]; av = a[6]; n = pv[0]; i = 0; + while (i < n) { if (!unify(pv[1 + i], av[1 + i], bs)) return 0; i++; } + return 1; + } + return compat(p, a); +} +fn tprint(t) +{ + let k = t[0], i, v; + if (k == TY_PTR) { putc('*'); return tprint(t[4]); } + if (k == TY_ARR) { putc('['); putn(t[3]); putc(']'); return tprint(t[4]); } + if (k == TY_FN) { + puts("fn("); + i = 0; + while (i < t[3]) { + if (i) puts(", "); + tprint(t[7 + i]); + if (i < 12 && tparamtag(t, i) == 1) puts(".m"); + if (i < 12 && tparamtag(t, i) == 2) puts(".d"); + i++; + } + putc(')'); + if (t[4] != tword || (t[5] & 1)) { puts(" -> "); if (t[4] != tword) tprint(t[4]); if (t[5] & 1) puts(".u"); } + return 0; + } + if (t[2]) puts(t[2]); else puts("?"); + if (k == TY_STRUCT && t[5]) { + v = t[6]; putc('<'); + i = 0; while (i < v[0]) { if (i) puts(", "); tprint(v[1 + i]); i++; } + putc('>'); + } + return 0; +} +fn tcerr(what, want, got) +{ + if (!tc_on || !live || dry) return 0; + puts("zc: line "); putn(tline); puts(": type error: "); puts(what); + puts(": expected "); tprint(want); puts(", got "); tprint(got); putc(10); + halt(); + return 0; +} +fn tcneed(ok, what, got) +{ + if (ok || !tc_on || !live || dry) return 0; + puts("zc: line "); putn(tline); puts(": type error: "); puts(what); puts(", got "); tprint(got); putc(10); + halt(); + return 0; +} +fn tpfind(n) { let i = ntp; while (i) { i--; if (tpn[i] == n) return i; } return -1; } +fn istypename(n) +{ + let s; + if (tpfind(n) >= 0) return 1; + if (findloc(n) >= 0) return 0; + s = lookup(n); + return s >= 0 && skind[s] == K_TYPE; +} +// the closing > of a type argument list; splits >> in two +fn closeangle() +{ + if (is_op(s_shr)) { tv = s_gt; return 0; } + expect(s_gt); + return 0; +} +fn ptype() +{ + let n, s, t, np = 0, ps[24], ret, args[8], na = 0, i; + if (accept(s_star)) return tptr(ptype()); + if (accept(s_lk)) { n = cexpr(); expect(s_rk); t = ptype(); if (n < 0) die("a negative array length"); return tarr(t, n); } + if (is_id(s_fn)) { + next(); expect(s_lp); + if (!is_op(s_rp)) { while (1) { if (np >= 24) die("too many parameters"); ps[np] = ptype(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + ret = tword; + i = 0; + if (accept(s_arrow)) { if (!is_op(s_dot)) ret = ptype(); if (accept(s_dot)) { if (!is_id(s_u)) die("the return tag is .u"); next(); i = 1; } } + return tfn(ret, np, ps, i + np + np); + } + if (tk != T_ID) die("expected a type"); + n = tv; + i = tpfind(n); + if (i >= 0) { next(); return tvar(i, n); } + s = lookup(n); + if (s < 0 || skind[s] != K_TYPE) dien(n, "isn't a type"); + next(); + t = sval[s]; + if (t[0] != TY_GEN) return t; + expect(s_lt); + while (1) { + if (na >= 8) die("too many type arguments"); + args[na] = ptype(); + if (tsz(args[na]) != 1) die("type arguments have to be one word (a pointer, a number, or a parameter)"); + na++; + if (!accept(s_comma)) break; + } + closeangle(); + if (na != t[3]) dien(n, "wrong number of type arguments"); + return tinst(t, args, na); +} +// does a declaration start here? (a type, or a bare .tag) +fn tstart() +{ + if (tk == T_OP) { + if (tv == s_lk || tv == s_dot) return 1; + if (tv == s_star) { peek(); return (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) || (pk_tk == T_OP && pk_tv == s_lk); } + return 0; + } + if (tk != T_ID) return 0; + return tv == s_fn || istypename(tv); +} +// [type] [.tag] +fn dtype() +{ + dty = 0; dtag = 0; + if (!is_op(s_dot)) dty = ptype(); + if (accept(s_dot)) { + if (tv == s_m) dtag = S_M; else if (tv == s_u) dtag = S_U; else if (tv == s_d) dtag = S_D; else die("a tag is .u, .m or .d"); + next(); + } + return 0; +} +// struct name { type field, ... } or struct name { ... } +fn kw_struct() +{ + let n, t, s, nf = 0, buf = R_QBUF, i, fs, off = 0, gen = 0, ft; + next(); + n = name(); + if (is_op(s_lt)) { // generic + next(); ntp = 0; + while (1) { if (ntp >= 8) die("too many type parameters"); tpn[ntp] = name(); ntp++; if (!accept(s_comma)) break; } + closeangle(); + gen = 1; + t = tnew(TY_GEN, 0, n, 0); t[3] = ntp; + fs = talloc(ntp); wcopy(fs, tpn, ntp); t[6] = fs; + } else { t = tnew(TY_STRUCT, 0, n, 0); t[3] = -2; } // -2 while its fields are read + s = addsym(n, K_TYPE, t); + expect(s_lb); + while (!is_op(s_rb)) { + ft = ptype(); + while (1) { + if (nf >= 1000) die("too many fields"); + buf[nf + nf] = name(); buf[nf + nf + 1] = ft; nf++; + if (!accept(s_comma)) break; + } + expect(s_semi); + } + next(); + if (gen) { + fs = talloc(nf + nf); wcopy(fs, buf, nf + nf); + t[4] = fs; t[5] = nf; + ntp = 0; + } else { + fs = talloc(nf * 3 + 1); + i = 0; + while (i < nf) { + ft = buf[i + i + 1]; + if (ft == t) die("a struct can't contain itself by value; use a pointer"); + fs[i * 3] = buf[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = nf; + } + accept(s_semi); + return s; +} +// type name = T; +fn kw_type() { let n; next(); n = name(); expect(s_eq); addsym(n, K_TYPE, ptype()); expect(s_semi); return 0; } +// typecheck on; / typecheck off; +fn kw_typecheck() +{ + next(); + if (is_id(s_on)) tc_on = 1; else if (is_id(s_off)) tc_on = 0; else die("typecheck on or typecheck off"); + next(); expect(s_semi); + return 0; +} +// the field of a struct type, or -1 +fn tfindfield(t, n) { let i = 0; tresolve(t); while (i < t[3]) { if (t[4][i * 3] == n) return i; i++; } return -1; } +// sizeof(T or expr), typeof(T or expr): the expression form is compiled dry, so it never runs +fn typearg() +{ + let t, sb, c; + expect(s_lp); + if (tstart() && !is_op(s_dot)) t = ptype(); + else { + sb = snap_push(); dry++; + c = expr(); rval(); + t = xty; + dry--; snap_restore(sb); snap_pop(sb); + } + expect(s_rp); + return t; +} +fn kw_sizeof() { let t; next(); t = typearg(); lit(tsz(t)); xty = tint; return 0; } +fn kw_typeof() { let t; next(); t = typearg(); lit(t); xty = tword; return 0; } +fn types_init() +{ + tytop = R_TY + NTL; ntl = 0; + tword = tnew(TY_WORD, 1, intern("word"), 0); + tint = tnew(TY_INT, 1, intern("int"), 0); + tchar = tnew(TY_CHAR, 1, intern("char"), 0); + tbool = tnew(TY_BOOL, 1, intern("bool"), 0); + tvoid = tnew(TY_VOID, 0, intern("void"), 0); + addsym(tword[2], K_TYPE, tword); addsym(tint[2], K_TYPE, tint); addsym(tchar[2], K_TYPE, tchar); + addsym(tbool[2], K_TYPE, tbool); addsym(tvoid[2], K_TYPE, tvoid); + s_lt = intern("<"); s_gt = intern(">"); s_shr = intern(">>"); s_le = intern("<="); s_ge = intern(">="); + s_eqeq = intern("=="); s_ne = intern("!="); s_plus = intern("+"); + s_struct = intern("struct"); s_type = intern("type"); s_typecheck = intern("typecheck"); + s_on = intern("on"); s_off = intern("off"); s_new = intern("new"); s_new_t = intern("new_t"); + numops[0] = intern("*"); numops[1] = intern("/"); numops[2] = intern("%"); numops[3] = intern("&"); + numops[4] = intern("|"); numops[5] = intern("^"); numops[6] = intern("<<"); numops[7] = s_shr; nnumops = 8; + return 0; +} +fn isnumop(o) { let i = 0; while (i < nnumops) { if (numops[i] == o) return 1; i++; } return 0; } +// the type of a binary operation, checking it when the typechecker is on +fn bintype(b, lt, rt) +{ + let o = bname[b]; + lt = decay(lt); rt = decay(rt); + if (blen[b] < 0) { tcneed(!isagg(lt) && !isagg(rt), "&& and || need scalars", lt); return tbool; } + if (o == s_eqeq || o == s_ne) { if (!compat(lt, rt) && !compat(rt, lt)) tcerr("comparison", lt, rt); return tbool; } + if (o == s_lt || o == s_gt || o == s_le || o == s_ge) { + if (!(lt == tword || rt == tword || (isnum(lt) && isnum(rt)) || (lt[0] == TY_PTR && rt[0] == TY_PTR))) tcerr("comparison", lt, rt); + return tbool; + } + if (o == s_plus) { + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (rt[0] == TY_PTR && isnum(lt)) return rt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("+", lt, rt); return tword; + } + if (o == s_minus) { + if (lt[0] == TY_PTR && rt[0] == TY_PTR) return tint; + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("-", lt, rt); return tword; + } + if (isnumop(o)) { + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + if (isnum(lt)) lt = rt; + tcneed(0, "arithmetic needs numbers", lt); return tword; + } + return tword; // operators a program added +} + +// ---- reflection ---- +// for programs (and parse words) looking at types at runtime +fn tkind(t) { return t[0]; } +fn tsize(t) { return tsz(t); } +fn tname(t) { return t[2]; } +fn tlen(t) { return t[3]; } +fn tnfields(t) { tresolve(t); return t[3]; } +fn tfname(t, i) { tresolve(t); return t[4][i * 3]; } +fn tftype(t, i) { tresolve(t); return t[4][i * 3 + 1]; } +fn tfoff(t, i) { tresolve(t); return t[4][i * 3 + 2]; } +fn tret(t) { return t[4]; } +fn tnparams(t) { return t[3]; } +fn tparam(t, i) { return t[7 + i]; } +fn tparamtag(t, i) { return ((t[5] >> 6) >> (i + i)) & 3; } // 0 untagged (m), 1 .m, 2 .d +fn tretu(t) { return t[5] & 1; } +fn tnargs(t) { if (t[0] != TY_STRUCT || !t[5]) return 0; return t[6][0]; } +fn targ(t, i) { return t[6][1 + i]; } +// the type of a function, by address. untyped functions get one made from their signature +fn sigof(f) +{ + let i = nsym, s = -1, ws[24], n, k; + while (i) { i--; if (skind[i] == K_FN && sval[i] == f && (sflag[i] & F_DEF)) { s = i; break; } } + if (s < 0) return 0; + if (stype[s]) return stype[s]; + n = (ssig[s] >> 1) & 31; k = 0; + while (k < n) { ws[k] = tword; k++; } + return tfn(tword, n, ws, ssig[s]); +} +fn sigofs(nm) { let s = lookups(nm); if (s < 0 || skind[s] != K_FN) return 0; return sigof(sval[s]); } + +// ---- expressions ---- +// every expression leaves its value on the stack, returns its analyzer class, +// and sets xty to its type. lv means the stack holds an address that hasn't +// been loaded yet; structs and arrays are never loaded, their address is +// their value. +fn rval() { if (lv) { if (!isagg(xty)) op(O_LD); lv = 0; } return 0; } +fn kwcall(s, e) +{ + let f = sval[s], old = kw_expr, c; + kw_expr = e; xcls = C_PLAIN; xty = tword; xzero = 0; + 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; } +// the arguments of a call. ft is the callee's type (or 0), bs the generic bindings +fn args(tags, ft, bs) +{ + let np = 0, c, pt; + expect(s_lp); + if (!is_op(s_rp)) { + while (1) { + c = expr(); rval(); + argcheck(c, (tags >> (np + np)) & 3); + if (ft && np < ft[3]) { pt = ft[7 + np]; if (!unify(pt, xty, bs)) tcerr("argument", subst(pt, bs), xty); } + np++; + if (!accept(s_comma)) break; + } + } + expect(s_rp); + return np; +} +// new(T) and new(T, count): a typed object, its type stamped into the header +fn newtyped() +{ + let t, c; + t = ptype(); + if (accept(s_comma)) { + c = expr(); rval(); plainuse(c); + if (tsz(t) != 1) { lit(tsz(t)); op(15); } + lit(tarr(t, 0)); + } else { lit(tsz(t)); lit(t); } + expect(s_rp); + callname(s_new_t); + lv = 0; lvk = LV_NONE; xty = tptr(t); xzero = 0; + return C_FRESH; +} +fn call(s) +{ + let np, tags = 0, ret = 0, ft = stype[s], bs[8]; + if (sname[s] == s_new && skind[s] == K_FN) { + peek(); + if (pk_tk == T_OP && (pk_tv == s_star || pk_tv == s_lk)) { next(); return newtyped(); } + if (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) { next(); return newtyped(); } + } + if (sflag[s] & F_SIG) { tags = ssig[s] >> 6; ret = ssig[s] & 1; } + else sflag[s] = sflag[s] | F_UNTYPED; + wfill(bs, 0, 8); + if (ngbind) { wcopy(bs, gbind, ngbind); ngbind = 0; } + np = args(tags, ft, bs); + 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; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + if (ret) return C_FRESH; + return C_PLAIN; +} +// an enhancement used like a function: the arguments, then its one opcode +fn enhcall(s) +{ + let nin = ssig[s] & 15, nout = (ssig[s] >> 4) & 15, n = 0, c; + expect(s_lp); + if (!is_op(s_rp)) { while (1) { c = expr(); rval(); plainuse(c); n++; if (!accept(s_comma)) break; } } + expect(s_rp); + if (n != nin) dien(sname[s], "wrong number of inputs"); + lv = 0; lvk = LV_NONE; xty = tword; xzero = 0; + if (sflag[s] & F_FALLBACK) { fnref(sfix[s] - 1); op(O_CALL); return C_PLAIN; } + op(XOP0 + sval[s]); + if (nout == 0) lit(0); + if (nout > 1) dien(sname[s], "leaves several values; use it from asm"); + return C_PLAIN; +} +fn primary() +{ + let n, i, s, c; + lv = 0; lvk = LV_NONE; xzero = 0; + if (tk == T_NUM) { lit(tv); xzero = tv == 0; xty = tint; next(); return C_PLAIN; } + if (tk == T_STR) { strlit(tv); next(); xty = tptr(tchar); 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]); + xty = ltype[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); + } + if (s >= 0 && skind[s] == K_TYPE) dien(n, "is a type, not a value"); + next(); + xty = tword; + if (s >= 0 && skind[s] == K_CONST) { lit(sval[s]); xty = tint; xzero = sval[s] == 0; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GVAR) { lit(sval[s]); if (stype[s]) xty = stype[s]; lv = 1; lvk = LV_GLOBAL; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GARR) { lit(sval[s]); if (stype[s]) xty = stype[s]; return C_PLAIN; } + if (s >= 0 && skind[s] == K_ENH) return enhcall(s); + if (s < 0) s = fwdfn(n); + if (is_op(s_lt) && (sflag[s] & F_GEN)) { // f(...) + next(); ngbind = 0; + while (1) { if (ngbind >= 8) die("too many type arguments"); gbind[ngbind] = ptype(); ngbind++; if (!accept(s_comma)) break; } + closeangle(); + if (!is_op(s_lp)) die("expected ( after the type arguments"); + } + if (is_op(s_lp)) return call(s); + fnref(s); + if (stype[s]) xty = stype[s]; + return C_PLAIN; +} +// ++ and -- on the address at the top of the stack +fn incdec(post, dlt) +{ + 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"); + tcneed(isnum(xty) || xty[0] == TY_PTR || xty == tword, "++ and -- need a number or a pointer", xty); + lv = 0; lvk = LV_NONE; xzero = 0; + lit(0); op(O_PICK); op(O_LD); + if (post) { lit(0); op(O_PICK); lit(dlt); op(O_ADD); lit(2); op(O_PICK); op(O_ST); } + else { lit(dlt); 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; +} +// p.x and p->x: a field of a struct, or of the struct a pointer points at +fn field(c) +{ + let n, st, i, b = -1; + next(); + n = name(); + rval(); + if (c == C_FRESH) cerr("use a field of a new object only after binding it to a name"); + else if (c >= C_VAR) { touch(c - C_VAR); b = c - C_VAR; } + st = xty; + if (st[0] == TY_PTR) st = st[4]; + if (st[0] != TY_STRUCT) { puts("zc: line "); putn(tline); puts(": ."); puts(n); puts(": that's a "); tprint(xty); puts(", not a struct or a pointer to one\n"); halt(); } + i = tfindfield(st, n); + if (i < 0) { puts("zc: line "); putn(tline); puts(": "); tprint(st); puts(" has no field "); puts(n); putc(10); halt(); } + if (st[4][i * 3 + 2]) { lit(st[4][i * 3 + 2]); op(O_ADD); } + xty = st[4][i * 3 + 1]; + lv = 1; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + return C_PLAIN; +} +fn postfix() +{ + let c = primary(), b, n, t, et, ft, bs[8]; + while (1) { + if (tk == T_ID && tv == s_as) { // e as T: same bits, another type + next(); t = ptype(); rval(); xty = 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; } + tcneed(isptr(xty) || xty == tword, "only pointers and arrays can be indexed", xty); + et = telem(xty); + c = expr(); rval(); plainuse(c); + tcneed(isnum(xty) || xty == tword, "an index has to be a number", xty); + expect(s_rk); + if (tsz(et) != 1) { lit(tsz(et)); op(15); } + op(O_ADD); + lv = 1; xty = et; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + c = C_PLAIN; + continue; + } + if (tv == s_dot || tv == s_arrow) { c = field(c); continue; } + if (tv == s_lp) { // call through a value + rval(); plainuse(c); + ft = 0; + if (xty[0] == TY_FN) ft = xty; + else tcneed(xty == tword, "only functions can be called", xty); + wfill(bs, 0, 8); + n = args(0, ft, bs); + lit(n); op(O_PICK); op(O_CALL); op(O_SWAP); op(O_DROP); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + 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() +{ + let c, un, t; + if (tk == T_ID && (tv == s_u || tv == s_m || tv == s_d)) { // u*x, d*x, m*x: recast + t = S_M; if (tv == s_u) t = S_U; if (tv == s_d) t = S_D; + next(); expect(s_star); + c = unary(); rval(); + lvk = LV_NONE; + return recast(c, t); + } + if (tk == T_OP) { + if (tv == s_star) { + next(); c = unary(); rval(); plainuse(c); + tcneed(xty[0] == TY_PTR || xty == tword, "only pointers can be dereferenced", xty); + xty = telem(xty); + lv = 1; lvk = LV_OTHER; xzero = 0; + return C_PLAIN; + } + if (tv == s_amp) { + next(); c = unary(); + if (!lv && !isagg(xty)) die("& needs something addressable"); + if (c >= C_VAR) touch(c - C_VAR); + lv = 0; lvk = LV_NONE; xzero = 0; + xty = tptr(xty); + return C_PLAIN; + } + if (tv == s_inc) { next(); unary(); return incdec(0, 1); } + if (tv == s_dec) { next(); unary(); return incdec(0, -1); } + un = unfind(tv); + if (un >= 0) { + next(); c = unary(); rval(); plainuse(c); + emitseq(useq[un], ulen[un]); + if (un <= 1) xty = tbool; + else if (xty != tword) { tcneed(isnum(xty), "this operator needs a number", xty); xty = tint; } + lv = 0; lvk = LV_NONE; xzero = 0; + return C_PLAIN; + } + } + return postfix(); +} +fn bin(minp) +{ + let c = unary(), b, p, a, j, lt; + while (tk == T_OP) { + b = binfind(tv); + if (b < 0) return c; + p = bprec[b]; + if (p < minp) return c; + next(); rval(); plainuse(c); + lt = xty; + 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]); + } + xty = bintype(b, lt, xty); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; + } + 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() +{ + let c = bin(1), k, i, a, rc, lt; + if (tk != T_OP) return c; + if (tv == s_eq) { + if (!lv) die("this can't be assigned to"); + k = lvk; i = lvi; lt = xty; + if (isagg(lt)) die("a whole struct or array can't be assigned; assign its fields"); + next(); + rc = expr(); rval(); + if (!compat(lt, xty)) tcerr("assignment", lt, xty); + storekeep(); + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + 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"); + lt = xty; + next(); + lit(0); op(O_PICK); op(O_LD); + lv = 0; + rc = expr(); rval(); plainuse(rc); + emitseq(bseq[abin[a]], blen[abin[a]]); + k = bintype(abin[a], lt, xty); + if (!compat(lt, k)) tcerr("compound assignment", lt, k); + storekeep(); + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + return C_PLAIN; + } + return c; +} +// does the current token start a statement rather than an expression? +fn stmtstart() +{ + let s; + if (tk == T_OP) return tv == s_semi || tv == s_lb || tstart(); + if (tk != T_ID || findloc(tv) >= 0) return 0; + if (tstart()) return 1; + 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() +{ + let save = nloc, c = C_PLAIN, tail = 0, t = tint; + 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; t = xty; + } + next(); + if (tail) c = handup(c); else lit(0); + block_close(save); + fdepth--; bxdepth--; + lv = 0; lvk = LV_NONE; xty = t; xzero = 0; + return c; +} + +// ---- constant expressions ---- +fn cprim() +{ + let 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() +{ + let 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() +{ + let 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 (tstart()) { localdecl(1); 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() +{ + let 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() +{ + let save = nloc; + if (is_op(s_lb)) return block(); + fdepth++; + stmt(); + block_close(save); + fdepth--; + return 0; +} +// let a = e, b[10]; or, typed: int a = 1, b; *node.m p = new(node); .u r; +// let infers pointer, struct and function types from the initializer and +// keeps numbers as plain words. +fn localdecl(typed) +{ + let n, i, c, k, t = 0, tg = 0; + if (typed) { dtype(); t = dty; tg = dtag; if (t == tvoid) die("a variable can't be void"); } + while (1) { + n = name(); + i = newloc(n); + ltag[i] = tg; + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + if (!t) t = tword; + larr[i] = 1; ltype[i] = tarr(t, k); fslots = fslots + tsz(ltype[i]); + } else if (t && isagg(t)) { larr[i] = 1; ltype[i] = t; fslots = fslots + tsz(t); } + else { fslots++; if (t) ltype[i] = t; } + if (accept(s_eq)) { + if (larr[i]) die("an array or a struct can't be initialized with ="); + c = expr(); rval(); laddr(lslot[i]); op(O_ST); + if (t) { if (!compat(t, xty)) tcerr("initializer", t, xty); } + else if (!isnum(xty)) ltype[i] = xty; + assigncheck(LV_LOCAL, i, c); + } + if (!accept(s_comma)) break; + } + expect(s_semi); + return 0; +} +fn kw_var() { stmtonly(); next(); return localdecl(0); } +fn kw_if() +{ + let 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) +{ + let 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() +{ + let 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() +{ + let save = nloc, s0, c0, a, b, st, c; + stmtonly(); + next(); + expect(s_lp); + fdepth++; + if (is_id(s_var)) kw_var(); + else if (tstart()) localdecl(1); + 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); + st = here; + if (!is_op(s_rp)) { c = expr(); rval(); op(O_DROP); discard(c); } + expect(s_rp); + jmp(c0); + setlit(b, here); + loop_push(st, s0); + substmt(); + loopcheck(s0); + jmp(st); + 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() +{ + let 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() +{ + let f = R_LOOP + (lsp - 1) * 6; + stmtonly(); + next(); expect(s_semi); + loopexit(f); + jmp(f[0]); + live = 0; + return 0; +} +fn kw_return() +{ + let 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(); + if (fty == tvoid) tcerr("return value", tvoid, xty); + else if (fty && !compat(fty, xty)) tcerr("return value", fty, xty); + } + 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() +{ + let 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() +{ + let 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_ENH) { op(XOP0 + sval[s]); next(); continue; } + 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 +{ + let 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 u*q; +} +unchecked fn qnew(src) -> .u { let n = src[0] * 2 + 1, q = new(n); wcopy(q, src, n); return q; } +fn qdup(.m q) -> .u { let n = q[0] * 2 + 1, r = new(n); wcopy(r, q, n); return u*r; } +fn wcopyto(.m q, n) { let i = 0; while (i < n) { emit(q[i]); i++; } return 0; } +fn kw_quote() +{ + let q, j, a, n; + next(); + q = grab(); + j = hole(); op(O_JMP); + a = here; + n = q[0] * 2 + 1; + wcopyto(q, n); + free(d*q); + 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 +{ + let 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 u*q; +} +// 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() +{ + let 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; + f[19] = fty; f[20] = ntp; f[21] = xty; wcopy(f + 22, tpn, 2); + return 0; +} +fn ctx_pop() +{ + let 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]; + fty = f[19]; ntp = f[20]; xty = f[21]; wcopy(tpn, f + 22, 2); + return 0; +} + +// ---- functions and the top level ---- +fn fn_begin(chk, ret) +{ + lbase = nloc; fdepth = 1; fslots = 0; fchk = chk && check_on; fret = ret; fty = 0; + 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 name(int a, *node.m n, .d x, b) -> *list.u { ... } +fn fndef(chk) +{ + let n, s, np = 0, tags = 0, t, ret = 0, sig, i, pn[24], pt[24], pty[24], rty = 0, typed = 0, ft; + next(); + n = name(); + ntp = 0; + if (is_op(s_lt)) { // type parameters + next(); + while (1) { if (ntp >= 8) die("too many type parameters"); tpn[ntp] = name(); ntp++; if (!accept(s_comma)) break; } + closeangle(); + typed = 1; + } + 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; + pty[np] = tword; + if (!is_op(s_dot) && ((tk == T_OP && (tv == s_star || tv == s_lk)) || (tk == T_ID && (tv == s_fn || istypename(tv))))) { + pty[np] = ptype(); typed = 1; + if (isagg(pty[np])) die("structs and arrays are passed by pointer"); + } + if (accept(s_dot)) { // .m lends, .d takes over + if (tv == s_m) t = 1; else if (tv == s_d) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + 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_op(s_dot)) { rty = ptype(); typed = 1; } + if (accept(s_dot)) { if (!is_id(s_u)) die("the 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 (ntp) sflag[s] = sflag[s] | F_GEN; + if (typed) { + if (!rty) rty = tword; + ft = tfn(rty, np, pty, sig); + if (stype[s] && stype[s] != ft) dien(n, "doesn't match its earlier declaration"); + stype[s] = ft; + } + if (accept(s_semi)) { ntp = 0; 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); + if (typed) fty = rty; + prologue(); + i = 0; + while (i < np) { + t = newloc(pn[i]); fslots++; + ltype[t] = pty[i]; + 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(); + ntp = 0; + return s; +} +// let g = 1, buf[10]; int g = 3; [10]int buf; point origin; +fn gdecl(typed) +{ + let n, a, k, t = 0, s; + if (typed) { dtype(); t = dty; if (dtag) die("tags go on locals and parameters, not globals"); if (t == tvoid) die("a variable can't be void"); } + else next(); + while (1) { + n = name(); + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + s = addsym(n, K_GARR, here); + if (!t) t = tword; + stype[s] = tarr(t, k); + k = tsz(stype[s]); + while (k) { emit(0); k--; } + } else if (t && isagg(t)) { + s = addsym(n, K_GARR, here); stype[s] = t; + k = tsz(t); + while (k) { emit(0); k--; } + } else { + a = here; + s = addsym(n, K_GVAR, a); + if (t) stype[s] = t; + 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() +{ + let n; + next(); + while (1) { n = name(); expect(s_eq); addsym(n, K_CONST, cexpr()); if (!accept(s_comma)) break; } + expect(s_semi); + return 0; +} +// enhance name(a, b) [-> n] micro "recipe" [else fn]; +// enhance name(a, b) [-> n] vm { asm } [else fn]; +// lays out the descriptor the install opcode reads, and wires it in right +// away (an image wires its own in when it boots). +fn enhdef() +{ + let n, np = 0, nout = 1, dsc, na, pay, len = 0, kind = 0, i, p, s, slot, r, pn[8]; + next(); + n = name(); + expect(s_lp); + if (!is_op(s_rp)) { while (1) { if (np == 8) die("an enhancement takes at most 8 inputs"); pn[np] = name(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + if (accept(s_arrow)) { if (tk != T_NUM || tv < 0 || tv > 8) die("expected the number of outputs"); nout = tv; next(); } + dsc = here; i = 0; while (i < 7) { emit(0); i++; } + na = here; i = 0; while (i < np) { emit(0); i++; } + i = 0; + while (i < np) { *(na + i + hdelta) = here; p = pn[i]; while (*p) { emit(*p); p++; } emit(0); i++; } + if (accept(s_micro)) { + pay = here; + if (tk != T_STR) die("expected the recipe as a string"); + while (tk == T_STR) { p = tv; while (*p) { emit(*p); p++; } next(); } + emit(0); + } else if (accept(s_vm)) { pay = here; asmblock(); op(O_RET); len = here - pay; kind = 1; } + else die("expected micro or vm"); + slot = nenh; + if (slot >= 512) die("all 512 enhancement slots are taken"); + nenh++; + p = dsc + hdelta; + p[0] = slot; p[1] = kind; p[2] = np; p[3] = nout; p[4] = pay; p[5] = len; p[6] = na; + s = addsym(n, K_ENH, slot); + ssig[s] = np + nout * 16 + dsc * 256; + if (accept(s_else)) { r = lookup(tv); if (r < 0) r = fwdfn(tv); next(); sfix[s] = r + 1; } + expect(s_semi); + if (!hdelta) { + r = install(dsc); + if (r < 0) { + if (!sfix[s]) { puts("zc: line "); putn(tline); puts(": "); puts(n); puts(": the enhancement didn't install ("); putn(r); puts(")\n"); halt(); } + sflag[s] = sflag[s] | F_FALLBACK; + } + } + return 0; +} +fn topitem() +{ + let 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 gdecl(0); + if (is_id(s_struct)) { kw_struct(); return 0; } + if (is_id(s_type)) return kw_type(); + if (is_id(s_typecheck)) return kw_typecheck(); + if (is_id(s_enhance)) return enhdef(); + 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; } + } + if (tstart()) return gdecl(1); + die("expected fn, let, const, struct, type or a declaration"); + return 0; +} +fn unit_top() { while (tk != T_EOF) topitem(); return 0; } +fn unit_end(from) +{ + let 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(q, top) +{ + let 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(q) { return compile_list(q, 0); } +fn load(q) { compile_list(q, 1); return 0; } +fn eval(q) { let f = compile_list(q, 0); return f(); } +fn evals(s) { let q = tokens(s), r = eval(q); free(d*q); 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) +{ + let i = from, p; + while (i < nsym) { + if ((skind[i] >= K_FN && skind[i] <= K_CONST) || skind[i] == K_ENH) { + 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) +{ + let 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; + if (p[0] == K_ENH) { if (p[1] >= nenh) nenh = p[1] + 1; install(p[2] >> 8); } + 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) +{ + let sh = here, sd = hdelta, sl = hlimit, sub = ubase, svl = vislo, sns = nsym, sen = nenh, n; + ubase = nsym; vislo = nsym; nenh = 0; + 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; nenh = sen; + 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 + 512); + 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_dot = intern("."); s_andand = intern("&&"); s_oror = intern("||"); + s_fn = intern("fn"); s_var = intern("let"); 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"); + s_enhance = intern("enhance"); s_micro = intern("micro"); s_vm = intern("vm"); + 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, "idiv"); // native divide, wired in by rt.zc + add_binop("%", 10, "imod"); + add_binop("+", 9, "+"); // 3 + add_binop("-", 9, "-"); // 4 + add_binop("<<", 8, "ishl"); // 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("let", 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); + add_kw("sizeof", kw_sizeof, F_EXPR); + add_kw("typeof", kw_typeof, F_EXPR); + return 0; +} +fn start() +{ + let s, f; + heap_init(); + zc_init(); + blob_load(GORG[5]); + zc_tables(); + types_init(); + 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/11-types-enhancements/code/src/rt.zc b/docs/history/11-types-enhancements/code/src/rt.zc new file mode 100644 index 0000000..750a2fe --- /dev/null +++ b/docs/history/11-types-enhancements/code/src/rt.zc @@ -0,0 +1,183 @@ +// ============================================================================ +// 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; + +// ---- virtual enhancements ---- +// install(desc) wires a custom opcode into the cpu (the % opcode). these three +// give the language native division and left shift (zdiv, zmod and zshl +// below are the same thing done in software). they come first, since the +// compiler resolves / % and << to them by name. +fn install(desc) { return asm { desc @ % }; } +enhance idiv(a, b) micro "a = sdiv a b"; +enhance imod(a, b) micro "a = srem a b"; +enhance ishl(a, b) micro "a = shl a b"; + +// ---- 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(s) { let i = 0; while (s[i]) { putc(s[i]); i++; } return 0; } +fn putn(n) +{ + let 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(s) { let n = 0; while (s[n]) n++; return n; } +fn streq(a, b) { let i = 0; while (a[i] && a[i] == b[i]) i++; return a[i] == b[i]; } +fn wcopy(dst, src, n) { let i = 0; while (i < n) { dst[i] = src[i]; i++; } return 0; } +fn wfill(dst, v, n) { let i = 0; while (i < n) { dst[i] = v; i++; } return 0; } + +// ---- arithmetic the hardware doesn't have ---- +let pow2[32]; +let zrem; +fn zudiv(n, dv) +{ + let q = 0, r = 0, i = 30; + if (n < dv) { zrem = n; return 0; } + while (i >= 0) { + r = r + r + ((n >> i) & 1); + q = q + q; + if (r >= dv) { r = r - dv; q++; } + i--; + } + zrem = r; + return q; +} +fn zdiv(a, b) +{ + let 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) { let neg = a < 0; if (b == 0) return a; 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 6 word header before the +// pointer the program sees: +// p[-6] block size p[-5] size class p[-4] flags (1 live, 2 marked) +// p[-3] p ^ MAGIC p[-2] owner (the container that owns it, or 0) +// p[-1] its type (a type record from new(T), or 0 from new(n)) +// 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]). +const HDR = 6; +let hbump, freel[32], gc_runs, gc_freed, gc_auto = 1; + +fn heap_init() +{ + let 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(x) { return x >= HEAP_LO + HDR && x < hbump && x[-3] == (x ^ MAGIC) && (x[-4] & 1); } + +fn oom() { puts("zc: out of heap memory\n"); halt(); return 0; } +// n words typed t +unchecked fn new_t(n, t) -> .u +{ + let need = n + HDR, k = 3, sz = 8, b = 0, p; + if (n < 0) need = HDR; + while (sz < need) { sz = sz + sz; k++; } + if (freel[k]) { b = freel[k]; freel[k] = b[HDR]; } + 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[HDR]; } + else if (hbump + sz <= HEAP_HI) { b = hbump; hbump = hbump + sz; } + else oom(); + } + p = b + HDR; + b[0] = sz; b[1] = k; b[2] = 1; b[3] = p ^ MAGIC; b[4] = 0; b[5] = t; + wfill(p, 0, sz - HDR); + return p; +} +unchecked fn new(n) -> .u { return new_t(n, 0); } +fn osize(p) { if (!isobj(p)) return 0; return p[-6] - HDR; } +fn typeof_obj(p) { if (!isobj(p)) return 0; return p[-1]; } + +// frees p and, recursively, every object p owns +fn release(p) +{ + let b = p - HDR, n = b[0] - HDR, i = 0, w; + b[2] = 0; + while (i < n) { w = p[i]; if (isobj(w) && w[-2] == p) release(w); i++; } + b[4] = 0; + b[HDR] = 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[-2] = 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. +let ms_top, ms_over, gc_lo, gc_hi; +fn mark(w) +{ + if (!isobj(w) || (w[-4] & 2)) return 0; + w[-4] = w[-4] | 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() +{ + let p; + while (ms_top) { ms_top--; p = MARK0[ms_top]; markrange(p, p + p[-6] - HDR); } + return 0; +} +fn gc_roots(); +unchecked fn gc() +{ + let 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 + HDR, 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[HDR] = 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() { let b = HEAP_LO, n = 0; while (b < hbump) { if (b[2] & 1) n++; b = b + b[0]; } return n; } diff --git a/docs/history/11-types-enhancements/code/test.sh b/docs/history/11-types-enhancements/code/test.sh new file mode 100755 index 0000000..02fac14 --- /dev/null +++ b/docs/history/11-types-enhancements/code/test.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# full check: bootstraps the compiler from zc0, verifies the fixpoint, then runs +# the examples and tests on the portable interpreter (host), the arm64 jit under +# qemu, and the llvm backend. needs gcc; the jit half needs aarch64-linux-gnu-gcc +# and qemu-aarch64, the llvm half needs llvm-config and libLLVM (each is skipped +# if 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 < examples/typed.zc | tr '\n' '/')" "last: 4/point is 2 words: x int, y int/vec<*point> is 3 words: len int, cap int, items **point/push is fn(*vec, T.d) -> bool/the heap says v is a vec, and v.items[0] is a point/" "$l typed example" + chk "$($vm < examples/wiring.zc)" "16 1234 25 4/9" "$l enhancement example" + 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" + chk "$($vm < tests/types.zc | tr '\n' '/')" "12 5 2 15 56 42 7 14 3/rect *rect *list fn(int) -> *list.u fn(*list) -> T fn(word.d)/a:point@0 b:point@2 tag:int@4 /point 1 1/" "$l types, generics, reflection" + chk "$($vm < tests/typeok.zc)" "14" "$l a program the typechecker accepts" + chk "$($vm < tests/typeoff.zc)" "6" "$l the typechecker is off by default" + chk "$($vm < tests/enhance.zc)" "100 0 343 3,2 5 -2 0" "$l virtual enhancements" + local r; r=$(tests/runerr.sh "$vm" tests/errors | tail -1) + chk "$r" "rejected: $(ls tests/errors/*.zc | wc -l) passed, 0 failed" "$l analyzer rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/typeerrors | tail -1) + chk "$r" "rejected: $(ls tests/typeerrors/*.zc | wc -l) passed, 0 failed" "$l typechecker 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 +if command -v llvm-config >/dev/null; then + gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c -o $T/zyl $(llvm-config --ldflags --libs) || exit 1 + run $T/zyl "llvm" + printf '#!/bin/sh\nZYHOT=1 exec %s "$@"\n' $T/zyl > $T/llall; chmod +x $T/llall + chk "$($T/llall < tests/types.zc | md5sum)" "$($T/zy < tests/types.zc | md5sum)" "llvm compiling every block agrees" + selfc $T/zyl $T/gl.bin; cmp -s $T/g1.bin $T/gl.bin && chk 1 1 "llvm self-compile matches" || chk 0 1 "llvm self-compile matches" +else echo "skip llvm (no llvm-config)"; fi +echo "$ok passed, $bad failed"; [ $bad = 0 ] diff --git a/docs/history/11-types-enhancements/code/tests/basics.zc b/docs/history/11-types-enhancements/code/tests/basics.zc new file mode 100644 index 0000000..c1f1faf --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/basics.zc @@ -0,0 +1,22 @@ +let table[10]; +let 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() +{ + let i, s = 0, a[5]; + for (i = 0; i < N; i++) table[i] = i * i; + for (let 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); + let b = { let 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); + let x = asm { 2 3 + }; + putn(x); putc(10); + asm { 'o' . 'k' . 10 . } + return 0; +} diff --git a/docs/history/11-types-enhancements/code/tests/enhance.zc b/docs/history/11-types-enhancements/code/tests/enhance.zc new file mode 100644 index 0000000..6acc742 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/enhance.zc @@ -0,0 +1,29 @@ +// custom opcodes: recipes, lifted vm code, several outputs, and a fallback +enhance clampadd(a, b) micro "a = add a b; a = min a 100; a = max a 0"; +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance divmod(a, b) -> 2 micro "r2 = sdiv a b" "\n r1 = srem a b\n r0 = r2"; +enhance div7(a) micro "a = sdiv a 7"; +enhance urem10(a) micro "a = urem a 10"; +enhance hi(a, b) micro "a = mulhu a b"; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // i/o can't be lifted, so calls use the fallback +fn soft_noisy(x) { return x + 1; } +let qq, rr, seed = 7; +fn rnd() { seed = seed * 1103515245 + 12345; return seed ^ (seed >> 11); } +fn main() +{ + let i = 0, a, bad = 0; + putn(clampadd(70, 50)); putc(' '); putn(clampadd(-50, 2)); putc(' '); putn(cube(7)); putc(' '); + asm { 17 5 divmod rr ! qq ! } + putn(qq); putc(','); putn(rr); putc(' '); + putn(noisy(4)); putc(' '); + putn(hi(-1, -1)); putc(' '); + while (i < 5000) { + a = rnd(); + if (div7(a) != zdiv(a, 7)) bad++; + if (urem10(a) < 0 || urem10(a) > 9) bad++; + if (a / (i + 1) != zdiv(a, i + 1)) bad++; + i++; + } + putn(bad); putc(10); + return 0; +} diff --git a/docs/history/11-types-enhancements/code/tests/errors/back_to_m.zc b/docs/history/11-types-enhancements/code/tests/errors/back_to_m.zc new file mode 100644 index 0000000..b8c160f --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/back_to_m.zc @@ -0,0 +1,2 @@ +// expect: x: can't be recast back to m +fn main() { let x = new(3); d*x; m*x; return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/borrow_escape.zc b/docs/history/11-types-enhancements/code/tests/errors/borrow_escape.zc new file mode 100644 index 0000000..ce24480 --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let x = new(1); f(x); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/branch_mismatch.zc b/docs/history/11-types-enhancements/code/tests/errors/branch_mismatch.zc new file mode 100644 index 0000000..a8498f8 --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let x = new(1); d*x; if (x[0]) take(x); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/child_dies.zc b/docs/history/11-types-enhancements/code/tests/errors/child_dies.zc new file mode 100644 index 0000000..67caca9 --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let p = new(2), c = new(1); p[0] = c; take(d*p); return c[0]; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/child_recast.zc b/docs/history/11-types-enhancements/code/tests/errors/child_recast.zc new file mode 100644 index 0000000..c9ccd62 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/child_recast.zc @@ -0,0 +1,2 @@ +// expect: c: belongs to a container; recast the container instead +fn main() { let p = new(2), c = new(1); p[0] = c; d*c; return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/copy_owned.zc b/docs/history/11-types-enhancements/code/tests/errors/copy_owned.zc new file mode 100644 index 0000000..862c7ef --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/copy_owned.zc @@ -0,0 +1,2 @@ +// expect: x: is an owned object and can't be copied +fn main() { let x = new(1); let y = x; return y[0]; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/d_into_block.zc b/docs/history/11-types-enhancements/code/tests/errors/d_into_block.zc new file mode 100644 index 0000000..2d7f526 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/d_into_block.zc @@ -0,0 +1,2 @@ +// expect: x: used after it was given away +fn main() { let x = new(1); d*x; { x[0] = 5; } return x[0]; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/d_kept.zc b/docs/history/11-types-enhancements/code/tests/errors/d_kept.zc new file mode 100644 index 0000000..dcbfb86 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/d_kept.zc @@ -0,0 +1,2 @@ +// expect: x: d object was never given away +fn main() { let x = new(3); d*x; x[0] = 1; return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/discard_u.zc b/docs/history/11-types-enhancements/code/tests/errors/discard_u.zc new file mode 100644 index 0000000..dd76e94 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/discard_u.zc @@ -0,0 +1,3 @@ +// expect: can't be thrown away +fn mk() -> .u { let p = new(1); return u*p; } +fn main() { mk(); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/give_m.zc b/docs/history/11-types-enhancements/code/tests/errors/give_m.zc new file mode 100644 index 0000000..cd67896 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/give_m.zc @@ -0,0 +1,3 @@ +// expect: x: is m; write d*x +fn take(.d p) { return p[0]; } +fn main() { let x = new(3); take(x); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/global_store.zc b/docs/history/11-types-enhancements/code/tests/errors/global_store.zc new file mode 100644 index 0000000..dc0e546 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/global_store.zc @@ -0,0 +1,3 @@ +// expect: x: must be d to be stored in a global +let g; +fn main() { let x = new(1); g = x; return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/leak_overwrite.zc b/docs/history/11-types-enhancements/code/tests/errors/leak_overwrite.zc new file mode 100644 index 0000000..d19b5fd --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/leak_overwrite.zc @@ -0,0 +1,2 @@ +// expect: x: still owns an object +fn main() { let x = new(1); x = new(2); return x[0]; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/lend_d.zc b/docs/history/11-types-enhancements/code/tests/errors/lend_d.zc new file mode 100644 index 0000000..55ac7e0 --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let x = new(3); d*x; look(x); take(x); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/loop_move.zc b/docs/history/11-types-enhancements/code/tests/errors/loop_move.zc new file mode 100644 index 0000000..6d2b8b2 --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let x = new(1); let i = 0; d*x; while (i < 3) { take(x); i++; } return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/plain_return.zc b/docs/history/11-types-enhancements/code/tests/errors/plain_return.zc new file mode 100644 index 0000000..4540714 --- /dev/null +++ b/docs/history/11-types-enhancements/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/11-types-enhancements/code/tests/errors/proto_needed.zc b/docs/history/11-types-enhancements/code/tests/errors/proto_needed.zc new file mode 100644 index 0000000..c4ab28a --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/proto_needed.zc @@ -0,0 +1,3 @@ +// expect: f: was called before its tags were declared +fn main() { let x = new(1); f(1); return x[0]; } +fn f(.d p) { return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/return_m.zc b/docs/history/11-types-enhancements/code/tests/errors/return_m.zc new file mode 100644 index 0000000..1acc4be --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/return_m.zc @@ -0,0 +1,3 @@ +// expect: x: has to be u to be returned +fn mk() -> .u { let x = new(1); return x; } +fn main() { let y = mk(); return y[0]; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/tag_mismatch.zc b/docs/history/11-types-enhancements/code/tests/errors/tag_mismatch.zc new file mode 100644 index 0000000..079f249 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/tag_mismatch.zc @@ -0,0 +1,2 @@ +// expect: c: its tag doesn't match its container's +fn main() { let p = new(2), c = new(1); u*p; p[0] = c; return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/u_dropped.zc b/docs/history/11-types-enhancements/code/tests/errors/u_dropped.zc new file mode 100644 index 0000000..e1ca68a --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/u_dropped.zc @@ -0,0 +1,2 @@ +// expect: x: u object must leave this block +fn main() { let x = new(3); u*x; return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/u_skip_level.zc b/docs/history/11-types-enhancements/code/tests/errors/u_skip_level.zc new file mode 100644 index 0000000..6caeeb3 --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let r; { { let t = new(1); u*t; r = t; } } return r[0]; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/unchecked_touch.zc b/docs/history/11-types-enhancements/code/tests/errors/unchecked_touch.zc new file mode 100644 index 0000000..141639d --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let x = new(1); unchecked { x[0] = 1; } return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/unused.zc b/docs/history/11-types-enhancements/code/tests/errors/unused.zc new file mode 100644 index 0000000..64aff1f --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/errors/unused.zc @@ -0,0 +1,2 @@ +// expect: x: m object is never used +fn main() { let x = new(3); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/errors/use_after_give.zc b/docs/history/11-types-enhancements/code/tests/errors/use_after_give.zc new file mode 100644 index 0000000..8a10922 --- /dev/null +++ b/docs/history/11-types-enhancements/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() { let x = new(3); take(d*x); return x[0]; } diff --git a/docs/history/11-types-enhancements/code/tests/gc.zc b/docs/history/11-types-enhancements/code/tests/gc.zc new file mode 100644 index 0000000..41f14a0 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/gc.zc @@ -0,0 +1,20 @@ +let keep; +unchecked fn churn(n) +{ + let i = 0, p; + while (i < n) { p = new(10); p[0] = i; if (i % 100 == 0) keep = p; i++; } + return 0; +} +fn main() +{ + let 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/11-types-enhancements/code/tests/meta.zc b/docs/history/11-types-enhancements/code/tests/meta.zc new file mode 100644 index 0000000..bc89454 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/meta.zc @@ -0,0 +1,46 @@ +fn ipow(a, b) { let 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() +{ + let 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() +{ + let n, body, i = 0; + next(); n = tv; next(); + body = grab(); + while (i < n) { feed(qdup(body)); i++; } + free(d*body); + 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); + let q = quote { putn(40 + 2); putc(10); return 7; }; + putn(q[0]); putc(' '); + putn(eval(q)); putc(10); + let f = compile(q); + putn(f()); putc(10); + free(d*q); + let defs = quote { fn sq(x) { return x * x; } }; + load(defs); + free(d*defs); + putn(evals("return sq(12);")); putc(10); + return 0; +} diff --git a/docs/history/11-types-enhancements/code/tests/misc.zc b/docs/history/11-types-enhancements/code/tests/misc.zc new file mode 100644 index 0000000..25fc53b --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/misc.zc @@ -0,0 +1,30 @@ +// ct { ... } runs a block while compiling and leaves its result as a constant +immediate fn ct() +{ + let q, v; + next(); + q = grab(); + v = eval(q); + free(d*q); + 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 { let 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() { let p = new(3); p[0] = 'o'; p[1] = 'k'; return p; } diff --git a/docs/history/11-types-enhancements/code/tests/runerr.sh b/docs/history/11-types-enhancements/code/tests/runerr.sh new file mode 100755 index 0000000..23ea054 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/runerr.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# runs every .zc in a folder (tests/errors by default) and checks the compiler +# rejects it with the message on its first line: // expect: ... +vm=${1:-zy}; dir=${2:-$(dirname "$0")/errors}; pass=0; fail=0 +for f in "$dir"/*.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 "rejected: $pass passed, $fail failed" diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/arg.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/arg.zc new file mode 100644 index 0000000..b762c19 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/arg.zc @@ -0,0 +1,5 @@ +// expect: type error: argument: expected *point, got *int +typecheck on; +struct point { int x, y; }; +fn f(*point p) -> int { return p.x; } +fn main() { *int q = new(int); f(q); free(d*q); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/arith.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/arith.zc new file mode 100644 index 0000000..76e3111 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/arith.zc @@ -0,0 +1,3 @@ +// expect: type error: arithmetic needs numbers, got *int +typecheck on; +fn main() { *int p = 0; int x = p * 2; return x; } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/assign.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/assign.zc new file mode 100644 index 0000000..8b8a888 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/assign.zc @@ -0,0 +1,3 @@ +// expect: type error: initializer: expected *char, got int +typecheck on; +fn main() { *char s = 5; return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/call.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/call.zc new file mode 100644 index 0000000..7b03dbf --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/call.zc @@ -0,0 +1,3 @@ +// expect: type error: only functions can be called, got int +typecheck on; +fn main() { int k = 3; return k(1); } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/deref.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/deref.zc new file mode 100644 index 0000000..ed030f5 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/deref.zc @@ -0,0 +1,3 @@ +// expect: type error: only pointers can be dereferenced, got int +typecheck on; +fn main() { int x = 3; return *x; } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/field.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/field.zc new file mode 100644 index 0000000..ba03697 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/field.zc @@ -0,0 +1,3 @@ +// expect: point has no field z +struct point { int x, y; }; +fn main() { point p; return p.z; } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/generic.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/generic.zc new file mode 100644 index 0000000..4a502ce --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/generic.zc @@ -0,0 +1,4 @@ +// expect: type error: argument: expected int, got *char +typecheck on; +fn same(T a, T b) -> T { return a; } +fn main() { return same(1, "x"); } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/notstruct.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/notstruct.zc new file mode 100644 index 0000000..0dff6bd --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/notstruct.zc @@ -0,0 +1,2 @@ +// expect: .x: that's a int, not a struct or a pointer to one +fn main() { int n = 1; return n.x; } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/ret.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/ret.zc new file mode 100644 index 0000000..cedd534 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/ret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected bool, got *char +typecheck on; +fn f() -> bool { return "no"; } +fn main() { return f(); } diff --git a/docs/history/11-types-enhancements/code/tests/typeerrors/voidret.zc b/docs/history/11-types-enhancements/code/tests/typeerrors/voidret.zc new file mode 100644 index 0000000..a897290 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeerrors/voidret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected void, got int +typecheck on; +fn f() -> void { return 3; } +fn main() { f(); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/typeoff.zc b/docs/history/11-types-enhancements/code/tests/typeoff.zc new file mode 100644 index 0000000..e44e450 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeoff.zc @@ -0,0 +1,2 @@ +// the typechecker is off unless asked for: this mismatch compiles and runs +fn main() { *char s = 5; putn(s as int + 1); putc(10); return 0; } diff --git a/docs/history/11-types-enhancements/code/tests/typeok.zc b/docs/history/11-types-enhancements/code/tests/typeok.zc new file mode 100644 index 0000000..3cdee0c --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/typeok.zc @@ -0,0 +1,22 @@ +// passes the typechecker: words mix with everything, literal 0 is null, +// arrays decay to pointers, generic calls bind their parameters +typecheck on; +struct pair { A a; B b; }; +fn mk(A x, B y) -> *pair.u { *pair p = new(pair); p.a = x; p.b = y; return u*p; } +fn left(*pair p) -> A { return p.a; } +fn strlen2(*char s) -> int { int n = 0; while (s[n]) n++; return n; } +fn main() -> int +{ + *pair p = mk(3, "four"); + int a = left(p); + *char s = p.b; + [8]char buf; + *char q = buf; + *int nothing = 0; + let w = 5; + int mixed = w + 1; + q[0] = 'h'; q[1] = 0; + putn(a + strlen2(s) + strlen2(buf) + mixed); putc(10); + free(d*p); + return 0; +} diff --git a/docs/history/11-types-enhancements/code/tests/types.zc b/docs/history/11-types-enhancements/code/tests/types.zc new file mode 100644 index 0000000..ccbbd26 --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/types.zc @@ -0,0 +1,57 @@ +struct point { int x, y; }; +struct rect { point a, b; int tag; }; +struct list { int len; *T items; }; +struct node { int v; *node next; }; +type num = int; + +int counter = 5; +[4]int squares; +point origin; + +fn area(*rect r) -> int { return (r.b.x - r.a.x) * (r.b.y - r.a.y); } +fn mklist(int cap) -> *list.u +{ + *list l = new(list); + l.len = 0; + l.items = new(T, cap) as *T; + return u*l; +} +fn first(*list l) -> T { return l.items[0]; } +fn sum(*node n) -> int { int s = 0; while (n) { s += n.v; n = n.next; } return s; } + +fn main() +{ + rect r; + r.a.x = 1; r.a.y = 2; r.b.x = 4; r.b.y = 6; + putn(area(&r)); putc(' '); + putn(sizeof(rect)); putc(' '); putn(sizeof(point)); putc(' '); putn(sizeof([3]rect)); putc(' '); + let p = new(point); // let infers *point + p.x = 7; p->y = 8; + putn(p.x * p.y); putc(' '); + free(d*p); + *list l = mklist(4); + l.items[0] = 42; l.len = 1; + putn(first(l)); putc(' '); + free(d*l); + *node a = new(node), b = new(node); + a.v = 3; b.v = 4; a.next = b; + putn(sum(a)); putc(' '); + free(d*a); // b went with it: a.next = b made a its owner + [3]point pts; + pts[2].y = 9; + putn(pts[2].y + counter); putc(' '); + num k = 3; + putn(k); putc(10); + + // reflection + tprint(typeof(r)); putc(' '); tprint(typeof(&r)); putc(' '); tprint(typeof(l)); putc(' '); + tprint(sigof(mklist)); putc(' '); tprint(sigof(first)); putc(' '); tprint(sigofs("free")); putc(10); + let t = typeof(r), i = 0; + while (i < tnfields(t)) { puts(tfname(t, i)); putc(':'); tprint(tftype(t, i)); putc('@'); putn(tfoff(t, i)); putc(' '); i++; } + putc(10); + *point q = new(point); + tprint(typeof_obj(q)); putc(' '); putn(typeof_obj(q) == typeof(point)); putc(' '); putn(tkind(typeof_obj(q)) == TY_STRUCT); + free(d*q); + putc(10); + return 0; +} diff --git a/docs/history/11-types-enhancements/code/tests/umd.zc b/docs/history/11-types-enhancements/code/tests/umd.zc new file mode 100644 index 0000000..ee463bf --- /dev/null +++ b/docs/history/11-types-enhancements/code/tests/umd.zc @@ -0,0 +1,52 @@ +// lists as [len, items...], items owned by the list +fn mklist(n) -> .u +{ + let l = new(n + 1); + l[0] = 0; + return u*l; +} +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn sum(.m l) { let s = 0, i = 1; while (i <= l[0]) { s += l[i][0]; i++; } return s; } +fn box(v) -> .u { let b = new(1); b[0] = v; return u*b; } +fn consume(.d b) { return b[0]; } + +fn main() +{ + let base = live_objects(); + { + let l = mklist(8); // u from mklist arrives m*here + let i = 0; + while (i < 5) { + let b = box(i * 10); // m in the loop body + d*b; // 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 + let outer; + { + let t = box(7); + u*t; + outer = t; + } + let v = { let w = box(8); u*w }; + putn(outer[0] + v[0]); putc(' '); + + // d given away to a callee + let g = box(99); + putn(consume(d*g)); putc(' '); + + // containers: child takes its parent's tag + let 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/11-types-enhancements/code/tools/build.zc b/docs/history/11-types-enhancements/code/tools/build.zc new file mode 100644 index 0000000..a38e97f --- /dev/null +++ b/docs/history/11-types-enhancements/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() +{ + let 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/11-types-enhancements/code/zc0.c b/docs/history/11-types-enhancements/code/zc0.c new file mode 100644 index 0000000..4df587e --- /dev/null +++ b/docs/history/11-types-enhancements/code/zc0.c @@ -0,0 +1,460 @@ +/* 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 +#include +#include +#include + +#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, K_KW, K_ENH }; +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, ""); 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 if (tk == T_ID && (!strcmp(ts, "u") || !strcmp(ts, "m") || !strcmp(ts, "d"))) { next(); expect("*"); unary(); } /* u*x: a recast, no code */ + 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("let") || 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("let") || 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 (accept(".")) { /* .m name, .d name */ + if (is("m")) t = 1; else if (is("d")) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + if (np < 12) tags += t << (2 * np); + strcpy(pn[np++], ident()); + } while (accept(",")); + expect(")"); + } + if (accept("->")) { expect("."); if (strcmp(ident(), "u")) die("the return tag is -> .u"); 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; +} +/* enhance name(params) [-> n] micro "recipe"; or ... vm { asm }; + emits the install descriptor; the booted genome installs it */ +static int nenh; +static void enhdef(void) +{ + char *n = ident(), pn[8][64]; int np = 0, nout = 1, d, na, pay, len = 0, i, j; Sym *s; + expect("("); + if (!accept(")")) { do { if (np == 8) die("at most 8 inputs"); strcpy(pn[np++], ident()); } while (accept(",")); expect(")"); } + if (accept("->")) { nout = tv; next(); } + d = here; for (i = 0; i < 7; i++) emit(0); + na = here; for (i = 0; i < np; i++) emit(0); + for (i = 0; i < np; i++) { img[na + i - GORG] = here; for (j = 0; pn[i][j]; j++) emit((unsigned char)pn[i][j]); emit(0); } + if (accept("micro")) { pay = here; while (tk == T_STR) { for (j = 0; ts[j]; j++) emit((unsigned char)ts[j]); next(); } emit(0); } + else if (accept("vm")) { pay = here; asmblock(); op(O_RET); len = here - pay; img[d + 1 - GORG] = 1; } + else die("expected micro or vm"); + img[d - GORG] = nenh; img[d + 2 - GORG] = np; img[d + 3 - GORG] = nout; + img[d + 4 - GORG] = pay; img[d + 5 - GORG] = len; img[d + 6 - GORG] = na; + s = add(n, K_ENH, nenh++); s->sig = np + nout * 16 + d * 256; + expect(";"); +} +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("enhance")) { enhdef(); continue; } + if (accept("let") || 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; +} diff --git a/docs/history/11-types-enhancements/notes.md b/docs/history/11-types-enhancements/notes.md new file mode 100644 index 0000000..ae79685 --- /dev/null +++ b/docs/history/11-types-enhancements/notes.md @@ -0,0 +1,73 @@ +# types, virtual enhancements, the llvm backend + +code/ next to this file is the tree at the end of this stage. + +## message 11 + +> progress report? +> add types please :) +> mostly as a compiler primitive though, plus type-inspection via reflection +> and a small optional typechecker (default off) +> oh and keep the stuff you write as a history scrapbook +> if it helps, add a path to the hardware which is called "virtual enhancements", and allows up to 512 custom operations to be compiled down via jit into hardware-level speeds and interoped directly into a fast path in the vm to become essentially custom wiring. useful for division and other stuff as a dynamic runtime path + +my answers to the clarifying questions, exactly: + +> types: words + structs + generics +> +> reflection: runtime type of heap objects, function signatures, typeof at compile time +> +> how an enhancement is defined: either actual C or llvm ir code or vm code or micro-ops passed through an optimizer. since for example, micro-ops and vm code are not sufficient for optimizing things like division +> +> scrapbook: notes + code snapshots + +**summary:** the progress report said the previous round was finished and shipped. i then laid out a plan where the core would compile c or llvm ir enhancement sources at runtime with the host toolchain and load the result. part of that reply was stopped by a safety check before it finished, so i stopped and checked in instead of building it. + +## message 12 + +> also make the umd syntax like `type.u name`, and casting is multiplication `u*name` +> ideally i'd prefer memory to be unlimited words growing until system oom, but 1m is fine +> core.c plain interp is also nice +> zc0.c own file is fine +> i mentioned llvm for portability to non-arm targets +> yes, d object semantic that was intended +> u object hands up one block and becomes an m, that's fine. the code can make it a u or a d or whatever +> explain your gaps more +> +> wait why safety check? what's wrong with that + +my answers to the clarifying questions, exactly: + +> declarations: c-style, var -> let +> +> tags on untyped values and the names u, m, d: names reserved, bare .u allowed, untype is m by default +> +> llvm: llvm jit backend (Recommended) + +**summary:** on the safety check: nothing was wrong with the request. my best guess was that it tripped on the plan for a program inside the vm handing source text to the system compiler and loading the result into the running process, since that pattern also shows up in malware. with llvm meant for portability, that path wasn't needed. the gaps got the longer explanations that are now under open ends above. then the round itself: + +**syntax.** declarations are c-style (`int x`, `*node.m p`), `let` replaces `var` for untyped and inferred declarations, tags are `.u .m .d` after the type or on their own, recasts are `u*x` / `d*x` / `m*x`, `u m d` are reserved, and an untagged parameter counts as an m lend. + +**types.** a compiler primitive: hash-consed records with structs, generic structs and functions, fixed arrays, function types, `typeof`/`sizeof`, `as` casts and a reflection api, with object headers carrying their type. the typechecker is off by default and turned on with `typecheck on;`. + +**virtual enhancements.** opcode 21 installs, 22 to 533 are the slots. micro-op recipes and lifted vm code go through an optimizer in the core (folding, cse, dce, multiply-high division by constants) and get inlined by both jits. the language's own `/ % <<` now run on them. + +**backends.** a tiered llvm backend (`-DZYLLVM`) for non-arm hosts. + +**bootstrap and history.** it still reaches its fixpoint on all three backends. `history/` holds notes for every stage and code from stages 7, 10 and 12. + +## working notes + +the first plan for enhancements had four source kinds: micro-op recipes, vm code, c and llvm ir. the last two would have been compiled at runtime by the host toolchain and loaded into the process. part of the reply describing that got stopped by a safety check, so i checked in instead of building it. the user's answer clarified that llvm was about portability, so llvm became a backend (vm blocks -> ir -> orc) and enhancements stayed with recipes and lifted vm code, both of which go through an optimizer in the core. + +order of work: the enhancement unit in core.c first, tested from zc with raw opcode words before the compiler knew about them (80000 random divisions against the software routine, including /0, INT_MIN/-1 and constant divisors through the magic-number path; the trace for x/7 came out as the textbook mulhs, add, sar, shr, add). then the syntax change, enhance declarations and native / % <<, then types, then the llvm backend, then tests, examples and docs. + +bugs along the way, kept here because they were instructive: +- the rebuild script compiled stage 0 against a stale copy of core.c that didn't know opcode 21, so the genome halted silently at boot. +- uses of % in rt.zc came before the `enhance imod` line, so they became forward function references that never resolved. the enhance lines moved to the top of the runtime. +- u, m and d becoming reserved meant renaming variables called d in the compiler and the runtime. +- stage 0 needs globals and constants declared before use, so the type tables had to move to the top of the compiler. +- i used `?:` in the compiler, which zc doesn't have. +- my own typed example lent heap points to a vector and let them be freed at the end of each loop pass, leaving dangling pointers. that's the untracked-alias gap from the open ends, and the example now hands them over with .d. + +numbers: the genome is 57463 words. the llvm tier runs a loop-and-recursion benchmark in 0.11 s against 0.40 s interpreted (threshold 5000), but takes about 1 s for the self-compile against 0.24 s, because compile time dominates short bursty work. O1 and O2 cost about the same here. everything also passes with ZYHOT=1, which compiles every block. diff --git a/docs/history/13-gap-fixes/code/README.md b/docs/history/13-gap-fixes/code/README.md new file mode 100644 index 0000000..ce56f28 --- /dev/null +++ b/docs/history/13-gap-fixes/code/README.md @@ -0,0 +1,422 @@ +# 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, compiled through llvm on other hosts if you build with it, or interpreted. 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, and 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. types are a compiler primitive, with structs, generics, reflection and an optional typechecker. a program can also wire up to 512 custom opcodes into the cpu (virtual enhancements), which the jits inline as native code. + +this folder has the latest code. `history/` is the scrapbook: notes for every stage, plus frozen code from the stages that still have it. + +## files + +`core.c` is the native core and the only native code at runtime: the arm64 jit, the llvm backend (behind `-DZYLLVM`), the portable interpreter, and the enhancement unit (recipe parser, vm-code lifter, optimizer and lowering). `src/rt.zc` is the runtime (i/o, the native division enhancements, 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` 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, an owning list, a repl, a typed program and an enhancement demo. `tests/` has feature tests, `tests/errors/` (programs the lifetime analyzer has to reject) and `tests/typeerrors/` (programs the typechecker has to reject). each of those starts with the message it expects, and `tests/runerr.sh` runs a folder of them. `test.sh` does the whole bootstrap and runs everything on all three backends. `history/` is the scrapbook. + +## build + +``` +cc -O2 core.c io_linux.c -o zy # io_linux.c provides Q, G and J +./zy `). `ZYNOLLVM=1` turns the llvm tier off. + +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, on every backend. + +## zc, the language + +it reads like c. underneath every value is a 32 bit word and memory is word addressed, so `p + 1` is the next word whatever `p` points at, and strings are one char per word with a 0 at the end. types are optional: untyped code is typed `word`, which goes with anything. + +``` +const N = 10; +[N]int table; // a global array +fn fib(int n) -> int { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +fn main() { + for (int i = 0; i < N; i++) table[i] = fib(i); + let sq = { let t = table[5]; t * t }; // a block is an expression too, its last line is its value + let x = asm { 2 3 + }; // raw vm code, leaves one value + putn(sq + x); putc(10); + return 0; +} +``` + +declarations are c-style, type first: `int a = 1, b;`, `*node p = new(node);`, `[4]char buf;`, `point origin;`. `let` declares without a type: it infers pointer, struct and function types from the initializer and keeps numbers as plain words, and `let a[10];` is an untyped array. statements are declarations, `if`/`else`, `while`, `for`, `switch`, `break`, `continue`, `return`, `{ }` blocks, `asm { }` and expressions. `switch (e) { case 1, 2: ... default: ... }` takes constant labels, and its cases don't fall through: each ends where the next begins, and `break` leaves early. operators are c's with c's precedence, including `c ? a : b`, plus `p.x` and `p->x` (the same thing: `.` goes through a pointer on its own), `e as T` to change a type without changing the bits, and the casts below. comparisons and `&& ||` give 0 or 1. `/`, `%` and `<<` compile to native enhancement opcodes. character literals, `0x` hex and the usual escapes are there. + +a unit is read whole and scanned for function signatures before it compiles, so calls can come before definitions, tags included, and prototypes are optional. `main` runs after the whole program has compiled. every function returns one word, 0 if it falls off the end. + +builtins from the runtime: `putc`, `getc`, `eof`, `puts`, `putn`, `halt`, `strlen`, `streq`, `wcopy`, `wfill`, `new`, `new_t`, `free`, `gc`, `isobj`, `osize`, `typeof_obj`, `live_objects`, `install`, `zdiv`, `zmod`, `zshl`. + +## memory model: u, m and d + +`new(n)` or `new(T)` gives back a fresh object. 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. a tag is written after the type, `*node.u p`, or alone, `.d x`. `u`, `m` and `d` are reserved words. + +**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, 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. the first time it's handed to a lower scope its life here is over: passing it to a `.d` parameter, 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. it has to leave this block for the one above, where it arrives as m. it leaves through `return` (the function's return type has to carry `.u`, like `-> *node.u` or just `-> .u`), as the value of a block expression, or by assignment to a variable of the directly enclosing block. letting it fall out of scope, or throwing away a u result, is an error. + +recasting is multiplication by the tag: `u*x`, `d*x`, `m*x`. it 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 declaration can carry a tag too, `.u r;`, and then whatever lands in it gets that tag. + +parameters: an untagged parameter is m from the caller's side, a lend, and the callee sees a plain word. `.m` makes it a checked borrow: the callee can read and write it but can't free it, return it, recast it or store it anywhere. `.d` hands the object over, and it arrives as m. + +``` +fn box(int v) -> *int.u { *int b = new(int); *b = v; return u*b; } +fn push(*list l, *int.d item) { l.items[l.len] = d*item; l.len++; return 0; } +``` + +containers own what you store in them. `p[i] = c` or `p.f = 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 gives the child away: it's dead here afterwards, and the caller's object owns it. 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 `d*`, and the mark-sweep collector takes it over. a fresh object can go straight in. + +where paths join (after an `if`, a loop, a `switch` or `?:`) every variable has to be in the same state on every path that reaches the join, with one exception. a variable that became d, or was given away, on some path is dead afterwards, and the compiler frees it on the paths where it's still alive, on their way in. a loop's exit state is the join of its `break`s and its normal exit, so giving something away and breaking is fine. what a loop can't do is give something away on a path that comes back around to the top, since the next pass would use it dead. a u object doesn't get the dead treatment: it still has to leave. + +### the analyzer + +it runs inside the compiler on every function, including code compiled at runtime by `eval` and friends, and reports each violation with a line number and the variable's name. the compiler keeps going after errors, up to 20: a syntax error skips to the next `;` or `}` (or the next top-level declaration), and analyzer and type errors just get reported, since the parse is still in step. a unit with errors doesn't run. `tests/errors/` has one small program per rule. 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 what it allocates belongs to the collector, and checked variables can't be touched from inside an unchecked block. + +## types + +types are a compiler primitive. the compiler keeps them as records in a type area at 0x9C000, hash-consed so the same type is always the same pointer. they stay in memory after compiling, so programs and parse words can look at them. + +``` +struct point { int x, y; }; +struct list { int len; *T items; }; +type num = int; +fn first(*list l) -> T { return l.items[0]; } +fn mk(int cap) -> *list.u { *list l = new(list); l.items = new(T, cap); return u*l; } +... +*list<*point> ps = mk<*point>(8); // explicit type arguments, or inferred from the arguments +``` + +the kinds are `word`, `int`, `char`, `bool`, `void`, pointers `*T`, fixed arrays `[n]T`, function types `fn(int, *char) -> int`, structs, generic structs and generic functions. structs and arrays live in place (in a frame, a global or inside another struct), and their value is their address, so they're passed around by pointer. `sizeof` counts words. type arguments have to be one word (a number, a pointer or another parameter), so a generic function is compiled once and works for every instance. indexing scales by the element's size, while plain pointer arithmetic stays in words, like b. `new(T)` and `new(T, n)` stamp the type into the object's header. + +### reflection + +`typeof(e)` and `typeof(T)` give a type record and `sizeof(...)` its size. both work on any expression, which is compiled dry and never runs. at runtime: `tkind(t)` (one of the `TY_` constants), `tsize`, `tname`, `tlen`, `tnfields`, `tfname(t, i)`, `tftype`, `tfoff`, `tret`, `tnparams`, `tparam`, `tparamtag` (the u/m/d tag of a parameter), `tretu`, `tnargs` and `targ` for generic instances, and `tprint(t)`. `sigof(f)` gives the type of a function by address (untyped ones get a signature built from their arity and tags), `sigofs("name")` by name, and `typeof_obj(p)` reads the type stamped on a heap object. + +### the typechecker + +off by default. `typecheck on;` turns it on for what follows and `typecheck off;` turns it back off (a parse word can flip `tc_on`). it checks initializers, assignments, arguments (unifying generic parameters), return values, arithmetic, comparisons, dereferencing, indexing and calls. `word` matches anything, numbers mix with each other, a literal 0 is a null pointer, and arrays decay to pointers. it stops at the first error, printing what it expected and what it got. `tests/typeerrors/` has one per rule. some things are checked whatever the setting, because the compiler needs them to generate code: field names, and field access on something that isn't a struct. + +## virtual enhancements + +the cpu has room for 512 custom opcodes (22 to 533), and opcode 21 (`%` in asm) installs one at runtime. it's the closest a soft cpu gets to rewiring itself. an enhancement takes up to 8 inputs off the data stack and leaves up to 8 outputs, and it's written one of two ways: + +``` +enhance clamp(x, lo, hi) micro "x = max x lo; x = min x hi"; +enhance divmod(a, b) -> 2 micro "r2 = sdiv a b; r1 = srem a b; r0 = r2"; +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // can't be lifted (it does i/o), so calls use the fallback +``` + +a micro recipe works on registers `r0`..`r15`, which the inputs arrive in (also under the parameter names), and the outputs leave from `r0` up. the micro-ops are `li mov add sub mul sdiv udiv srem urem and or xor shl shr sar neg not lt ltu eq ne min max minu maxu mulhs mulhu clz abs sel ld st`. a `vm` body is straight-line vm code that gets lifted by running it symbolically. both turn into ssa, and the core's optimizer folds constants, simplifies algebra, removes common subexpressions and dead code, and turns division by a constant into a multiply-high sequence (`ZYTRACE=1` prints the result). the arm64 jit then inlines the code at every use with registers allocated, the llvm backend inlines it as ir, and the interpreter runs the optimized list. if something doesn't fit in registers, the jit calls the interpreter for that op. + +an enhancement is called like a function when it has one output, or by name from asm. `enhance` installs at compile time, so the wiring is there before `main` runs, and a parse word can use it right away. an image installs its own enhancements when it boots, from its symbol table. that's how `/`, `%` and `<<` work: `rt.zc` declares `idiv`, `imod` and `ishl` as one-instruction recipes. `install(desc)` is the raw interface, and its descriptor format is documented in `core.c`. stores done by an enhancement don't invalidate compiled code, so use them for data. + +this replaces my first plan for enhancements, which compiled c or llvm ir sources at runtime. part of that reply got stopped by a safety check, and once it turned out llvm was meant for portability, it moved into the backend below instead. + +## the llvm backend + +a tiered jit for hosts the arm64 backend doesn't cover. the interpreter counts how often each block start gets reached, and a hot block is translated to llvm ir using the same block rules as the arm64 jit: it ends at call, jump, ret or halt, keeps going past a jz, and literal targets are fused. the ir goes through the O2 pipeline and gets compiled by orc's lljit. stores into compiled words drop the blocks covering them, like on arm64. it pays off for long-running code: a loop-and-recursion benchmark runs about 3.3x faster than the interpreter. short bursty work like the self-compile is slower, since compile time dominates there. `ZYHOT=1` compiles every block, which is a good stress test, and the test suite runs that way too. + +## the heap + +0x40000 to 0x9BFFF, managed by a buddy allocator. the heap is split into aligned power-of-two chunks, every block is a power of two words, and a freed block merges with its buddy whenever that one is free too, so freed space can be reused at any size. allocation finds the smallest free block that fits and splits it down. free blocks sit on a doubly linked list per class, so taking a buddy off its list during a merge is constant time. checked code frees deterministically. under that runs a mark-sweep collector, conservative and non-moving, which handles globals, unchecked code and anything given to it. it runs on `gc()`, which returns how many objects it freed, or when an allocation doesn't fit. the sweep frees through the same merging path. + +## code as data + +the compiler is in memory with your program and every name in it is callable. + +`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, enhancement names emit their opcode, and other names push the address of a variable or function. + +`quote { ... }` is a token list as a fresh object: `[n, kind, value, line, kind, value, line, ...]`, so errors inside a macro expansion point at the line the tokens came from, where names, strings and operators are interned pointers (`intern("while")` gets one). `tokens(s)` makes one from a string, and `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)` runs `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()`, `peek()` and `peekat(k)` (up to 4 tokens ahead), `tk`/`tv` (current token kind and value), `expect`, `accept`, `expr()`, `stmt()`, `substmt()`, `ptype()`, `emit`, `lit`, `op`, `hole`/`setlit` for jumps, and `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` partway through a 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 both. `mnem` is the asm mnemonic table, `q@!$_~cjzr,?.+-*&|^><%`, and can be rewritten. + +## the bootstrap + +`zc0.c` compiles the subset `compiler.zc` uses (no analyzer, types, quote, parse words or block expressions, but it does lay out `enhance` declarations) into a first genome. that genome compiles `compiler.zc` again on the vm. that's where the real compiler, the analyzer and native division first meet their own source, and `compiler.zc` passes its own lifetime checks. the result compiles itself into identical words, on all three backends, and that's the `genome.h` that ships (71014 words). an image build (`build_image(org, dst)`) compiles with only the image's own names visible (plus keywords and builtin types), writes code meant for one address into another, and appends a symbol table so the booted genome knows its own names and enhancements. + +## the instruction set + +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 21 % install +2 ! store 7 j jump 12 . out (G) 17 | or 22..533 enhancements +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, `c` and `j` take their target from the stack, and `%` is `(descriptor -- status)`. there's still no div or mod in the base set, because a divider can't finish in one cycle in hardware. an enhancement can add one. + +## memory map and abi + +memory is 1m (1048576) words. it could grow until the host runs out (literals already reach 1g words), but that would mean reserving the jit tables with mmap instead of static arrays, and 1m is plenty for now. + +``` +0x00000.. the program: code, with globals between functions +0x40000..0x9BFFF heap +0x9C000..0x9FFFF type records +0xA0000 frame pointer word +0xA0100..0xBFFFF 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. heap objects have a 6 word header: size, size class, flags, a check word, owner, type. + +## 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, install hook, enhancement fallback). + +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 dispatch stub that checks both stack pointers against their limits (kept in x24 and x25), bounds-checks the target, loads `tab[t]`, and branches straight to it when it's already compiled. otherwise it returns to c, which compiles the block and re-enters. enhancements are inlined: inputs load from the data stack into w0..w15, the optimized micro-ops run in registers with x16 and x17 as scratch, and the outputs go back. an install calls into c and then returns to the loop, which flushes every translation, since code built before the install may have inlined the old version. + +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. + +the stacks are checked. the data and return stacks are checked at every block exit on all three backends, so the cost is a couple of compares per block rather than per push. a block pushes at most about 1024 words, which the data stack limit leaves room for. overflowing either one stops the cpu with `zy: data stack overflow` or `zy: return stack overflow`. the frame stack is checked in every function prologue, which resets the frame pointer and stops with `zy: frame stack overflow`. + +platform: the darwin path uses `MAP_JIT`, `pthread_jit_write_protect_np` and `sys_icache_invalidate`. linux uses rwx mmap and `__builtin___clear_cache`. only linux arm64 has actually been run, under qemu. the darwin path follows apple's documented recipe but hasn't been tested, and under the hardened runtime it also needs the allow-jit entitlement. every host shares the same semantics: shift counts wrap at 32, stores outside memory are ignored, loads outside memory read 0, and jumping outside memory or to an unwired opcode halts. + +## test results + +`test.sh` passes all 83 checks on x86-64 linux: the fixpoint, an up-to-date `genome.h`, and then every example and feature test on the interpreter, on the arm64 jit under qemu, and on the llvm backend, all with identical output. it also covers joins and fixup frees (with a leak count), `switch` and `?:`, the buddy allocator, several errors in one run, and all three stack overflows. it checks that all 22 programs in `tests/errors/` and all 10 in `tests/typeerrors/` get rejected with the expected message on each backend, that llvm agrees when it compiles every block, and that the self-compile matches byte for byte on all three. separately, 80000 random divisions through enhancements matched the software routine, covering divide by zero, INT_MIN/-1, negatives and the magic-number path for constants. + +## open ends + +fixed in stage 13 (details in `history/13-gap-fixes`): branch and loop joins, free lists that never merged (now a buddy allocator), missing stack checks, stopping at the first error, macro line numbers, required prototypes, `d*` for storing into borrowed objects, `**` declarations, and `?:` and `switch`. still open: + +**untracked aliases.** the analyzer only follows bare variable names, so `let q = p + 0;` or `let c = list[1];` is a plain word nobody tracks, and it dangles once the owner is freed. two cheap fixes, and they combine well. at runtime: don't reuse a freed block right away. `free` would put it on a quarantine list, and the collector's next sweep only releases quarantined blocks that no word points at. the conservative mark already finds such words, so that's maybe 30 lines in rt.zc. a stale alias then reads a dead but intact block, and a second free through it is a no-op, because the header's flags say free. at compile time: now that there are types, a pointer-typed value computed from a tracked variable (`p + k`, `p.field`, `p[i]` when the element is a pointer) can carry a "borrowed from p" mark into the local it's stored in. using that local after `p` dies becomes an error. that's the same machinery children already use. + +**the conservative collector.** it scans the whole data stack region, because the vm can't read its own stack pointer, and stale words keep garbage alive a little longer. the fix is one base opcode that pushes the data stack depth, which is trivial in hardware since the register already exists. then the collector scans only the live part. zeroing a frame in the prologue would do the same for the frame stack, at a few words per call. + +**coarse invalidation.** a store to a covered word rescans every block, and an install flushes everything. three fixes, in order of payoff. first, index blocks by page (say 64 words): a covered store only looks at the blocks touching its page, and dropping a block only rebuilds the coverage bytes for that block. second, record which enhancement slots each translation inlines, so an install only drops those. third, on llvm, give each block its own resource tracker, so dropped code actually gets freed. + +**tiering on arm64.** answered when you asked: a run counter per block costs about 4 instructions per block entry, and a hot block could be relifted to ssa, optimized with the enhancement optimizer, and given registers instead of the memory stack. that's likely 2 to 4x on tight loops, and it would also beat llvm's warm-up on x86. not built yet. + +**generics are erased.** a generic function is compiled once, so the type stamped by `new(T)` inside it says `T`, and type arguments have to be one word. + +**the rest.** the prescan only knows tags, not types, so a call to a typed function that's defined further down gets `word` as its result type until the definition shows up. the llvm backend compiles one module per block, so it warms up slowly. stores done by enhancements don't invalidate compiled code. a parse word that changes the syntax can confuse the prescan. it only records signatures, though, and a real definition always overrides what the prescan guessed. + +--- + +## 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 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/`. + +### 11 + +> progress report? +> add types please :) +> mostly as a compiler primitive though, plus type-inspection via reflection +> and a small optional typechecker (default off) +> oh and keep the stuff you write as a history scrapbook +> if it helps, add a path to the hardware which is called "virtual enhancements", and allows up to 512 custom operations to be compiled down via jit into hardware-level speeds and interoped directly into a fast path in the vm to become essentially custom wiring. useful for division and other stuff as a dynamic runtime path + +my answers to the clarifying questions, exactly: + +> types: words + structs + generics +> +> reflection: runtime type of heap objects, function signatures, typeof at compile time +> +> how an enhancement is defined: either actual C or llvm ir code or vm code or micro-ops passed through an optimizer. since for example, micro-ops and vm code are not sufficient for optimizing things like division +> +> scrapbook: notes + code snapshots + +**summary:** the progress report said the previous round was finished and shipped. i then laid out a plan where the core would compile c or llvm ir enhancement sources at runtime with the host toolchain and load the result. part of that reply was stopped by a safety check before it finished, so i stopped and checked in instead of building it. + +### 12 + +> also make the umd syntax like `type.u name`, and casting is multiplication `u*name` +> ideally i'd prefer memory to be unlimited words growing until system oom, but 1m is fine +> core.c plain interp is also nice +> zc0.c own file is fine +> i mentioned llvm for portability to non-arm targets +> yes, d object semantic that was intended +> u object hands up one block and becomes an m, that's fine. the code can make it a u or a d or whatever +> explain your gaps more +> +> wait why safety check? what's wrong with that + +my answers to the clarifying questions, exactly: + +> declarations: c-style, var -> let +> +> tags on untyped values and the names u, m, d: names reserved, bare .u allowed, untype is m by default +> +> llvm: llvm jit backend (Recommended) + +**summary:** on the safety check: nothing was wrong with the request. my best guess was that it tripped on the plan for a program inside the vm handing source text to the system compiler and loading the result into the running process, since that pattern also shows up in malware. with llvm meant for portability, that path wasn't needed. the gaps got the longer explanations that are now under open ends above. then the round itself: + +**syntax.** declarations are c-style (`int x`, `*node.m p`), `let` replaces `var` for untyped and inferred declarations, tags are `.u .m .d` after the type or on their own, recasts are `u*x` / `d*x` / `m*x`, `u m d` are reserved, and an untagged parameter counts as an m lend. + +**types.** a compiler primitive: hash-consed records with structs, generic structs and functions, fixed arrays, function types, `typeof`/`sizeof`, `as` casts and a reflection api, with object headers carrying their type. the typechecker is off by default and turned on with `typecheck on;`. + +**virtual enhancements.** opcode 21 installs, 22 to 533 are the slots. micro-op recipes and lifted vm code go through an optimizer in the core (folding, cse, dce, multiply-high division by constants) and get inlined by both jits. the language's own `/ % <<` now run on them. + +**backends.** a tiered llvm backend (`-DZYLLVM`) for non-arm hosts. + +**bootstrap and history.** it still reaches its fixpoint on all three backends. `history/` holds notes for every stage and code from stages 7, 10 and this one (in 11-types-enhancements). + +### 13 + +> gaps +> 1. when there's a var state change to d, mark that var as dead by default for any other scope that can access it afterwards. u is fine since it just returns +> 2. any suggestions for a cheap fix? +> 3. it's fine, rare occurrence (probably?), suggest a fix +> 4. fix that +> 5. suggest a fix +> 6. fix +> 7. fix + +**summary:** the numbers followed the gap list from my previous chat message. here's what each one got. + +**1. joins.** a variable that became d, or was given away, on any path is dead after the join, and fixup code frees it on the paths that still own it. a loop's exit state is the join of its breaks and its normal exit. giving something away on a path that loops back is still an error. u and borrows don't get the dead treatment. + +**2, 3 and 5.** suggestions only, now under open ends: a quarantine on reuse plus "borrowed from" marks on pointer-typed values for aliases, a stack-depth opcode for the collector, and page-indexed invalidation plus per-slot install tracking for the jit. + +**4. heap.** a buddy allocator. + +**6. stack checks.** all three stacks are checked: data and return at every block exit on all backends, and frames in every prologue. + +**7. the small stuff.** error recovery with up to 20 reported errors, line numbers carried in token lists, a signature prescan over the whole unit so prototypes are optional, storing into a borrowed object moving the object automatically, `?:`, and go-style `switch`. on the side, a 4-token lookahead fixed `**` declarations. + +### 14 + +> how costly is it if we add a counter to each block to see how many times it runs, then run the optimizer on it if it's a hot path? + +> continue + +**summary:** answered without building anything. about 4 instructions per block entry while a block is being counted, and nothing once its optimized translation replaces it. the optimizing pass would reuse the enhancement lifter, optimizer and register allocator. lifting whole blocks would need jz side exits and barriers at calls and i/o. compiling a block that way takes microseconds, against milliseconds for llvm, and keeping values in registers instead of the memory stack likely gives 2 to 4x on tight loops. it's listed under open ends. then the gap fixes continued. diff --git a/docs/history/13-gap-fixes/code/core.c b/docs/history/13-gap-fixes/code/core.c new file mode 100644 index 0000000..ce353c8 --- /dev/null +++ b/docs/history/13-gap-fixes/code/core.c @@ -0,0 +1,1183 @@ +/* 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 +#include +#include +#if defined(__aarch64__) && !defined(ZYINTERP) +#define ZYJIT 1 +#include +#ifdef __APPLE__ +#include +#include +#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 DSLIM (0xFC000 + 1100) /* data stack overflows below this (a block pushes at most ~1024) */ +#define RSLIM (0xF8000 - 8) /* return stack overflows above this */ +/* why the cpu stopped, when it wasn't a halt */ +static int stopped(int p) +{ + if (p == MW + 1) { fprintf(stderr, "zy: data stack overflow\n"); return 2; } + if (p == MW + 2) { fprintf(stderr, "zy: return stack overflow\n"); return 2; } + return 0; +} +#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; + +/* ---- virtual enhancements ---- + up to 512 custom opcodes (22 .. 533), wired in at runtime by the install + opcode (21). an enhancement is a short program over native micro-ops, + written either as a recipe (text) or as straight-line vm code that gets + lifted. both become ssa, go through the optimizer below, and then run in + the interpreter or get inlined by the jit as native code. */ +#define NENH 512 +#define XOP0 22 +enum { U_LI, U_MOV, U_ADD, U_SUB, U_MUL, U_SDIV, U_UDIV, U_SREM, U_UREM, U_AND, U_OR, U_XOR, + U_SHL, U_SHR, U_SAR, U_NEG, U_NOT, U_LT, U_LTU, U_EQ, U_NE, U_MIN, U_MAX, U_MINU, U_MAXU, + U_MULHS, U_MULHU, U_CLZ, U_ABS, U_SEL, U_LD, U_ST, U_N }; +static const char *unames[U_N] = { "li", "mov", "add", "sub", "mul", "sdiv", "udiv", "srem", "urem", + "and", "or", "xor", "shl", "shr", "sar", "neg", "not", "lt", "ltu", "eq", "ne", "min", "max", + "minu", "maxu", "mulhs", "mulhu", "clz", "abs", "sel", "ld", "st" }; +static const signed char uarity[U_N] = { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2 }; +typedef struct { int op, d, a, b, c, imm; } Uop; /* ssa: d is a fresh value, a b c are values */ +typedef struct { + int live, kind, nin, nout, n, nv, out[8]; + Uop *u; + signed char *reg; /* physical register per value, for the jit; 0 if it didn't fit */ +} Enh; +static Enh enh[NENH]; +static int need_flush; + +#define MAXUOP 4096 +static Uop ub[MAXUOP]; static int un, unv, uerr; /* the program being built */ +static int unew(int op, int a, int b, int c, int imm) +{ + Uop *u; + if (un >= MAXUOP) { uerr = -5; return 0; } + u = &ub[un++]; u->op = op; u->d = unv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + return u->d; +} +static int mread(int a) { return (unsigned)a < MW ? m[a] : 0; } + +/* recipe text: one statement per line or per ';' + r0 = sdiv r0 r1 dst = op operands, operands are rN, parameter names or numbers + r2 = r0 a copy, or a number + st r1 r0 memory[r1] = r0 + inputs arrive in r0.. (and under the parameter names), outputs leave from r0.. */ +static int parse_recipe(int src, int names, int nin, int nout, int *out) +{ + int cur[16], i, p = src, n, k, op, args[3], na, dst, isst; + char tok[8][32]; int nt; + for (i = 0; i < 16; i++) cur[i] = i < nin ? i : -1; + for (;;) { + /* read one statement into tokens */ + nt = 0; + for (;;) { + int c = mread(p); + while (c == ' ' || c == '\t' || c == '\r') c = mread(++p); + if (!c || c == '\n' || c == ';') break; + if (c == '=') { if (nt < 8) strcpy(tok[nt++], "="); p++; continue; } + n = 0; + while (c && c != ' ' && c != '\t' && c != '\n' && c != ';' && c != '=' && c != '\r') { if (n < 31) tok[nt < 8 ? nt : 7][n++] = (char)c; c = mread(++p); } + if (nt < 8) tok[nt++][n] = 0; + } + if (nt) { + isst = !strcmp(tok[0], "st"); + if (!isst && (nt < 3 || strcmp(tok[1], "="))) return -2; + /* destination register */ + dst = -1; + if (!isst) { + if (tok[0][0] == 'r' && tok[0][1] >= '0' && tok[0][1] <= '9') dst = atoi(tok[0] + 1); + else for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)tok[0][j]) j++; + if (!mread(s + j) && !tok[0][j]) dst = i; + } + if (dst < 0 || dst > 15) return -2; + } + k = isst ? 1 : 2; /* first token after "=" (or after st) */ + op = -1; + if (!isst && nt > 3) { for (i = 0; i < U_N; i++) if (!strcmp(tok[k], unames[i])) op = i; if (op < 0) return -2; k++; } + if (isst) op = U_ST; + na = 0; + for (; k < nt; k++) { + char *t = tok[k], *e; int v = -1; + if (na >= 3) return -2; + if (t[0] == 'r' && t[1] >= '0' && t[1] <= '9') { int r = atoi(t + 1); if (r > 15) return -2; if (cur[r] < 0) cur[r] = unew(U_LI, 0, 0, 0, 0); v = cur[r]; } + else if ((t[0] >= '0' && t[0] <= '9') || t[0] == '-') { long x = strtol(t, &e, 0); if (*e) return -2; v = unew(U_LI, 0, 0, 0, (int)x); } + else { + for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)t[j]) j++; + if (!mread(s + j) && !t[j]) v = cur[i] < 0 ? (cur[i] = unew(U_LI, 0, 0, 0, 0)) : cur[i]; + } + if (v < 0) return -2; + } + args[na++] = v; + } + if (op < 0) { /* x = y */ + if (na != 1) return -2; + cur[dst] = args[0]; + } else { + if (na != (op == U_LI ? 0 : uarity[op])) { + if (!(op == U_LI && na == 1)) return -2; + } + if (op == U_LI) cur[dst] = args[0]; + else if (op == U_ST) unew(U_ST, args[0], args[1], 0, 0); + else cur[dst] = unew(op, args[0], na > 1 ? args[1] : 0, na > 2 ? args[2] : 0, 0); + } + if (uerr) return uerr; + } + if (!mread(p)) break; + p++; + } + for (i = 0; i < nout; i++) { if (cur[i] < 0) cur[i] = unew(U_LI, 0, 0, 0, 0); out[i] = cur[i]; } + return uerr; +} + +/* straight-line vm code from addr up to its ret, run symbolically */ +static int lift_vm(int a, int len, int nin, int nout, int *out) +{ + int st[256], sp = 0, i, w, k, x, y; + for (i = 0; i < nin; i++) st[sp++] = i; + for (i = 0; i < len; i++) { + w = mread(a + i); + if (w & 1) { if (sp >= 256) return -4; st[sp++] = unew(U_LI, 0, 0, 0, w >> 1); continue; } + k = w / 2; + if (k == 9) break; + switch (k) { + case 1: if (sp < 1) return -4; st[sp - 1] = unew(U_LD, st[sp - 1], 0, 0, 0); break; + case 2: if (sp < 2) return -4; unew(U_ST, st[sp - 1], st[sp - 2], 0, 0); sp -= 2; break; + case 3: /* pick needs a constant index */ + if (sp < 1) return -4; + x = st[sp - 1]; + if (x < nin) return -4; + { int j; for (j = 0; j < un && ub[j].d != x; j++); if (j == un || ub[j].op != U_LI) return -4; y = ub[j].imm; } + if (y < 0 || y >= sp - 1) return -4; + st[sp - 1] = st[sp - 2 - y]; + break; + case 4: if (sp < 1) return -4; sp--; break; + case 5: if (sp < 2) return -4; x = st[sp - 1]; st[sp - 1] = st[sp - 2]; st[sp - 2] = x; break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: { + static const int map[] = { U_ADD, U_SUB, U_MUL, U_AND, U_OR, U_XOR, U_SAR, U_LT }; + if (sp < 2) return -4; + x = st[sp - 1]; y = st[sp - 2]; sp -= 2; + st[sp++] = unew(map[k - 13], y, x, 0, 0); + break; } + default: return -4; /* control flow, i/o and other enhancements don't lift */ + } + if (uerr) return uerr; + } + if (sp != nout) return -4; + for (i = 0; i < nout; i++) out[i] = st[i]; + return uerr; +} + +/* ---- the optimizer ---- + one forward pass of copy propagation, constant folding, algebraic + simplification, division by constants (the multiply-high trick) and + common subexpression elimination, then dead code removal. */ +static int ev(int op, int a, int b, int c) +{ + unsigned ua = (unsigned)a, ub_ = (unsigned)b; + switch (op) { + case U_ADD: return (int)(ua + ub_); + case U_SUB: return (int)(ua - ub_); + case U_MUL: return (int)(ua * ub_); + case U_SDIV: return b == 0 ? 0 : (a == (int)0x80000000 && b == -1) ? a : a / b; + case U_UDIV: return b == 0 ? 0 : (int)(ua / ub_); + case U_SREM: return b == 0 ? a : (a == (int)0x80000000 && b == -1) ? 0 : a % b; + case U_UREM: return b == 0 ? a : (int)(ua % ub_); + case U_AND: return a & b; + case U_OR: return a | b; + case U_XOR: return a ^ b; + case U_SHL: return (int)(ua << (b & 31)); + case U_SHR: return (int)(ua >> (b & 31)); + case U_SAR: return a >> (b & 31); + case U_NEG: return (int)(0u - ua); + case U_NOT: return ~a; + case U_LT: return a < b; + case U_LTU: return ua < ub_; + case U_EQ: return a == b; + case U_NE: return a != b; + case U_MIN: return a < b ? a : b; + case U_MAX: return a > b ? a : b; + case U_MINU: return ua < ub_ ? a : b; + case U_MAXU: return ua > ub_ ? a : b; + case U_MULHS: return (int)(((long long)a * (long long)b) >> 32); + case U_MULHU: return (int)(((unsigned long long)ua * ub_) >> 32); + case U_CLZ: { int n = 0; if (!ua) return 32; while (!(ua & 0x80000000u)) { ua <<= 1; n++; } return n; } + case U_ABS: return a < 0 ? (int)(0u - ua) : a; + case U_SEL: return a ? b : c; + } + return 0; +} +static void smagic(int d, int *mul, int *sh) /* hacker's delight, signed */ +{ + const unsigned two31 = 0x80000000u; + unsigned ad = d < 0 ? 0u - (unsigned)d : (unsigned)d, t = two31 + ((unsigned)d >> 31); + unsigned anc = t - 1 - t % ad, q1 = two31 / anc, r1 = two31 - q1 * anc, q2 = two31 / ad, r2 = two31 - q2 * ad, delta; + int p = 31; + do { + p++; + q1 *= 2; r1 *= 2; if (r1 >= anc) { q1++; r1 -= anc; } + q2 *= 2; r2 *= 2; if (r2 >= ad) { q2++; r2 -= ad; } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + *mul = (int)(q2 + 1); if (d < 0) *mul = -*mul; + *sh = p - 32; +} +static void umagic(unsigned d, unsigned *mul, int *add, int *sh) /* hacker's delight, unsigned */ +{ + unsigned nc = 0xFFFFFFFFu - (0u - d) % d, q1, r1, q2, r2, delta; + int p = 31; + *add = 0; + q1 = 0x80000000u / nc; r1 = 0x80000000u - q1 * nc; + q2 = 0x7FFFFFFFu / d; r2 = 0x7FFFFFFFu - q2 * d; + do { + p++; + if (r1 >= nc - r1) { q1 = 2 * q1 + 1; r1 = 2 * r1 - nc; } else { q1 = 2 * q1; r1 = 2 * r1; } + if (r2 + 1 >= d - r2) { if (q2 >= 0x7FFFFFFFu) *add = 1; q2 = 2 * q2 + 1; r2 = 2 * r2 + 1 - d; } + else { if (q2 >= 0x80000000u) *add = 1; q2 = 2 * q2; r2 = 2 * r2 + 1; } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + *mul = q2 + 1; *sh = p - 32; +} + +static Uop ob[MAXUOP]; static int on, onv; +static int *omap, *isk, *kv; /* old value -> new value; constness of new values */ +static int pure(int op) { return op != U_LD && op != U_ST; } +static int ispow2(unsigned x) { return x && !(x & (x - 1)); } +static int lg2(unsigned x) { int n = 0; while (x > 1) { x >>= 1; n++; } return n; } +static int oe(int op, int a, int b, int c, int imm); +static int K(int v) { return oe(U_LI, 0, 0, 0, v); } +static int raw(int op, int a, int b, int c, int imm) +{ + Uop *u; int i; + if (pure(op)) /* cse */ + for (i = 0; i < on; i++) { + u = &ob[i]; + if (u->op == op && u->a == a && u->b == b && u->c == c && u->imm == imm) return u->d; + } + if (on >= MAXUOP) { uerr = -5; return 0; } + u = &ob[on++]; u->op = op; u->d = onv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + isk[u->d] = op == U_LI; kv[u->d] = imm; + return u->d; +} +static int sdivk(int a, int d) /* a / d for a constant d, no divide instruction */ +{ + int mul, sh, q, t; + if (d == 1) return a; + if (d == -1) return oe(U_NEG, a, 0, 0, 0); + if (d == (int)0x80000000) return oe(U_EQ, a, K(d), 0, 0); + if (ispow2((unsigned)(d < 0 ? -d : d))) { + int k = lg2((unsigned)(d < 0 ? -d : d)); + t = oe(U_SAR, a, K(31), 0, 0); + t = oe(U_SHR, t, K(32 - k), 0, 0); + q = oe(U_SAR, oe(U_ADD, a, t, 0, 0), K(k), 0, 0); + return d < 0 ? oe(U_NEG, q, 0, 0, 0) : q; + } + smagic(d, &mul, &sh); + q = oe(U_MULHS, a, K(mul), 0, 0); + if (d > 0 && mul < 0) q = oe(U_ADD, q, a, 0, 0); + if (d < 0 && mul > 0) q = oe(U_SUB, q, a, 0, 0); + if (sh) q = oe(U_SAR, q, K(sh), 0, 0); + return oe(U_ADD, q, oe(U_SHR, q, K(31), 0, 0), 0, 0); +} +static int udivk(int a, unsigned d) +{ + unsigned mul; int add, sh, t; + if (d == 1) return a; + if (ispow2(d)) return oe(U_SHR, a, K(lg2(d)), 0, 0); + if (d > 0x80000000u) return oe(U_XOR, oe(U_LTU, a, K((int)d), 0, 0), K(1), 0, 0); /* a >= d */ + umagic(d, &mul, &add, &sh); + t = oe(U_MULHU, a, K((int)mul), 0, 0); + if (!add) return sh ? oe(U_SHR, t, K(sh), 0, 0) : t; + t = oe(U_ADD, oe(U_SHR, oe(U_SUB, a, t, 0, 0), K(1), 0, 0), t, 0, 0); + return sh > 1 ? oe(U_SHR, t, K(sh - 1), 0, 0) : t; +} +static int oe(int op, int a, int b, int c, int imm) +{ + int ka, kb, A, B; + if (op == U_LI) return raw(U_LI, 0, 0, 0, imm); + if (op == U_MOV) return a; + if (op == U_LD || op == U_ST) return raw(op, a, b, 0, 0); + ka = isk[a]; kb = uarity[op] > 1 && isk[b]; + A = kv[a]; B = kv[b]; + /* everything constant: fold */ + if (ka && (uarity[op] < 2 || kb) && (uarity[op] < 3 || isk[c])) return K(ev(op, A, B, kv[c])); + /* constants go right for commutative ops */ + if (ka && !kb && (op == U_ADD || op == U_MUL || op == U_AND || op == U_OR || op == U_XOR || op == U_EQ || op == U_NE || + op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU || op == U_MULHS || op == U_MULHU)) { + int t = a; a = b; b = t; kb = 1; B = A; ka = 0; + } + if (op == U_SEL && ka) return A ? b : c; + if (op == U_SEL && b == c) return b; + if (kb) switch (op) { + case U_ADD: case U_SUB: case U_OR: case U_XOR: case U_SHL: case U_SHR: case U_SAR: + if (!B || (op >= U_SHL && op <= U_SAR && !(B & 31))) return a; + break; + case U_MUL: + if (B == 0) return K(0); + if (B == 1) return a; + if (B == -1) return oe(U_NEG, a, 0, 0, 0); + if (ispow2((unsigned)B)) return oe(U_SHL, a, K(lg2((unsigned)B)), 0, 0); + break; + case U_AND: if (B == 0) return K(0); if (B == -1) return a; break; + case U_SDIV: if (B == 0) return K(0); return sdivk(a, B); + case U_SREM: if (B == 0) return a; if (B == 1 || B == -1) return K(0); + return oe(U_SUB, a, oe(U_MUL, sdivk(a, B), b, 0, 0), 0, 0); + case U_UDIV: if (B == 0) return K(0); return udivk(a, (unsigned)B); + case U_UREM: if (B == 0) return a; + if (ispow2((unsigned)B)) return oe(U_AND, a, K(B - 1), 0, 0); + return oe(U_SUB, a, oe(U_MUL, udivk(a, (unsigned)B), b, 0, 0), 0, 0); + } + if (a == b && uarity[op] == 2) { + if (op == U_SUB || op == U_XOR || op == U_LT || op == U_LTU || op == U_NE) return K(0); + if (op == U_AND || op == U_OR || op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU) return a; + if (op == U_EQ) return K(1); + } + return raw(op, a, b, c, 0); +} +/* runs the optimizer over ub[0..un) with nin inputs; leaves the result in e */ +static int optimize(Enh *e, int nin, int *out, int nout) +{ + int i, *live, n = 0; + static int omap_[MAXUOP + 16], isk_[MAXUOP * 4], kv_[MAXUOP * 4]; + omap = omap_; isk = isk_; kv = kv_; + on = 0; onv = nin; + for (i = 0; i < nin; i++) { omap[i] = i; isk[i] = 0; } + for (i = 0; i < un && !uerr; i++) { + Uop *u = &ub[i]; + int a = uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD ? omap[u->a] : 0; + int b = uarity[u->op] > 1 || u->op == U_ST ? omap[u->b] : 0; + int c = uarity[u->op] > 2 ? omap[u->c] : 0; + if (u->op == U_ST) oe(U_ST, a, b, 0, 0); + else omap[u->d] = oe(u->op, a, b, c, u->imm); + } + if (uerr) return uerr; + /* dead code: outputs and stores are live */ + live = calloc(onv + 1, sizeof *live); + for (i = 0; i < nout; i++) { e->out[i] = omap[out[i]]; live[e->out[i]] = 1; } + for (i = on; i--;) { + Uop *u = &ob[i]; + if (u->op != U_ST && !live[u->d]) { u->op = -1; continue; } + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) live[u->a] = 1; + if (uarity[u->op] > 1 || u->op == U_ST) live[u->b] = 1; + if (uarity[u->op] > 2) live[u->c] = 1; + } + free(live); + e->u = malloc((on + 1) * sizeof(Uop)); + for (i = 0; i < on; i++) if (ob[i].op >= 0) e->u[n++] = ob[i]; + e->n = n; e->nv = onv; e->nin = nin; e->nout = nout; + return 0; +} +/* run an installed enhancement on a downward-growing stack; returns the new top */ +static int *xexec(Enh *e, int *sp) +{ + int vb[256], *v = e->nv <= 256 ? vb : malloc(e->nv * sizeof(int)), i, j; + for (j = 0; j < e->nin; j++) v[j] = sp[e->nin - 1 - j]; + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + switch (u->op) { + case U_LI: v[u->d] = u->imm; break; + case U_LD: v[u->d] = mread(v[u->a]); break; + case U_ST: if ((unsigned)v[u->a] < MW) m[v[u->a]] = v[u->b]; break; + default: v[u->d] = ev(u->op, v[u->a], v[u->b], v[u->c]); + } + } + sp += e->nin - e->nout; + for (j = 0; j < e->nout; j++) sp[e->nout - 1 - j] = v[e->out[j]]; + if (v != vb) free(v); + return sp; +} +static void xdump(int slot, Enh *e) +{ + int i; + fprintf(stderr, "enh %d: %d in, %d out, %d ops\n", slot, e->nin, e->nout, e->n); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (u->op == U_ST) fprintf(stderr, " st v%d v%d\n", u->a, u->b); + else if (u->op == U_LI) fprintf(stderr, " v%d = %d\n", u->d, u->imm); + else { fprintf(stderr, " v%d = %s v%d", u->d, unames[u->op], u->a); if (uarity[u->op] > 1) fprintf(stderr, " v%d", u->b); if (uarity[u->op] > 2) fprintf(stderr, " v%d", u->c); fprintf(stderr, "\n"); } + } + for (i = 0; i < e->nout; i++) fprintf(stderr, " out%d = v%d\n", i, e->out[i]); +} +/* registers for the jit: values live in w0..w15, straight-line linear scan. + if they don't fit, reg stays 0 and the jit calls the interpreter instead. */ +static void regalloc(Enh *e) +{ + int *last = malloc(e->nv * sizeof(int)), i, j, k, fr = 0xffff; + signed char *r = malloc(e->nv); + for (i = 0; i < e->nv; i++) { last[i] = -2; r[i] = -1; } + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) last[u->a] = i; + if (uarity[u->op] > 1 || u->op == U_ST) last[u->b] = i; + if (uarity[u->op] > 2) last[u->c] = i; + } + for (i = 0; i < e->nout; i++) last[e->out[i]] = e->n; +#define TAKE(v) do { for (k = 0; k < 16 && !(fr >> k & 1); k++); if (k == 16) goto fail; fr &= ~(1 << k); r[v] = (signed char)k; } while (0) + for (j = 0; j < e->nin; j++) if (last[j] >= -1 && last[j] != -2) TAKE(j); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; int ops[3], no = 0; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) ops[no++] = u->a; + if (uarity[u->op] > 1 || u->op == U_ST) ops[no++] = u->b; + if (uarity[u->op] > 2) ops[no++] = u->c; + for (j = 0; j < no; j++) if (last[ops[j]] == i && r[ops[j]] >= 0 && (fr >> r[ops[j]] & 1) == 0) fr |= 1 << r[ops[j]]; + if (u->op != U_ST) TAKE(u->d); + if (u->op != U_ST && last[u->d] == -2) fr |= 1 << r[u->d]; /* never used */ + } +#undef TAKE + free(last); e->reg = r; return; +fail: + free(last); free(r); e->reg = 0; +} +/* the install opcode. descriptor: slot, kind (0 recipe, 1 vm code), inputs, + outputs, payload address, payload length, parameter names (or 0). + returns 0, or -1 bad descriptor, -2 recipe syntax, -4 code doesn't lift, + -5 too big. */ +static int install(int d) +{ + int slot = mread(d), kind = mread(d + 1), nin = mread(d + 2), nout = mread(d + 3); + int pay = mread(d + 4), len = mread(d + 5), names = mread(d + 6), out[8], r; + Enh ne; + if ((unsigned)slot >= NENH || (unsigned)nin > 8 || (unsigned)nout > 8 || (kind != 0 && kind != 1)) return -1; + un = 0; unv = nin; uerr = 0; + r = kind == 0 ? parse_recipe(pay, names, nin, nout, out) : lift_vm(pay, len, nin, nout, out); + if (r) { if (trace) fprintf(stderr, "enh %d: install failed (%d)\n", slot, r); return r; } + memset(&ne, 0, sizeof ne); + if ((r = optimize(&ne, nin, out, nout))) return r; + ne.kind = kind; ne.live = 1; + regalloc(&ne); + if (enh[slot].live) { free(enh[slot].u); free(enh[slot].reg); } + enh[slot] = ne; + need_flush = 1; + if (trace) xdump(slot, &enh[slot]); + return 0; +} +#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[13]; /* m, s, r, tab, cov, Q, G, &J, store hook, install, enhancement fallback, stack limits */ + +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(0xa9bb7bfd); /* stp x29, x30, [sp, #-80]! */ + 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(0xa90467f8); /* stp x24, x25, [sp, #64] */ + E(0xaa0003f7); /* mov x23, x0 */ + ldrx_u(M, ST, 0); + ldrx_u(24, ST, 88); ldrx_u(25, ST, 96); /* x24, x25: the stack limits, as addresses */ + 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(0xa94467f8); /* ldp x24, x25, [sp, #64] */ + E(0xa8c57bfd); /* ldp x29, x30, [sp], #80 */ + E(0xd65f03c0); /* ret */ + { + unsigned *ovd = cp, *ovr; + li(W0, MW + 1); b_to(x_exit); /* data stack overflow */ + ovr = cp; + li(W0, MW + 2); b_to(x_exit); /* return stack overflow */ + x_disp = cp; /* w0 = target: check the stacks, chain through tab[] or fall back to c */ + E(0xeb18029f); /* cmp x20, x24 */ + E(0x54000003 | ((ovd - cp) & 0x7ffff) << 5); /* b.lo data overflow */ + E(0xeb1902bf); /* cmp x21, x25 */ + E(0x54000002 | ((ovr - cp) & 0x7ffff) << 5); /* b.hs return overflow */ + } + 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); +} + +/* an enhancement, inlined: inputs from the data stack into w0..w15, the + optimized micro-ops, outputs back. x16 and x17 are scratch. */ +static void emit_enh(int s) +{ + Enh *e = &enh[s]; + signed char *r = e->reg; + int i, j, delta; + if (!r) { /* didn't fit in registers: x0 = data stack, w1 = slot, call the interpreter */ + E(0xaa1403e0); li(W1, s); ldrx_u(X11, ST, 80); blr(X11); E(0xaa0003f4); + return; + } + for (j = 0; j < e->nin; j++) if (r[j] >= 0) ldr_u(r[j], SP, 4 * (e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + int d = u->op == U_ST ? 0 : r[u->d], a = r[u->a], b = r[u->b], c = r[u->c]; + switch (u->op) { + case U_LI: li(d, u->imm); break; + case U_ADD: op3(0x0b000000, d, a, b); break; + case U_SUB: op3(0x4b000000, d, a, b); break; + case U_MUL: op3(0x1b007c00, d, a, b); break; + case U_SDIV: op3(0x1ac00c00, d, a, b); break; + case U_UDIV: op3(0x1ac00800, d, a, b); break; + case U_SREM: op3(0x1ac00c00, 16, a, b); E(0x1b008000 | b << 16 | a << 10 | 16 << 5 | d); break; /* msub */ + case U_UREM: op3(0x1ac00800, 16, a, b); E(0x1b008000 | b << 16 | a << 10 | 16 << 5 | d); break; + case U_AND: op3(0x0a000000, d, a, b); break; + case U_OR: op3(0x2a000000, d, a, b); break; + case U_XOR: op3(0x4a000000, d, a, b); break; + case U_SHL: op3(0x1ac02000, d, a, b); break; + case U_SHR: op3(0x1ac02400, d, a, b); break; + case U_SAR: op3(0x1ac02800, d, a, b); break; + case U_NEG: E(0x4b0003e0 | a << 16 | d); break; + case U_NOT: E(0x2a2003e0 | a << 16 | d); break; + case U_LT: E(0x6b00001f | b << 16 | a << 5); E(0x1a9fa7e0 | d); break; /* cmp; cset lt */ + case U_LTU: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f27e0 | d); break; /* cset lo */ + case U_EQ: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f17e0 | d); break; + case U_NE: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f07e0 | d); break; + case U_MIN: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 11 << 12 | a << 5 | d); break; + case U_MAX: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 12 << 12 | a << 5 | d); break; + case U_MINU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 3 << 12 | a << 5 | d); break; + case U_MAXU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 8 << 12 | a << 5 | d); break; + case U_MULHS: E(0x9b207c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; /* smull; lsr #32 */ + case U_MULHU: E(0x9ba07c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; + case U_CLZ: E(0x5ac01000 | a << 5 | d); break; + case U_ABS: E(0x7100001f | a << 5); E(0x5a800400 | a << 16 | 10 << 12 | a << 5 | d); break; /* cmp #0; cneg */ + case U_SEL: E(0x7100001f | a << 5); E(0x1a800000 | c << 16 | 1 << 12 | b << 5 | d); break; /* csel ne */ + case U_LD: /* out of range reads 0, like the interpreter */ + E(0x52800011); E(0x7144001f | a << 5); E(0x54000042); ldr_rr(17, M, a, UXTW); movw(d, 17); + break; + case U_ST: E(0x7144001f | a << 5); E(0x54000042); str_rr(b, M, a, UXTW); break; + } + } + delta = 4 * (e->nin - e->nout); + if (delta > 0) E(0x91000294 | delta << 10); + if (delta < 0) E(0xd1000294 | (-delta) << 10); + for (j = 0; j < e->nout; j++) str_u(r[e->out[j]], SP, 4 * (e->nout - 1 - j)); +} +static int inst_hook(int d) { return install(d); } +static long xrun(long sp, int slot) { return (long)xexec(&enh[slot], (int *)sp); } + +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; } + if (k == 21) { /* install: call into c, then return to it so it can flush */ + ldr_u(W0, SP, 0); ldrx_u(X11, ST, 72); blr(X11); str_u(W0, SP, 0); + li(W0, i + 1); b_to(x_exit); i++; break; + } + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { emit_enh(k - XOP0); i++; continue; } + if (k > 20) { E(0x12800000); b_to(x_exit); i++; break; } /* not wired: halt */ + 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). */ +#ifdef ZYLLVM +/* ---- llvm backend ---- + a tiered jit for hosts the arm64 backend doesn't cover. the interpreter + counts how often each block start is reached; a hot block is translated to + llvm ir (same block rules as the arm64 jit: it ends at call, jump, ret or + halt, and keeps going past a jz), optimized at O2 and compiled with orc. + enhancements are inlined as ir. stores into compiled words drop the blocks + that cover them, so self-modifying code still works. */ +#include +#include +#include +#include +#include +#include +static int HOT = 5000; /* runs before a block gets compiled: ZYHOT */ +static const char *lpasses = "default"; /* ZYPASSES */ +#define LMAXB 65536 +typedef int (*Blk)(int *mem, int *regs); +static Blk lt[MW]; /* address -> compiled block */ +static unsigned short hot[MW]; +static unsigned char lcov[MW]; /* 1 if a compiled block covers the word */ +static struct { int a, b; } lbl[LMAXB]; +static int nlbl, llvm_ok, nblocks; +static LLVMOrcLLJITRef jit; +static LLVMOrcThreadSafeContextRef tsc; +static LLVMContextRef ctx; +static LLVMTypeRef i8t, i32t, i64t, ptrt, i1t; +static LLVMBuilderRef bd; +static LLVMValueRef fn_, vm_, vregs, vs, vr; /* function, memory, regs, s and r slots */ +static LLVMModuleRef mod_; + +static void ldrop_all(void) +{ + memset(lt, 0, sizeof lt); memset(lcov, 0, sizeof lcov); memset(hot, 0, sizeof hot); nlbl = 0; + if (trace) fprintf(stderr, "llvm: dropped every block\n"); +} +/* a store to a word some block covers: write it, drop those blocks */ +static int lhook(int a, int v) +{ + int j, x, hit = 0; + if (m[a] == v) return 0; + m[a] = v; + for (j = 0; j < nlbl; j++) + if (lbl[j].a >= 0 && lbl[j].a <= a && a < lbl[j].b) { + lt[lbl[j].a] = 0; hot[lbl[j].a] = 0; + if (trace) fprintf(stderr, "llvm: dropped %d..%d\n", lbl[j].a, lbl[j].b - 1); + lbl[j].a = -1; hit = 1; + } + if (hit) { + memset(lcov, 0, sizeof lcov); + for (j = 0; j < nlbl; j++) if (lbl[j].a >= 0) for (x = lbl[j].a; x < lbl[j].b; x++) lcov[x] = 1; + } + return hit; +} +static int linstall(int d) { return install(d); } + +static LLVMValueRef K32(int v) { return LLVMConstInt(i32t, (unsigned)v, 0); } +static LLVMValueRef cptr(void *p) { return LLVMConstIntToPtr(LLVMConstInt(i64t, (unsigned long long)(size_t)p, 0), ptrt); } +static LLVMValueRef mslot(LLVMValueRef idx) { return LLVMBuildGEP2(bd, i32t, vm_, &idx, 1, ""); } +static LLVMValueRef ld(LLVMValueRef idx) { return LLVMBuildLoad2(bd, i32t, mslot(idx), ""); } +static void st(LLVMValueRef idx, LLVMValueRef v) { LLVMBuildStore(bd, v, mslot(idx)); } +static LLVMValueRef gets(void) { return LLVMBuildLoad2(bd, i32t, vs, ""); } +static void sets(LLVMValueRef v) { LLVMBuildStore(bd, v, vs); } +static LLVMValueRef add(LLVMValueRef a, int k) { return LLVMBuildAdd(bd, a, K32(k), ""); } +/* a load that reads 0 outside memory */ +static LLVMValueRef safeld(LLVMValueRef a) +{ + LLVMValueRef in = LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""); + LLVMValueRef v = ld(LLVMBuildSelect(bd, in, a, K32(0), "")); + return LLVMBuildSelect(bd, in, v, K32(0), ""); +} +static void push(LLVMValueRef v) { LLVMValueRef s = add(gets(), -1); sets(s); st(s, v); } +/* leave the block: write s and r back, return the next vm address */ +static void leave(LLVMValueRef next) +{ + LLVMValueRef r0 = K32(0), r1 = K32(1); + LLVMBuildStore(bd, gets(), LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, vr, ""), LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, "")); + LLVMBuildRet(bd, next); +} +static LLVMBasicBlockRef newbb(void) { return LLVMAppendBasicBlockInContext(ctx, fn_, ""); } +static LLVMValueRef callp(void *f, LLVMTypeRef ret, LLVMTypeRef *at, int n, LLVMValueRef *args) +{ + LLVMTypeRef ft = LLVMFunctionType(ret, at, (unsigned)n, 0); + return LLVMBuildCall2(bd, ft, cptr(f), args, (unsigned)n, ""); +} +/* an enhancement as ir: the same semantics as ev() */ +static void ir_enh(Enh *e) +{ + LLVMValueRef *v = calloc(e->nv + 1, sizeof *v), s = gets(), z = K32(0), q, d, t, c1, c2; + int i, j; + LLVMTypeRef i64 = i64t; + for (j = 0; j < e->nin; j++) v[j] = ld(add(s, e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + LLVMValueRef a = u->op == U_LI ? 0 : v[u->a], b = uarity[u->op] > 1 || u->op == U_ST ? v[u->b] : 0, c = uarity[u->op] > 2 ? v[u->c] : 0, r = 0; + switch (u->op) { + case U_LI: r = K32(u->imm); break; + case U_ADD: r = LLVMBuildAdd(bd, a, b, ""); break; + case U_SUB: r = LLVMBuildSub(bd, a, b, ""); break; + case U_MUL: r = LLVMBuildMul(bd, a, b, ""); break; + case U_SDIV: case U_SREM: /* /0 and INT_MIN/-1 are defined, like the cpu */ + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + c2 = LLVMBuildAnd(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32((int)0x80000000), ""), LLVMBuildICmp(bd, LLVMIntEQ, b, K32(-1), ""), ""); + d = LLVMBuildSelect(bd, LLVMBuildOr(bd, c1, c2, ""), K32(1), b, ""); + if (u->op == U_SDIV) { q = LLVMBuildSDiv(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, z, q, ""); } + else { q = LLVMBuildSRem(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, a, LLVMBuildSelect(bd, c2, z, q, ""), ""); } + break; + case U_UDIV: case U_UREM: + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + d = LLVMBuildSelect(bd, c1, K32(1), b, ""); + if (u->op == U_UDIV) r = LLVMBuildSelect(bd, c1, z, LLVMBuildUDiv(bd, a, d, ""), ""); + else r = LLVMBuildSelect(bd, c1, a, LLVMBuildURem(bd, a, d, ""), ""); + break; + case U_AND: r = LLVMBuildAnd(bd, a, b, ""); break; + case U_OR: r = LLVMBuildOr(bd, a, b, ""); break; + case U_XOR: r = LLVMBuildXor(bd, a, b, ""); break; + case U_SHL: r = LLVMBuildShl(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SHR: r = LLVMBuildLShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SAR: r = LLVMBuildAShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_NEG: r = LLVMBuildSub(bd, z, a, ""); break; + case U_NOT: r = LLVMBuildNot(bd, a, ""); break; + case U_LT: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), i32t, ""); break; + case U_LTU: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), i32t, ""); break; + case U_EQ: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, b, ""), i32t, ""); break; + case U_NE: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntNE, a, b, ""), i32t, ""); break; + case U_MIN: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), a, b, ""); break; + case U_MAX: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSGT, a, b, ""), a, b, ""); break; + case U_MINU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), a, b, ""); break; + case U_MAXU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntUGT, a, b, ""), a, b, ""); break; + case U_MULHS: case U_MULHU: { + LLVMValueRef x = u->op == U_MULHS ? LLVMBuildSExt(bd, a, i64, "") : LLVMBuildZExt(bd, a, i64, ""); + LLVMValueRef y = u->op == U_MULHS ? LLVMBuildSExt(bd, b, i64, "") : LLVMBuildZExt(bd, b, i64, ""); + r = LLVMBuildTrunc(bd, LLVMBuildLShr(bd, LLVMBuildMul(bd, x, y, ""), LLVMConstInt(i64, 32, 0), ""), i32t, ""); + break; } + case U_CLZ: { + unsigned id = LLVMLookupIntrinsicID("llvm.ctlz", 9); + LLVMValueRef f = LLVMGetIntrinsicDeclaration(mod_, id, &i32t, 1), args[2]; + args[0] = a; args[1] = LLVMConstInt(i1t, 0, 0); + r = LLVMBuildCall2(bd, LLVMIntrinsicGetType(ctx, id, &i32t, 1), f, args, 2, ""); + break; } + case U_ABS: t = LLVMBuildICmp(bd, LLVMIntSLT, a, z, ""); r = LLVMBuildSelect(bd, t, LLVMBuildSub(bd, z, a, ""), a, ""); break; + case U_SEL: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntNE, a, z, ""), b, c, ""); break; + case U_LD: r = safeld(a); break; + case U_ST: { + LLVMBasicBlockRef yes = newbb(), done = newbb(); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), yes, done); + LLVMPositionBuilderAtEnd(bd, yes); st(a, b); LLVMBuildBr(bd, done); + LLVMPositionBuilderAtEnd(bd, done); + break; } + } + if (u->op != U_ST) v[u->d] = r; + } + s = add(s, e->nin - e->nout); sets(s); + for (j = 0; j < e->nout; j++) st(add(s, e->nout - 1 - j), v[e->out[j]]); + free(v); +} +static void llvm_init(void) +{ + LLVMErrorRef err; + if (getenv("ZYHOT")) HOT = atoi(getenv("ZYHOT")); + if (HOT < 1) HOT = 1; + if (HOT > 65000) HOT = 65000; + if (getenv("ZYPASSES")) lpasses = getenv("ZYPASSES"); + LLVMInitializeNativeTarget(); LLVMInitializeNativeAsmPrinter(); + if ((err = LLVMOrcCreateLLJIT(&jit, 0))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return; } + tsc = LLVMOrcCreateNewThreadSafeContext(); + ctx = LLVMOrcThreadSafeContextGetContext(tsc); + i1t = LLVMInt1TypeInContext(ctx); i8t = LLVMInt8TypeInContext(ctx); i32t = LLVMInt32TypeInContext(ctx); + i64t = LLVMInt64TypeInContext(ctx); ptrt = LLVMPointerTypeInContext(ctx, 0); + bd = LLVMCreateBuilderInContext(ctx); + llvm_ok = 1; +} +/* compile the block at p; 0 if it couldn't be */ +static Blk lcompile(int p) +{ + char name[32]; LLVMTypeRef pt[2], ft; LLVMValueRef s, a, b, v, r, args[2]; LLVMTypeRef at[2]; + LLVMOrcExecutorAddress addr; LLVMErrorRef err; LLVMPassBuilderOptionsRef po; + int i = p, n = 0, w, k, t, done = 0; + if (!llvm_ok || nlbl >= LMAXB) return 0; + sprintf(name, "b%d_%d", p, nblocks++); + mod_ = LLVMModuleCreateWithNameInContext(name, ctx); + pt[0] = ptrt; pt[1] = ptrt; + ft = LLVMFunctionType(i32t, pt, 2, 0); + fn_ = LLVMAddFunction(mod_, name, ft); + vm_ = LLVMGetParam(fn_, 0); vregs = LLVMGetParam(fn_, 1); + LLVMPositionBuilderAtEnd(bd, newbb()); + vs = LLVMBuildAlloca(bd, i32t, "s"); vr = LLVMBuildAlloca(bd, i32t, "r"); + { LLVMValueRef r0 = K32(0), r1 = K32(1); + sets(LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, ""), "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, ""), ""), vr); } + while (!done) { + if (i >= MW) { leave(K32(MW)); break; } + if (n++ >= 1024) { leave(K32(i)); break; } + w = m[i]; + lcov[i] = 1; + if (w & 1) { + /* a literal followed by call, jump or jz: a known target */ + if (i + 1 < MW && !(m[i + 1] & 1) && (k = m[i + 1] / 2) >= 6 && k <= 8) { + t = w >> 1; lcov[i + 1] = 1; + if (k == 8) { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + s = gets(); a = ld(s); sets(add(s, 1)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(K32(t)); + LLVMPositionBuilderAtEnd(bd, go); + i += 2; continue; + } + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 2)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(K32(t)); i += 2; break; + } + push(K32(w >> 1)); i++; continue; + } + k = w / 2; + s = gets(); + switch (k) { + case 0: leave(K32(MW)); done = 1; break; + case 1: st(s, safeld(ld(s))); break; + case 2: { + LLVMBasicBlockRef in = newbb(), cv = newbb(), plain = newbb(), out = newbb(), quit = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), in, out); + LLVMPositionBuilderAtEnd(bd, in); + v = LLVMBuildLoad2(bd, i8t, LLVMBuildGEP2(bd, i8t, cptr(lcov), &a, 1, ""), ""); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, LLVMConstInt(i8t, 0, 0), ""), cv, plain); + LLVMPositionBuilderAtEnd(bd, plain); st(a, b); LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, cv); + at[0] = i32t; at[1] = i32t; args[0] = a; args[1] = b; + v = callp((void *)lhook, i32t, at, 2, args); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, K32(0), ""), quit, out); + LLVMPositionBuilderAtEnd(bd, quit); leave(K32(i + 1)); /* a block died: back to the loop */ + LLVMPositionBuilderAtEnd(bd, out); + break; } + case 3: a = ld(s); st(s, safeld(LLVMBuildAdd(bd, add(s, 1), a, ""))); break; + case 4: sets(add(s, 1)); break; + case 5: a = ld(s); b = ld(add(s, 1)); st(s, b); st(add(s, 1), a); break; + case 6: case 7: + a = ld(s); sets(add(s, 1)); + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 1)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(a); done = 1; break; + case 8: { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, b, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(a); + LLVMPositionBuilderAtEnd(bd, go); + break; } + case 9: + r = add(LLVMBuildLoad2(bd, i32t, vr, ""), -1); LLVMBuildStore(bd, r, vr); + leave(ld(r)); done = 1; break; + case 10: v = callp((void *)Q, i8t, 0, 0, 0); push(LLVMBuildSExt(bd, v, i32t, "")); break; + case 11: + if (sizeof J == 1) push(LLVMBuildZExt(bd, LLVMBuildLoad2(bd, i8t, cptr(&J), ""), i32t, "")); + else push(LLVMBuildLoad2(bd, i32t, cptr(&J), "")); + break; + case 12: at[0] = i8t; args[0] = LLVMBuildTrunc(bd, ld(s), i8t, ""); callp((void *)G, LLVMVoidTypeInContext(ctx), at, 1, args); sets(add(s, 1)); break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + a = ld(s); b = ld(add(s, 1)); s = add(s, 1); sets(s); + switch (k) { + case 13: v = LLVMBuildAdd(bd, b, a, ""); break; + case 14: v = LLVMBuildSub(bd, b, a, ""); break; + case 15: v = LLVMBuildMul(bd, b, a, ""); break; + case 16: v = LLVMBuildAnd(bd, b, a, ""); break; + case 17: v = LLVMBuildOr(bd, b, a, ""); break; + case 18: v = LLVMBuildXor(bd, b, a, ""); break; + case 19: v = LLVMBuildAShr(bd, b, LLVMBuildAnd(bd, a, K32(31), ""), ""); break; + default: v = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, b, a, ""), i32t, ""); + } + st(s, v); break; + case 21: /* install: then back to the loop, which drops every block */ + at[0] = i32t; args[0] = ld(s); + st(s, callp((void *)linstall, i32t, at, 1, args)); + leave(K32(i + 1)); done = 1; break; + default: + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { ir_enh(&enh[k - XOP0]); break; } + leave(K32(MW)); done = 1; /* not wired: halt */ + } + i++; + } + lbl[nlbl].a = p; lbl[nlbl++].b = i; + po = LLVMCreatePassBuilderOptions(); + if ((err = LLVMRunPasses(mod_, lpasses, 0, po))) { LLVMConsumeError(err); } + LLVMDisposePassBuilderOptions(po); + if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, LLVMOrcLLJITGetMainJITDylib(jit), LLVMOrcCreateNewThreadSafeModule(mod_, tsc)))) { + char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; + } + if ((err = LLVMOrcLLJITLookup(jit, &addr, name))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; } + if (trace) fprintf(stderr, "llvm: %d..%d compiled\n", p, i - 1); + return (Blk)(size_t)addr; +} +#endif +#define LD(x) ((unsigned)(x) < MW ? m[x] : 0) +static int run(int p) +{ + int s = DS0, r = RS0, w, a, b, xfer = 1; + unsigned long long steps = 0; +#ifdef ZYLLVM + int regs[2]; + if (!getenv("ZYNOLLVM")) llvm_init(); +#endif + while ((unsigned)p < MW) { + if (xfer && (s < DSLIM || r > RSLIM)) { p = s < DSLIM ? MW + 1 : MW + 2; break; } +#ifdef ZYLLVM + if (xfer && llvm_ok) { /* at a block start: run it compiled, or count it */ + xfer = 0; + if (!lt[p] && hot[p] < 65535 && ++hot[p] == HOT && !(lt[p] = lcompile(p))) hot[p] = 65535; + if (lt[p]) { + regs[0] = s; regs[1] = r; + p = lt[p](m, regs); + s = regs[0]; r = regs[1]; + if (need_flush) { need_flush = 0; ldrop_all(); } + xfer = 1; + continue; + } + } +#endif + 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) { +#ifdef ZYLLVM + if (lcov[a]) lhook(a, b); else +#endif + 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++; xfer = 1; break; + case 7: p = a; s++; xfer = 1; break; + case 8: if (!b) { p = a; xfer = 1; } s += 2; break; + case 9: p = m[--r]; xfer = 1; 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; + case 21: + m[s] = install(a); +#ifdef ZYLLVM + if (need_flush) { need_flush = 0; ldrop_all(); } +#endif + break; + default: + if (w / 2 >= XOP0 && w / 2 < XOP0 + NENH && enh[w / 2 - XOP0].live) s = (int)(xexec(&enh[w / 2 - XOP0], m + s) - m); + else p = MW; /* halt: unwired opcodes and the reserved negative ones */ + } + } + if (trace) fprintf(stderr, "interp: %llu steps\n", steps); + return stopped(p); +} +#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; + S[9] = (long)inst_hook; S[10] = (long)xrun; + S[11] = (long)(m + DSLIM); S[12] = (long)(m + RSLIM); + 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); + if (need_flush) { need_flush = 0; jitwrite(1); flush(); jitwrite(0); } + } + return stopped(p); + } +#else + return run(GORG); +#endif + return 0; +} diff --git a/docs/history/13-gap-fixes/code/examples/echo.zc b/docs/history/13-gap-fixes/code/examples/echo.zc new file mode 100644 index 0000000..01f28b0 --- /dev/null +++ b/docs/history/13-gap-fixes/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/13-gap-fixes/code/examples/fact.zc b/docs/history/13-gap-fixes/code/examples/fact.zc new file mode 100644 index 0000000..2a218b2 --- /dev/null +++ b/docs/history/13-gap-fixes/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/13-gap-fixes/code/examples/hello.zc b/docs/history/13-gap-fixes/code/examples/hello.zc new file mode 100644 index 0000000..f36a810 --- /dev/null +++ b/docs/history/13-gap-fixes/code/examples/hello.zc @@ -0,0 +1 @@ +fn main() { puts("hello, world!\n"); return 0; } diff --git a/docs/history/13-gap-fixes/code/examples/lists.zc b/docs/history/13-gap-fixes/code/examples/lists.zc new file mode 100644 index 0000000..6ac276e --- /dev/null +++ b/docs/history/13-gap-fixes/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 { let b = new(1); b[0] = v; return u*b; } +fn mklist(cap) -> .u { let l = new(cap + 1); l[0] = 0; return u*l; } +// item m*arrives (it was given down), and goes d*on into the borrowed list +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn show(.m l) +{ + let i = 1; + putc('['); + while (i <= l[0]) { if (i > 1) putc(' '); putn(l[i][0]); i++; } + putc(']'); + return 0; +} +fn squares(n) -> .u +{ + let l = mklist(n), i = 0; + while (i < n) { + let b = box(i * i); + push(l, d*b); + i++; + } + return u*l; +} +fn main() +{ + let before = live_objects(); + { + let 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/13-gap-fixes/code/examples/repl.zc b/docs/history/13-gap-fixes/code/examples/repl.zc new file mode 100644 index 0000000..b7b81b8 --- /dev/null +++ b/docs/history/13-gap-fixes/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. +let buf[4000]; +fn readchunk() +{ + let 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() +{ + let 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(d*q); + } + return 0; +} diff --git a/docs/history/13-gap-fixes/code/examples/selfpatch.zc b/docs/history/13-gap-fixes/code/examples/selfpatch.zc new file mode 100644 index 0000000..074ccec --- /dev/null +++ b/docs/history/13-gap-fixes/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() +{ + let 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/13-gap-fixes/code/examples/typed.zc b/docs/history/13-gap-fixes/code/examples/typed.zc new file mode 100644 index 0000000..d91fe6a --- /dev/null +++ b/docs/history/13-gap-fixes/code/examples/typed.zc @@ -0,0 +1,47 @@ +// types: structs, a generic container, and looking at it all through reflection +typecheck on; +struct point { int x, y; }; +struct vec { int len, cap; *T items; }; + +fn mkvec(int cap) -> *vec.u +{ + *vec v = new(vec); + v.cap = cap; + v.items = new(T, cap); + return u*v; +} +// x is given away (.d): the vector's memory holds it from now on, and the +// collector looks after it +fn push(*vec v, T.d x) -> bool +{ + if (v.len == v.cap) { free(d*x); return 0; } + v.items[v.len] = d*x; + v.len++; + return 1; +} +fn show(word t) +{ + let i = 0; + tprint(t); puts(" is "); putn(tsize(t)); puts(" words: "); + while (i < tnfields(t)) { if (i) puts(", "); puts(tfname(t, i)); puts(" "); tprint(tftype(t, i)); i++; } + putc(10); + return 0; +} +fn main() -> int +{ + *vec<*point> v = mkvec<*point>(4); + int i = 0; + while (i < 3) { + *point p = new(point); + p.x = i; p.y = i * i; + push(v, d*p); + i++; + } + puts("last: "); putn(v.items[2].y); putc(10); + show(typeof(point)); + show(typeof(*v)); + puts("push is "); tprint(sigof(push)); putc(10); + // generic code is compiled once, so what mkvec stamped is vec + puts("the heap says v is a "); tprint(typeof_obj(v)); puts(", and v.items[0] is a "); tprint(typeof_obj(v.items[0])); putc(10); + return 0; +} diff --git a/docs/history/13-gap-fixes/code/examples/wiring.zc b/docs/history/13-gap-fixes/code/examples/wiring.zc new file mode 100644 index 0000000..ed30935 --- /dev/null +++ b/docs/history/13-gap-fixes/code/examples/wiring.zc @@ -0,0 +1,19 @@ +// virtual enhancements: custom opcodes wired into the cpu while compiling. +// the recipes run through the core's optimizer; the jit inlines the result. +enhance popcount(x) micro + "r1 = shr x 1; r1 = and r1 0x55555555; x = sub x r1" + "; r1 = shr x 2; r1 = and r1 0x33333333; x = and x 0x33333333; x = add x r1" + "; r1 = shr x 4; x = add x r1; x = and x 0x0f0f0f0f; x = mul x 0x01010101; x = shr x 24"; +enhance div10(x) micro "x = udiv x 10"; // becomes a multiply-high, no divide +enhance hypot2(a, b) vm { 0 $ * ~ 0 $ * + }; // lifted from vm code +enhance minmax(a, b) -> 2 micro "r2 = min a b; r1 = max a b; r0 = r2"; +let lo, hi; +fn main() +{ + putn(popcount(0xff00ff)); putc(' '); + putn(div10(12345)); putc(' '); + putn(hypot2(3, 4)); putc(' '); + asm { 9 4 minmax hi ! lo ! } + putn(lo); putc('/'); putn(hi); putc(10); + return 0; +} diff --git a/docs/history/13-gap-fixes/code/genome.h b/docs/history/13-gap-fixes/code/genome.h new file mode 100644 index 0000000..fecb1c9 --- /dev/null +++ b/docs/history/13-gap-fixes/code/genome.h @@ -0,0 +1,4443 @@ +#define GORG 786432 +static const int genome[] = { +1966081,1310721,4,1703963,14,852206,857446,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1572913,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,42,1572933, +14,1,1310721,2,3,26,1310721,4,18,0,0,2,1,786486,0,786480, +786482,786484,97,0,98,0,97,32,61,32,115,100,105,118,32,97, +32,98,0,1,0,2,1,786512,0,786506,786508,786510,97,0,98,0, +97,32,61,32,115,114,101,109,32,97,32,98,0,2,0,2, +1,786538,0,786532,786534,786536,97,0,98,0,97,32,61,32,115,104, +108,32,97,32,98,0,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1573135,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,24,1,1573157, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1573205,16,1966081,1310721,4,1579069,12,20,1573213,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1573261, +16,1966081,1310721,4,1579069,12,22,1573269,14,1,1310721,2,1,26,1310721,4, +18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1573317,16,1966081,1310721,4, +1579069,12,0,1,1573327,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1573375,16,1966081,1310721,4,1579069,12,1310721, +2,4,1,1310721,2,3,26,4,1310721,2,2,1310721,2,3,26,2, +26,2,1573481,16,1310721,2,2,1310721,2,3,26,2,26,2,1573101,12, +8,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1573393,14,1,1573489,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,29,28,1310721,4,1310721,2,1835009,40,1573537,16,1966081,1310721,4,1579069,12, +1310721,2,4,1,1310721,2,27,26,4,1310721,2,2,1,40,1573603,16, +91,1573101,12,8,1310721,2,1,1310721,2,2,28,10,3,6,10,4, +8,1310721,2,2,1,40,1573657,16,1573643,14,50,49,52,55,52,56, +51,54,52,56,0,1573621,1573341,12,8,1,1573871,14,3,1573795,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,46,26,10,3,6,10,4, +8,1310721,2,1310721,2,2,21,44,10,3,6,10,4,8,1310721,2, +2,1,6,1,10,28,34,63,38,3,26,1573791,16,1573795,14,1573657, +14,1310721,2,27,26,2,1573863,16,1310721,2,3,26,1310721,2,27,26, +1,6,2,-1,26,1,6,5,6,4,10,8,26,2,1573101,12, +8,1573795,14,1,1573871,14,1,1310721,2,29,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1573919,16,1966081,1310721,4,1579069,12,1310721, +2,4,1,1310721,2,3,26,4,1310721,2,2,1310721,2,3,26,2, +26,2,1573999,16,1310721,2,3,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1573937,14,1310721,2,3,26,2,1574015,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40, +1574063,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1, +1310721,2,5,26,4,1310721,2,2,1310721,2,5,26,2,26,2,1574207, +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,1574209,14,1, +1574251,16,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1574091,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,1574323,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,1835009,40,1574371,16,1966081,1310721,4,1579069, +12,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,1574527, +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,1574409,14,1, +1574535,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4, +1310721,2,1835009,40,1574583,16,1966081,1310721,4,1579069,12,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,1574725,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, +1574621,14,1,1574733,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,1835009,40,1574847,16,1966081,1310721,4,1579069,12,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,1574947,16,1574811,1310721,2,2,10,3,6,10,4,8,1,1575261, +14,1310721,2,9,26,2,1,40,3,36,1575221,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,1575183, +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,1574947,14,1574811,1310721,2,7,26,2, +10,3,6,10,4,8,1310721,2,5,26,2,1575261,14,1,1310721,2, +11,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1575309, +16,1966081,1310721,4,1579069,12,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,1575401,16,1574811,1310721,2,2,10,3,6,10,4, +8,1,1575637,14,1310721,2,2,1,40,1575463,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,1575549,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,1574813,12,10,3,6,10, +4,8,1310721,2,5,26,2,1575621,16,1,1310721,2,7,26,2,28, +1575637,14,1310721,2,7,26,2,1575637,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1575685,16,1966081,1310721,4, +1579069,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1,40,1310721, +2,5,26,4,1310721,2,3,26,2,1,28,1,6,1,10,28, +34,63,38,3,26,1575769,16,1310721,2,2,1575827,14,1310721,2,2,1310721, +2,3,26,2,1575275,12,8,1310721,2,5,26,2,1575817,16,1,1574811, +2,28,1575827,14,1574811,2,1575827,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1575875,16,1966081,1310721,4,1579069, +12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1574747,1310721,2,3, +26,2,63,32,26,2,30,1575925,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,9,28,1310721,4,1310721,2,1835009,40,1576045, +16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,524289,28,1310721,2,3,26, +4,1,1310721,2,5,26,4,1310721,2,3,26,2,1576341,16,1310721,2, +7,26,3,10,3,6,10,4,8,1310721,2,7,26,2,1310721,2, +7,26,2,26,1310721,2,3,26,2,10,40,3,36,1576205,16,1310721, +2,7,26,1310721,2,7,26,2,1310721,2,7,26,2,26,10,3, +6,10,4,8,1576115,14,1310721,2,2,1310721,2,5,26,2,1310721,2, +7,26,2,26,40,1576253,16,1310721,2,7,26,2,1576349,14,1310721,2, +5,26,1310721,2,5,26,2,1310721,2,7,26,2,26,10,3,6, +10,4,8,1310721,2,3,26,1310721,2,3,26,2,1310721,2,7,26, +2,28,10,3,6,10,4,8,1576079,14,1,1576349,14,1,1310721,2, +9,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1576397, +16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,5,26,1,10,3,6,10,4,8,1310721,2,2,13,26,1575941, +1310721,2,3,26,2,26,2,10,3,6,10,4,8,1310721,2,2, +15,26,1,10,3,6,10,4,8,1575941,1310721,2,3,26,2,26, +2,1576557,16,1575941,1310721,2,3,26,2,26,2,15,26,1310721,2,2, +10,3,6,10,4,8,1575941,1310721,2,3,26,2,26,1310721,2,2, +10,3,6,10,4,8,1,1576597,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1576645,16,1966081,1310721,4, +1579069,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,15,26,2, +1576721,16,1310721,2,2,15,26,2,13,26,1310721,2,2,13,26,2, +10,3,6,10,4,8,1576759,14,1575941,1310721,2,3,26,2,26,1310721, +2,2,13,26,2,10,3,6,10,4,8,1310721,2,2,13,26, +2,1576815,16,1310721,2,2,13,26,2,15,26,1310721,2,2,15,26, +2,10,3,6,10,4,8,1,1576823,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1576871,16,1966081,1310721, +4,1579069,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1,26, +1574747,1310721,2,3,26,2,26,2,10,3,6,10,4,8,1310721,2, +2,3,26,1310721,2,3,26,2,10,3,6,10,4,8,1310721,2, +2,5,26,1,10,3,6,10,4,8,1310721,2,2,7,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,1,10,3,6,10,4,8,1310721,2, +2,1577065,14,1,1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,1835009,40,1577113,16,1966081,1310721,4,1579069,12,3,1310721,2,4, +524289,1310721,2,3,26,4,1574747,1,26,3,10,3,6,10,4,8, +1310721,2,2,65,40,1577257,16,1574747,1310721,2,2,26,1574747,1310721,2,2, +3,28,26,2,1574747,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,1577153,14,1575939,1310721,10,3,6,10,4,8,1575941,1,65,1574549, +12,8,1310721,2,3,26,2,1310721,40,1577519,16,1310721,2,5,26,1310721, +2,3,26,2,524289,28,1576011,12,10,3,6,10,4,8,1310721,2, +7,26,1,10,3,6,10,4,8,1574747,1310721,2,7,26,2,26, +2,1310721,2,5,26,2,40,1577433,16,1310721,2,7,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1577363,14,1310721,2,3,26, +2,1310721,2,7,26,2,1576837,12,1310721,2,7,26,2,1576363,12,8, +1310721,2,3,26,1310721,2,3,26,2,1310721,2,5,26,2,26,10, +3,6,10,4,8,1577285,14,1,1577527,14,1,1310721,2,9,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1577575,16,1966081,1310721, +4,1579069,12,1310721,2,4,1310721,2,2,1310721,2,3,26,4,1310721,2, +3,26,2,65,40,1577677,16,1575941,1310721,2,3,26,2,26,2,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1577679,14,1,1577721,16,1310721,2,3,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1577597,14,1310721,2,3,26, +2,65,40,3,36,1577749,16,1,1577999,14,1310721,2,5,26,1575941,1310721, +2,3,26,2,26,2,10,3,6,10,4,8,1310721,2,5,26, +2,1310721,2,3,26,2,1576611,12,8,1310721,2,3,26,2,1310721,2, +2,10,40,1577961,16,1310721,2,3,26,1,6,2,1,6,-1,26, +5,6,4,10,8,8,1310721,2,7,26,1310721,2,5,26,2,1574747, +1310721,2,3,26,2,26,2,26,10,3,6,10,4,8,1310721,2, +7,26,2,1310721,2,3,26,2,1576837,12,1310721,2,3,26,2,1576363, +12,8,1577811,14,1310721,2,5,26,2,1310721,2,2,1576837,12,8,1310721, +2,5,26,2,1577999,14,1,1310721,2,9,26,1310721,4,18,0,1310721, +2,11,28,1310721,4,1310721,2,1835009,40,1578049,16,1966081,1310721,4,1579069,12, +1310721,2,4,1310721,2,2,3,26,2,1310721,2,3,26,4,1574747,1310721, +2,3,26,2,26,2,1310721,2,5,26,4,3,1578721,16,1310721,2, +7,26,1310721,2,2,524289,28,10,3,6,10,4,8,1310721,2,5, +26,2,1310721,2,7,26,2,1576011,12,40,3,36,1578177,16,1578721,14, +1310721,2,9,26,524289,1310721,2,7,26,2,1310721,2,5,26,2,36, +26,10,3,6,10,4,8,1310721,2,9,26,2,5,26,2,1, +28,1,6,1,10,28,34,63,38,1,10,28,1578275,16,3,1578347, +14,1310721,2,9,26,2,3,26,2,1310721,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,1578357,16,3,1578429,14,1310721,2,9,26,2,1, +26,2,1310721,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,1578437,16, +1578721,14,1310721,2,9,26,2,1310721,2,3,26,2,1576611,12,8,1310721, +2,9,26,2,1310721,2,2,40,1578563,16,1310721,2,2,1,26,1, +10,3,6,10,4,8,1310721,2,2,7,26,1,10,3,6,10, +4,8,1310721,2,1310721,2,9,26,2,10,3,6,10,4,8,1578619, +14,1310721,2,9,26,2,1,26,1,10,3,6,10,4,8,1310721, +2,9,26,2,7,26,1,10,3,6,10,4,8,1310721,2,3, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1310721,2, +5,26,1310721,2,5,26,2,1310721,2,5,26,2,26,10,3,6, +10,4,8,1310721,2,2,1310721,2,3,26,2,1576837,12,8,1578103,14, +1310721,2,2,1310721,2,3,26,2,1576837,12,1310721,2,3,26,2,1576363, +12,8,1578013,1310721,2,2,1310721,2,5,26,2,26,10,3,6,10, +4,8,1,1578797,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1578845,16,1966081,1310721,4,1579069,12,1310721,2, +4,1310721,2,2,524289,13,26,40,3,36,1578911,16,1310721,2,2,1575939, +2,40,1,6,1,10,28,34,63,38,1,10,28,1578913,14,1, +1578993,16,1310721,2,2,7,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,1578995,14,1,1579047,16,1310721,2,2,9,1, +10,28,26,2,3,32,1,6,1,10,28,34,63,38,1,10, +28,1579049,14,1,1579055,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +1,28,1310721,4,1310721,2,1835009,40,1579103,16,1966081,1310721,4,1579069,12,1579159, +14,122,121,58,32,102,114,97,109,101,32,115,116,97,99,107, +32,111,118,101,114,102,108,111,119,10,0,1579107,1573341,12,8,1573283, +12,8,1,1579181,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1, +28,1310721,4,1310721,2,1835009,40,1579229,16,1966081,1310721,4,1579069,12,1579281,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,1579233,1573341,12,8,1573283,12,8,1, +1579303,14,1,1310721,2,1,26,1310721,4,18,1310721,2,13,28,1310721,4, +1310721,2,1835009,40,1579351,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,13,26,1310721,2,5,26,4,7,1310721,2, +7,26,4,1310721,2,2,1,40,1579435,16,1310721,2,5,26,13,10, +3,6,10,4,8,1574747,1310721,2,7,26,2,26,2,1310721,2,5, +26,2,40,1579505,16,1310721,2,7,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1579435,14,1310721,2,9,26,1310721,2,7,26, +2,1577541,12,10,3,6,10,4,8,1310721,2,9,26,2,1,6, +1,10,28,34,63,38,3,26,1579603,16,1576009,2,1,6,1,10, +28,34,63,38,1,10,28,1579605,14,1,1579649,16,1581445,12,8,1310721, +2,9,26,1310721,2,7,26,2,1577541,12,10,3,6,10,4,8, +1310721,2,9,26,2,1,6,1,10,28,34,63,38,3,26,1579689, +16,1579195,12,8,1310721,2,11,26,1310721,2,9,26,2,13,26,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,9,26,2,11,26,1310721,2,3,26, +2,10,3,6,10,4,8,1310721,2,11,26,2,1,1574747,1310721,2, +7,26,2,26,2,13,28,1574549,12,8,1310721,2,11,26,2,1579909, +14,1,1310721,2,13,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1579957,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2, +1,1579317,12,1579981,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1580029,16,1966081,1310721,4,1579069,12,1310721,2, +4,1310721,2,2,1578811,12,1,6,1,10,28,34,63,38,3,26, +1580075,16,1,1580103,14,1310721,2,2,13,1,10,28,26,2,13,28, +1580103,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1580151,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2, +2,1578811,12,1,6,1,10,28,34,63,38,3,26,1580197,16,1, +1580221,14,1310721,2,2,3,1,10,28,26,2,1580221,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1580269, +16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,13,28,1310721,2, +3,26,4,1310721,2,3,26,2,1,26,2,13,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,1580585,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,1578811,12,1580525,16, +1310721,2,9,26,2,5,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,1580527,14,1,1580547,16,1310721,2,9,26,2,1580235,12, +8,1310721,2,7,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1580365,14,1310721,2,3,26,2,1578015,12,8,1,1580609,14,1, +1310721,2,11,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1580657,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1578811,12, +1580689,16,1310721,2,2,1580235,12,8,1,1580697,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1580745,16,1966081, +1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1578811, +12,1580813,16,1310721,2,2,5,1,10,28,26,1310721,2,3,26,2, +10,3,6,10,4,8,1310721,2,2,1580825,14,1,1310721,2,5,26, +1310721,4,18,0,0,0,0,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1580881,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1578811,12, +1,6,1,10,28,34,63,38,3,26,1580927,16,3,1580971,14,1310721, +2,2,9,1,10,28,26,2,5,32,1,6,1,10,28,34, +63,38,1,10,28,1580981,16,1,1581125,14,1310721,2,2,9,1,10, +28,26,1310721,2,2,9,1,10,28,26,2,5,34,10,3,6, +10,4,8,1580839,2,32769,40,1581101,16,2031617,1580839,2,26,1310721,2,2, +10,3,6,10,4,8,1580839,1,6,2,1,6,3,26,5,6, +4,10,8,8,1581117,14,1580841,3,10,3,6,10,4,8,1,1581125, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1581173,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721, +2,4,1310721,2,2,1310721,2,3,26,2,40,1581259,16,1310721,2,2, +2,1580847,12,8,1310721,2,1,6,2,1,6,3,26,5,6,4, +10,8,8,1581189,14,1,1581267,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1581315,16,1966081,1310721,4,1579069, +12,1580839,2,1581423,16,1580839,1,6,2,1,6,-1,26,5,6,4, +10,8,8,1310721,2,2031617,1580839,2,26,2,10,3,6,10,4,8, +1310721,2,2,1310721,2,2,1310721,2,2,13,1,10,28,26,2,26, +13,28,1581139,12,8,1581315,14,1,1581431,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1581479,16,1966081,1310721, +4,1579069,12,1,1310721,2,5,26,4,1580839,1,10,3,6,10,4, +8,1580841,1,10,3,6,10,4,8,1700815,12,8,1581281,12,8,1580841, +2,1581717,16,1580841,1,10,3,6,10,4,8,1310721,2,524289,10,3, +6,10,4,8,1310721,2,2,1310721,40,1581713,16,1310721,2,2,5,26, +2,7,28,1,6,1,10,28,34,63,38,3,26,1581667,16,1310721, +2,2,13,26,1310721,2,2,1310721,2,2,1,26,2,26,1581139,12, +8,1310721,2,1310721,2,2,1310721,2,2,1,26,2,26,10,3,6, +10,4,8,1581281,12,8,1581577,14,1581535,14,1310721,2,524289,10,3,6, +10,4,8,1310721,2,2,1310721,40,1581993,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,1581891,16,1310721,2, +2,1578015,12,8,1310721,2,5,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1310721,2,1578013,2,10,3,6,10,4,8,1581989, +14,1310721,2,2,5,26,2,7,28,1,6,1,10,28,34,63, +38,3,26,1581955,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,1581735,14,1576005,1,6,2,1,6,3,26,5,6,4,10, +8,8,1576007,1576007,2,1310721,2,5,26,2,26,10,3,6,10,4, +8,1310721,2,5,26,2,1582067,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1582115,16,1966081,1310721,4,1579069, +12,524289,1310721,2,4,1,1310721,2,3,26,4,1310721,2,2,1310721,40, +1582243,16,1310721,2,2,5,26,2,3,32,1582203,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,1582135, +14,1310721,2,3,26,2,1582259,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1582307,16,1966081,1310721,4,1579069, +12,63,1310721,2,4,1310721,2,2,1,10,40,1582389,16,1575941,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,1582391,14,1,1582429,16,1310721,2,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1582315,14,1575941,1310721, +2,2,26,2,1,6,1,10,28,34,63,38,3,26,1582471,16, +1,1582489,14,1574747,1310721,2,2,26,2,1582489,14,1,1310721,2,3,26, +1310721,4,18,0,0,0,0,0,0,0,0,0,0,0,0,791264, +113,64,33,36,95,126,99,106,122,114,44,63,46,43,45,42, +38,124,94,62,60,37,0,1,0,0,0,0,1,0,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,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,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,1,28,1310721,4,1310721,2,1835009,40,1585127,16,1966081,1310721, +4,1579069,12,1585151,14,122,99,58,32,108,105,110,101,32,0,1585131, +1573341,12,8,1582583,2,1573503,12,8,1585179,14,58,32,0,1585173,1573341,12, +8,1585089,1,6,2,1,6,3,26,5,6,4,10,8,8,1, +1585223,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1585271,16,1966081,1310721,4,1579069,12,21,1573101,12,8,1585089, +2,41,40,3,36,1585375,16,1585361,14,122,99,58,32,116,111,111, +32,109,97,110,121,32,101,114,114,111,114,115,44,32,115,116, +111,112,112,105,110,103,10,0,1585299,1573341,12,8,1573283,12,8,1, +1585383,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1585431,16,1966081,1310721,4,1579069,12,1585445,14,122,99,58, +32,0,1585435,1573341,12,8,1585089,2,1573503,12,8,1585089,2,3,28,1, +6,1,10,28,34,63,38,3,26,1585527,16,1585515,14,32,101,114, +114,111,114,10,0,1585499,1573341,12,8,1585557,14,1585549,14,32,101,114, +114,111,114,115,10,0,1585531,1573341,12,8,1573283,12,8,1,1585571,14, +1,1310721,2,1,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1585619,16,1966081,1310721,4,1579069,12,1310721,2,4,1585093,12,8,1310721, +2,2,1573341,12,8,21,1573101,12,8,1573283,12,8,1,1585665,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1585713,16,1966081,1310721,4,1579069,12,1310721,2,4,1585091,2,1,6,1, +10,28,34,63,38,3,26,1585797,16,1584991,2,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1585799,14,1,1585827,16,1585093,12,8,1310721,2,2,1573341,12,8,1585237,12, +8,1,1585835,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1585883,16,1966081,1310721,4,1579069,12,1310721,2,3, +26,4,1310721,2,4,1585091,2,1,6,1,10,28,34,63,38,3, +26,1585977,16,1584991,2,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1585979,14,1,1586041,16,1585093, +12,8,1310721,2,2,1573341,12,8,1586011,14,58,32,0,1586005,1573341,12, +8,1310721,2,3,26,2,1573341,12,8,1585237,12,8,1,1586049,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1586097,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1585679,12, +8,1585091,3,10,3,6,10,4,8,1582577,2,1,28,1,6,1, +10,28,34,63,38,3,26,1586169,16,1585397,12,8,1597071,12,8,1, +1586183,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1586231,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,1310721,2,3,26,2,1585849,12,8,1585091,3, +10,3,6,10,4,8,1582577,2,1,28,1,6,1,10,28,34, +63,38,3,26,1586323,16,1585397,12,8,1597071,12,8,1,1586337,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1586385,16,1966081,1310721,4,1579069,12,1310721,2,4,1584853,2,1586429,16,1584857, +2,1,6,1,10,28,34,63,38,1,10,28,1586431,14,1,1586447, +16,1310721,2,2,1585679,12,8,1,1586455,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1586503,16,1966081,1310721, +4,1579069,12,1310721,2,3,26,4,1310721,2,4,1584853,2,1586557,16,1584857, +2,1,6,1,10,28,34,63,38,1,10,28,1586559,14,1,1586591, +16,1466881,1310721,2,2,26,2,1310721,2,3,26,2,1585849,12,8,1, +1586599,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1586647,16,1966081,1310721,4,1579069,12,1310721,2,4,1,1310721, +2,3,26,4,1310721,2,2,2,1586755,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,1586665, +14,1310721,2,3,26,2,16385,3,28,32,1586779,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1586827,16, +1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1586613,12,1310721,2,3, +26,4,3,1587017,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,1586933,16,1587017,14,1310721,2,5,26,2,1310721, +2,2,1574029,12,1586971,16,1310721,2,5,26,2,1587297,14,1310721,2,3, +26,1310721,2,3,26,2,3,26,16385,3,28,32,10,3,6,10, +4,8,1586853,14,1310721,2,7,26,1310721,2,2,1573885,12,10,3,6, +10,4,8,1582505,2,1310721,2,7,26,2,26,5,26,1409025,40,3, +36,1587125,16,1587117,14,115,116,114,105,110,103,32,112,111,111,108, +32,102,117,108,108,0,1587083,1585585,12,8,1582505,2,1,26,1,10, +3,6,10,4,8,1310721,2,5,26,1582505,2,3,26,10,3,6, +10,4,8,1310721,2,5,26,2,1310721,2,2,1310721,2,7,26,2, +3,26,1574337,12,8,1582505,1582505,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,1587297,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009, +40,1587345,16,1966081,1310721,4,1579069,12,1310721,2,5,26,4,1310721,2,3, +26,4,1310721,2,4,1582507,2,1310721,2,7,26,4,1582507,2,8193,40, +3,36,1587449,16,1587441,14,115,121,109,98,111,108,32,116,97,98, +108,101,32,102,117,108,108,0,1587405,1585585,12,8,1582507,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,1559041,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,1587795,14,1,1310721,2,9,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1587843,16,1966081,1310721,4,1579069, +12,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,1588129,16,1310721, +2,3,26,2,1582511,2,40,3,36,1587933,16,3,1587995,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,1588005,16,3, +1588067,14,1417729,1310721,2,3,26,2,26,2,15,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1588085,16,1310721,2,3,26,2,1588143,14,1310721,2,3,26,1458689,1310721, +2,3,26,2,26,2,3,28,10,3,6,10,4,8,1587881,14, +3,1,10,28,1588143,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1588191,16,1966081,1310721,4,1579069,12,1310721, +2,4,1582507,2,1310721,2,2,10,40,1588289,16,1582507,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1409537,1582507,2,26,2,3,1, +10,28,26,1458689,1582507,2,26,2,10,3,6,10,4,8,1588197,14, +1,1588297,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1588345,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721, +2,2,1586793,12,1587809,12,1588371,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,7,28,1310721,4,1310721,2,1835009,40,1588419,16,1966081,1310721,4,1579069, +12,1310721,2,3,26,4,1310721,2,4,1582515,2,1310721,2,5,26,4, +1310721,2,5,26,2,1588497,16,1582515,1491457,1310721,2,5,26,2,26,2, +10,3,6,10,4,8,1588639,14,1582513,1,6,2,1,6,3,26, +5,6,4,10,8,8,1310721,2,5,26,1582513,2,10,3,6,10, +4,8,1310721,2,5,26,2,16385,40,3,36,1588639,16,1588631,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,1588575,1585585,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,1588723,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,7,28,1310721,4,1310721,2,1835009,40,1588771,16,1966081,1310721,4,1579069, +12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1588933,16,1475073,1310721, +2,2,26,2,1310721,2,3,26,2,1589317,12,8,1310721,2,5,26, +1491457,1310721,2,2,26,2,10,3,6,10,4,8,1491457,1310721,2,2, +26,1582515,2,10,3,6,10,4,8,1582515,1310721,2,2,10,3,6, +10,4,8,1310721,2,1310721,2,5,26,2,10,3,6,10,4,8, +1588787,14,1,1588941,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1588989,16,1966081,1310721,4,1579069,12,1310721,2, +4,1584991,2,1589009,16,1,1589135,14,1584837,2,1584841,2,40,3,36,1589071, +16,1589063,14,112,114,111,103,114,97,109,32,116,111,111,32,98, +105,103,0,1589031,1585585,12,8,1584837,2,1584839,2,26,1310721,2,2,10, +3,6,10,4,8,1584837,1,6,2,1,6,3,26,5,6,4, +10,8,8,1,1589135,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1589183,16,1966081,1310721,4,1579069,12,1310721, +2,4,1310721,2,2,1310721,2,2,26,3,26,1588955,12,8,1,1589221, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1589269,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2, +1310721,2,2,26,1588955,12,8,1,1589303,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1589351,16,1966081,1310721, +4,1579069,12,1310721,2,3,26,4,1310721,2,4,1584991,2,1589381,16,1, +1589439,14,1310721,2,2,1584839,2,26,1310721,2,3,26,2,1310721,2,3, +26,2,26,3,26,10,3,6,10,4,8,1,1589439,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1589487,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1589149,12,8, +15,1589235,12,8,1,1589521,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1589569,16,1966081,1310721,4,1579069,12, +1584837,2,1310721,2,4,2097153,3,28,1589149,12,8,1310721,2,2,1589603,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +1835009,40,1589651,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,3, +1582583,2,1587311,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,1589727,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1589775,16,1966081,1310721,4,1579069,12,1310721,2,4,1442305,1310721,2,2,26,2, +3,32,1589825,16,1425921,1310721,2,2,26,2,1589149,12,8,1,1589901,14, +1584991,2,1589839,16,1,1589901,14,1450497,1310721,2,2,26,1584837,2,1450497,1310721, +2,2,26,2,1588385,12,10,3,6,10,4,8,2097153,3,28,1589149, +12,8,1,1589901,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1589949,16,1966081,1310721,4,1579069,12,1310721,2, +4,1310721,2,2,1587809,12,1310721,2,3,26,4,1310721,2,3,26,2, +1,40,1590023,16,1310721,2,3,26,1310721,2,2,1589617,12,10,3,6, +10,4,8,1310721,2,3,26,2,1589741,12,8,13,1589235,12,8,1, +1590055,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1590103,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,1589149, +12,8,3,1589235,12,8,1310721,2,2,1590155,16,1310721,2,2,1589149,12, +8,27,1589235,12,8,1,1590163,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,7,28,1310721,4,1310721,2,1835009,40,1590211,16,1966081,1310721,4,1579069, +12,1310721,2,4,1589535,12,1310721,2,3,26,4,15,1589235,12,8,1310721, +2,5,26,1584837,2,10,3,6,10,4,8,1310721,2,2,2,1590323, +16,1310721,2,2,2,1588955,12,8,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1590263,14,1,1588955,12,8,1310721,2,3, +26,2,1584837,2,1589317,12,8,1310721,2,5,26,2,1589149,12,8,1, +1590375,14,1,1310721,2,7,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1590423,16,1966081,1310721,4,1579069,12,1582589,2,1,28,1, +6,1,10,28,34,63,38,3,26,1590629,16,1582595,2,1590469,16,3, +1590495,14,1573227,12,1,6,1,10,28,34,63,38,1,10,28,1590527, +16,1582587,3,1,10,28,10,3,6,10,4,8,1,1590929,14,1582587, +1573171,12,511,32,10,3,6,10,4,8,1582587,2,193,28,1,6, +1,10,28,34,63,38,3,26,1590625,16,1582595,3,10,3,6,10, +4,8,1582587,3,1,10,28,10,3,6,10,4,8,1,1590929,14, +1590861,14,1582589,2,7,28,1,6,1,10,28,34,63,38,3,26, +1590775,16,1582587,1582593,2,1582591,2,5,38,26,2,1582591,2,7,32,17, +30,38,511,32,10,3,6,10,4,8,1582587,2,1590749,16,1582591,1, +6,2,1,6,3,26,5,6,4,10,8,8,1590771,14,1582587,3, +1,10,28,10,3,6,10,4,8,1590861,14,1582587,1582591,2,2,511, +32,10,3,6,10,4,8,1582587,2,1590839,16,1582591,1,6,2,1, +6,3,26,5,6,4,10,8,8,1590861,14,1582587,3,1,10,28, +10,3,6,10,4,8,1582587,2,21,28,1,6,1,10,28,34, +63,38,3,26,1590921,16,1582585,1,6,2,1,6,3,26,5,6, +4,10,8,8,1,1590929,14,1,1310721,2,1,26,1310721,4,18,1310721, +2,13,28,1310721,4,1310721,2,1835009,40,1590977,16,1966081,1310721,4,1579069,12, +1310721,2,7,26,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721, +2,4,1582597,1,6,2,1,6,3,26,5,6,4,10,8,8, +1582597,2,65,40,3,36,1591121,16,1591113,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,1591061,1585585,12,8,1310721,2,9,26,1540609,1582597,2,65, +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,1582577,2,10,3,6,10,4,8,1310721,2,9,26,2,13,26, +1582579,2,10,3,6,10,4,8,1310721,2,9,26,2,15,26,1582581, +2,10,3,6,10,4,8,1310721,2,9,26,2,17,26,1582587,2, +10,3,6,10,4,8,1310721,2,9,26,2,19,26,1582589,2,10, +3,6,10,4,8,1310721,2,9,26,2,21,26,1582591,2,10,3, +6,10,4,8,1310721,2,9,26,2,25,26,1582585,2,10,3,6, +10,4,8,1310721,2,9,26,2,27,26,1582583,2,10,3,6,10, +4,8,1310721,2,9,26,2,29,26,1584803,2,10,3,6,10,4, +8,1310721,2,9,26,2,63,26,1582593,2,10,3,6,10,4,8, +1310721,2,11,26,1,10,3,6,10,4,8,1310721,2,11,26,2, +1584803,2,40,1591961,16,1310721,2,9,26,2,31,1310721,2,11,26,2, +9,30,26,26,1584805,1310721,2,11,26,2,26,2,10,3,6,10, +4,8,1310721,2,9,26,2,33,1310721,2,11,26,2,9,30,26, +26,1584813,1310721,2,11,26,2,26,2,10,3,6,10,4,8,1310721, +2,9,26,2,35,1310721,2,11,26,2,9,30,26,26,1584821,1310721, +2,11,26,2,26,2,10,3,6,10,4,8,1310721,2,9,26, +2,37,1310721,2,11,26,2,9,30,26,26,1584829,1310721,2,11,26, +2,26,2,10,3,6,10,4,8,1310721,2,11,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1591671,14,1584803,1,10,3, +6,10,4,8,1310721,2,2,3,28,1,6,1,10,28,34,63, +38,3,26,1592053,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,1592141,16,1582589,1,10,3,6, +10,4,8,1582595,1,10,3,6,10,4,8,1582585,3,10,3,6, +10,4,8,1590389,12,8,1310721,2,2,5,28,1,6,1,10,28, +34,63,38,3,26,1592237,16,1582589,5,10,3,6,10,4,8,1582591, +1310721,2,3,26,2,10,3,6,10,4,8,1582585,3,10,3,6, +10,4,8,1590389,12,8,1310721,2,2,7,28,1,6,1,10,28, +34,63,38,3,26,1592349,16,1582589,7,10,3,6,10,4,8,1582593, +1310721,2,3,26,2,10,3,6,10,4,8,1582591,1,10,3,6, +10,4,8,1582585,3,10,3,6,10,4,8,1590389,12,8,1,1592357, +14,1,1310721,2,13,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1592405,16,1966081,1310721,4,1579069,12,1540609,1582597,2,65,30,26, +1310721,2,4,1,1310721,2,3,26,4,1582577,1310721,2,2,11,26,2, +10,3,6,10,4,8,1582579,1310721,2,2,13,26,2,10,3,6, +10,4,8,1582581,1310721,2,2,15,26,2,10,3,6,10,4,8, +1582587,1310721,2,2,17,26,2,10,3,6,10,4,8,1582589,1310721,2, +2,19,26,2,10,3,6,10,4,8,1582591,1310721,2,2,21,26, +2,10,3,6,10,4,8,1582585,1310721,2,2,25,26,2,10,3, +6,10,4,8,1582583,1310721,2,2,27,26,2,10,3,6,10,4, +8,1584803,1310721,2,2,29,26,2,10,3,6,10,4,8,1582593,1310721, +2,2,63,26,2,10,3,6,10,4,8,1310721,2,3,26,2, +1584803,2,40,1592969,16,1584805,1310721,2,3,26,2,26,1310721,2,2,31, +1310721,2,3,26,2,9,30,26,26,2,10,3,6,10,4,8, +1584813,1310721,2,3,26,2,26,1310721,2,2,33,1310721,2,3,26,2, +9,30,26,26,2,10,3,6,10,4,8,1584821,1310721,2,3,26, +2,26,1310721,2,2,35,1310721,2,3,26,2,9,30,26,26,2, +10,3,6,10,4,8,1584829,1310721,2,3,26,2,26,1310721,2,2, +37,1310721,2,3,26,2,9,30,26,26,2,10,3,6,10,4, +8,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1592695,14,1582597,1,6,2,1,6,-1,26,5,6,4,10, +8,8,1310721,2,2,23,26,2,1593031,16,1310721,2,2,3,26,2, +1580623,12,8,1,1593039,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1593087,16,1966081,1310721,4,1579069,12,1310721, +2,4,1593137,14,43,45,42,47,37,61,60,62,33,38,124,94, +126,63,58,46,64,35,36,0,1593097,1310721,2,3,26,4,1310721,2, +3,26,2,2,1593253,16,1310721,2,3,26,2,2,1310721,2,2,28, +1,6,1,10,28,34,63,38,3,26,1593215,16,3,1593261,14,1310721, +2,3,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1593149,14,1,1593261,14,1,1310721,2,5,26,1310721,4,18,1310721,2,11, +28,1310721,4,1310721,2,1835009,40,1593309,16,1966081,1310721,4,1579069,12,1310721,2, +3,26,4,1310721,2,4,1,1310721,2,5,26,4,1310721,2,5,26, +2,1582523,2,40,1593739,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,1593525,16,1310721,2, +7,26,2,1310721,2,9,26,2,26,2,1582599,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,1593527,14,1,1593569,16,1310721,2,9, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1593415,14, +1310721,2,9,26,2,1310721,2,2,28,1,6,1,10,28,34,63, +38,3,26,1593689,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,1593691,14,1,1593701,16,3, +1593747,14,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1593337,14,1,1593747,14,1,1310721,2,11,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1593795,16,1966081,1310721,4,1579069, +12,1310721,2,4,1310721,2,2,97,40,3,36,1593861,16,1310721,2,2, +115,10,40,3,36,1,6,1,10,28,34,63,38,1,10,28, +1593863,14,1,1593869,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1593917,16,1966081,1310721,4,1579069,12,1310721,2, +4,1310721,2,2,195,40,3,36,1593983,16,1310721,2,2,245,10,40, +3,36,1,6,1,10,28,34,63,38,1,10,28,1593985,14,1, +1593995,16,3,1594079,14,1310721,2,2,131,40,3,36,1594055,16,1310721,2, +2,181,10,40,3,36,1,6,1,10,28,34,63,38,1,10, +28,1594057,14,1,1,6,1,10,28,34,63,38,1,10,28,1594089, +16,3,1594141,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,1594147,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1594195,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1593761, +12,1594229,16,1310721,2,2,97,28,1594411,14,1310721,2,2,195,40,3, +36,1594289,16,1310721,2,2,205,10,40,3,36,1,6,1,10,28, +34,63,38,1,10,28,1594291,14,1,1594313,16,1310721,2,2,195,28, +21,26,1594411,14,1310721,2,2,131,40,3,36,1594373,16,1310721,2,2, +141,10,40,3,36,1,6,1,10,28,34,63,38,1,10,28, +1594375,14,1,1594397,16,1310721,2,2,131,28,21,26,1594411,14,3,1, +10,28,1594411,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1594459,16,1966081,1310721,4,1579069,12,1582587,2,1310721, +2,4,1590389,12,8,1310721,2,2,185,28,1,6,1,10,28,34, +63,38,1,10,28,1594521,16,1310721,2,2,1594759,14,1310721,2,1582587,2, +10,3,6,10,4,8,1590389,12,8,1310721,2,2,221,28,1,6, +1,10,28,34,63,38,3,26,1594587,16,21,1594759,14,1310721,2,2, +233,28,1,6,1,10,28,34,63,38,3,26,1594627,16,19,1594759, +14,1310721,2,2,229,28,1,6,1,10,28,34,63,38,3,26, +1594667,16,27,1594759,14,1310721,2,2,97,28,1,6,1,10,28,34, +63,38,3,26,1594707,16,1,1594759,14,1310721,2,2,203,28,1,6, +1,10,28,34,63,38,3,26,1594747,16,55,1594759,14,1310721,2,2, +1594759,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1594807,16,1966081,1310721,4,1579069,12,1310721,2,4,1582587,2, +1,40,3,36,1594863,16,1582587,2,1593053,12,1,6,1,10,28,34, +63,38,1,10,28,1594865,14,1,1594909,16,1310721,2,2,1582587,2,1593275, +12,1,6,1,10,28,34,63,38,1,10,28,1594911,14,1,1594981, +16,1582599,1310721,2,2,26,1582587,2,10,3,6,10,4,8,1310721,2, +1,6,2,1,6,3,26,5,6,4,10,8,8,1590389,12,8, +1594813,14,1582599,1310721,2,2,26,1,10,3,6,10,4,8,1582577,9, +10,3,6,10,4,8,1582579,1582599,1586793,12,10,3,6,10,4,8, +1,1595049,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1595097,16,1966081,1310721,4,1579069,12,1,1310721,2,4, +1582581,3,10,3,6,10,4,8,3,1595773,16,1582587,2,65,28,1, +6,1,10,28,34,63,38,3,26,1595165,16,3,1595215,14,1582587,2, +19,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1595225,16,3,1595275,14,1582587,2,21,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1595285,16,3,1595335,14,1582587,2,27,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1595365,16,1590389,12,8,1582581,1,10,3,6,10,4,8, +1595127,14,1582587,2,95,28,1,6,1,10,28,34,63,38,1,10, +28,1595403,16,1595773,14,1590389,12,8,1582587,2,95,28,1,6,1,10, +28,34,63,38,3,26,1595549,16,1582587,2,1,40,3,36,1595513,16, +1582587,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,1595515,14,1,1595529,16,1590389, +12,8,1595441,14,1582581,1,10,3,6,10,4,8,1595121,14,1582587,2, +85,28,1,6,1,10,28,34,63,38,3,26,1595717,16,1590389,12, +8,1582587,2,1,40,3,36,1595691,16,1582587,2,85,28,1,6,1, +10,28,34,63,38,3,26,1595681,16,1590389,12,8,1582587,2,95,28, +1,6,1,10,28,34,63,38,3,26,1595677,16,1595691,14,1595687,14, +1590389,12,8,1595587,14,1590389,12,8,1582581,1,10,3,6,10,4,8, +1595121,14,1582583,1582585,2,10,3,6,10,4,8,1582599,1,26,95,10, +3,6,10,4,8,3,1594773,12,8,1,1597057,14,1595121,14,1582583,1582585, +2,10,3,6,10,4,8,1582587,2,1,40,1595841,16,1582577,1,10, +3,6,10,4,8,1582579,1,10,3,6,10,4,8,1,1597057,14, +1582587,2,1593761,12,1596263,16,1310721,2,3,26,1,10,3,6,10,4, +8,1582587,2,97,28,1,6,1,10,28,34,63,38,3,26,1596151, +16,1590389,12,8,1582587,2,241,28,1,6,1,10,28,34,63,38, +3,26,1595951,16,3,1596001,14,1582587,2,177,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1596151,16,1590389,12,8,1310721,2,5,26,1582587,2,1594161,12,10,3,6, +10,4,1,40,3,36,1596105,16,1310721,2,3,26,1310721,2,3,26, +2,33,30,1310721,2,5,26,2,26,10,3,6,10,4,8,1590389, +12,8,1596011,14,1582577,3,10,3,6,10,4,8,1582579,1310721,2,3, +26,2,10,3,6,10,4,8,1,1597057,14,1582587,2,1593761,12,1596217, +16,1310721,2,3,26,1310721,2,3,26,2,21,30,1582587,2,26,97, +28,10,3,6,10,4,8,1590389,12,8,1596151,14,1582577,3,10,3, +6,10,4,8,1582579,1310721,2,3,26,2,10,3,6,10,4,8, +1,1597057,14,1582587,2,1593883,12,1596473,16,1582587,2,1593883,12,1596293,16,3, +1596323,14,1582587,2,1593761,12,1,6,1,10,28,34,63,38,1,10, +28,1596407,16,1310721,2,2,2001,40,1596397,16,1582599,1310721,2,2,26,1582587, +2,10,3,6,10,4,8,1310721,2,1,6,2,1,6,3,26, +5,6,4,10,8,8,1590389,12,8,1596275,14,1582599,1310721,2,2,26, +1,10,3,6,10,4,8,1582577,5,10,3,6,10,4,8,1582579, +1582599,1586793,12,10,3,6,10,4,8,1,1597057,14,1582587,2,79,28, +1,6,1,10,28,34,63,38,3,26,1596647,16,1590389,12,8,1582579, +1594425,12,10,3,6,10,4,8,1582587,2,79,28,1,6,1,10, +28,34,63,38,1,10,28,1596619,16,1596611,14,98,97,100,32,99, +104,97,114,97,99,116,101,114,32,108,105,116,101,114,97,108, +0,1596567,1586063,12,8,1590389,12,8,1582577,3,10,3,6,10,4,8, +1,1597057,14,1582587,2,69,28,1,6,1,10,28,34,63,38,3, +26,1596939,16,1590389,12,8,1582587,2,1,40,3,36,1596757,16,1582587,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,1596759,14,1,1596867,16,1310721,2,3, +26,1594425,12,10,3,6,10,4,8,1310721,2,2,2001,40,1596863,16, +1582599,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,1596685, +14,1590389,12,8,1582599,1310721,2,2,26,1,10,3,6,10,4,8, +1582577,7,10,3,6,10,4,8,1582579,1582599,1586793,12,10,3,6,10, +4,8,1,1597057,14,1582599,1,26,1582587,2,10,3,6,10,4,8, +1590389,12,8,1582599,1,26,2,1593053,12,1596993,16,3,1594773,12,1597057,14, +1582599,3,26,1,10,3,6,10,4,8,1582577,9,10,3,6,10, +4,8,1582579,1582599,1586793,12,10,3,6,10,4,8,1,1597057,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1597105,16,1966081,1310721,4,1579069,12,3,1310721,2,4,1584803,2,1597445,16, +1582577,1584805,1,26,2,10,3,6,10,4,8,1582579,1584813,1,26,2, +10,3,6,10,4,8,1582581,1584821,1,26,2,10,3,6,10,4, +8,1582583,1584829,1,26,2,10,3,6,10,4,8,1310721,2,2,1584803, +2,40,1597411,16,1584805,1310721,2,2,3,28,26,1584805,1310721,2,2,26, +2,10,3,6,10,4,8,1584813,1310721,2,2,3,28,26,1584813,1310721, +2,2,26,2,10,3,6,10,4,8,1584821,1310721,2,2,3,28, +26,1584821,1310721,2,2,26,2,10,3,6,10,4,8,1584829,1310721,2, +2,3,28,26,1584829,1310721,2,2,26,2,10,3,6,10,4,8, +1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8,1597209, +14,1584803,1,6,2,1,6,-1,26,5,6,4,10,8,8,1, +1597455,14,1597991,12,1597455,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +11,28,1310721,4,1310721,2,1835009,40,1597503,16,1966081,1310721,4,1579069,12,1310721, +2,4,1584803,2,1310721,2,2,10,40,3,36,1597857,16,1310721,2,3, +26,1582577,2,10,3,6,10,4,8,1310721,2,5,26,1582579,2,10, +3,6,10,4,8,1310721,2,7,26,1582581,2,10,3,6,10,4, +8,1310721,2,9,26,1582583,2,10,3,6,10,4,8,1597991,12,8, +1584805,1584803,2,26,1582577,2,10,3,6,10,4,8,1584813,1584803,2,26, +1582579,2,10,3,6,10,4,8,1584821,1584803,2,26,1582581,2,10,3, +6,10,4,8,1584829,1584803,2,26,1582583,2,10,3,6,10,4,8, +1584803,1,6,2,1,6,3,26,5,6,4,10,8,8,1582577,1310721, +2,3,26,2,10,3,6,10,4,8,1582579,1310721,2,5,26,2, +10,3,6,10,4,8,1582581,1310721,2,7,26,2,10,3,6,10, +4,8,1582583,1310721,2,9,26,2,10,3,6,10,4,8,1597509,14, +1584799,1584805,1310721,2,2,26,2,10,3,6,10,4,8,1584801,1584813,1310721, +2,2,26,2,10,3,6,10,4,8,1,1597917,14,1,1310721,2, +11,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1597965, +16,1966081,1310721,4,1579069,12,1,1597469,12,1597977,14,1,1310721,2,1,26, +1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1598025,16,1966081, +1310721,4,1579069,12,1310721,2,1540609,1582597,2,65,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,1598107,16,1595063,12,8,1,1598483,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,1598395,16,1310721,2,3,26,1310721, +2,2,3,26,2,10,3,6,10,4,8,1582577,1310721,2,3,26, +2,3,1310721,2,5,26,2,7,30,26,26,2,10,3,6,10, +4,8,1582579,1310721,2,3,26,2,5,1310721,2,5,26,2,7,30, +26,26,2,10,3,6,10,4,8,1582583,1310721,2,3,26,2,7, +1310721,2,5,26,2,7,30,26,26,2,10,3,6,10,4,8, +1582581,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,1598483,14,1310721,2,2, +9,26,2,1,6,1,10,28,34,63,38,3,26,1598469,16,1582577, +1,10,3,6,10,4,8,1582579,1,10,3,6,10,4,8,1, +1598483,14,1592371,12,8,1,1598483,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1598531,16,1966081,1310721,4,1579069, +12,1310721,2,4,1582577,2,9,28,1,6,1,10,28,34,63,38, +3,26,1598627,16,1582579,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,1598629, +14,1,1598635,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1598683,16,1966081,1310721,4,1579069,12,1310721,2,4, +1582577,2,5,28,1,6,1,10,28,34,63,38,3,26,1598779,16, +1582579,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,1598781,14,1,1598787,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1598835,16,1966081,1310721,4,1579069,12,1310721,2,4,1582577,2,9,28, +1,6,1,10,28,34,63,38,3,26,1598879,16,3,1598929,14,1582577, +2,5,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1598991,16,1582579,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,1598993,14,1,1599009,16,1597071,12,8,3,1599017,14, +1,1599017,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1599065,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721, +2,2,1598801,12,1,6,1,10,28,34,63,38,3,26,1599299,16, +1585091,2,1,6,1,10,28,34,63,38,3,26,1599183,16,1584991,2, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1599185,14,1,1599245,16,1585093,12,8,1599219,14,101, +120,112,101,99,116,101,100,32,0,1599199,1573341,12,8,1310721,2,2, +1573341,12,8,1585237,12,8,1585091,3,10,3,6,10,4,8,1582577,2, +1,28,1,6,1,10,28,34,63,38,3,26,1599299,16,1585397,12, +8,1,1599307,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1599355,16,1966081,1310721,4,1579069,12,1582579,2,1310721, +2,4,1582577,2,5,28,1,6,1,10,28,34,63,38,1,10, +28,1599443,16,1599435,14,101,120,112,101,99,116,101,100,32,97,32, +110,97,109,101,0,1599403,1586063,12,8,1597071,12,8,1310721,2,2,1599461, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721, +2,1835009,40,1599509,16,1966081,1310721,4,1579069,12,1310721,2,4,1582525,2,1310721, +2,3,26,4,3,1600583,16,1310721,2,2,2,65,28,1,6,1, +10,28,34,63,38,3,26,1599605,16,1310721,2,1,6,2,1,6, +3,26,5,6,4,10,8,8,1599535,14,1310721,2,2,2,1,6, +1,10,28,34,63,38,3,26,1599641,16,1600583,14,1310721,2,5,26, +1,10,3,6,10,4,8,1310721,2,2,1310721,2,5,26,2,26, +2,1599759,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,1599761,14,1,1599849,16,1582599,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,1599663,14,1582599,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,1582599,1,26,2,91,28,1,6,1, +10,28,34,63,38,3,26,1599993,16,1582599,3,26,2,1593761,12,1, +6,1,10,28,34,63,38,1,10,28,1599995,14,1,10,3,6, +10,4,8,1582599,1310721,2,7,26,2,26,2,1593761,12,1600323,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,1582599,1310721,2,11,26,2,26, +2,1600197,16,1310721,2,9,26,1310721,2,9,26,2,21,30,1582599,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, +1600083,14,1310721,2,7,26,2,1600245,16,1310721,2,9,26,1,1310721,2, +9,26,2,28,10,3,6,10,4,8,1542657,1582525,2,26,1310721,2, +9,26,2,1310721,2,9,26,2,26,3,26,10,3,6,10,4, +8,1582525,1,6,2,1,6,3,26,5,6,4,10,8,8,1600579, +14,1310721,2,5,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1600425,16,1310721,2,13,26,1582599,1,26,2,1600613,12,10,3, +6,10,4,1,40,3,36,1,6,1,10,28,34,63,38,1, +10,28,1600427,14,1,1600505,16,1542657,1582525,2,26,1310721,2,13,26,2, +1310721,2,13,26,2,26,10,3,6,10,4,8,1582525,1,6,2, +1,6,3,26,5,6,4,10,8,8,1600579,14,1542657,1582525,2,26, +-3,10,3,6,10,4,8,1542657,1582525,2,3,26,26,1582599,1586793,12, +10,3,6,10,4,8,1582525,1582525,2,5,26,10,3,6,10,4, +8,1599529,14,1310721,2,3,26,2,1600599,14,1,1310721,2,15,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1600647,16,1966081,1310721, +4,1579069,12,1310721,2,4,1,1310721,2,3,26,4,1582527,2,1310721,2, +3,26,2,26,2,1600789,16,1582527,2,1310721,2,3,26,2,26,2, +1310721,2,2,28,1,6,1,10,28,34,63,38,3,26,1600751,16, +1310721,2,3,26,2,1600803,14,1310721,2,3,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1600665,14,3,1,10,28,1600803,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2, +1835009,40,1600851,16,1966081,1310721,4,1579069,12,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,1601297,16,1542657,1310721,2,2,26,2, +-3,28,1,6,1,10,28,34,63,38,3,26,1601245,16,1310721,2, +7,26,1542657,1310721,2,2,3,26,26,2,1587809,12,10,3,6,10, +4,8,1310721,2,7,26,2,1,40,1601055,16,1310721,2,7,26,1542657, +1310721,2,2,3,26,26,2,1589617,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,1601119,16,1310721,2,7,26,2,1589741,12,8,1601215,14,1417729, +1310721,2,7,26,2,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1601193,16,45,1425921,1310721,2,7,26,2,26,2,26,1589235, +12,8,1601215,14,1425921,1310721,2,7,26,2,26,2,1589149,12,8,1310721, +2,1310721,2,2,5,26,10,3,6,10,4,8,1601293,14,1542657,1310721, +2,2,26,2,1588955,12,8,1310721,2,1,6,2,1,6,3,26, +5,6,4,10,8,8,1600895,14,1,1601305,14,1,1310721,2,9,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1601353,16,1966081, +1310721,4,1579069,12,1310721,2,4,1,1310721,2,3,26,4,1310721,2,3, +26,2,1582523,2,40,1601483,16,1547777,1310721,2,3,26,2,26,2,1310721, +2,2,28,1,6,1,10,28,34,63,38,3,26,1601445,16,1, +1601545,14,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1601371,14,1547777,1582523,2,26,1310721,2,2,10,3,6,10, +4,8,1582523,1,6,2,1,6,3,26,5,6,4,10,8,8, +1,1601545,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1601593,16,1966081,1310721,4,1579069,12,1310721,2,4,1582517, +2,1310721,2,3,26,4,1310721,2,3,26,2,1601727,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,1601723,16,1310721,2,3,26,2,1601741,14,1601613,14,3, +1,10,28,1601741,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1601789,16,1966081,1310721,4,1579069,12,1310721,2, +4,1582519,2,1310721,2,3,26,4,1310721,2,3,26,2,1601923,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,1601919,16,1310721,2,3,26,2,1601937,14,1601809, +14,3,1,10,28,1601937,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1601985,16,1966081,1310721,4,1579069,12, +1310721,2,4,1582521,2,1310721,2,3,26,4,1310721,2,3,26,2,1602119, +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,1602115,16,1310721,2,3,26,2,1602133, +14,1602005,14,3,1,10,28,1602133,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1602181,16,1966081,1310721,4, +1579069,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1310721, +2,2,1586793,12,1310721,2,7,26,4,1310721,2,7,26,2,1601559,12, +1310721,2,9,26,4,1310721,2,9,26,2,1,40,1602321,16,1310721,2, +9,26,1582517,2,10,3,6,10,4,8,1582517,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,1602545,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,1601319,12, +8,1310721,2,9,26,2,1603173,14,1547009,1310721,2,9,26,2,26,1310721, +2,5,26,2,1599475,12,10,3,6,10,4,8,1547137,1310721,2,9, +26,2,26,1582525,2,1547009,1310721,2,9,26,2,26,2,28,10,3, +6,10,4,8,1310721,2,7,26,2,1601319,12,8,1310721,2,13,26, +1310721,2,2,1573885,12,10,3,6,10,4,8,1582599,2001,26,1310721,2, +2,1310721,2,13,26,2,1574337,12,8,1582599,2001,1310721,2,13,26,2, +26,26,123,10,3,6,10,4,8,1582599,2003,1310721,2,13,26,2, +26,26,1,10,3,6,10,4,8,1310721,2,11,26,1582599,2001,26, +1586793,12,10,3,6,10,4,8,1310721,2,3,26,2,17,40,3, +36,1602829,16,3,1602885,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,1602895,16,3,1602951,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,1602961,16,3,1603017,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,1603157,16,1310721,2,11,26,2,1601951,12,1,40,1603101, +16,1547457,1582521,2,26,1310721,2,11,26,2,10,3,6,10,4,8, +1582521,1,6,2,1,6,3,26,5,6,4,10,8,8,1547585,1310721, +2,11,26,2,1601951,12,26,1310721,2,9,26,2,10,3,6,10, +4,8,1310721,2,11,26,2,1601319,12,8,1310721,2,9,26,2,1603173, +14,1,1310721,2,15,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721, +2,1835009,40,1603221,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721, +2,4,1310721,2,2,1586793,12,1310721,2,5,26,4,1310721,2,5,26, +2,1601755,12,1310721,2,7,26,4,1310721,2,7,26,2,1,40,1603351, +16,1310721,2,7,26,1582519,2,10,3,6,10,4,8,1582519,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,1599475,12,10,3,6,10,4, +8,1547393,1310721,2,7,26,2,26,1582525,2,1547329,1310721,2,7,26,2, +26,2,28,10,3,6,10,4,8,1310721,2,5,26,2,1601319,12, +8,1310721,2,7,26,2,1603507,14,1,1310721,2,9,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,1835009,40,1603555,16,1966081,1310721,4,1579069, +12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,1586793,12,11,1310721,2,3,26,2,1587311,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,1603673,14,1,1310721,2,9,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1603721,16,1966081, +1310721,4,1579069,12,1310721,2,4,1584845,2,1310721,2,3,26,4,1310721,2, +3,26,2,1584847,2,10,40,1603863,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, +1603859,16,1310721,2,3,26,2,1603877,14,1603741,14,3,1,10,28,1603877, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1603925,16,1966081,1310721,4,1579069,12,1310721,2,4,1584845,2,1310721, +2,3,26,4,1584845,2,1025,40,3,36,1604005,16,1603997,14,116,111, +111,32,109,97,110,121,32,108,111,99,97,108,115,0,1603965,1585585, +12,8,1584845,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,1584851,2,10,3,6,10,4,8,1468929, +1310721,2,3,26,2,26,1584849,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,1556993,1310721,2,3,26,2,26,1584975,2,10,3,6, +10,4,8,1558017,1310721,2,3,26,2,26,1,10,3,6,10,4, +8,1310721,2,3,26,2,1604339,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1604387,16,1966081,1310721,4,1579069, +12,1310721,2,4,1469953,1310721,2,2,26,2,11,28,1,6,1,10, +28,34,63,38,3,26,1604465,16,1310721,2,1470977,1310721,2,2,26,2, +10,3,6,10,4,8,1604393,14,1310721,2,2,1604477,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1604525, +16,1966081,1310721,4,1579069,12,1310721,2,4,1469953,1310721,2,2,26,2,1, +28,1,6,1,10,28,34,63,38,1,10,28,1604575,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40, +1604623,16,1966081,1310721,4,1579069,12,1310721,2,4,1472001,1310721,2,2,26,3, +10,3,6,10,4,8,1584853,2,1,6,1,10,28,34,63,38, +3,26,1604687,16,1,1605063,14,1310721,2,3,26,1310721,2,2,1604353,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,1604871,16,1310721,2,2,1604857,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,1604799,1586469,12,8, +1,1605063,14,1469953,1310721,2,3,26,2,26,2,7,28,1,6,1, +10,28,34,63,38,3,26,1604963,16,1468929,1310721,2,3,26,2,26, +2,1584849,2,40,1,6,1,10,28,34,63,38,1,10,28,1604965, +14,1,1605055,16,1468929,1310721,2,3,26,2,26,1584849,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, +1605063,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1605111,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2, +2,3,28,1,6,1,10,28,34,63,38,3,26,1605301,16,1605293, +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,1605155,1586351,12,8,1310721,2,2,5,40,3, +36,1605335,16,1310721,2,2,5,28,1604589,12,8,1,1605343,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1605391,16,1966081,1310721,4,1579069,12,1310721,2,4,1467905,1310721,2,2,26,2, +1590069,12,8,3,1589235,12,8,1584959,2,1589915,12,8,9,1589235,12,8, +1,1605449,14,1,1310721,2,3,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,1835009,40,1605497,16,1966081,1310721,4,1579069,12,1310721,2,3,26, +4,1310721,2,4,1584845,2,1310721,2,5,26,4,1584853,2,1,6,1, +10,28,34,63,38,3,26,1605561,16,3,1605607,14,1584857,2,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1605617,16,1,1606177,14,1310721,2,5,26,2,1584847,2,10, +40,1606169,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, +1605705,16,1605617,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,1605799,16,1310721,2,5,26,2,1605357,12, +8,1606165,14,1310721,2,7,26,2,5,28,1,6,1,10,28,34, +63,38,3,26,1606045,16,1310721,2,5,26,2,1606033,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,1605851,1586469,12,8,1606165,14,1310721,2, +7,26,2,7,28,1,6,1,10,28,34,63,38,3,26,1606165, +16,1310721,2,5,26,2,1606157,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,1606097,1586469,12,8,1605617,14,1,1606177,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1606225,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1584845,2, +40,1606467,16,1584853,2,1606293,16,1474049,1310721,2,2,26,2,1,6,1, +10,28,34,63,38,1,10,28,1606295,14,1,1606357,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,1606359,14,1,1606433,16,1466881,1310721,2, +2,26,2,1606425,14,109,32,111,98,106,101,99,116,32,105,115, +32,110,101,118,101,114,32,117,115,101,100,0,1606379,1585849,12,8, +1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8,1606231, +14,1,1606475,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1606523,16,1966081,1310721,4,1579069,12,1310721,2,4, +1584847,2,1310721,2,3,26,4,1310721,2,2,1606191,12,8,1584849,2,3, +1605463,12,8,1310721,2,3,26,2,1310721,2,2,40,1606719,16,1468929,1310721, +2,3,26,2,26,2,1584849,2,40,3,36,1606681,16,1469953,1310721,2, +3,26,2,26,9,10,3,6,10,4,8,1468929,1310721,2,3,26, +2,26,1584849,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,1606567,14,1584845, +1310721,2,2,10,3,6,10,4,8,1,1606747,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1606795,16, +1966081,1310721,4,1579069,12,1584873,2,1310721,2,4,1584847,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,1584847,2,10,3,6,10,4,8,1310721, +2,5,26,2,3,26,1584845,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,1584845,2,40,1607161,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,1606943,14,1584873,1310721,2,5, +26,2,1507841,28,10,3,6,10,4,8,1584873,2,16001,40,3,36, +1607285,16,1607277,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,1607209,1585585,12,8,1310721,2,2,1607297,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1607345,16,1966081,1310721,4,1579069,12,1310721,2,4,1584873,1310721,2,2,10, +3,6,10,4,8,1,1607379,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,1835009,40,1607427,16,1966081,1310721,4,1579069, +12,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,1584845,2,10, +40,1607551,16,1310721,2,7,26,1584845,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,1607809,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,1607585,14, +1,1607817,14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1607865,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721, +2,2,1,28,1,6,1,10,28,34,63,38,3,26,1607911,16, +3,1607963,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,1607969,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009, +40,1608017,16,1966081,1310721,4,1579069,12,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,1584845,2,10,40,1608141,16,1310721,2,7,26,1584845,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,1608765,16,1310721,2,9,26,1469953,1310721,2,5,26,2,26,2, +10,3,6,10,4,8,1310721,2,9,26,2,1607831,12,1608301,16,1310721, +2,3,26,2,1,26,2,1607831,12,1,6,1,10,28,34,63, +38,1,10,28,1608303,14,1,1608383,16,1310721,2,3,26,2,1,26, +2,9,28,1,6,1,10,28,34,63,38,3,26,1608379,16,1469953, +1310721,2,5,26,2,26,9,10,3,6,10,4,8,1608693,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,1608443,16,3,1608521,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,1608531,16,3,1608675,14,1310721,2,9,26,2,11,28, +1,6,1,10,28,34,63,38,3,26,1608651,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,1608653,14,1,1,6,1,10,28,34,63,38,1,10, +28,1608693,16,1310721,2,5,26,2,1608779,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,1608175,14,3,1, +10,28,1608779,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1608827,16,1966081,1310721,4,1579069,12,1310721,2,4, +1310721,2,2,1,28,1,6,1,10,28,34,63,38,3,26,1608889, +16,1608883,14,101,109,112,116,121,0,1608871,1609215,14,1310721,2,2,3, +28,1,6,1,10,28,34,63,38,3,26,1608937,16,1608931,14,109, +0,1608927,1609215,14,1310721,2,2,5,28,1,6,1,10,28,34,63, +38,3,26,1608985,16,1608979,14,117,0,1608975,1609215,14,1310721,2,2,7, +28,1,6,1,10,28,34,63,38,3,26,1609033,16,1609027,14,100, +0,1609023,1609215,14,1310721,2,2,9,28,1,6,1,10,28,34,63, +38,3,26,1609099,16,1609093,14,103,105,118,101,110,32,97,119,97, +121,0,1609071,1609215,14,1310721,2,2,11,28,1,6,1,10,28,34, +63,38,3,26,1609185,16,1609179,14,111,119,110,101,100,32,98,121, +32,97,32,99,111,110,116,97,105,110,101,114,0,1609137,1609215,14, +1609207,14,98,111,114,114,111,119,101,100,0,1609189,1609215,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40, +1609263,16,1966081,1310721,4,1579069,12,1310721,2,5,26,4,1310721,2,3,26, +4,1310721,2,4,1584853,2,1,6,1,10,28,34,63,38,3,26, +1609323,16,3,1609349,14,1585091,2,1,6,1,10,28,34,63,38,1, +10,28,1609359,16,3,1609385,14,1584991,2,1,6,1,10,28,34,63, +38,1,10,28,1609395,16,1,1609615,14,1585093,12,8,1466881,1310721,2,2, +26,2,1573341,12,8,1609429,14,58,32,0,1609423,1573341,12,8,1310721,2, +5,26,2,1573341,12,8,1609501,14,32,40,111,110,101,32,112,97, +116,104,32,108,101,97,118,101,115,32,105,116,32,0,1609457,1573341, +12,8,1310721,2,3,26,2,1608793,12,1573341,12,8,1609555,14,44,32, +97,110,111,116,104,101,114,32,0,1609533,1573341,12,8,1469953,1310721,2, +2,26,2,1608793,12,1573341,12,8,1609593,14,41,0,1609589,1573341,12,8, +1585237,12,8,1,1609615,14,1,1310721,2,7,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,0,0,0,0,0,0,0,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,5,28,1310721,4,1310721,2,1835009,40,1609795,16,1966081,1310721,4,1579069, +12,1310721,2,3,26,4,1310721,2,4,1310721,2,3,26,2,1310721,2, +2,3,26,2,40,3,36,1609849,16,1,1609897,14,1310721,2,2,5, +7,1310721,2,3,26,2,1310721,2,2,1,26,2,28,30,26,26, +2,1609897,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1609945,16,1966081,1310721,4,1579069,12,1310721,2,3,26, +4,1310721,2,4,1310721,2,2,7,7,1310721,2,3,26,2,1310721,2, +2,1,26,2,28,30,26,26,2,1610009,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1610057,16,1966081, +1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,9, +7,1310721,2,3,26,2,1310721,2,2,1,26,2,28,30,26,26, +2,1610121,14,1,1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,1835009,40,1610169,16,1966081,1310721,4,1579069,12,1310721,2,4,1567233, +1609629,2,26,1310721,2,3,26,4,1584847,2,1310721,2,5,26,4,1609629, +2,7,26,7,1584845,2,1584847,2,28,30,26,1572353,1567233,28,40,3, +36,1610325,16,1610317,14,116,111,111,32,109,97,110,121,32,98,114, +101,97,107,115,32,102,111,114,32,116,104,101,32,97,110,97, +108,121,122,101,114,0,1610251,1585585,12,8,1310721,2,3,26,2,1, +26,1310721,2,2,10,3,6,10,4,8,1310721,2,3,26,2,3, +26,1584847,2,10,3,6,10,4,8,1310721,2,3,26,2,5,26, +1584845,2,10,3,6,10,4,8,1310721,2,7,26,1310721,2,3,26, +2,7,26,10,3,6,10,4,8,1310721,2,5,26,2,1584845,2, +40,1610669,16,1310721,2,7,26,2,1,26,1469953,1310721,2,5,26,2, +26,2,10,3,6,10,4,8,1310721,2,7,26,2,3,26,1470977, +1310721,2,5,26,2,26,2,10,3,6,10,4,8,1310721,2,7, +26,2,5,26,1468929,1310721,2,5,26,2,26,2,10,3,6,10, +4,8,1310721,2,7,26,1310721,2,7,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,1610451,14,1609629,1310721,2,7,26,2,1567233,28,10,3, +6,10,4,8,1310721,2,3,26,2,1610713,14,1,1310721,2,9,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1610761,16,1966081, +1310721,4,1579069,12,1310721,2,4,1609759,2,129,40,3,36,1610859,16,1610851, +14,116,111,111,32,109,97,110,121,32,112,97,116,104,115,32, +102,111,114,32,116,104,101,32,97,110,97,108,121,122,101,114, +0,1610787,1585585,12,8,1609631,1609759,2,26,1310721,2,2,10,3,6,10, +4,8,1609759,1,6,2,1,6,3,26,5,6,4,10,8,8, +1,1610921,14,1,1310721,2,3,26,1310721,4,18,1310721,2,11,28,1310721, +4,1310721,2,1835009,40,1610969,16,1966081,1310721,4,1579069,12,1310721,2,5,26, +4,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1310721,2,5,26, +2,1609761,12,1310721,2,7,26,4,1310721,2,3,26,2,1310721,2,5, +26,2,1609761,12,1310721,2,9,26,4,1310721,2,7,26,2,1607831,12, +1611117,16,1310721,2,9,26,2,1607831,12,1,6,1,10,28,34,63, +38,1,10,28,1611119,14,1,1611129,16,3,1611441,14,1310721,2,7,26, +2,1310721,2,9,26,2,28,1,6,1,10,28,34,63,38,3, +26,1611267,16,1310721,2,2,1310721,2,5,26,2,1610023,12,1310721,2,3, +26,2,1310721,2,5,26,2,1610023,12,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1611269, +14,1,1611433,16,1310721,2,7,26,2,11,28,1,6,1,10,28, +34,63,38,1,10,28,1611319,16,3,1611407,14,1310721,2,2,1310721,2, +5,26,2,1609911,12,1310721,2,3,26,2,1310721,2,5,26,2,1609911, +12,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,1611435,14,1,1611441,14,1,1310721,2,11,26,1310721,4,18,1310721, +2,21,28,1310721,4,1310721,2,1835009,40,1611489,16,1966081,1310721,4,1579069,12, +1310721,2,3,26,4,1310721,2,4,1584847,2,1310721,2,5,26,4,1609759, +2,1,6,1,10,28,34,63,38,3,26,1611553,16,1,1613025,14, +1310721,2,5,26,2,1310721,2,2,40,1613017,16,1310721,2,9,26,1609631, +1,26,2,10,3,6,10,4,8,1310721,2,13,26,1310721,2,9, +26,2,1310721,2,5,26,2,1609761,12,10,3,6,10,4,8,1310721, +2,15,26,1,10,3,6,10,4,8,1310721,2,17,26,3,10, +3,6,10,4,8,1310721,2,19,26,3,1,10,28,10,3,6, +10,4,8,1310721,2,7,26,1,10,3,6,10,4,8,1310721,2, +7,26,2,1609759,2,40,1612195,16,1310721,2,11,26,1609631,1310721,2,7, +26,2,26,2,1310721,2,5,26,2,1609761,12,10,3,6,10,4, +8,1310721,2,11,26,2,9,28,1,6,1,10,28,34,63,38, +3,26,1611855,16,3,1611911,14,1310721,2,11,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,1611937,16,1310721,2,15,26,3,10,3,6,10,4,8, +1310721,2,11,26,2,5,28,1,6,1,10,28,34,63,38,3, +26,1611981,16,3,1612037,14,1310721,2,11,26,2,13,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1612063,16,1310721,2,17,26,1,10,3,6,10,4,8,1310721, +2,9,26,2,1609631,1310721,2,7,26,2,26,2,1310721,2,5,26, +2,1610935,12,1,6,1,10,28,34,63,38,3,26,1612157,16,1310721, +2,19,26,1310721,2,7,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,1611741, +14,1469953,1310721,2,5,26,2,26,1310721,2,13,26,2,10,3,6, +10,4,8,1470977,1310721,2,5,26,2,26,1310721,2,9,26,2,1310721, +2,5,26,2,1609911,12,10,3,6,10,4,8,1468929,1310721,2,5, +26,2,26,1310721,2,9,26,2,1310721,2,5,26,2,1610023,12,10, +3,6,10,4,8,1310721,2,19,26,2,1,40,1612537,16,1310721,2, +13,26,2,1607831,12,1612533,16,1310721,2,7,26,1,10,3,6,10, +4,8,1310721,2,7,26,2,1609759,2,40,1612533,16,1609631,1310721,2,7, +26,2,26,2,1310721,2,5,26,2,1609761,12,9,28,1,6,1, +10,28,34,63,38,3,26,1612495,16,1469953,1310721,2,5,26,2,26, +9,10,3,6,10,4,8,1310721,2,7,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1612389,14,1612979,14,1310721,2,15,26, +2,1612587,16,1310721,2,17,26,2,1,6,1,10,28,34,63,38, +1,10,28,1612589,14,1,1612625,16,1469953,1310721,2,5,26,2,26,9, +10,3,6,10,4,8,1612979,14,1584853,2,1612683,16,1585091,2,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1612685,14,1,1612739,16,1584991,2,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1612741, +14,1,1612979,16,1585093,12,8,1466881,1310721,2,5,26,2,26,2,1573341, +12,8,1612783,14,58,32,0,1612777,1573341,12,8,1310721,2,3,26,2, +1573341,12,8,1612855,14,32,40,111,110,101,32,112,97,116,104,32, +108,101,97,118,101,115,32,105,116,32,0,1612811,1573341,12,8,1310721, +2,13,26,2,1608793,12,1573341,12,8,1612909,14,44,32,97,110,111, +116,104,101,114,32,0,1612887,1573341,12,8,1609631,1310721,2,19,26,2, +26,2,1310721,2,5,26,2,1609761,12,1608793,12,1573341,12,8,1612965,14, +41,0,1612961,1573341,12,8,1585237,12,8,1310721,2,5,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1611553,14,1,1613025,14,1, +1310721,2,21,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009, +40,1613073,16,1966081,1310721,4,1579069,12,1310721,2,5,26,4,1310721,2,3, +26,4,1310721,2,4,1584847,2,1310721,2,7,26,4,1,1310721,2,9, +26,4,1584853,2,1,6,1,10,28,34,63,38,3,26,1613159,16, +1,1613519,14,1310721,2,7,26,2,1310721,2,3,26,2,40,1613503,16, +1310721,2,11,26,1310721,2,2,1310721,2,7,26,2,1609761,12,10,3, +6,10,4,8,1469953,1310721,2,7,26,2,26,2,9,28,1,6, +1,10,28,34,63,38,3,26,1613395,16,1310721,2,11,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1613313,16,3,1613369,14, +1310721,2,11,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,1,6,1,10, +28,34,63,38,1,10,28,1613397,14,1,1613465,16,1310721,2,9,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1310721,2,5, +26,2,1613465,16,1310721,2,7,26,2,1605357,12,8,1310721,2,7,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1613159,14,1310721, +2,9,26,2,1613519,14,1,1310721,2,13,26,1310721,4,18,1310721,2, +11,28,1310721,4,1310721,2,1835009,40,1613567,16,1966081,1310721,4,1579069,12,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,1584853,2,1,6,1,10,28,34,63,38, +3,26,1613679,16,3,1613725,14,1584857,2,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1613735,16, +1,1615101,14,1310721,2,7,26,2,1584845,2,10,40,1613781,16,1310721,2, +7,26,1584845,2,10,3,6,10,4,8,1310721,2,5,26,2,1310721, +2,7,26,2,40,1615093,16,1310721,2,9,26,1469953,1310721,2,5,26, +2,26,2,10,3,6,10,4,8,1310721,2,9,26,2,1607831,12, +1613915,16,1310721,2,3,26,2,1310721,2,5,26,2,1609761,12,1607831,12, +1,6,1,10,28,34,63,38,1,10,28,1613917,14,1,1614005,16, +1310721,2,3,26,2,1310721,2,5,26,2,1609761,12,9,28,1,6, +1,10,28,34,63,38,3,26,1614001,16,1469953,1310721,2,5,26,2, +26,9,10,3,6,10,4,8,1615055,14,1310721,2,9,26,2,1310721, +2,3,26,2,1310721,2,5,26,2,1609761,12,28,1,6,1,10, +28,34,63,38,1,10,28,1614073,16,3,1614159,14,1468929,1310721,2,5, +26,2,26,2,1310721,2,3,26,2,1310721,2,5,26,2,1610023,12, +28,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,1,10,28,1614169,16,3,1614321,14,1310721,2,9,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1614297,16,1470977, +1310721,2,5,26,2,26,2,1310721,2,3,26,2,1310721,2,5,26, +2,1609911,12,28,1,6,1,10,28,34,63,38,1,10,28,1, +6,1,10,28,34,63,38,1,10,28,1614299,14,1,1,6,1, +10,28,34,63,38,1,10,28,1615055,16,1310721,2,9,26,2,9, +28,1,6,1,10,28,34,63,38,3,26,1614369,16,3,1614425,14, +1310721,2,9,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,1614659,16,1310721,2, +5,26,2,1614647,14,105,115,32,103,105,118,101,110,32,97,119, +97,121,32,105,110,115,105,100,101,32,97,32,108,111,111,112, +32,116,104,97,116,32,99,111,109,101,115,32,98,97,99,107, +32,97,114,111,117,110,100,32,116,111,32,105,116,59,32,103, +105,118,101,32,105,116,32,97,119,97,121,32,111,110,32,97, +32,112,97,116,104,32,116,104,97,116,32,108,101,97,118,101, +115,32,116,104,101,32,108,111,111,112,0,1614443,1586469,12,8,1615055, +14,1585091,2,1,6,1,10,28,34,63,38,3,26,1614737,16,1584991, +2,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1614739,14,1,1615055,16,1585093,12,8,1466881,1310721, +2,5,26,2,26,2,1573341,12,8,1614949,14,58,32,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,32,40,105,116,32,119,101,110,116,32,102,114,111,109, +32,0,1614775,1573341,12,8,1310721,2,3,26,2,1310721,2,5,26,2, +1609761,12,1608793,12,1573341,12,8,1615005,14,32,116,111,32,0,1614995,1573341, +12,8,1310721,2,9,26,2,1608793,12,1573341,12,8,1615041,14,41,0, +1615037,1573341,12,8,1585237,12,8,1310721,2,5,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1613781,14,1,1615101,14,1,1310721,2, +11,26,1310721,4,18,1310721,2,19,28,1310721,4,1310721,2,1835009,40,1615149, +16,1966081,1310721,4,1579069,12,1310721,2,11,26,4,1310721,2,9,26,4, +1310721,2,7,26,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721, +2,4,1310721,2,13,26,1606761,12,10,3,6,10,4,8,1609759,1, +10,3,6,10,4,8,1310721,2,3,26,2,1615275,16,1507841,1310721,2, +2,26,1610727,12,8,1310721,2,7,26,2,1615309,16,1507841,1310721,2,13, +26,2,26,1610727,12,8,1310721,2,9,26,2,1310721,2,11,26,2, +1611455,12,8,1310721,2,7,26,2,1615381,16,1507841,1310721,2,13,26,2, +26,1310721,2,9,26,2,3,1613039,12,8,1310721,2,15,26,1,10, +3,6,10,4,8,1310721,2,3,26,2,1615463,16,1310721,2,15,26, +1507841,1310721,2,2,26,1310721,2,9,26,2,1,1613039,12,10,3,6, +10,4,8,1310721,2,15,26,2,1615581,16,1310721,2,17,26,1589535,12, +10,3,6,10,4,8,15,1589235,12,8,1310721,2,5,26,2,1584837, +2,1589317,12,8,1507841,1310721,2,2,26,1310721,2,9,26,2,3,1613039, +12,8,1310721,2,17,26,2,1584837,2,1589317,12,8,1615601,14,1310721,2, +5,26,2,1584837,2,1589317,12,8,1584857,1310721,2,3,26,2,1615623,16, +3,1615655,14,1310721,2,7,26,2,1,6,1,10,28,34,63,38, +1,10,28,10,3,6,10,4,8,1,1615675,14,1,1310721,2,19, +26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1615723,16, +1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1584853,2,1, +6,1,10,28,34,63,38,3,26,1615777,16,1310721,2,2,1616747,14, +1310721,2,2,5,40,1615893,16,1615875,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,1615795,1586351,12,8,1310721,2,2,1616747,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,1616157,16,1310721,2,5,26, +2,1616145,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,1616039,1586469,12,8,1616735,14,1310721,2, +7,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1616285, +16,1310721,2,5,26,2,1616273,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,1616209,1586469,12,8,1616735,14,1310721,2, +7,26,2,1,28,1,6,1,10,28,34,63,38,3,26,1616393, +16,1310721,2,5,26,2,1616381,14,105,115,110,39,116,32,97,110, +32,111,119,110,101,100,32,111,98,106,101,99,116,0,1616337,1586469, +12,8,1616735,14,1310721,2,7,26,2,9,28,1,6,1,10,28, +34,63,38,3,26,1616515,16,1310721,2,5,26,2,1616503,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,1616445,1586469,12,8,1616735, +14,1310721,2,3,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1616615,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,1616617,14,1,1616699,16,1310721,2,5,26,2,1616687,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,1616635,1586469,12,8,1616735,14,1469953,1310721,2, +5,26,2,26,1310721,2,3,26,2,10,3,6,10,4,8,1310721, +2,2,1616747,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28, +1310721,4,1310721,2,1835009,40,1616795,16,1966081,1310721,4,1579069,12,1310721,2,3, +26,4,1310721,2,4,1584853,2,1,6,1,10,28,34,63,38,3, +26,1616845,16,1,1618279,14,1310721,2,2,3,28,1,6,1,10,28, +34,63,38,3,26,1617089,16,1310721,2,3,26,2,5,28,1,6, +1,10,28,34,63,38,1,10,28,1617083,16,1617075,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,1616923,1586351,12,8,1,1618279,14, +1310721,2,2,5,40,1617109,16,3,1617165,14,1310721,2,2,5,28,1604491, +12,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1617175,16,1,1618279,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,1604353,12,26,2,9,28,1,6,1,10,28,34,63,38, +3,26,1617375,16,1310721,2,5,26,2,1617361,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,1617303,1586469,12,8,1,1618279,14,1310721, +2,3,26,2,3,10,40,3,36,1617603,16,1310721,2,7,26,2, +7,28,1,6,1,10,28,34,63,38,3,26,1617581,16,1310721,2, +5,26,2,1617567,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,1617451, +1586469,12,8,1,1618279,14,1310721,2,5,26,2,1604589,12,8,1,1618279, +14,1310721,2,7,26,2,7,28,1,6,1,10,28,34,63,38, +3,26,1617703,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,1618279,14,1310721,2,7,26,2,3,28,1,6,1,10,28,34, +63,38,3,26,1617831,16,1310721,2,5,26,2,1617819,14,105,115,32, +109,59,32,119,114,105,116,101,32,100,42,120,32,116,111,32, +103,105,118,101,32,105,116,32,97,119,97,121,0,1617755,1586469,12, +8,1618271,14,1310721,2,7,26,2,5,28,1,6,1,10,28,34, +63,38,3,26,1618007,16,1310721,2,5,26,2,1617995,14,105,115,32, +117,59,32,119,114,105,116,101,32,100,42,120,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,1617883,1586469,12,8,1618271,14,1310721,2,7,26,2, +11,28,1,6,1,10,28,34,63,38,3,26,1618177,16,1310721,2, +5,26,2,1618165,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,1618059,1586469,12,8,1618271,14, +1310721,2,5,26,2,1618263,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,1618191,1586469,12,8,1, +1618279,14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1618327,16,1966081,1310721,4,1579069,12,1310721,2,4,1467905,1310721, +2,2,26,2,1590069,12,8,3,1589235,12,8,1584961,2,1589915,12,8, +1,1618377,14,1,1310721,2,3,26,1310721,4,18,1310721,2,15,28,1310721, +4,1310721,2,1835009,40,1618425,16,1966081,1310721,4,1579069,12,1310721,2,5,26, +4,1310721,2,3,26,4,1310721,2,4,1584853,2,1,6,1,10,28, +34,63,38,3,26,1618485,16,1,1621915,14,1310721,2,9,26,3,1, +10,28,10,3,6,10,4,8,1310721,2,5,26,2,5,40,3, +36,1618579,16,1310721,2,5,26,2,5,28,1604491,12,1,6,1,10, +28,34,63,38,1,10,28,1618581,14,1,1618619,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,1618711,16,1469953,1310721,2,9,26,2,1604353,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,1618713,14,1,1618803,16,1310721,2, +9,26,2,1618789,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,1618731,1586469,12,8,1,1621915,14,1310721,2,2,3,28,1,6, +1,10,28,34,63,38,3,26,1620259,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,1618953,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,1618955,14,1,1619159,16,1310721,2,7,26,2,1607831,12,1,6, +1,10,28,34,63,38,3,26,1619125,16,1310721,2,3,26,2,1619113, +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,1619011,1586469,12,8,1619153,14,1469953,1310721,2,3,26,2, +26,1,10,3,6,10,4,8,1,1621915,14,1310721,2,7,26,2, +1607831,12,1,6,1,10,28,34,63,38,3,26,1619327,16,1310721,2, +3,26,2,1619313,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,1619211,1586469,12,8,1,1621915,14,1310721, +2,5,26,2,3,28,1,6,1,10,28,34,63,38,3,26, +1619517,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,1558017,1310721,2,3, +26,2,26,2,1619511,16,1469953,1310721,2,3,26,2,26,1558017,1310721,2, +3,26,2,26,2,10,3,6,10,4,8,1,1621915,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,1619675,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,1619677,14,1,1619889,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,1558017,1310721,2,3,26,2,26,2,1619883,16, +1469953,1310721,2,3,26,2,26,1558017,1310721,2,3,26,2,26,2,10, +3,6,10,4,8,1,1621915,14,1310721,2,13,26,2,5,28,1, +6,1,10,28,34,63,38,3,26,1620109,16,1310721,2,9,26,2, +1620097,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, +1619941,1586469,12,8,1620253,14,1310721,2,9,26,2,1620245,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,1620123,1586469,12,8,1,1621915, +14,1310721,2,2,7,28,1,6,1,10,28,34,63,38,3,26, +1621583,16,1310721,2,11,26,1310721,2,3,26,2,1604353,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,1604589,12,8,1310721,2,5, +26,2,3,28,1,6,1,10,28,34,63,38,3,26,1620439,16, +1310721,2,3,26,2,1618293,12,8,1,1621915,14,1310721,2,9,26,2, +1,40,1620463,16,1,1621915,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,1620625,16,1310721,2,9,26, +2,1620613,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,1620551,1586469,12,8,1621577,14,1310721,2,13,26,2,13,28,1, +6,1,10,28,34,63,38,3,26,1620753,16,1310721,2,9,26,2, +1620741,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,1620677,1586469,12,8,1621577,14,1310721,2,7,26,2,13,28,1, +6,1,10,28,34,63,38,3,26,1621079,16,1310721,2,13,26,2, +5,28,1,6,1,10,28,34,63,38,3,26,1621003,16,1310721,2, +9,26,2,1620991,14,105,115,32,117,59,32,105,116,32,104,97, +115,32,116,111,32,108,101,97,118,101,32,116,104,114,111,117, +103,104,32,116,104,101,32,98,108,111,99,107,32,97,98,111, +118,101,44,32,110,111,116,32,105,110,116,111,32,97,32,98, +111,114,114,111,119,101,100,32,111,98,106,101,99,116,0,1620843, +1586469,12,8,1621075,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,1618293,12,8,1621577,14,1310721,2,13,26,2, +1310721,2,7,26,2,28,1,6,1,10,28,34,63,38,1,10, +28,1621285,16,1310721,2,9,26,2,1621273,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,1621141,1586469,12,8, +1621577,14,1468929,1310721,2,9,26,2,26,2,1468929,1310721,2,11,26,2, +26,2,40,1621469,16,1310721,2,9,26,2,1621457,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,1621337,1586469,12,8,1621577,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,1618293,12,8,1,1621915,14,1310721,2,9,26,2,1,40,3,36, +1621907,16,1469953,1310721,2,9,26,2,26,2,7,28,1,6,1,10, +28,34,63,38,3,26,1621709,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,1621907,14,1310721,2,9,26,2,1621899,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,1621723,1586469,12,8,1,1621915,14,1,1310721,2,15, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1621963,16, +1966081,1310721,4,1579069,12,1310721,2,4,1584853,2,1,6,1,10,28,34, +63,38,3,26,1622003,16,1,1622897,14,1310721,2,3,26,3,1,10, +28,10,3,6,10,4,8,1310721,2,2,5,40,3,36,1622089,16, +1310721,2,2,5,28,1604491,12,1,6,1,10,28,34,63,38,1, +10,28,1622091,14,1,1622125,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,1622217, +16,1469953,1310721,2,3,26,2,1604353,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,1622219,14,1,1622309,16,1310721,2,3,26,2,1622295,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,1622237,1586469,12,8,1, +1622897,14,1584855,2,1622565,16,1310721,2,3,26,2,1,40,3,36,1622559, +16,1469953,1310721,2,3,26,2,26,2,5,28,1,6,1,10,28, +34,63,38,3,26,1622443,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,1622559,14,1310721,2,3,26,2,1622551,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,117,42,120,39,0,1622457,1586469,12,8,1, +1622897,14,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3, +26,1622723,16,1622711,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,46,117,0,1622603,1586351,12,8,1622889, +14,1310721,2,3,26,2,1,40,3,36,1622889,16,1310721,2,3,26, +2,1622881,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,46,117,0, +1622759,1586469,12,8,1,1622897,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1622945,16,1966081,1310721,4,1579069,12, +1310721,2,4,1584853,2,1,6,1,10,28,34,63,38,3,26,1622985, +16,1,1623613,14,1310721,2,2,3,28,1,6,1,10,28,34,63, +38,3,26,1623025,16,3,1623613,14,1310721,2,2,5,40,1623045,16,3, +1623101,14,1310721,2,2,5,28,1604491,12,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1623111,16, +1,1623613,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,1623253,16,1468929,1310721,2,3,26,2,26,2, +1584849,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1623255,14,1,1623321,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,1623613,14,1469953,1310721,2,3, +26,2,26,2,5,28,1,6,1,10,28,34,63,38,3,26, +1623485,16,1310721,2,3,26,2,1623473,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,1623379,1586469,12,8,1623605,14,1310721,2, +3,26,2,1623597,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,1623499,1586469,12,8,1,1623613,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1623661, +16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,3,28,1,6, +1,10,28,34,63,38,3,26,1623817,16,1623805,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,1623705,1586351, +12,8,1623851,14,1310721,2,2,5,40,3,36,1623851,16,1310721,2,2, +5,28,1604589,12,8,1,1623859,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1623907,16,1966081,1310721,4,1579069, +12,1310721,2,4,1584971,2,1310721,2,3,26,4,1584971,2,1310721,2,2, +26,1310721,40,3,36,1624007,16,1623999,14,116,104,101,32,116,121,112, +101,32,97,114,101,97,32,105,115,32,102,117,108,108,0,1623955, +1585585,12,8,1584971,1584971,2,1310721,2,2,26,10,3,6,10,4,8, +1310721,2,3,26,2,1,1310721,2,2,1574549,12,8,1310721,2,3,26, +2,1624073,14,1,1310721,2,5,26,1310721,4,18,1310721,2,11,28,1310721, +4,1310721,2,1835009,40,1624121,16,1966081,1310721,4,1579069,12,1310721,2,7,26, +4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,15,1310721, +2,7,26,2,26,1623873,12,1310721,2,9,26,4,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,1310721,2,5,26,2,10,3,6,10,4,8, +1584973,2,2049,40,3,36,1624347,16,1624339,14,116,111,111,32,109,97, +110,121,32,116,121,112,101,115,0,1624309,1585585,12,8,1277953,1584973,2, +26,1310721,2,9,26,2,10,3,6,10,4,8,1584973,1,6,2, +1,6,3,26,5,6,4,10,8,8,1310721,2,9,26,2,1624421, +14,1,1310721,2,11,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721, +2,1835009,40,1624469,16,1966081,1310721,4,1579069,12,1310721,2,4,1,1310721,2, +3,26,4,1310721,2,3,26,2,1584973,2,40,1624715,16,1310721,2,5, +26,1277953,1310721,2,3,26,2,26,2,10,3,6,10,4,8,1310721, +2,5,26,2,1,26,2,11,28,1,6,1,10,28,34,63, +38,3,26,1624657,16,1310721,2,5,26,2,9,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,1624659,14,1,1624677,16,1310721,2,5,26,2, +1624795,14,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1624487,14,1310721,2,5,26,11,3,1,1,1624087,12,10, +3,6,10,4,8,1310721,2,5,26,2,9,26,1310721,2,2,10, +3,6,10,4,8,1310721,2,5,26,2,1624795,14,1,1310721,2,7, +26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1624843,16, +1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1,1310721,2, +5,26,4,1310721,2,5,26,2,1584973,2,40,1625179,16,1310721,2,7, +26,1277953,1310721,2,5,26,2,26,2,10,3,6,10,4,8,1310721, +2,7,26,2,1,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1625041,16,1310721,2,7,26,2,9,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,1625043,14,1,1625121,16,1310721,2,7,26,2, +7,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,1625123,14, +1,1625141,16,1310721,2,7,26,2,1625315,14,1310721,2,5,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1624871,14,1310721,2,7, +26,13,1310721,2,3,26,2,1310721,2,2,1628577,12,30,1,1,1624087, +12,10,3,6,10,4,8,1310721,2,7,26,2,9,26,1310721,2, +2,10,3,6,10,4,8,1310721,2,7,26,2,7,26,1310721,2, +3,26,2,10,3,6,10,4,8,1310721,2,7,26,2,1625315,14, +1,1310721,2,9,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2, +1835009,40,1625363,16,1966081,1310721,4,1579069,12,1310721,2,7,26,4,1310721,2, +5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2,9,26, +4,1310721,2,9,26,2,1584973,2,40,1626037,16,1310721,2,13,26,1277953, +1310721,2,9,26,2,26,2,10,3,6,10,4,8,1310721,2,13, +26,2,1,26,2,15,28,1,6,1,10,28,34,63,38,3, +26,1625581,16,1310721,2,13,26,2,9,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,1625583,14,1,1625661,16,1310721,2,13,26,2,7,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,1625663,14,1,1625741, +16,1310721,2,13,26,2,11,26,2,1310721,2,7,26,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1625743,14,1,1625999,16,1310721,2,11,26,1,10,3, +6,10,4,8,1310721,2,11,26,2,1310721,2,3,26,2,40,1625895, +16,1310721,2,13,26,2,15,1310721,2,11,26,2,26,26,2,1310721, +2,5,26,2,1310721,2,11,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,1625897,14,1,1625939,16,1310721,2,11,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1625769,14,1310721,2,11,26,2,1310721,2, +3,26,2,28,1,6,1,10,28,34,63,38,3,26,1625999,16, +1310721,2,13,26,2,1626237,14,1310721,2,9,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1625411,14,1310721,2,13,26,15,3, +1,1310721,2,3,26,2,1624087,12,10,3,6,10,4,8,1310721,2, +13,26,2,9,26,1310721,2,2,10,3,6,10,4,8,1310721,2, +13,26,2,7,26,1310721,2,3,26,2,10,3,6,10,4,8, +1310721,2,13,26,2,11,26,1310721,2,7,26,2,10,3,6,10, +4,8,1310721,2,13,26,2,15,26,1310721,2,5,26,2,1310721,2, +3,26,2,1574337,12,8,1310721,2,13,26,2,1626237,14,1,1310721,2, +15,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1626285, +16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1,1310721, +2,5,26,4,1310721,2,5,26,2,1584973,2,40,1626541,16,1310721,2, +7,26,1277953,1310721,2,5,26,2,26,2,10,3,6,10,4,8, +1310721,2,7,26,2,1,26,2,19,28,1,6,1,10,28,34, +63,38,3,26,1626483,16,1310721,2,7,26,2,7,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,1626485,14,1,1626503,16,1310721,2,7,26, +2,1626629,14,1310721,2,5,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1626313,14,1310721,2,7,26,19,3,1310721,2,3,26, +2,1,1624087,12,10,3,6,10,4,8,1310721,2,7,26,2,7, +26,1310721,2,2,10,3,6,10,4,8,1310721,2,7,26,2,1626629, +14,1,1310721,2,9,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721, +2,1835009,40,1626677,16,1966081,1310721,4,1579069,12,1310721,2,5,26,4,1310721, +2,3,26,4,1310721,2,4,1,1310721,2,7,26,4,1310721,2,7, +26,2,1584973,2,40,1627217,16,1310721,2,11,26,1277953,1310721,2,7,26, +2,26,2,10,3,6,10,4,8,1310721,2,11,26,2,1,26, +2,17,28,1,6,1,10,28,34,63,38,3,26,1626885,16,1310721, +2,11,26,2,11,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, +1626887,14,1,1627179,16,1310721,2,13,26,1310721,2,11,26,2,13,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,5,26,2,40,1627075,16,1310721, +2,13,26,2,3,1310721,2,9,26,2,26,26,2,1310721,2,3, +26,2,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,1627077, +14,1,1627119,16,1310721,2,9,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1626949,14,1310721,2,9,26,2,1310721,2,5,26, +2,28,1,6,1,10,28,34,63,38,3,26,1627179,16,1310721,2, +11,26,2,1627491,14,1310721,2,7,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1626715,14,1310721,2,13,26,1310721,2,5,26, +2,3,26,1623873,12,10,3,6,10,4,8,1310721,2,13,26,2, +1,26,1310721,2,5,26,2,10,3,6,10,4,8,1310721,2,13, +26,2,3,26,1310721,2,3,26,2,1310721,2,5,26,2,1574337,12, +8,1310721,2,11,26,17,1,1310721,2,2,5,26,2,1,1624087,12, +10,3,6,10,4,8,1310721,2,11,26,2,7,26,3,1,10, +28,10,3,6,10,4,8,1310721,2,11,26,2,11,26,1310721,2, +2,10,3,6,10,4,8,1310721,2,11,26,2,13,26,1310721,2, +13,26,2,10,3,6,10,4,8,1310721,2,11,26,2,1627491,14, +1,1310721,2,15,26,1310721,4,18,1310721,2,33,28,1310721,4,1310721,2, +1835009,40,1627539,16,1966081,1310721,4,1579069,12,1310721,2,4,1,1310721,2,13, +26,4,1310721,2,2,1,26,2,17,28,1,6,1,10,28,34, +63,38,1,10,28,1627605,16,3,1627647,14,1310721,2,2,7,26,2, +1,40,3,36,1,6,1,10,28,34,63,38,1,10,28,1627661, +16,1310721,2,2,1628563,14,1310721,2,2,7,26,2,5,1,10,28, +28,1,6,1,10,28,34,63,38,3,26,1627831,16,1627789,14,97, +32,115,116,114,117,99,116,32,99,97,110,39,116,32,99,111, +110,116,97,105,110,32,105,116,115,101,108,102,32,98,121,32, +118,97,108,117,101,0,1627711,1585679,12,8,1310721,2,2,7,26,1, +10,3,6,10,4,8,1310721,2,2,1628563,14,1310721,2,2,7,26, +5,1,10,28,10,3,6,10,4,8,1310721,2,3,26,1310721,2, +2,11,26,2,10,3,6,10,4,8,1310721,2,7,26,1310721,2, +3,26,2,11,26,2,10,3,6,10,4,8,1310721,2,5,26, +1310721,2,3,26,2,9,26,2,10,3,6,10,4,8,1310721,2, +17,26,1,17,1574549,12,8,1310721,2,17,26,1310721,2,2,13,26, +2,3,26,1310721,2,2,13,26,2,1,26,2,1574337,12,8,1310721, +2,11,26,1310721,2,7,26,2,7,30,3,26,1623873,12,10,3, +6,10,4,8,1310721,2,9,26,1,10,3,6,10,4,8,1310721, +2,9,26,2,1310721,2,7,26,2,40,1628455,16,1310721,2,15,26, +1310721,2,5,26,2,1310721,2,9,26,2,1310721,2,9,26,2,26, +3,26,26,2,1310721,2,17,26,1628749,12,10,3,6,10,4,8, +1310721,2,11,26,2,1310721,2,9,26,2,7,30,26,1310721,2,5, +26,2,1310721,2,9,26,2,1310721,2,9,26,2,26,26,2,10, +3,6,10,4,8,1310721,2,11,26,2,1310721,2,9,26,2,7, +30,3,26,26,1310721,2,15,26,2,10,3,6,10,4,8,1310721, +2,11,26,2,1310721,2,9,26,2,7,30,5,26,26,1310721,2, +13,26,2,10,3,6,10,4,8,1310721,2,13,26,1310721,2,13, +26,2,1310721,2,15,26,2,1628577,12,26,10,3,6,10,4,8, +1310721,2,9,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1628095,14,1310721,2,2,9,26,1310721,2,11,26,2,10,3,6, +10,4,8,1310721,2,2,3,26,1310721,2,13,26,2,10,3,6, +10,4,8,1310721,2,2,7,26,1310721,2,7,26,2,10,3,6, +10,4,8,1310721,2,2,1628563,14,1,1310721,2,33,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1628611,16,1966081,1310721,4,1579069, +12,1310721,2,4,1310721,2,2,1,26,2,17,28,1,6,1,10, +28,34,63,38,3,26,1628699,16,1310721,2,2,7,26,2,1,40, +1,6,1,10,28,34,63,38,1,10,28,1628701,14,1,1628717,16, +1310721,2,2,1627505,12,8,1310721,2,2,3,26,2,1628735,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,61,28,1310721,4,1310721,2,1835009,40, +1628783,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1310721, +2,2,1,26,2,1310721,2,5,26,4,1310721,2,5,26,2,19, +28,1,6,1,10,28,34,63,38,3,26,1628927,16,1310721,2,3, +26,2,1310721,2,2,7,26,2,26,2,1628919,16,1310721,2,3,26, +2,1310721,2,2,7,26,2,26,2,1629733,14,1584975,2,1629733,14,1310721, +2,5,26,2,11,28,1,6,1,10,28,34,63,38,3,26, +1628999,16,1310721,2,2,9,26,2,1310721,2,3,26,2,1628749,12,1624435, +12,1629733,14,1310721,2,5,26,2,13,28,1,6,1,10,28,34, +63,38,3,26,1629083,16,1310721,2,2,9,26,2,1310721,2,3,26, +2,1628749,12,1310721,2,2,7,26,2,1624809,12,1629733,14,1310721,2,5, +26,2,15,28,1,6,1,10,28,34,63,38,3,26,1629373,16, +1310721,2,9,26,1310721,2,2,7,26,2,10,3,6,10,4,8, +1310721,2,7,26,1,10,3,6,10,4,8,1310721,2,7,26,2, +1310721,2,9,26,2,40,1629309,16,1310721,2,11,26,1310721,2,7,26, +2,26,1310721,2,2,15,1310721,2,7,26,2,26,26,2,1310721,2, +3,26,2,1628749,12,10,3,6,10,4,8,1310721,2,7,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1629175,14,1310721,2, +2,9,26,2,1310721,2,3,26,2,1628749,12,1310721,2,9,26,2, +1310721,2,11,26,1310721,2,2,11,26,2,1625329,12,1629733,14,1310721,2, +5,26,2,17,28,1,6,1,10,28,34,63,38,3,26,1629449, +16,1310721,2,2,11,26,2,1,6,1,10,28,34,63,38,1, +10,28,1629451,14,1,1629721,16,1310721,2,59,26,1310721,2,2,13,26, +2,10,3,6,10,4,8,1310721,2,9,26,1310721,2,59,26,2, +1,26,2,10,3,6,10,4,8,1310721,2,7,26,1,10,3, +6,10,4,8,1310721,2,7,26,2,1310721,2,9,26,2,40,1629683, +16,1310721,2,11,26,1310721,2,7,26,2,26,1310721,2,59,26,2, +3,1310721,2,7,26,2,26,26,2,1310721,2,3,26,2,1628749,12, +10,3,6,10,4,8,1310721,2,7,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1629545,14,1310721,2,2,11,26,2,1310721, +2,11,26,1310721,2,9,26,2,1626643,12,1629733,14,1310721,2,2,1629733, +14,1,1310721,2,61,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1629781,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2, +1,26,2,3,28,1,6,1,10,28,34,63,38,3,26,1629833, +16,3,1629891,14,1310721,2,2,1,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,1629901,16,3,1629959,14,1310721,2,2,1,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,1629965,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1630013,16,1966081,1310721,4,1579069,12,1310721,2, +4,1310721,2,2,1,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1630065,16,3,1630123,14,1310721,2,2,1,26,2,17,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1630129,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1630177,16,1966081,1310721,4,1579069,12, +1310721,2,4,1310721,2,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1630229,16,3,1630287,14,1310721,2,2,1,26,2, +13,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1630293,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1630341,16,1966081,1310721,4, +1579069,12,1310721,2,4,1310721,2,2,1,26,2,13,28,1,6,1, +10,28,34,63,38,3,26,1630407,16,1310721,2,2,9,26,2,1624435, +12,1630419,14,1310721,2,2,1630419,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1630467,16,1966081,1310721,4,1579069, +12,1310721,2,4,1310721,2,2,1,26,2,11,28,1,6,1,10, +28,34,63,38,3,26,1630519,16,3,1630577,14,1310721,2,2,1,26, +2,13,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1630597,16,1310721,2,2,9,26,2, +1630607,14,1584975,2,1630607,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1630655,16,1966081,1310721,4,1579069,12,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,1310721,2,3,26,2,28, +1,6,1,10,28,34,63,38,3,26,1630719,16,3,1630773,14,1310721, +2,2,1584975,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1630783,16,3,1630841,14,1310721, +2,3,26,2,1584975,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1630851,16,3,1631577, +14,1310721,2,2,1629747,12,1630905,16,1310721,2,3,26,2,1629747,12,1, +6,1,10,28,34,63,38,1,10,28,1630907,14,1,1630917,16,3, +1631577,14,1310721,2,3,26,1310721,2,3,26,2,1630307,12,10,3,6, +10,4,8,1310721,2,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1631057,16,1310721,2,3,26,2,1,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,1631059,14,1,1631383,16,1310721,2,2,9,26, +2,1584975,2,28,1,6,1,10,28,34,63,38,3,26,1631111,16, +3,1631175,14,1310721,2,3,26,2,9,26,2,1584975,2,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1631185,16,3,1631245,14,1310721,2,2,9,26,2,1584983,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1631255,16,3,1631319,14,1310721,2,3,26,2, +9,26,2,1584983,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1631329,16,3,1631577,14, +1310721,2,2,9,26,2,1310721,2,3,26,2,9,26,2,28,1, +6,1,10,28,34,63,38,3,26,1631577,14,1310721,2,2,1,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1631429,16,3, +1631487,14,1310721,2,2,1,26,2,15,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1631521, +16,1584989,2,1,6,1,10,28,34,63,38,1,10,28,1631523,14, +1,1631533,16,3,1631577,14,1310721,2,2,1310721,2,3,26,2,28,1, +6,1,10,28,34,63,38,3,26,1631577,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1631625,16,1966081, +1310721,4,1579069,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2, +4,1310721,2,2,1,26,2,19,28,1,6,1,10,28,34,63, +38,3,26,1631863,16,1310721,2,7,26,1310721,2,2,7,26,2,10, +3,6,10,4,8,1310721,2,5,26,2,1310721,2,7,26,2,26, +2,1,6,1,10,28,34,63,38,3,26,1631821,16,1310721,2,5, +26,2,1310721,2,7,26,2,26,1310721,2,3,26,2,10,3,6, +10,4,8,3,1632667,14,1310721,2,5,26,2,1310721,2,7,26,2, +26,2,1310721,2,3,26,2,1630621,12,1632667,14,1310721,2,3,26,1310721, +2,3,26,2,1630307,12,10,3,6,10,4,8,1310721,2,2,1, +26,2,11,28,1,6,1,10,28,34,63,38,3,26,1632003,16, +1310721,2,3,26,2,1,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,1632005, +14,1,1632107,16,1310721,2,3,26,2,9,26,2,1584975,2,28,1, +6,1,10,28,34,63,38,3,26,1632061,16,3,1632667,14,1310721,2, +2,9,26,2,1310721,2,3,26,2,9,26,2,1310721,2,5,26, +2,1631591,12,1632667,14,1310721,2,2,1,26,2,17,28,1,6,1, +10,28,34,63,38,3,26,1632185,16,1310721,2,2,11,26,2,1, +6,1,10,28,34,63,38,1,10,28,1632187,14,1,1632257,16,1310721, +2,3,26,2,1,26,2,17,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1632259,14, +1,1632339,16,1310721,2,3,26,2,11,26,2,1310721,2,2,11,26, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1632341,14,1,1632641,16,1310721,2,11,26, +1310721,2,2,13,26,2,10,3,6,10,4,8,1310721,2,13,26, +1310721,2,3,26,2,13,26,2,10,3,6,10,4,8,1310721,2, +9,26,1310721,2,11,26,2,1,26,2,10,3,6,10,4,8, +1310721,2,7,26,1,10,3,6,10,4,8,1310721,2,7,26,2, +1310721,2,9,26,2,40,1632635,16,1310721,2,11,26,2,3,1310721,2, +7,26,2,26,26,2,1310721,2,13,26,2,3,1310721,2,7,26, +2,26,26,2,1310721,2,5,26,2,1631591,12,1,6,1,10,28, +34,63,38,3,26,1632597,16,1,1632667,14,1310721,2,7,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1632471,14,3,1632667,14, +1310721,2,2,1310721,2,3,26,2,1630621,12,1632667,14,1,1310721,2,15, +26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1632715,16, +1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1,26,2,1310721,2, +3,26,4,1310721,2,3,26,2,11,28,1,6,1,10,28,34, +63,38,3,26,1632809,16,85,1573101,12,8,1310721,2,2,9,26,2, +1632681,12,1633911,14,1310721,2,3,26,2,13,28,1,6,1,10,28, +34,63,38,3,26,1632901,16,183,1573101,12,8,1310721,2,2,7,26, +2,1573503,12,8,187,1573101,12,8,1310721,2,2,9,26,2,1632681,12, +1633911,14,1310721,2,3,26,2,15,28,1,6,1,10,28,34,63, +38,3,26,1633561,16,1632951,14,102,110,40,0,1632943,1573341,12,8,1310721, +2,5,26,1,10,3,6,10,4,8,1310721,2,5,26,2,1310721, +2,2,7,26,2,40,1633333,16,1310721,2,5,26,2,1633041,16,1633033, +14,44,32,0,1633027,1573341,12,8,1310721,2,2,15,1310721,2,5,26, +2,26,26,2,1632681,12,8,1310721,2,5,26,2,25,40,1633159,16, +1310721,2,2,1310721,2,5,26,2,1646457,12,3,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1633161,14,1,1633183,16,1633175,14,46,109,0,1633169,1573341,12,8,1310721, +2,5,26,2,25,40,1633271,16,1310721,2,2,1310721,2,5,26,2, +1646457,12,5,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1633273,14,1,1633295,16,1633287,14, +46,100,0,1633281,1573341,12,8,1310721,2,5,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1632981,14,83,1573101,12,8,1310721,2, +2,9,26,2,1584975,2,28,1,6,1,10,28,34,63,38,1, +10,28,1633391,16,3,1633429,14,1310721,2,2,11,26,2,3,32,1, +6,1,10,28,34,63,38,1,10,28,1633555,16,1633447,14,32,45, +62,32,0,1633437,1573341,12,8,1310721,2,2,9,26,2,1584975,2,28, +1,6,1,10,28,34,63,38,1,10,28,1633517,16,1310721,2,2, +9,26,2,1632681,12,8,1310721,2,2,11,26,2,3,32,1633555,16, +1633547,14,46,117,0,1633541,1573341,12,8,1,1633911,14,1310721,2,2,5, +26,2,1633599,16,1310721,2,2,5,26,2,1573341,12,8,1633615,14,1633607, +14,63,0,1633603,1573341,12,8,1310721,2,3,26,2,17,28,1,6, +1,10,28,34,63,38,3,26,1633691,16,1310721,2,2,11,26,2, +1,6,1,10,28,34,63,38,1,10,28,1633693,14,1,1633903,16, +1310721,2,7,26,1310721,2,2,13,26,2,10,3,6,10,4,8, +121,1573101,12,8,1310721,2,5,26,1,10,3,6,10,4,8,1310721, +2,5,26,2,1310721,2,7,26,2,1,26,2,40,1633895,16,1310721, +2,5,26,2,1633823,16,1633815,14,44,32,0,1633809,1573341,12,8,1310721, +2,7,26,2,3,1310721,2,5,26,2,26,26,2,1632681,12,8, +1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1633759,14,125,1573101,12,8,1,1633911,14,1,1310721,2,9,26,1310721, +4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1633959,16,1966081,1310721, +4,1579069,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4, +1584985,2,1,6,1,10,28,34,63,38,3,26,1634019,16,3,1634065, +14,1584857,2,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1634075,16,3,1634101,14,1584991,2,1, +6,1,10,28,34,63,38,1,10,28,1634111,16,3,1634137,14,1585091, +2,1,6,1,10,28,34,63,38,1,10,28,1634147,16,1,1634311, +14,1585093,12,8,1634183,14,116,121,112,101,32,101,114,114,111,114, +58,32,0,1634157,1573341,12,8,1310721,2,2,1573341,12,8,1634231,14,58, +32,101,120,112,101,99,116,101,100,32,0,1634207,1573341,12,8,1310721, +2,3,26,2,1632681,12,8,1634273,14,44,32,103,111,116,32,0, +1634259,1573341,12,8,1310721,2,5,26,2,1632681,12,8,1585237,12,8,1, +1634311,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1634359,16,1966081,1310721,4,1579069,12,1310721,2,5,26,4, +1310721,2,3,26,4,1310721,2,4,1310721,2,2,1634401,16,3,1634447,14, +1584985,2,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1634457,16,3,1634503,14,1584857,2,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1634513,16,3,1634539,14,1584991,2,1,6,1,10,28,34, +63,38,1,10,28,1634549,16,3,1634575,14,1585091,2,1,6,1,10, +28,34,63,38,1,10,28,1634585,16,1,1634701,14,1585093,12,8,1634621, +14,116,121,112,101,32,101,114,114,111,114,58,32,0,1634595,1573341, +12,8,1310721,2,3,26,2,1573341,12,8,1634663,14,44,32,103,111, +116,32,0,1634649,1573341,12,8,1310721,2,5,26,2,1632681,12,8,1585237, +12,8,1,1634701,14,1,1310721,2,7,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1634749,16,1966081,1310721,4,1579069,12,1310721,2, +4,1585009,2,1310721,2,3,26,4,1310721,2,3,26,2,1634883,16,1310721, +2,3,26,1,6,2,1,6,-1,26,5,6,4,10,8,8, +1584993,1310721,2,3,26,2,26,2,1310721,2,2,28,1,6,1,10, +28,34,63,38,3,26,1634879,16,1310721,2,3,26,2,1634897,14,1634769, +14,3,1,10,28,1634897,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1634945,16,1966081,1310721,4,1579069,12, +1310721,2,4,1310721,2,2,1634715,12,1,40,3,36,1634979,16,3,1635133, +14,1310721,2,2,1603687,12,1,40,3,36,1635007,16,1,1635133,14,1310721, +2,3,26,1310721,2,2,1587809,12,10,3,6,10,4,8,1310721,2, +3,26,2,1,40,3,36,1635125,16,1417729,1310721,2,3,26,2,26, +2,15,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1635127,14,1,1635133,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1635181, +16,1966081,1310721,4,1579069,12,1585019,2,1598497,12,1635217,16,1582579,1585017,2,10, +3,6,10,4,8,1,1635235,14,1585017,2,1599031,12,8,1,1635235,14, +1,1310721,2,1,26,1310721,4,18,1310721,2,79,28,1310721,4,1310721,2, +1835009,40,1635283,16,1966081,1310721,4,1579069,12,1,1310721,2,7,26,4,1, +1310721,2,75,26,4,1584911,2,1598801,12,1635331,16,1635249,12,1624435,12,1637129, +14,1584895,2,1598801,12,1635495,16,1310721,2,1665803,12,10,3,6,10,4, +8,1584897,2,1599031,12,8,1310721,2,5,26,1635249,12,10,3,6,10, +4,8,1310721,2,2,1,40,1635471,16,1635463,14,97,32,110,101,103, +97,116,105,118,101,32,97,114,114,97,121,32,108,101,110,103, +116,104,0,1635415,1585679,12,8,1310721,2,5,26,2,1310721,2,2,1624809, +12,1637129,14,1584927,2,1598649,12,1636065,16,1597071,12,8,1584887,2,1599031,12, +8,1584889,2,1598497,12,1,6,1,10,28,34,63,38,3,26,1635745, +16,3,1635745,16,1310721,2,7,26,2,49,40,3,36,1635635,16,1635627, +14,116,111,111,32,109,97,110,121,32,112,97,114,97,109,101, +116,101,114,115,0,1635587,1586063,12,8,1310721,2,9,26,1310721,2,7, +26,2,26,1635249,12,10,3,6,10,4,8,1310721,2,7,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1584899,2,1598801,12, +1,6,1,10,28,34,63,38,3,26,1635741,16,1635745,14,1635555,14, +1584889,2,1599031,12,8,1310721,2,57,26,1584975,2,10,3,6,10,4, +8,1310721,2,77,26,1,10,3,6,10,4,8,1584905,2,1598801,12, +1635995,16,1584925,2,1598497,12,1,6,1,10,28,34,63,38,3,26, +1635869,16,1310721,2,57,26,1635249,12,10,3,6,10,4,8,1584925,2, +1598801,12,1635995,16,1584945,2,1598649,12,1,6,1,10,28,34,63,38, +3,26,1635967,16,1635959,14,116,104,101,32,114,101,116,117,114,110, +32,116,97,103,32,105,115,32,46,117,0,1635917,1586063,12,8,1597071, +12,8,1310721,2,77,26,3,10,3,6,10,4,8,1310721,2,57, +26,2,1310721,2,7,26,2,1310721,2,9,26,1310721,2,77,26,2, +1310721,2,7,26,2,26,1310721,2,7,26,2,26,1625329,12,1637129,14, +1582577,2,5,28,1,6,1,10,28,34,63,38,1,10,28,1636151, +16,1636135,14,101,120,112,101,99,116,101,100,32,97,32,116,121, +112,101,0,1636103,1586063,12,8,1584975,2,1637129,14,1310721,2,1582579,2,10, +3,6,10,4,8,1310721,2,77,26,1310721,2,2,1634715,12,10,3, +6,10,4,8,1310721,2,77,26,2,1,40,3,36,1636253,16,1597071, +12,8,1310721,2,77,26,2,1310721,2,2,1626251,12,1637129,14,1310721,2, +3,26,1310721,2,2,1587809,12,10,3,6,10,4,8,1310721,2,3, +26,2,1,40,1636307,16,3,1636371,14,1417729,1310721,2,3,26,2,26, +2,15,28,1,6,1,10,28,34,63,38,1,10,28,1,6, +1,10,28,34,63,38,1,10,28,1636427,16,1310721,2,2,1636411,14, +105,115,110,39,116,32,97,32,116,121,112,101,0,1636385,1586197,12, +8,1584975,2,1637129,14,1597071,12,8,1310721,2,5,26,1425921,1310721,2,3, +26,2,26,2,10,3,6,10,4,8,1310721,2,5,26,2,1, +26,2,21,28,1,6,1,10,28,34,63,38,1,10,28,1636529, +16,1310721,2,5,26,2,1637129,14,1585015,2,1599031,12,8,3,1636951,16, +1310721,2,75,26,2,17,40,3,36,1636627,16,1636619,14,116,111,111, +32,109,97,110,121,32,116,121,112,101,32,97,114,103,117,109, +101,110,116,115,0,1636571,1586063,12,8,1310721,2,59,26,1310721,2,75, +26,2,26,1635249,12,10,3,6,10,4,8,1310721,2,59,26,1310721, +2,75,26,2,26,2,1628577,12,3,28,1,6,1,10,28,34, +63,38,1,10,28,1636877,16,1636869,14,116,121,112,101,32,97,114, +103,117,109,101,110,116,115,32,104,97,118,101,32,116,111,32, +98,101,32,111,110,101,32,119,111,114,100,32,40,97,32,112, +111,105,110,116,101,114,44,32,97,32,110,117,109,98,101,114, +44,32,111,114,32,97,32,112,97,114,97,109,101,116,101,114, +41,0,1636723,1585679,12,8,1310721,2,75,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1584899,2,1598801,12,1,6,1,10,28, +34,63,38,3,26,1636947,16,1636951,14,1636539,14,1635147,12,8,1310721,2, +75,26,2,1310721,2,5,26,2,7,26,2,28,1,6,1,10, +28,34,63,38,1,10,28,1637091,16,1310721,2,2,1637083,14,119,114, +111,110,103,32,110,117,109,98,101,114,32,111,102,32,116,121, +112,101,32,97,114,103,117,109,101,110,116,115,0,1637021,1585849,12, +8,1310721,2,5,26,2,1310721,2,59,26,1310721,2,75,26,2,1626643, +12,1637129,14,1,1310721,2,79,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1637177,16,1966081,1310721,4,1579069,12,1582577,2,9,28, +1,6,1,10,28,34,63,38,3,26,1637815,16,1582579,2,1584895,2, +28,1,6,1,10,28,34,63,38,3,26,1637249,16,3,1637301,14, +1582579,2,1584925,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1637311,16,3,1637931,14,1582579, +2,1584911,2,28,1,6,1,10,28,34,63,38,3,26,1637809,16, +1310721,2,1,10,3,6,10,4,8,1310721,2,2,7,40,1637541,16, +1310721,2,2,1597469,12,8,1584799,2,9,28,1,6,1,10,28,34, +63,38,3,26,1637477,16,1584801,2,1584911,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1637479,14,1,1,6,1,10,28,34,63,38,3,26,1637507,16,1637541, +14,1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8, +1637363,14,1310721,2,2,1597469,12,8,1584799,2,5,28,1,6,1,10, +28,34,63,38,3,26,1637681,16,1584801,2,1634911,12,1637603,16,3,1637655, +14,1584801,2,1584927,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,1637683,14,1,1637693,16,3,1637805,14,1584799,2, +9,28,1,6,1,10,28,34,63,38,3,26,1637781,16,1584801,2, +1584895,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1637783,14,1,1,6,1,10,28, +34,63,38,1,10,28,1637931,14,1,1637931,14,1582577,2,5,28,1, +6,1,10,28,34,63,38,1,10,28,1637855,16,1,1637931,14,1582579, +2,1584927,2,28,1,6,1,10,28,34,63,38,3,26,1637895,16, +3,1637925,14,1582579,2,1634911,12,1,6,1,10,28,34,63,38,1, +10,28,1637931,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28, +1310721,4,1310721,2,1835009,40,1637979,16,1966081,1310721,4,1579069,12,1585011,1,10, +3,6,10,4,8,1585013,1,10,3,6,10,4,8,1584925,2,1598497, +12,1,6,1,10,28,34,63,38,3,26,1638061,16,1585011,1635249,12, +10,3,6,10,4,8,1584925,2,1598801,12,1638297,16,1582579,2,1584941,2, +28,1,6,1,10,28,34,63,38,3,26,1638127,16,1585013,3,10, +3,6,10,4,8,1638291,14,1582579,2,1584945,2,28,1,6,1,10, +28,34,63,38,3,26,1638181,16,1585013,5,10,3,6,10,4,8, +1638291,14,1582579,2,1584943,2,28,1,6,1,10,28,34,63,38,3, +26,1638235,16,1585013,7,10,3,6,10,4,8,1638291,14,1638283,14,97, +32,116,97,103,32,105,115,32,46,117,44,32,46,109,32,111, +114,32,46,100,0,1638239,1586063,12,8,1597071,12,8,1,1638305,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,21,28,1310721,4,1310721,2,1835009, +40,1638353,16,1966081,1310721,4,1579069,12,1,1310721,2,7,26,4,1524225,1310721, +2,9,26,4,1,1310721,2,15,26,4,1,1310721,2,17,26,4, +1597071,12,8,1310721,2,1599321,12,10,3,6,10,4,8,1585015,2,1598497, +12,1638821,16,1597071,12,8,1585009,1,10,3,6,10,4,8,3,1638637, +16,1585009,2,17,40,3,36,1638545,16,1638537,14,116,111,111,32,109, +97,110,121,32,116,121,112,101,32,112,97,114,97,109,101,116, +101,114,115,0,1638487,1586063,12,8,1584993,1585009,2,26,1599321,12,10,3, +6,10,4,8,1585009,1,6,2,1,6,3,26,5,6,4,10, +8,8,1584899,2,1598801,12,1,6,1,10,28,34,63,38,3,26, +1638633,16,1638637,14,1638461,14,1635147,12,8,1310721,2,17,26,3,10,3, +6,10,4,8,1310721,2,3,26,21,1,1310721,2,2,1,1624087,12, +10,3,6,10,4,8,1310721,2,3,26,2,7,26,1585009,2,10, +3,6,10,4,8,1310721,2,13,26,1585009,2,1623873,12,10,3,6, +10,4,8,1310721,2,13,26,2,1584993,1585009,2,1574337,12,8,1310721,2, +3,26,2,13,26,1310721,2,13,26,2,10,3,6,10,4,8, +1638891,14,1310721,2,3,26,17,1,1310721,2,2,1,1624087,12,10,3, +6,10,4,8,1310721,2,3,26,2,7,26,5,1,10,28,10, +3,6,10,4,8,1310721,2,5,26,1310721,2,2,15,1310721,2,3, +26,2,1587311,12,10,3,6,10,4,8,1584891,2,1599031,12,8,1584893, +2,1598497,12,1,6,1,10,28,34,63,38,3,26,1639269,16,1310721, +2,19,26,1635249,12,10,3,6,10,4,8,3,1639255,16,1310721,2, +7,26,2,2001,40,3,36,1639071,16,1639063,14,116,111,111,32,109, +97,110,121,32,102,105,101,108,100,115,0,1639031,1585585,12,8,1310721, +2,9,26,2,1310721,2,7,26,2,1310721,2,7,26,2,26,26, +1599321,12,10,3,6,10,4,8,1310721,2,9,26,2,1310721,2,7, +26,2,1310721,2,7,26,2,26,3,26,26,1310721,2,19,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,1584899,2,1598801,12,1,6,1,10,28, +34,63,38,3,26,1639251,16,1639255,14,1638999,14,1584901,2,1599031,12,8, +1638943,14,1597071,12,8,1310721,2,17,26,2,1639475,16,1310721,2,13,26, +1310721,2,7,26,2,1310721,2,7,26,2,26,1623873,12,10,3,6, +10,4,8,1310721,2,13,26,2,1310721,2,9,26,2,1310721,2,7, +26,2,1310721,2,7,26,2,26,1574337,12,8,1310721,2,3,26,2, +9,26,1310721,2,13,26,2,10,3,6,10,4,8,1310721,2,3, +26,2,11,26,1310721,2,7,26,2,10,3,6,10,4,8,1585009, +1,10,3,6,10,4,8,1640185,14,1310721,2,13,26,1310721,2,7, +26,2,7,30,3,26,1623873,12,10,3,6,10,4,8,1310721,2, +11,26,1,10,3,6,10,4,8,1310721,2,11,26,2,1310721,2, +7,26,2,40,1640077,16,1310721,2,19,26,1310721,2,9,26,2,1310721, +2,11,26,2,1310721,2,11,26,2,26,3,26,26,2,10,3, +6,10,4,8,1310721,2,19,26,2,1310721,2,3,26,2,28,1, +6,1,10,28,34,63,38,3,26,1639815,16,1639783,14,97,32,115, +116,114,117,99,116,32,99,97,110,39,116,32,99,111,110,116, +97,105,110,32,105,116,115,101,108,102,32,98,121,32,118,97, +108,117,101,59,32,117,115,101,32,97,32,112,111,105,110,116, +101,114,0,1639675,1585679,12,8,1310721,2,19,26,1584975,2,10,3,6, +10,4,8,1310721,2,13,26,2,1310721,2,11,26,2,7,30,26, +1310721,2,9,26,2,1310721,2,11,26,2,1310721,2,11,26,2,26, +26,2,10,3,6,10,4,8,1310721,2,13,26,2,1310721,2,11, +26,2,7,30,3,26,26,1310721,2,19,26,2,10,3,6,10, +4,8,1310721,2,13,26,2,1310721,2,11,26,2,7,30,5,26, +26,1310721,2,15,26,2,10,3,6,10,4,8,1310721,2,15,26, +1310721,2,15,26,2,1310721,2,19,26,2,1628577,12,26,10,3,6, +10,4,8,1310721,2,11,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1639539,14,1310721,2,3,26,2,9,26,1310721,2,13, +26,2,10,3,6,10,4,8,1310721,2,3,26,2,3,26,1310721, +2,15,26,2,10,3,6,10,4,8,1310721,2,3,26,2,7, +26,1310721,2,7,26,2,10,3,6,10,4,8,1584901,2,1598801,12, +8,1310721,2,5,26,2,1640211,14,1,1310721,2,21,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1640259,16,1966081,1310721,4,1579069, +12,1597071,12,8,1310721,2,1599321,12,10,3,6,10,4,8,1584903,2, +1599031,12,8,1310721,2,2,15,1635249,12,1587311,12,8,1584901,2,1599031,12, +8,1,1640331,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28, +1310721,4,1310721,2,1835009,40,1640379,16,1966081,1310721,4,1579069,12,1597071,12,8, +1585037,2,1598649,12,1640417,16,1584985,3,10,3,6,10,4,8,1640521,14, +1585039,2,1598649,12,1640449,16,1584985,1,10,3,6,10,4,8,1640521,14, +1640513,14,116,121,112,101,99,104,101,99,107,32,111,110,32,111, +114,32,116,121,112,101,99,104,101,99,107,32,111,102,102,0, +1640453,1586063,12,8,1597071,12,8,1584901,2,1599031,12,8,1,1640545,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009, +40,1640593,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4, +1,1310721,2,5,26,4,1310721,2,2,1627505,12,8,1310721,2,5,26, +2,1310721,2,2,7,26,2,40,1640779,16,1310721,2,2,9,26,2, +1310721,2,5,26,2,7,30,26,2,1310721,2,3,26,2,28,1, +6,1,10,28,34,63,38,3,26,1640741,16,1310721,2,5,26,2, +1640793,14,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1640633,14,3,1,10,28,1640793,14,1,1310721,2,7,26, +1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1640841,16,1966081, +1310721,4,1579069,12,1584887,2,1599031,12,8,1637143,12,1640913,16,1584925,2,1598497, +12,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1640915,14,1,1640943,16,1310721,2,1635249,12,10, +3,6,10,4,8,1641105,14,1310721,2,3,26,1606761,12,10,3,6, +10,4,8,1584991,1,6,2,1,6,3,26,5,6,4,10,8, +8,1310721,2,5,26,1662195,12,10,3,6,10,4,8,1647757,12,8, +1310721,2,1584987,2,10,3,6,10,4,8,1584991,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1310721,2,3,26,2,1607393,12,8, +1310721,2,3,26,2,1607311,12,8,1584889,2,1599031,12,8,1310721,2,2, +1641127,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1641175,16,1966081,1310721,4,1579069,12,1597071,12,8,1310721,2, +1640807,12,10,3,6,10,4,8,1310721,2,2,1628577,12,1589149,12,8, +1584987,1584977,2,10,3,6,10,4,8,1,1641243,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1641291,16, +1966081,1310721,4,1579069,12,1597071,12,8,1310721,2,1640807,12,10,3,6,10, +4,8,1310721,2,2,1589149,12,8,1584987,1584975,2,10,3,6,10,4, +8,1,1641355,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28, +1310721,4,1310721,2,1835009,40,1641403,16,1966081,1310721,4,1579069,12,1584971,1277953,2049, +26,10,3,6,10,4,8,1584973,1,10,3,6,10,4,8,1584975, +1,3,1641459,14,119,111,114,100,0,1641449,1586793,12,1,1624087,12,10, +3,6,10,4,8,1584977,3,3,1641501,14,105,110,116,0,1641493,1586793, +12,1,1624087,12,10,3,6,10,4,8,1584979,5,3,1641545,14,99, +104,97,114,0,1641535,1586793,12,1,1624087,12,10,3,6,10,4,8, +1584981,7,3,1641589,14,98,111,111,108,0,1641579,1586793,12,1,1624087,12, +10,3,6,10,4,8,1584983,9,1,1641633,14,118,111,105,100,0, +1641623,1586793,12,1,1624087,12,10,3,6,10,4,8,1584975,2,5,26, +2,15,1584975,2,1587311,12,8,1584977,2,5,26,2,15,1584977,2,1587311, +12,8,1584979,2,5,26,2,15,1584979,2,1587311,12,8,1584981,2,5, +26,2,15,1584981,2,1587311,12,8,1584983,2,5,26,2,15,1584983,2, +1587311,12,8,1585015,1641777,14,60,0,1641773,1586793,12,10,3,6,10,4, +8,1585017,1641805,14,62,0,1641801,1586793,12,10,3,6,10,4,8,1585019, +1641835,14,62,62,0,1641829,1586793,12,10,3,6,10,4,8,1585021,1641865, +14,60,61,0,1641859,1586793,12,10,3,6,10,4,8,1585023,1641895,14, +62,61,0,1641889,1586793,12,10,3,6,10,4,8,1585025,1641925,14,61, +61,0,1641919,1586793,12,10,3,6,10,4,8,1585027,1641955,14,33,61, +0,1641949,1586793,12,10,3,6,10,4,8,1585029,1641983,14,43,0,1641979, +1586793,12,10,3,6,10,4,8,1585031,1642021,14,115,116,114,117,99, +116,0,1642007,1586793,12,10,3,6,10,4,8,1585033,1642055,14,116,121, +112,101,0,1642045,1586793,12,10,3,6,10,4,8,1585035,1642099,14,116, +121,112,101,99,104,101,99,107,0,1642079,1586793,12,10,3,6,10, +4,8,1585037,1642129,14,111,110,0,1642123,1586793,12,10,3,6,10,4, +8,1585039,1642161,14,111,102,102,0,1642153,1586793,12,10,3,6,10,4, +8,1585041,1642193,14,110,101,119,0,1642185,1586793,12,10,3,6,10,4, +8,1585043,1642229,14,110,101,119,95,116,0,1642217,1586793,12,10,3,6, +10,4,8,1585045,1,26,1642261,14,42,0,1642257,1586793,12,10,3,6, +10,4,8,1585045,3,26,1642293,14,47,0,1642289,1586793,12,10,3,6, +10,4,8,1585045,5,26,1642325,14,37,0,1642321,1586793,12,10,3,6, +10,4,8,1585045,7,26,1642357,14,38,0,1642353,1586793,12,10,3,6, +10,4,8,1585045,9,26,1642389,14,124,0,1642385,1586793,12,10,3,6, +10,4,8,1585045,11,26,1642421,14,94,0,1642417,1586793,12,10,3,6, +10,4,8,1585045,13,26,1642455,14,60,60,0,1642449,1586793,12,10,3, +6,10,4,8,1585045,15,26,1585019,2,10,3,6,10,4,8,1585069, +17,10,3,6,10,4,8,1,1642519,14,1,1310721,2,1,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1642567,16,1966081,1310721, +4,1579069,12,1310721,2,4,1,1310721,2,3,26,4,1310721,2,3,26, +2,1585069,2,40,1642697,16,1585045,1310721,2,3,26,2,26,2,1310721,2, +2,28,1,6,1,10,28,34,63,38,3,26,1642659,16,3,1642705, +14,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1642585,14,1,1642705,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,9,28,1310721,4,1310721,2,1835009,40,1642753,16,1966081,1310721,4,1579069,12, +1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1546753,1310721,2, +2,26,2,1310721,2,7,26,4,1310721,2,3,26,1310721,2,3,26, +2,1630307,12,10,3,6,10,4,8,1310721,2,5,26,1310721,2,5, +26,2,1630307,12,10,3,6,10,4,8,1547137,1310721,2,2,26,2, +1,40,1643065,16,1310721,2,3,26,2,1629979,12,1,6,1,10,28, +34,63,38,3,26,1642987,16,1310721,2,5,26,2,1629979,12,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1642989,14,1,1643039,14,38,38,32,97,110,100,32,124, +124,32,110,101,101,100,32,115,99,97,108,97,114,115,0,1642993, +1310721,2,3,26,2,1634325,12,8,1584981,2,1645491,14,1310721,2,7,26, +2,1585025,2,28,1,6,1,10,28,34,63,38,3,26,1643111,16, +3,1643169,14,1310721,2,7,26,2,1585027,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1643359,16,1310721,2,3,26,2,1310721,2,5,26,2,1630621,12,1,6, +1,10,28,34,63,38,3,26,1643291,16,1310721,2,5,26,2,1310721, +2,3,26,2,1630621,12,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1643293,14,1,1643351,16, +1643323,14,99,111,109,112,97,114,105,115,111,110,0,1643301,1310721,2, +3,26,2,1310721,2,5,26,2,1633925,12,8,1584981,2,1645491,14,1310721, +2,7,26,2,1585015,2,28,1,6,1,10,28,34,63,38,3, +26,1643405,16,3,1643463,14,1310721,2,7,26,2,1585017,2,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1643473,16,3,1643531,14,1310721,2,7,26,2,1585021,2,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1643541,16,3,1643599,14,1310721,2,7,26,2,1585023, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1644029,16,1310721,2,3,26,2,1584975,2, +28,1,6,1,10,28,34,63,38,3,26,1643649,16,3,1643707,14, +1310721,2,5,26,2,1584975,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1643717,16,3, +1643799,14,1310721,2,3,26,2,1629747,12,1643775,16,1310721,2,5,26,2, +1629747,12,1,6,1,10,28,34,63,38,1,10,28,1643777,14,1, +1,6,1,10,28,34,63,38,1,10,28,1643809,16,3,1643943,14, +1310721,2,3,26,2,1,26,2,11,28,1,6,1,10,28,34, +63,38,3,26,1643919,16,1310721,2,5,26,2,1,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,1643921,14,1,1,6,1,10,28,34,63,38, +1,10,28,1,6,1,10,28,34,63,38,3,26,1644021,16,1643993, +14,99,111,109,112,97,114,105,115,111,110,0,1643971,1310721,2,3, +26,2,1310721,2,5,26,2,1633925,12,8,1584981,2,1645491,14,1310721,2, +7,26,2,1585029,2,28,1,6,1,10,28,34,63,38,3,26, +1644577,16,1310721,2,3,26,2,1,26,2,11,28,1,6,1,10, +28,34,63,38,3,26,1644221,16,1310721,2,5,26,2,1629747,12,1644137, +16,3,1644195,14,1310721,2,5,26,2,1584975,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,1644223,14,1,1644241, +16,1310721,2,3,26,2,1645491,14,1310721,2,5,26,2,1,26,2, +11,28,1,6,1,10,28,34,63,38,3,26,1644325,16,1310721,2, +3,26,2,1629747,12,1,6,1,10,28,34,63,38,1,10,28, +1644327,14,1,1644345,16,1310721,2,5,26,2,1645491,14,1310721,2,3,26, +2,1584975,2,28,1,6,1,10,28,34,63,38,3,26,1644391,16, +3,1644449,14,1310721,2,5,26,2,1584975,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1644461,16,1584975,2,1645491,14,1310721,2,3,26,2,1629747,12,1644519,16,1310721, +2,5,26,2,1629747,12,1,6,1,10,28,34,63,38,1,10, +28,1644521,14,1,1644533,16,1584977,2,1645491,14,1644541,14,43,0,1644537,1310721, +2,3,26,2,1310721,2,5,26,2,1633925,12,8,1584975,2,1645491,14, +1310721,2,7,26,2,1584919,2,28,1,6,1,10,28,34,63,38, +3,26,1645145,16,1310721,2,3,26,2,1,26,2,11,28,1,6, +1,10,28,34,63,38,3,26,1644727,16,1310721,2,5,26,2,1, +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,1644729,14,1,1644741,16,1584977,2, +1645491,14,1310721,2,3,26,2,1,26,2,11,28,1,6,1,10, +28,34,63,38,3,26,1644893,16,1310721,2,5,26,2,1629747,12,1644809, +16,3,1644867,14,1310721,2,5,26,2,1584975,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,1644895,14,1,1644913, +16,1310721,2,3,26,2,1645491,14,1310721,2,3,26,2,1584975,2,28, +1,6,1,10,28,34,63,38,3,26,1644959,16,3,1645017,14,1310721, +2,5,26,2,1584975,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1645029,16,1584975,2, +1645491,14,1310721,2,3,26,2,1629747,12,1645087,16,1310721,2,5,26,2, +1629747,12,1,6,1,10,28,34,63,38,1,10,28,1645089,14,1, +1645101,16,1584977,2,1645491,14,1645109,14,45,0,1645105,1310721,2,3,26,2, +1310721,2,5,26,2,1633925,12,8,1584975,2,1645491,14,1310721,2,7,26, +2,1642533,12,1645481,16,1310721,2,3,26,2,1584975,2,28,1,6,1, +10,28,34,63,38,3,26,1645209,16,3,1645267,14,1310721,2,5,26, +2,1584975,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1645279,16,1584975,2,1645491,14,1310721, +2,3,26,2,1629747,12,1645337,16,1310721,2,5,26,2,1629747,12,1, +6,1,10,28,34,63,38,1,10,28,1645339,14,1,1645351,16,1584977, +2,1645491,14,1310721,2,3,26,2,1629747,12,1645399,16,1310721,2,3,26, +1310721,2,5,26,2,10,3,6,10,4,8,1,1645455,14,97,114, +105,116,104,109,101,116,105,99,32,110,101,101,100,115,32,110, +117,109,98,101,114,115,0,1645405,1310721,2,3,26,2,1634325,12,8, +1584975,2,1645491,14,1584975,2,1645491,14,1,1310721,2,9,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1645539,16,1966081,1310721,4,1579069, +12,1310721,2,4,1310721,2,2,1,26,2,1645563,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1645611,16, +1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1628577,12,1645633,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1645681,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,5,26, +2,1645705,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1645753,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721, +2,2,7,26,2,1645777,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1645825,16,1966081,1310721,4,1579069,12, +1310721,2,4,1310721,2,2,1627505,12,8,1310721,2,2,7,26,2,1645861, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1645909,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721, +2,4,1310721,2,2,1627505,12,8,1310721,2,2,9,26,2,1310721,2, +3,26,2,7,30,26,2,1645973,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1646021,16,1966081,1310721,4, +1579069,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1627505,12,8, +1310721,2,2,9,26,2,1310721,2,3,26,2,7,30,3,26,26, +2,1646089,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1646137,16,1966081,1310721,4,1579069,12,1310721,2,3,26, +4,1310721,2,4,1310721,2,2,1627505,12,8,1310721,2,2,9,26,2, +1310721,2,3,26,2,7,30,5,26,26,2,1646205,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1646253, +16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,9,26,2,1646277, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1646325,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2, +7,26,2,1646349,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1646397,16,1966081,1310721,4,1579069,12,1310721,2, +3,26,4,1310721,2,4,1310721,2,2,15,1310721,2,3,26,2,26, +26,2,1646443,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1646491,16,1966081,1310721,4,1579069,12,1310721,2,3, +26,4,1310721,2,4,1310721,2,2,11,26,2,13,38,1310721,2,3, +26,2,1310721,2,3,26,2,26,38,7,32,1646557,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1646605, +16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,11,26,2,3, +32,1646633,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1646681,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721, +2,2,1,26,2,17,28,1,6,1,10,28,34,63,38,1, +10,28,1646735,16,3,1646789,14,1310721,2,2,11,26,2,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1646799,16,1,1646823,14,1310721,2,2,13,26,2,1,26,2, +1646823,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1646871,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,13,26,2,3,1310721,2,3,26,2,26, +26,2,1646923,14,1,1310721,2,5,26,1310721,4,18,1310721,2,59,28, +1310721,4,1310721,2,1835009,40,1646971,16,1966081,1310721,4,1579069,12,1310721,2,4, +1582507,2,1310721,2,3,26,4,3,1,10,28,1310721,2,5,26,4, +1310721,2,3,26,2,1647267,16,1310721,2,3,26,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1417729,1310721,2,3,26,2,26,2, +3,28,1,6,1,10,28,34,63,38,3,26,1647171,16,1425921,1310721, +2,3,26,2,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,1647173, +14,1,1647223,16,1442305,1310721,2,3,26,2,26,2,3,32,1,6, +1,10,28,34,63,38,1,10,28,1647225,14,1,1647263,16,1310721,2, +5,26,1310721,2,3,26,2,10,3,6,10,4,8,1647267,14,1647009, +14,1310721,2,5,26,2,1,40,1647291,16,1,1647545,14,1559041,1310721,2, +5,26,2,26,2,1647331,16,1559041,1310721,2,5,26,2,26,2,1647545, +14,1310721,2,55,26,1434113,1310721,2,5,26,2,26,2,3,38,63, +32,10,3,6,10,4,8,1310721,2,57,26,1,10,3,6,10, +4,8,1310721,2,57,26,2,1310721,2,55,26,2,40,1647497,16,1310721, +2,7,26,1310721,2,57,26,2,26,1584975,2,10,3,6,10,4, +8,1310721,2,57,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1647397,14,1584975,2,1310721,2,55,26,2,1310721,2,7,26,1434113, +1310721,2,5,26,2,26,2,1625329,12,1647545,14,1,1310721,2,59,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1647593,16,1966081, +1310721,4,1579069,12,1310721,2,4,1310721,2,2,1588311,12,1310721,2,3,26, +4,1310721,2,3,26,2,1,40,1647643,16,3,1647707,14,1417729,1310721,2, +3,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,1647717,16,1, +1647743,14,1425921,1310721,2,3,26,2,26,2,1646937,12,1647743,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40, +1647791,16,1966081,1310721,4,1579069,12,1584875,2,1647855,16,1584987,2,1629979,12,1, +6,1,10,28,34,63,38,3,26,1647839,16,3,1589235,12,8,1584875, +1,10,3,6,10,4,8,1,1647863,14,1,1310721,2,1,26,1310721, +4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1647911,16,1966081,1310721, +4,1579069,12,1310721,2,3,26,4,1310721,2,4,1425921,1310721,2,2,26, +2,1310721,2,5,26,4,1584881,2,1310721,2,7,26,4,1584881,1310721,2, +3,26,2,10,3,6,10,4,8,1584883,1,10,3,6,10,4, +8,1584987,1584975,2,10,3,6,10,4,8,1584989,1,10,3,6,10, +4,8,1310721,2,5,26,2,1,6,12,10,8,8,1584881,1310721,2, +7,26,2,10,3,6,10,4,8,1310721,2,9,26,1584883,2,10, +3,6,10,4,8,1584875,1,10,3,6,10,4,8,1584877,1,10, +3,6,10,4,8,1310721,2,9,26,2,1648155,14,1,1310721,2,11, +26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1648203,16, +1966081,1310721,4,1579069,12,1584881,2,1648303,16,1648295,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,1648215,1585679,12,8,1,1648311,14,1,1310721,2,1,26,1310721, +4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1648359,16,1966081,1310721, +4,1579069,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4, +1,1310721,2,7,26,4,1584887,2,1599031,12,8,1584889,2,1598497,12,1, +6,1,10,28,34,63,38,3,26,1648831,16,3,1648831,16,1310721,2, +9,26,1662195,12,10,3,6,10,4,8,1647757,12,8,1310721,2,9, +26,2,1310721,2,2,1310721,2,7,26,2,1310721,2,7,26,2,26, +38,7,32,1616761,12,8,1310721,2,3,26,2,1648593,16,1310721,2,7, +26,2,1310721,2,3,26,2,7,26,2,40,1,6,1,10,28, +34,63,38,1,10,28,1648595,14,1,1648757,16,1310721,2,11,26,1310721, +2,3,26,2,15,1310721,2,7,26,2,26,26,2,10,3,6, +10,4,8,1310721,2,11,26,2,1584987,2,1310721,2,5,26,2,1631591, +12,1,6,1,10,28,34,63,38,3,26,1648757,16,1648721,14,97, +114,103,117,109,101,110,116,0,1648703,1310721,2,11,26,2,1310721,2, +5,26,2,1628749,12,1584987,2,1633925,12,8,1310721,2,7,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1584899,2,1598801,12,1, +6,1,10,28,34,63,38,3,26,1648827,16,1648831,14,1648439,14,1584889, +2,1599031,12,8,1310721,2,7,26,2,1648857,14,1,1310721,2,13,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1648905,16,1966081, +1310721,4,1579069,12,1310721,2,1635249,12,10,3,6,10,4,8,1584899,2, +1598801,12,1649069,16,1310721,2,3,26,1662195,12,10,3,6,10,4,8, +1647757,12,8,1310721,2,3,26,2,1605077,12,8,1310721,2,2,1628577,12, +3,28,1,6,1,10,28,34,63,38,1,10,28,1649047,16,1310721, +2,2,1628577,12,1589149,12,8,31,1589235,12,8,1310721,2,2,1,1624809, +12,1589149,12,8,1649097,14,1310721,2,2,1628577,12,1589149,12,8,1310721,2, +2,1589149,12,8,1584889,2,1599031,12,8,1585043,2,1589915,12,8,1584875,1, +10,3,6,10,4,8,1584877,1,10,3,6,10,4,8,1584987,1310721, +2,2,1624435,12,10,3,6,10,4,8,1584989,1,10,3,6,10, +4,8,3,1649197,14,1,1310721,2,5,26,1310721,4,18,1310721,2,27, +28,1310721,4,1310721,2,1835009,40,1649245,16,1966081,1310721,4,1579069,12,1310721,2, +4,1,1310721,2,5,26,4,1,1310721,2,7,26,4,1559041,1310721,2, +2,26,2,1310721,2,9,26,4,1409537,1310721,2,2,26,2,1585041,2, +28,1,6,1,10,28,34,63,38,3,26,1649401,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,1649403,14,1,1649731,16,1597931, +12,8,1584799,2,9,28,1,6,1,10,28,34,63,38,3,26, +1649563,16,1584801,2,1584911,2,28,1,6,1,10,28,34,63,38,3, +26,1649485,16,3,1649537,14,1584801,2,1584895,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,1649565,14,1,1649583,16, +1597071,12,8,1648871,12,1650331,14,1584799,2,5,28,1,6,1,10,28, +34,63,38,3,26,1649711,16,1584801,2,1634911,12,1649633,16,3,1649685,14, +1584801,2,1584927,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,1649713,14,1,1649731,16,1597071,12,8,1648871,12,1650331, +14,1442305,1310721,2,2,26,2,5,32,1649827,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,1649865, +14,1442305,1310721,2,2,26,1442305,1310721,2,2,26,2,9,34,10,3, +6,10,4,8,1310721,2,11,26,1,17,1574549,12,8,1585087,2,1649927, +16,1310721,2,11,26,1585071,1585087,2,1574337,12,8,1585087,1,10,3,6, +10,4,8,1310721,2,3,26,1310721,2,5,26,2,1310721,2,9,26, +2,1310721,2,11,26,1648325,12,10,3,6,10,4,8,1442305,1310721,2, +2,26,2,5,32,1650079,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,1650081,14,1, +1650161,16,1409537,1310721,2,2,26,2,1650153,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,1650101,1585849,12,8,1310721,2,2,1589741,12,8,13,1589235, +12,8,1584875,1,10,3,6,10,4,8,1584877,1,10,3,6,10, +4,8,1584989,1,10,3,6,10,4,8,1584987,1584975,2,10,3,6, +10,4,8,1310721,2,9,26,2,1650303,16,1584987,1310721,2,9,26,2, +9,26,2,1310721,2,11,26,1628749,12,10,3,6,10,4,8,1310721, +2,7,26,2,1650323,16,3,1650331,14,1,1650331,14,1,1310721,2,27, +26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1650379,16, +1966081,1310721,4,1579069,12,1310721,2,4,1434113,1310721,2,2,26,2,31,32, +1310721,2,3,26,4,1434113,1310721,2,2,26,2,9,38,31,32,1310721, +2,5,26,4,1,1310721,2,7,26,4,1584887,2,1599031,12,8,1584889, +2,1598497,12,1,6,1,10,28,34,63,38,3,26,1650621,16,3, +1650621,16,1310721,2,9,26,1662195,12,10,3,6,10,4,8,1647757,12, +8,1310721,2,9,26,2,1605077,12,8,1310721,2,7,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1584899,2,1598801,12,1,6, +1,10,28,34,63,38,3,26,1650617,16,1650621,14,1650495,14,1584889,2, +1599031,12,8,1310721,2,7,26,2,1310721,2,3,26,2,28,1,6, +1,10,28,34,63,38,1,10,28,1650749,16,1409537,1310721,2,2,26, +2,1650741,14,119,114,111,110,103,32,110,117,109,98,101,114,32, +111,102,32,105,110,112,117,116,115,0,1650695,1585849,12,8,1584875,1, +10,3,6,10,4,8,1584877,1,10,3,6,10,4,8,1584987,1584975, +2,10,3,6,10,4,8,1584989,1,10,3,6,10,4,8,1442305, +1310721,2,2,26,2,129,32,1650871,16,1450497,1310721,2,2,26,2,3, +28,1589741,12,8,13,1589235,12,8,1,1651069,14,45,1425921,1310721,2,2, +26,2,26,1589235,12,8,1310721,2,5,26,2,1,28,1,6,1, +10,28,34,63,38,3,26,1650939,16,1,1589149,12,8,1310721,2,5, +26,2,3,10,40,1651061,16,1409537,1310721,2,2,26,2,1651053,14,108, +101,97,118,101,115,32,115,101,118,101,114,97,108,32,118,97, +108,117,101,115,59,32,117,115,101,32,105,116,32,102,114,111, +109,32,97,115,109,0,1650975,1585849,12,8,1,1651069,14,1,1310721,2, +11,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1651117, +16,1966081,1310721,4,1579069,12,1584875,1,10,3,6,10,4,8,1584877,1, +10,3,6,10,4,8,1584989,1,10,3,6,10,4,8,1582577,2, +3,28,1,6,1,10,28,34,63,38,3,26,1651279,16,1582579,2, +1589149,12,8,1584989,1582579,2,1,28,1,6,1,10,28,34,63,38, +3,26,10,3,6,10,4,8,1584987,1584977,2,10,3,6,10,4, +8,1597071,12,8,1,1653909,14,1582577,2,7,28,1,6,1,10,28, +34,63,38,3,26,1651355,16,1582579,2,1590177,12,8,1597071,12,8,1584987, +1584979,2,1624435,12,10,3,6,10,4,8,1,1653909,14,1582577,2,9, +28,1,6,1,10,28,34,63,38,3,26,1651607,16,1582579,2,1584887, +2,28,1,6,1,10,28,34,63,38,3,26,1651475,16,1597071,12, +8,1310721,2,7,26,1662195,12,10,3,6,10,4,8,1584889,2,1599031, +12,8,1310721,2,7,26,2,1653909,14,1582579,2,1584891,2,28,1,6, +1,10,28,34,63,38,3,26,1651517,16,1664235,12,1653909,14,1651567,14, +101,120,112,101,99,116,101,100,32,97,110,32,101,120,112,114, +101,115,115,105,111,110,0,1651521,1586063,12,8,1,1589149,12,8,1584987, +1584975,2,10,3,6,10,4,8,1,1653909,14,1582577,2,5,28,1, +6,1,10,28,34,63,38,1,10,28,1651731,16,1651691,14,101,120, +112,101,99,116,101,100,32,97,110,32,101,120,112,114,101,115, +115,105,111,110,0,1651645,1586063,12,8,1,1589149,12,8,1584987,1584975,2, +10,3,6,10,4,8,1,1653909,14,1310721,2,1582579,2,10,3,6, +10,4,8,1310721,2,3,26,1310721,2,2,1603687,12,10,3,6,10, +4,8,1310721,2,3,26,2,1,40,3,36,1652203,16,1597071,12,8, +1584853,2,1,6,1,10,28,34,63,38,3,26,1651877,16,1310721,2, +3,26,2,1604491,12,1,6,1,10,28,34,63,38,1,10,28, +1651879,14,1,1652027,16,1310721,2,2,1652019,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,1651893,1585849,12,8,1467905,1310721,2, +3,26,2,26,2,1590069,12,8,1584987,1556993,1310721,2,3,26,2,26, +2,10,3,6,10,4,8,1473025,1310721,2,3,26,2,26,2,1652105, +16,1,1653909,14,1584875,3,10,3,6,10,4,8,1584877,3,10,3, +6,10,4,8,1584879,1310721,2,3,26,2,10,3,6,10,4,8, +1310721,2,3,26,2,1604491,12,1652197,16,5,1310721,2,3,26,2,26, +1653909,14,1,1653909,14,1310721,2,5,26,1310721,2,2,1587809,12,10,3, +6,10,4,8,1310721,2,5,26,2,1,40,3,36,1652321,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,1652323,14, +1,1652479,16,1442305,1310721,2,5,26,2,26,2,33,32,1,6,1, +10,28,34,63,38,3,26,1652459,16,1310721,2,2,1652451,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,1652381,1586197,12,8,1310721,2,5,26,2,3,1647877,12,1653909,14,1310721, +2,5,26,2,1,40,3,36,1652567,16,1417729,1310721,2,5,26,2, +26,2,15,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1652569,14,1,1652669,16,1310721,2, +2,1652629,14,105,115,32,97,32,116,121,112,101,44,32,110,111, +116,32,97,32,118,97,108,117,101,0,1652583,1586197,12,8,1,1589149, +12,8,1584987,1584975,2,10,3,6,10,4,8,1,1653909,14,1597071,12, +8,1584987,1584975,2,10,3,6,10,4,8,1310721,2,5,26,2,1, +40,3,36,1652781,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,1652783,14,1,1652887,16,1425921,1310721,2,5,26,2,26, +2,1589149,12,8,1584987,1584977,2,10,3,6,10,4,8,1584989,1425921,1310721, +2,5,26,2,26,2,1,28,1,6,1,10,28,34,63,38, +3,26,10,3,6,10,4,8,1,1653909,14,1310721,2,5,26,2, +1,40,3,36,1652975,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,1652977,14,1,1653091,16,1425921,1310721,2,5,26,2, +26,2,1589149,12,8,1559041,1310721,2,5,26,2,26,2,1653053,16,1584987, +1559041,1310721,2,5,26,2,26,2,10,3,6,10,4,8,1584875,3, +10,3,6,10,4,8,1584877,5,10,3,6,10,4,8,1,1653909, +14,1310721,2,5,26,2,1,40,3,36,1653179,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,1653181,14,1,1653263,16, +1425921,1310721,2,5,26,2,26,2,1589149,12,8,1559041,1310721,2,5,26, +2,26,2,1653257,16,1584987,1559041,1310721,2,5,26,2,26,2,10,3, +6,10,4,8,1,1653909,14,1310721,2,5,26,2,1,40,3,36, +1653351,16,1417729,1310721,2,5,26,2,26,2,13,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1653353,14,1,1653375,16,1310721,2,5,26,2,1650345,12,1653909,14,1310721, +2,5,26,2,1,40,1653423,16,1310721,2,5,26,1310721,2,2,1589617, +12,10,3,6,10,4,8,1585015,2,1598497,12,1653481,16,1442305,1310721,2, +5,26,2,26,2,257,32,1,6,1,10,28,34,63,38,1, +10,28,1653483,14,1,1653805,16,1597071,12,8,1585087,1,10,3,6,10, +4,8,3,1653683,16,1585087,2,17,40,3,36,1653591,16,1653583,14,116, +111,111,32,109,97,110,121,32,116,121,112,101,32,97,114,103, +117,109,101,110,116,115,0,1653535,1586063,12,8,1585071,1585087,2,26,1635249, +12,10,3,6,10,4,8,1585087,1,6,2,1,6,3,26,5, +6,4,10,8,8,1584899,2,1598801,12,1,6,1,10,28,34,63, +38,3,26,1653679,16,1653683,14,1653509,14,1635147,12,8,1584887,2,1598497,12, +1,6,1,10,28,34,63,38,3,26,1653805,16,1653797,14,101,120, +112,101,99,116,101,100,32,40,32,97,102,116,101,114,32,116, +104,101,32,116,121,112,101,32,97,114,103,117,109,101,110,116, +115,0,1653725,1586063,12,8,1584887,2,1598497,12,1653835,16,1310721,2,5,26, +2,1649211,12,1653909,14,1310721,2,5,26,2,1589741,12,8,1559041,1310721,2, +5,26,2,26,2,1653901,16,1584987,1559041,1310721,2,5,26,2,26,2, +10,3,6,10,4,8,1,1653909,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1653957,16,1966081,1310721,4, +1579069,12,1310721,2,3,26,4,1310721,2,4,1584875,2,1,6,1,10, +28,34,63,38,3,26,1654089,16,1654081,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, +1654005,1586063,12,8,1584877,2,3,28,1,6,1,10,28,34,63,38, +3,26,1654151,16,1584853,2,1,6,1,10,28,34,63,38,1,10, +28,1654153,14,1,1654191,16,1584879,2,1604491,12,1,6,1,10,28,34, +63,38,1,10,28,1654193,14,1,1654293,16,1584879,2,1654285,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,1654205,1586469,12,8,1584987,2,1629747,12,1654311,16, +3,1654367,14,1584987,2,1,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,1654377, +16,3,1654429,14,1584987,2,1584975,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1654507,14, +43,43,32,97,110,100,32,45,45,32,110,101,101,100,32,97, +32,110,117,109,98,101,114,32,111,114,32,97,32,112,111,105, +110,116,101,114,0,1654433,1584987,2,1634325,12,8,1584875,1,10,3,6, +10,4,8,1584877,1,10,3,6,10,4,8,1584989,1,10,3,6, +10,4,8,1,1589149,12,8,7,1589235,12,8,3,1589235,12,8,1310721, +2,2,1654669,16,1,1589149,12,8,7,1589235,12,8,1310721,2,3,26, +2,1589149,12,8,27,1589235,12,8,5,1589149,12,8,7,1589235,12,8, +5,1589235,12,8,1654733,14,1310721,2,3,26,2,1589149,12,8,27,1589235, +12,8,1,1589149,12,8,7,1589235,12,8,5,1589149,12,8,7,1589235, +12,8,5,1589235,12,8,11,1589235,12,8,9,1589235,12,8,1,1654757, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721, +2,1835009,40,1654805,16,1966081,1310721,4,1579069,12,1310721,2,4,3,1,10, +28,1310721,2,9,26,4,1597071,12,8,1310721,2,3,26,1599321,12,10, +3,6,10,4,8,1647757,12,8,1310721,2,2,3,28,1,6,1, +10,28,34,63,38,3,26,1655035,16,1655023,14,117,115,101,32,97, +32,102,105,101,108,100,32,111,102,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,1654903,1586351,12,8,1655099,14,1310721,2,2, +5,40,3,36,1655099,16,1310721,2,2,5,28,1604589,12,8,1310721,2, +9,26,1310721,2,2,5,28,10,3,6,10,4,8,1310721,2,5, +26,1584987,2,10,3,6,10,4,8,1310721,2,5,26,2,1,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1655203,16,1310721, +2,5,26,1310721,2,5,26,2,9,26,2,10,3,6,10,4, +8,1310721,2,5,26,2,1,26,2,17,28,1,6,1,10,28, +34,63,38,1,10,28,1655553,16,1585091,2,1,6,1,10,28,34, +63,38,3,26,1655327,16,1584991,2,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1655329,14,1, +1655497,16,1585093,12,8,93,1573101,12,8,1310721,2,3,26,2,1573341,12, +8,1655391,14,58,32,116,104,97,116,39,115,32,97,32,0,1655367, +1573341,12,8,1584987,2,1632681,12,8,1655483,14,44,32,110,111,116,32, +97,32,115,116,114,117,99,116,32,111,114,32,97,32,112,111, +105,110,116,101,114,32,116,111,32,111,110,101,0,1655413,1573341,12, +8,1585237,12,8,1584987,1584975,2,10,3,6,10,4,8,1584875,3,10, +3,6,10,4,8,1584877,9,10,3,6,10,4,8,1,1656109,14, +1310721,2,7,26,1310721,2,5,26,2,1310721,2,3,26,2,1640559,12, +10,3,6,10,4,8,1310721,2,7,26,2,1,40,1655841,16,1585091, +2,1,6,1,10,28,34,63,38,3,26,1655693,16,1584991,2,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1655695,14,1,1655785,16,1585093,12,8,1310721,2,5,26, +2,1632681,12,8,1655755,14,32,104,97,115,32,110,111,32,102,105, +101,108,100,32,0,1655725,1573341,12,8,1310721,2,3,26,2,1573341,12, +8,1585237,12,8,1584987,1584975,2,10,3,6,10,4,8,1584875,3,10, +3,6,10,4,8,1584877,9,10,3,6,10,4,8,1,1656109,14, +1310721,2,5,26,2,9,26,2,1310721,2,7,26,2,7,30,5, +26,26,2,1655935,16,1310721,2,5,26,2,9,26,2,1310721,2,7, +26,2,7,30,5,26,26,2,1589149,12,8,27,1589235,12,8,1584987, +1310721,2,5,26,2,9,26,2,1310721,2,7,26,2,7,30,3, +26,26,2,10,3,6,10,4,8,1584875,3,10,3,6,10,4, +8,1584989,1,10,3,6,10,4,8,1310721,2,9,26,2,1,40, +3,36,1656085,16,1584877,7,10,3,6,10,4,8,1584879,1310721,2,9, +26,2,10,3,6,10,4,8,1656101,14,1584877,9,10,3,6,10, +4,8,1,1656109,14,1,1310721,2,11,26,1310721,4,18,1310721,2,29, +28,1310721,4,1310721,2,1835009,40,1656157,16,1966081,1310721,4,1579069,12,1651083,12, +1310721,2,4,3,1658085,16,1582577,2,5,28,1,6,1,10,28,34, +63,38,3,26,1656261,16,1582579,2,1584935,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1656263,14,1,1656347,16,1597071,12,8,1310721,2,7,26,1635249,12,10,3, +6,10,4,8,1647757,12,8,1584987,1310721,2,7,26,2,10,3,6, +10,4,8,1584877,1,10,3,6,10,4,8,1656167,14,1582577,2,9, +28,1,6,1,10,28,34,63,38,1,10,28,1656391,16,1310721,2, +2,1658097,14,1582579,2,1584895,2,28,1,6,1,10,28,34,63,38, +3,26,1657305,16,1597071,12,8,1647757,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,1656617,16,1656605,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,1656503,1586351, +12,8,1656681,14,1310721,2,2,5,40,3,36,1656681,16,1310721,2,2, +5,28,1604589,12,8,1310721,2,3,26,1310721,2,2,5,28,10,3, +6,10,4,8,1584987,2,1630143,12,1656699,16,3,1656751,14,1584987,2,1584975, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1656835,14,111,110,108,121,32,112,111, +105,110,116,101,114,115,32,97,110,100,32,97,114,114,97,121, +115,32,99,97,110,32,98,101,32,105,110,100,101,120,101,100, +0,1656755,1584987,2,1634325,12,8,1310721,2,9,26,1584987,2,1630433,12,10, +3,6,10,4,8,1310721,2,1662195,12,10,3,6,10,4,8,1647757, +12,8,1310721,2,2,1605077,12,8,1584987,2,1629747,12,1656931,16,3,1656983, +14,1584987,2,1584975,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1657043,14,97,110,32, +105,110,100,101,120,32,104,97,115,32,116,111,32,98,101,32, +97,32,110,117,109,98,101,114,0,1656987,1584987,2,1634325,12,8,1584897, +2,1599031,12,8,1310721,2,9,26,2,1628577,12,3,28,1,6,1, +10,28,34,63,38,1,10,28,1657137,16,1310721,2,9,26,2,1628577, +12,1589149,12,8,31,1589235,12,8,27,1589235,12,8,1584875,3,10,3, +6,10,4,8,1584987,1310721,2,9,26,2,10,3,6,10,4,8, +1584989,1,10,3,6,10,4,8,1310721,2,3,26,2,1,40,3, +36,1657267,16,1584877,7,10,3,6,10,4,8,1584879,1310721,2,3,26, +2,10,3,6,10,4,8,1657283,14,1584877,9,10,3,6,10,4, +8,1310721,2,1,10,3,6,10,4,8,1656167,14,1582579,2,1584925,2, +28,1,6,1,10,28,34,63,38,3,26,1657345,16,3,1657397,14, +1582579,2,1584905,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1657431,16,1310721,2,1310721,2, +2,1654771,12,10,3,6,10,4,8,1656167,14,1582579,2,1584887,2,28, +1,6,1,10,28,34,63,38,3,26,1657929,16,1647757,12,8,1310721, +2,2,1605077,12,8,1310721,2,11,26,1,10,3,6,10,4,8, +1584987,2,1,26,2,15,28,1,6,1,10,28,34,63,38,3, +26,1657571,16,1310721,2,11,26,1584987,2,10,3,6,10,4,8,1657675, +14,1584987,2,1584975,2,28,1,6,1,10,28,34,63,38,3,26, +1657663,14,111,110,108,121,32,102,117,110,99,116,105,111,110,115, +32,99,97,110,32,98,101,32,99,97,108,108,101,100,0,1657605, +1584987,2,1634325,12,8,1310721,2,13,26,1,17,1574549,12,8,1310721,2, +5,26,1,1310721,2,11,26,2,1310721,2,13,26,1648325,12,10,3, +6,10,4,8,1310721,2,5,26,2,1589149,12,8,7,1589235,12,8, +13,1589235,12,8,11,1589235,12,8,9,1589235,12,8,1584875,1,10,3, +6,10,4,8,1584877,1,10,3,6,10,4,8,1310721,2,1,10, +3,6,10,4,8,1584989,1,10,3,6,10,4,8,1584987,1584975,2, +10,3,6,10,4,8,1310721,2,11,26,2,1657925,16,1584987,1310721,2, +11,26,2,9,26,2,1310721,2,13,26,1628749,12,10,3,6,10, +4,8,1656167,14,1582579,2,1584907,2,28,1,6,1,10,28,34,63, +38,3,26,1657997,16,1597071,12,8,1310721,2,3,3,1653923,12,10,3, +6,10,4,8,1656167,14,1582579,2,1584909,2,28,1,6,1,10,28, +34,63,38,3,26,1658071,16,1597071,12,8,1310721,2,3,3,1,10, +28,1653923,12,10,3,6,10,4,8,1656167,14,1310721,2,2,1658097,14, +1656167,14,1310721,2,2,1658097,14,1,1310721,2,29,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,1835009,40,1658145,16,1966081,1310721,4,1579069,12, +1582577,2,5,28,1,6,1,10,28,34,63,38,3,26,1658357,16, +1582579,2,1584945,2,28,1,6,1,10,28,34,63,38,3,26,1658217, +16,3,1658269,14,1582579,2,1584941,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1658279,16, +3,1658331,14,1582579,2,1584943,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,1658359,14,1,1658579,16,1310721,2,5, +26,3,10,3,6,10,4,8,1582579,2,1584945,2,28,1,6,1, +10,28,34,63,38,3,26,1658441,16,1310721,2,5,26,5,10,3, +6,10,4,8,1582579,2,1584943,2,28,1,6,1,10,28,34,63, +38,3,26,1658497,16,1310721,2,5,26,7,10,3,6,10,4,8, +1597071,12,8,1584911,2,1599031,12,8,1310721,2,1658111,12,10,3,6,10, +4,8,1647757,12,8,1584877,1,10,3,6,10,4,8,1310721,2,2, +1310721,2,5,26,2,1615689,12,1659775,14,1582577,2,9,28,1,6,1, +10,28,34,63,38,3,26,1659765,16,1582579,2,1584911,2,28,1,6, +1,10,28,34,63,38,3,26,1658945,16,1597071,12,8,1310721,2,1658111, +12,10,3,6,10,4,8,1647757,12,8,1310721,2,2,1605077,12,8, +1584987,2,1,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1658733,16,3,1658785,14,1584987,2,1584975,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1658857,14,111,110,108,121,32,112,111,105,110,116,101,114,115,32, +99,97,110,32,98,101,32,100,101,114,101,102,101,114,101,110, +99,101,100,0,1658789,1584987,2,1634325,12,8,1584987,1584987,2,1630433,12,10, +3,6,10,4,8,1584875,3,10,3,6,10,4,8,1584877,9,10, +3,6,10,4,8,1584989,1,10,3,6,10,4,8,1,1659775,14, +1582579,2,1584913,2,28,1,6,1,10,28,34,63,38,3,26,1659275, +16,1597071,12,8,1310721,2,1658111,12,10,3,6,10,4,8,1584875,2, +1,6,1,10,28,34,63,38,3,26,1659087,16,1584987,2,1629979,12, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1659089,14,1,1659165,16,1659157,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,1659097,1586063,12,8,1310721,2, +2,5,40,3,36,1659199,16,1310721,2,2,5,28,1604589,12,8,1584875, +1,10,3,6,10,4,8,1584877,1,10,3,6,10,4,8,1584989, +1,10,3,6,10,4,8,1584987,1584987,2,1624435,12,10,3,6,10, +4,8,1,1659775,14,1582579,2,1584907,2,28,1,6,1,10,28,34, +63,38,3,26,1659333,16,1597071,12,8,1658111,12,8,1,3,1653923,12, +1659775,14,1582579,2,1584909,2,28,1,6,1,10,28,34,63,38,3, +26,1659397,16,1597071,12,8,1658111,12,8,1,3,1,10,28,1653923,12, +1659775,14,1310721,2,3,26,1582579,2,1601755,12,10,3,6,10,4,8, +1310721,2,3,26,2,1,40,3,36,1659765,16,1597071,12,8,1310721,2, +1658111,12,10,3,6,10,4,8,1647757,12,8,1310721,2,2,1605077,12, +8,1547329,1310721,2,3,26,2,26,2,1547393,1310721,2,3,26,2,26, +2,1600817,12,8,1310721,2,3,26,2,3,10,40,3,36,1659575,16, +1584987,1584981,2,10,3,6,10,4,8,1659711,14,1584987,2,1584975,2,28, +1,6,1,10,28,34,63,38,1,10,28,1659711,16,1584987,2,1629747, +12,1659681,14,116,104,105,115,32,111,112,101,114,97,116,111,114, +32,110,101,101,100,115,32,97,32,110,117,109,98,101,114,0, +1659623,1584987,2,1634325,12,8,1584987,1584977,2,10,3,6,10,4,8,1584875, +1,10,3,6,10,4,8,1584877,1,10,3,6,10,4,8,1584989, +1,10,3,6,10,4,8,1,1659775,14,1656123,12,1659775,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40, +1659823,16,1966081,1310721,4,1579069,12,1310721,2,4,1658111,12,1310721,2,3,26, +4,1582577,2,9,28,1,6,1,10,28,34,63,38,3,26,1660769, +16,1310721,2,5,26,1582579,2,1601559,12,10,3,6,10,4,8,1310721, +2,5,26,2,1,40,1659935,16,1310721,2,3,26,2,1660785,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,1660007,16,1310721,2,3,26, +2,1660785,14,1597071,12,8,1647757,12,8,1310721,2,3,26,2,1605077,12, +8,1310721,2,13,26,1584987,2,10,3,6,10,4,8,1547137,1310721,2, +5,26,2,26,2,3,1,10,28,28,1,6,1,10,28,34, +63,38,3,26,1660307,16,1310721,2,9,26,1589535,12,10,3,6,10, +4,8,17,1589235,12,8,1310721,2,3,26,1310721,2,7,26,2,3, +26,1659789,12,10,3,6,10,4,8,1647757,12,8,1310721,2,3,26, +2,1605077,12,8,1547329,3,26,2,1547393,3,26,2,1600817,12,8,1310721, +2,11,26,1589535,12,10,3,6,10,4,8,15,1589235,12,8,1310721, +2,9,26,2,1584837,2,1589317,12,8,1,1589149,12,8,1310721,2,11, +26,2,1584837,2,1589317,12,8,1660653,14,1547137,1310721,2,5,26,2,26, +2,5,1,10,28,28,1,6,1,10,28,34,63,38,3,26, +1660555,16,1310721,2,9,26,1589535,12,10,3,6,10,4,8,17,1589235, +12,8,3,1589149,12,8,1310721,2,11,26,1589535,12,10,3,6,10, +4,8,15,1589235,12,8,1310721,2,9,26,2,1584837,2,1589317,12,8, +1310721,2,3,26,1310721,2,7,26,2,3,26,1659789,12,10,3,6, +10,4,8,1647757,12,8,1310721,2,3,26,2,1605077,12,8,1547329,3, +26,2,1547393,3,26,2,1600817,12,8,1310721,2,11,26,2,1584837,2, +1589317,12,8,1660653,14,1310721,2,3,26,1310721,2,7,26,2,3,26, +1659789,12,10,3,6,10,4,8,1647757,12,8,1310721,2,3,26,2, +1605077,12,8,1547009,1310721,2,5,26,2,26,2,1547137,1310721,2,5,26, +2,26,2,1600817,12,8,1584987,1310721,2,5,26,2,1310721,2,13,26, +2,1584987,2,1642719,12,10,3,6,10,4,8,1584875,1,10,3,6, +10,4,8,1584877,1,10,3,6,10,4,8,1310721,2,3,26,1, +10,3,6,10,4,8,1584989,1,10,3,6,10,4,8,1659843,14, +1310721,2,3,26,2,1660785,14,1,1310721,2,15,26,1310721,4,18,1310721, +2,1,28,1310721,4,1310721,2,1835009,40,1660833,16,1966081,1310721,4,1579069,12, +11,1589235,12,8,3,1589149,12,8,7,1589235,12,8,11,1589235,12,8, +5,1589235,12,8,1,1660881,14,1,1310721,2,1,26,1310721,4,18,1310721, +2,23,28,1310721,4,1310721,2,1835009,40,1660929,16,1966081,1310721,4,1579069,12, +1310721,2,4,1584857,2,1310721,2,13,26,4,1584845,2,1310721,2,15,26, +4,1647757,12,8,1310721,2,2,1605077,12,8,1597071,12,8,1310721,2,3, +26,1589535,12,10,3,6,10,4,8,17,1589235,12,8,1310721,2,7, +26,1606761,12,10,3,6,10,4,8,1310721,2,17,26,1662195,12,10, +3,6,10,4,8,1647757,12,8,1310721,2,21,26,1584987,2,10,3, +6,10,4,8,1310721,2,17,26,2,3,28,1,6,1,10,28, +34,63,38,1,10,28,1661153,16,1310721,2,17,26,2,1605077,12,8, +1310721,2,11,26,1584857,2,10,3,6,10,4,8,1310721,2,9,26, +1606761,12,10,3,6,10,4,8,1310721,2,5,26,1589535,12,10,3, +6,10,4,8,15,1589235,12,8,1584915,2,1599031,12,8,1310721,2,3, +26,2,1584837,2,1589317,12,8,1310721,2,7,26,2,1607393,12,8,1584857, +1310721,2,13,26,2,10,3,6,10,4,8,1310721,2,19,26,1662195, +12,10,3,6,10,4,8,1647757,12,8,1310721,2,19,26,2,3, +28,1,6,1,10,28,34,63,38,1,10,28,1661389,16,1310721,2, +19,26,2,1605077,12,8,1310721,2,9,26,2,1310721,2,11,26,2, +1310721,2,5,26,2,1584857,2,1310721,2,15,26,2,1661527,14,101,110, +100,115,32,116,104,101,32,116,119,111,32,115,105,100,101,115, +32,111,102,32,63,58,32,105,110,32,100,105,102,102,101,114, +101,110,116,32,115,116,97,116,101,115,0,1661437,1615115,12,8,1310721, +2,7,26,2,1607311,12,8,1310721,2,21,26,2,1584987,2,1630621,12, +1,6,1,10,28,34,63,38,3,26,1661657,16,1584987,2,1310721,2, +21,26,2,1630621,12,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1661659,14,1,1661729,16,1661707, +14,116,104,101,32,116,119,111,32,115,105,100,101,115,32,111, +102,32,63,58,0,1661667,1310721,2,21,26,2,1584987,2,1633925,12,8, +1310721,2,21,26,2,1584975,2,28,1,6,1,10,28,34,63,38, +1,10,28,1661795,16,1584987,1310721,2,21,26,2,10,3,6,10,4, +8,1584875,1,10,3,6,10,4,8,1584877,1,10,3,6,10,4, +8,1584989,1,10,3,6,10,4,8,1310721,2,17,26,2,3,28, +1,6,1,10,28,34,63,38,3,26,1661941,16,1310721,2,19,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,1661943,14,1,1661953,16,3,1662181,14, +1310721,2,17,26,2,3,28,1,6,1,10,28,34,63,38,3, +26,1661997,16,3,1662053,14,1310721,2,19,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,1662173,16,1662165,14,98,111,116,104,32,115,105,100,101,115, +32,111,102,32,63,58,32,104,97,118,101,32,116,111,32,98, +101,32,110,101,119,32,111,98,106,101,99,116,115,44,32,111, +114,32,110,101,105,116,104,101,114,0,1662061,1586351,12,8,1,1662181, +14,1,1310721,2,23,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721, +2,1835009,40,1662229,16,1966081,1310721,4,1579069,12,3,1659789,12,1310721,2,4, +1582577,2,9,28,1,6,1,10,28,34,63,38,1,10,28,1662285, +16,1310721,2,2,1663727,14,1582579,2,1584947,2,28,1,6,1,10,28, +34,63,38,3,26,1662333,16,1310721,2,2,1660895,12,1663727,14,1582579,2, +1584903,2,28,1,6,1,10,28,34,63,38,3,26,1662925,16,1584875, +2,1,6,1,10,28,34,63,38,3,26,1662459,16,1662451,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,1662399,1586063,12,8,1310721,2,3, +26,1584877,2,10,3,6,10,4,8,1310721,2,5,26,1584879,2,10, +3,6,10,4,8,1310721,2,11,26,1584987,2,10,3,6,10,4, +8,1310721,2,11,26,2,1629979,12,1662683,16,1662675,14,97,32,119,104, +111,108,101,32,115,116,114,117,99,116,32,111,114,32,97,114, +114,97,121,32,99,97,110,39,116,32,98,101,32,97,115,115, +105,103,110,101,100,59,32,97,115,115,105,103,110,32,105,116, +115,32,102,105,101,108,100,115,0,1662553,1585679,12,8,1597071,12,8, +1310721,2,9,26,1662195,12,10,3,6,10,4,8,1647757,12,8,1310721, +2,11,26,2,1584987,2,1630621,12,1,6,1,10,28,34,63,38, +3,26,1662809,16,1662787,14,97,115,115,105,103,110,109,101,110,116, +0,1662765,1310721,2,11,26,2,1584987,2,1633925,12,8,1660799,12,8,1584875, +1,10,3,6,10,4,8,1584877,1,10,3,6,10,4,8,1584987, +1310721,2,11,26,2,10,3,6,10,4,8,1584989,1,10,3,6, +10,4,8,1310721,2,3,26,2,1310721,2,5,26,2,1310721,2,9, +26,2,1618391,12,1663727,14,1310721,2,7,26,1582579,2,1601951,12,10,3, +6,10,4,8,1310721,2,7,26,2,1,40,3,36,1663715,16,1584875, +2,1,6,1,10,28,34,63,38,3,26,1663067,16,1663059,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,1663007,1586063,12,8,1584877,2,3, +28,1,6,1,10,28,34,63,38,3,26,1663129,16,1584853,2,1, +6,1,10,28,34,63,38,1,10,28,1663131,14,1,1663169,16,1584879, +2,1604491,12,1,6,1,10,28,34,63,38,1,10,28,1663171,14, +1,1663291,16,1584879,2,1663283,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,1663183,1586469,12,8,1310721,2,11, +26,1584987,2,10,3,6,10,4,8,1597071,12,8,1,1589149,12,8, +7,1589235,12,8,3,1589235,12,8,1584875,1,10,3,6,10,4,8, +1310721,2,9,26,1662195,12,10,3,6,10,4,8,1647757,12,8,1310721, +2,9,26,2,1605077,12,8,1547009,1547585,1310721,2,7,26,2,26,2, +26,2,1547137,1547585,1310721,2,7,26,2,26,2,26,2,1600817,12,8, +1310721,2,3,26,1547585,1310721,2,7,26,2,26,2,1310721,2,11,26, +2,1584987,2,1642719,12,10,3,6,10,4,8,1310721,2,11,26,2, +1310721,2,3,26,2,1630621,12,1,6,1,10,28,34,63,38,3, +26,1663631,16,1663603,14,99,111,109,112,111,117,110,100,32,97,115, +115,105,103,110,109,101,110,116,0,1663563,1310721,2,11,26,2,1310721, +2,3,26,2,1633925,12,8,1660799,12,8,1584875,1,10,3,6,10, +4,8,1584877,1,10,3,6,10,4,8,1584987,1310721,2,11,26,2, +10,3,6,10,4,8,1584989,1,10,3,6,10,4,8,1,1663727, +14,1310721,2,2,1663727,14,1,1310721,2,13,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1663775,16,1966081,1310721,4,1579069,12,1582577, +2,9,28,1,6,1,10,28,34,63,38,3,26,1663939,16,1582579, +2,1584901,2,28,1,6,1,10,28,34,63,38,3,26,1663847,16, +3,1663899,14,1582579,2,1584891,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1663909,16,3, +1663935,14,1637143,12,1,6,1,10,28,34,63,38,1,10,28,1664221, +14,1582577,2,5,28,1,6,1,10,28,34,63,38,1,10,28, +1663979,16,3,1664017,14,1582579,2,1603687,12,1,40,3,36,1,6,1, +10,28,34,63,38,1,10,28,1664027,16,1,1664221,14,1637143,12,1664041, +16,3,1664221,14,1310721,2,1582579,2,1587809,12,10,3,6,10,4,8, +1310721,2,2,1,40,3,36,1664145,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,1664147,14,1,1664213,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,1664215,14,1,1664221,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1664269, +16,1966081,1310721,4,1579069,12,1584845,2,1310721,2,4,1,1310721,2,3,26, +4,1,1310721,2,5,26,4,1584977,2,1310721,2,7,26,4,1597071,12, +8,1584849,1,6,2,1,6,3,26,5,6,4,10,8,8,1584859, +1,6,2,1,6,3,26,5,6,4,10,8,8,1584893,2,1598497, +12,1,6,1,10,28,34,63,38,3,26,1664751,16,1582577,2,1, +28,1,6,1,10,28,34,63,38,3,26,1664475,16,1664467,14,109, +105,115,115,105,110,103,32,125,0,1664447,1586063,12,8,1663741,12,1664493, +16,1666771,12,8,1664379,14,1310721,2,3,26,1662195,12,10,3,6,10, +4,8,1647757,12,8,1584901,2,1598801,12,1664585,16,9,1589235,12,8,1310721, +2,3,26,2,1623627,12,8,1310721,2,3,26,1,10,3,6,10, +4,8,1664379,14,1584893,2,1598497,12,1,6,1,10,28,34,63,38, +3,26,1664701,16,1664693,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,1664621,1586063,12,8,1310721,2, +5,26,3,10,3,6,10,4,8,1310721,2,7,26,1584987,2,10, +3,6,10,4,8,1664379,14,1597071,12,8,1310721,2,5,26,2,1664809, +16,1310721,2,3,26,1310721,2,3,26,2,1622911,12,10,3,6,10, +4,8,1664817,14,1,1589149,12,8,1310721,2,2,1606489,12,8,1584849,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1584859,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1584875,1,10,3,6,10, +4,8,1584877,1,10,3,6,10,4,8,1584987,1310721,2,7,26,2, +10,3,6,10,4,8,1584989,1,10,3,6,10,4,8,1310721,2, +3,26,2,1664973,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1665021,16,1966081,1310721,4,1579069,12,1582577,2, +3,28,1,6,1,10,28,34,63,38,3,26,1665089,16,1310721,2, +1582579,2,10,3,6,10,4,8,1597071,12,8,1310721,2,2,1665789,14, +1584919,2,1598801,12,1665113,16,1,1664987,12,28,1665789,14,1582577,2,9,28, +1,6,1,10,28,34,63,38,3,26,1665205,16,1582579,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,1665207,14,1,1665229,16,1597071,12,8, +1664987,12,-1,36,1665789,14,1584887,2,1598801,12,1665281,16,1310721,2,1665803,12, +10,3,6,10,4,8,1584889,2,1599031,12,8,1310721,2,2,1665789,14, +1582577,2,5,28,1,6,1,10,28,34,63,38,3,26,1665729,16, +1310721,2,3,26,1582579,2,1587809,12,10,3,6,10,4,8,1310721,2, +3,26,2,1,40,3,36,1665697,16,1417729,1310721,2,3,26,2,26, +2,9,28,1,6,1,10,28,34,63,38,3,26,1665413,16,3, +1665475,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,1665485,16,3,1665599,14,1417729,1310721,2,3,26,2,26,2,3,28, +1,6,1,10,28,34,63,38,3,26,1665575,16,1442305,1310721,2,3, +26,2,26,2,3,32,1,6,1,10,28,34,63,38,1,10, +28,1665577,14,1,1,6,1,10,28,34,63,38,1,10,28,1665609, +16,3,1665671,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,1665699,14, +1,1665729,16,1597071,12,8,1425921,1310721,2,3,26,2,26,2,1665789,14, +1665773,14,101,120,112,101,99,116,101,100,32,97,32,99,111,110, +115,116,97,110,116,0,1665733,1586063,12,8,1,1665789,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1665837, +16,1966081,1310721,4,1579069,12,1664987,12,1310721,2,4,1582577,2,9,28,1, +6,1,10,28,34,63,38,3,26,1666491,16,1310721,2,3,26,1582579, +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,1665985,16,1597071,12,8, +1310721,2,1310721,2,2,1664987,12,26,10,3,6,10,4,8,1666487,14, +1310721,2,3,26,2,1546753,9,26,2,28,1,6,1,10,28,34, +63,38,3,26,1666067,16,1597071,12,8,1310721,2,1310721,2,2,1664987,12, +28,10,3,6,10,4,8,1666487,14,1310721,2,3,26,2,1546753,1, +26,2,28,1,6,1,10,28,34,63,38,3,26,1666149,16,1597071, +12,8,1310721,2,1310721,2,2,1664987,12,30,10,3,6,10,4,8, +1666487,14,1310721,2,3,26,2,1546753,31,26,2,28,1,6,1,10, +28,34,63,38,3,26,1666231,16,1597071,12,8,1310721,2,1310721,2,2, +1664987,12,34,10,3,6,10,4,8,1666487,14,1310721,2,3,26,2, +1546753,27,26,2,28,1,6,1,10,28,34,63,38,3,26,1666313, +16,1597071,12,8,1310721,2,1310721,2,2,1664987,12,32,10,3,6,10, +4,8,1666487,14,1310721,2,3,26,2,1546753,11,26,2,28,1,6, +1,10,28,34,63,38,3,26,1666395,16,1597071,12,8,1310721,2,1310721, +2,2,1664987,12,48,10,3,6,10,4,8,1666487,14,1310721,2,3, +26,2,1546753,13,26,2,28,1,6,1,10,28,34,63,38,3, +26,1666477,16,1597071,12,8,1310721,2,1310721,2,2,1664987,12,38,10,3, +6,10,4,8,1666487,14,1310721,2,2,1666503,14,1665847,14,1310721,2,2, +1666503,14,1,1310721,2,5,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1666551,16,1966081,1310721,4,1579069,12,1582577,2,1,28,1, +6,1,10,28,34,63,38,1,10,28,1666639,16,1584901,2,1598497,12, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1666641,14,1,1666699,16,1584893,2,1598497,12,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1666701,14,1,1666715,16,1597071,12,8,1666551,14,1584901,2,1598497, +12,1666733,16,1597071,12,8,1585091,1,10,3,6,10,4,8,1,1666757, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1666805,16,1966081,1310721,4,1579069,12,1585091,2,1666821,16,1666517,12, +1667293,14,1582577,2,5,28,1,6,1,10,28,34,63,38,3,26, +1666891,16,1582579,2,1603687,12,1,40,1,6,1,10,28,34,63,38, +1,10,28,1666893,14,1,1667075,16,1310721,2,1582579,2,1587809,12,10,3, +6,10,4,8,1310721,2,2,1,40,3,36,1667001,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,1667003,14,1,1667049,16,1442305, +1310721,2,2,26,2,17,32,1,6,1,10,28,34,63,38,1, +10,28,1667051,14,1,1667075,16,1310721,2,2,1,1647877,12,8,1,1667293, +14,1637143,12,1667097,16,3,1667723,12,8,1,1667293,14,1582577,2,9,28, +1,6,1,10,28,34,63,38,3,26,1667221,16,1582579,2,1584901,2, +28,1,6,1,10,28,34,63,38,3,26,1667175,16,1597071,12,8, +1,1667293,14,1582579,2,1584891,2,28,1,6,1,10,28,34,63,38, +3,26,1667221,16,1667307,12,8,1,1667293,14,1310721,2,3,26,1662195,12, +10,3,6,10,4,8,1647757,12,8,9,1589235,12,8,1584901,2,1599031, +12,8,1310721,2,3,26,2,1623627,12,8,1,1667293,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1667341, +16,1966081,1310721,4,1579069,12,1584845,2,1310721,2,4,1584891,2,1599031,12,8, +1584849,1,6,2,1,6,3,26,5,6,4,10,8,8,1584893,2, +1598497,12,1,6,1,10,28,34,63,38,3,26,1667495,16,1582577,2, +1,28,1,6,1,10,28,34,63,38,3,26,1667485,16,1667477,14, +109,105,115,115,105,110,103,32,125,0,1667457,1586063,12,8,1666771,12, +8,1667389,14,1310721,2,2,1606489,12,8,1597071,12,8,1584849,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1,1667549,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1667597, +16,1966081,1310721,4,1579069,12,1584845,2,1310721,2,4,1584891,2,1598497,12,1667627, +16,1667307,12,1667709,14,1584849,1,6,2,1,6,3,26,5,6,4, +10,8,8,1666771,12,8,1310721,2,2,1606489,12,8,1584849,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1,1667709,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1667757, +16,1966081,1310721,4,1579069,12,1310721,2,4,1,1310721,2,11,26,4,1, +1310721,2,13,26,4,1310721,2,2,1667953,16,1637945,12,8,1310721,2,11, +26,1585011,2,10,3,6,10,4,8,1310721,2,13,26,1585013,2,10, +3,6,10,4,8,1310721,2,11,26,2,1584983,2,28,1,6,1, +10,28,34,63,38,3,26,1667953,16,1667945,14,97,32,118,97,114, +105,97,98,108,101,32,99,97,110,39,116,32,98,101,32,118, +111,105,100,0,1667895,1585679,12,8,3,1668961,16,1310721,2,3,26,1599321, +12,10,3,6,10,4,8,1310721,2,5,26,1310721,2,3,26,2, +1603891,12,10,3,6,10,4,8,1558017,1310721,2,5,26,2,26,1310721, +2,13,26,2,10,3,6,10,4,8,1584895,2,1598801,12,1668279,16, +1310721,2,9,26,1665803,12,10,3,6,10,4,8,1584897,2,1599031,12, +8,1310721,2,11,26,2,1,6,1,10,28,34,63,38,3,26, +1668157,16,1310721,2,11,26,1584975,2,10,3,6,10,4,8,1473025,1310721, +2,5,26,2,26,3,10,3,6,10,4,8,1556993,1310721,2,5, +26,2,26,1310721,2,11,26,2,1310721,2,9,26,2,1624809,12,10, +3,6,10,4,8,1584851,1584851,2,1556993,1310721,2,5,26,2,26,2, +1628577,12,26,10,3,6,10,4,8,1668519,14,1310721,2,11,26,2, +1668333,16,1310721,2,11,26,2,1629979,12,1,6,1,10,28,34,63, +38,1,10,28,1668335,14,1,1668441,16,1473025,1310721,2,5,26,2,26, +3,10,3,6,10,4,8,1556993,1310721,2,5,26,2,26,1310721,2, +11,26,2,10,3,6,10,4,8,1584851,1584851,2,1310721,2,11,26, +2,1628577,12,26,10,3,6,10,4,8,1668519,14,1584851,1,6,2, +1,6,3,26,5,6,4,10,8,8,1310721,2,11,26,2,1668519, +16,1556993,1310721,2,5,26,2,26,1310721,2,11,26,2,10,3,6, +10,4,8,1584903,2,1598801,12,1668921,16,1473025,1310721,2,5,26,2,26, +2,1668661,16,1668653,14,97,110,32,97,114,114,97,121,32,111,114, +32,97,32,115,116,114,117,99,116,32,99,97,110,39,116,32, +98,101,32,105,110,105,116,105,97,108,105,122,101,100,32,119, +105,116,104,32,61,0,1668555,1585679,12,8,1310721,2,7,26,1662195,12, +10,3,6,10,4,8,1647757,12,8,1467905,1310721,2,5,26,2,26, +2,1590069,12,8,5,1589235,12,8,1310721,2,11,26,2,1668831,16,1310721, +2,11,26,2,1584987,2,1630621,12,1,6,1,10,28,34,63,38, +3,26,1668827,16,1668805,14,105,110,105,116,105,97,108,105,122,101, +114,0,1668781,1310721,2,11,26,2,1584987,2,1633925,12,8,1668893,14,1584987, +2,1629747,12,1,6,1,10,28,34,63,38,3,26,1668893,16,1556993, +1310721,2,5,26,2,26,1584987,2,10,3,6,10,4,8,3,1310721, +2,5,26,2,1310721,2,7,26,2,1618391,12,8,1584899,2,1598801,12, +1,6,1,10,28,34,63,38,3,26,1668957,16,1668961,14,1667953,14, +1584901,2,1599031,12,8,1,1668979,14,1,1310721,2,15,26,1310721,4,18, +1310721,2,1,28,1310721,4,1310721,2,1835009,40,1669027,16,1966081,1310721,4,1579069, +12,1648169,12,8,1597071,12,8,1,1667723,12,1669051,14,1,1310721,2,1, +26,1310721,4,18,1310721,2,21,28,1310721,4,1310721,2,1835009,40,1669099,16, +1966081,1310721,4,1579069,12,1584845,2,1310721,2,15,26,4,1648169,12,8,1597071, +12,8,1584887,2,1599031,12,8,1310721,2,5,26,1662195,12,10,3,6, +10,4,8,1647757,12,8,1310721,2,5,26,2,1605077,12,8,1584889,2, +1599031,12,8,1310721,2,1589535,12,10,3,6,10,4,8,17,1589235,12, +8,1310721,2,11,26,1584857,2,10,3,6,10,4,8,1310721,2,7, +26,1606761,12,10,3,6,10,4,8,1667563,12,8,1310721,2,13,26, +1584857,2,10,3,6,10,4,8,1310721,2,9,26,1606761,12,10,3, +6,10,4,8,1584933,2,1598649,12,1669587,16,1597071,12,8,1310721,2,3, +26,1589535,12,10,3,6,10,4,8,15,1589235,12,8,1310721,2,2, +1584837,2,1589317,12,8,1310721,2,7,26,2,1607393,12,8,1584857,1310721,2, +11,26,2,10,3,6,10,4,8,1667563,12,8,1310721,2,9,26, +2,1310721,2,13,26,2,1310721,2,3,26,2,1584857,2,1310721,2,15, +26,2,1669575,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,1669481,1615115,12,8,1670119,14,1609759,1,10,3,6,10,4, +8,1310721,2,13,26,2,1669637,16,1507841,1310721,2,9,26,2,26,1610727, +12,8,1310721,2,11,26,2,1669671,16,1507841,1310721,2,7,26,2,26, +1610727,12,8,1310721,2,15,26,2,1669779,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,1669685,1611455,12,8,1310721,2,13, +26,2,1669833,16,1507841,1310721,2,9,26,2,26,1310721,2,15,26,2, +3,1613039,12,8,1310721,2,17,26,1,10,3,6,10,4,8,1310721, +2,11,26,2,1669919,16,1310721,2,17,26,1507841,1310721,2,7,26,2, +26,1310721,2,15,26,2,1,1613039,12,10,3,6,10,4,8,1310721, +2,17,26,2,1670037,16,1310721,2,19,26,1589535,12,10,3,6,10, +4,8,15,1589235,12,8,1310721,2,2,1584837,2,1589317,12,8,1507841,1310721, +2,7,26,2,26,1310721,2,15,26,2,3,1613039,12,8,1310721,2, +19,26,2,1584837,2,1589317,12,8,1670053,14,1310721,2,2,1584837,2,1589317, +12,8,1584857,1310721,2,13,26,2,1670075,16,3,1670107,14,1310721,2,11, +26,2,1,6,1,10,28,34,63,38,1,10,28,10,3,6, +10,4,8,1310721,2,7,26,2,1607311,12,8,1,1670143,14,1,1310721, +2,21,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40, +1670191,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1552897, +1584867,2,17,30,26,1310721,2,5,26,4,1584867,2,121,40,3,36, +1670305,16,1670297,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,1670249,1585585,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,1584849,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,1584859,2,10,3,6,10,4,8,1310721,2, +5,26,2,11,26,1584845,2,10,3,6,10,4,8,1310721,2,5, +26,2,13,26,1609629,2,10,3,6,10,4,8,1584867,1,6,2, +1,6,3,26,5,6,4,10,8,8,1,1670557,14,1,1310721,2, +7,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1670605, +16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1,1310721, +2,13,26,4,1584867,1,6,2,1,6,-1,26,5,6,4,10, +8,8,1310721,2,5,26,1552897,1584867,2,17,30,26,10,3,6,10, +4,8,1310721,2,11,26,1310721,2,5,26,2,11,26,2,10,3, +6,10,4,8,1609759,1,10,3,6,10,4,8,1310721,2,3,26, +2,1,40,3,36,1670787,16,1507841,1310721,2,3,26,2,26,1610727,12, +8,1310721,2,7,26,1567233,1310721,2,5,26,2,13,26,2,26,10, +3,6,10,4,8,1310721,2,9,26,1567233,1609629,2,26,10,3,6, +10,4,8,1310721,2,7,26,2,1310721,2,9,26,2,40,1670979,16, +1310721,2,7,26,2,3,26,1610727,12,8,1310721,2,7,26,1310721,2, +7,26,2,7,26,7,1310721,2,7,26,2,5,26,2,1310721,2, +7,26,2,3,26,2,28,30,26,10,3,6,10,4,8,1670855, +14,1310721,2,11,26,2,1671103,14,108,101,97,118,101,115,32,116, +104,101,32,108,111,111,112,32,105,110,32,100,105,102,102,101, +114,101,110,116,32,115,116,97,116,101,115,32,111,110,32,100, +105,102,102,101,114,101,110,116,32,112,97,116,104,115,0,1670993, +1611455,12,8,1584857,1609759,2,1,10,40,10,3,6,10,4,8,1310721, +2,7,26,1567233,1310721,2,5,26,2,13,26,2,26,10,3,6, +10,4,8,1310721,2,7,26,2,1310721,2,9,26,2,40,1671471,16, +1310721,2,7,26,2,3,26,1310721,2,11,26,2,1,1613039,12,1671343, +16,1310721,2,7,26,2,1,26,2,1584837,2,1589317,12,8,1310721,2, +7,26,2,3,26,1310721,2,11,26,2,3,1613039,12,8,1310721,2, +13,26,1589535,12,1310721,2,13,26,2,1588385,12,10,3,6,10,4, +8,15,1589235,12,8,1671393,14,1310721,2,13,26,1310721,2,7,26,2, +1,26,2,1310721,2,13,26,2,1588385,12,10,3,6,10,4,8, +1310721,2,7,26,1310721,2,7,26,2,7,26,7,1310721,2,7,26, +2,5,26,2,1310721,2,7,26,2,3,26,2,28,30,26,10, +3,6,10,4,8,1671175,14,1310721,2,2,1,40,3,36,1671505,16, +1310721,2,2,1584837,2,1589317,12,8,1310721,2,3,26,2,1,40,3, +36,1671559,16,1507841,1310721,2,3,26,2,26,1310721,2,11,26,2,3, +1613039,12,8,1310721,2,13,26,2,1584837,2,1588737,12,8,1609629,1310721,2, +5,26,2,13,26,2,10,3,6,10,4,8,1,1671617,14,1, +1310721,2,15,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009, +40,1671665,16,1966081,1310721,4,1579069,12,1584837,2,1310721,2,4,3,1,10, +28,1310721,2,7,26,4,1,1310721,2,11,26,4,1648169,12,8,1597071, +12,8,1310721,2,5,26,1606761,12,10,3,6,10,4,8,1584887,2, +1599031,12,8,1582577,2,3,28,1,6,1,10,28,34,63,38,3, +26,1671813,16,1582579,2,1,6,1,10,28,34,63,38,1,10,28, +1671815,14,1,1671941,16,1597931,12,8,1584799,2,9,28,1,6,1,10, +28,34,63,38,3,26,1671913,16,1584801,2,1584889,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1671915,14,1,1671941,16,1310721,2,11,26,3,10,3,6,10, +4,8,1310721,2,9,26,1662195,12,10,3,6,10,4,8,1647757,12, +8,1310721,2,9,26,2,1605077,12,8,1584889,2,1599031,12,8,1310721,2, +3,26,1589535,12,10,3,6,10,4,8,17,1589235,12,8,1310721,2, +11,26,2,1,6,1,10,28,34,63,38,3,26,1672093,16,1584857, +2,1,6,1,10,28,34,63,38,1,10,28,1672095,14,1,1672123, +16,1310721,2,7,26,1606761,12,10,3,6,10,4,8,1310721,2,2, +1310721,2,5,26,2,1670157,12,8,1667563,12,8,1310721,2,5,26,2, +1613533,12,8,1310721,2,2,1589453,12,8,1310721,2,3,26,2,1310721,2, +7,26,2,1670571,12,8,1310721,2,5,26,2,1607311,12,8,1,1672229, +14,1,1310721,2,13,26,1310721,4,18,1310721,2,19,28,1310721,4,1310721, +2,1835009,40,1672277,16,1966081,1310721,4,1579069,12,1584845,2,1310721,2,4,3, +1,10,28,1310721,2,5,26,4,1,1310721,2,17,26,4,1648169,12, +8,1597071,12,8,1584887,2,1599031,12,8,1584849,1,6,2,1,6,3, +26,5,6,4,10,8,8,1584929,2,1598649,12,1672389,16,1668993,12,8, +1672505,14,1637143,12,1672409,16,3,1667723,12,8,1672505,14,1584901,2,1598497,12, +1,6,1,10,28,34,63,38,3,26,1672495,16,1310721,2,15,26, +1662195,12,10,3,6,10,4,8,1647757,12,8,9,1589235,12,8,1310721, +2,15,26,2,1623627,12,8,1584901,2,1599031,12,8,1310721,2,3,26, +1606761,12,10,3,6,10,4,8,1310721,2,7,26,1584837,2,10,3, +6,10,4,8,1584901,2,1598497,12,1,6,1,10,28,34,63,38, +3,26,1672825,16,1582577,2,3,28,1,6,1,10,28,34,63,38, +3,26,1672647,16,1582579,2,1,6,1,10,28,34,63,38,1,10, +28,1672649,14,1,1672775,16,1597931,12,8,1584799,2,9,28,1,6,1, +10,28,34,63,38,3,26,1672747,16,1584801,2,1584901,2,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1672749,14,1,1672775,16,1310721,2,17,26,3,10,3,6, +10,4,8,1310721,2,15,26,1662195,12,10,3,6,10,4,8,1647757, +12,8,1310721,2,15,26,2,1605077,12,8,1672855,14,3,1589149,12,8, +1310721,2,17,26,3,10,3,6,10,4,8,1584901,2,1599031,12,8, +1310721,2,9,26,1589535,12,10,3,6,10,4,8,17,1589235,12,8, +1310721,2,17,26,2,1,6,1,10,28,34,63,38,3,26,1672961, +16,1584857,2,1,6,1,10,28,34,63,38,1,10,28,1672963,14, +1,1672991,16,1310721,2,5,26,1606761,12,10,3,6,10,4,8,1310721, +2,11,26,1589535,12,10,3,6,10,4,8,15,1589235,12,8,1310721, +2,13,26,1584837,2,10,3,6,10,4,8,1584889,2,1598497,12,1, +6,1,10,28,34,63,38,3,26,1673133,16,1310721,2,15,26,1662195, +12,10,3,6,10,4,8,1647757,12,8,9,1589235,12,8,1310721,2, +15,26,2,1623627,12,8,1584889,2,1599031,12,8,1310721,2,7,26,2, +1589453,12,8,1310721,2,11,26,2,1584837,2,1589317,12,8,1310721,2,13, +26,2,1310721,2,3,26,2,1670157,12,8,1667563,12,8,1310721,2,3, +26,2,1613533,12,8,1310721,2,13,26,2,1589453,12,8,1310721,2,9, +26,2,1310721,2,5,26,2,1670571,12,8,1310721,2,3,26,2,1607311, +12,8,1310721,2,2,1606489,12,8,1584849,1,6,2,1,6,-1,26, +5,6,4,10,8,8,1,1673333,14,1,1310721,2,19,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1673381,16,1966081,1310721,4, +1579069,12,1648169,12,8,1597071,12,8,1584901,2,1599031,12,8,1584867,2,1584869, +2,10,40,3,36,1673507,16,1673493,14,98,114,101,97,107,32,111, +117,116,115,105,100,101,32,97,32,108,111,111,112,32,111,114, +32,97,32,115,119,105,116,99,104,0,1673427,1585679,12,8,1,1673759, +14,1310721,2,1552897,1584867,2,3,28,17,30,26,10,3,6,10,4, +8,1310721,2,2,9,26,2,1584859,2,28,1,6,1,10,28,34, +63,38,1,10,28,1673675,16,1673661,14,98,114,101,97,107,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,1673587,1585679, +12,8,1,1673759,14,1310721,2,2,5,26,2,3,26,1,1605463,12, +8,1584857,2,1673721,16,1589535,12,1610135,12,8,1673727,14,1589535,12,8,15, +1589235,12,8,1584857,1,10,3,6,10,4,8,1,1673759,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40, +1673807,16,1966081,1310721,4,1579069,12,1584867,2,3,28,1310721,2,4,1648169,12, +8,1597071,12,8,1584901,2,1599031,12,8,1310721,2,2,1584869,2,40,3, +36,1673935,16,1552897,1310721,2,2,17,30,26,2,3,1,10,28,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1673937,14,1,1673975,16,1310721,2,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1673843,14,1310721,2,2,1584869,2, +40,1674057,16,1674043,14,99,111,110,116,105,110,117,101,32,111,117, +116,115,105,100,101,32,97,32,108,111,111,112,0,1673995,1585679,12, +8,1,1674333,14,1310721,2,3,26,1552897,1310721,2,2,17,30,26,10, +3,6,10,4,8,1310721,2,3,26,2,9,26,2,1584859,2,28, +1,6,1,10,28,34,63,38,1,10,28,1674237,16,1674223,14,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,1674143,1585679,12,8,1,1674333,14,1310721,2, +3,26,2,7,26,2,1613533,12,8,1310721,2,3,26,2,5,26, +2,3,26,1,1605463,12,8,1310721,2,3,26,2,1,26,2,1589453, +12,8,1584857,1,10,3,6,10,4,8,1,1674333,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1674381, +16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1584845,2, +1310721,2,5,26,4,1310721,2,2,1607393,12,8,1584857,1310721,2,3,26, +2,10,3,6,10,4,8,1584849,1,6,2,1,6,3,26,5, +6,4,10,8,8,1584893,2,1598497,12,1,6,1,10,28,34,63, +38,3,26,1674561,16,1584949,2,1598649,12,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1674563,14, +1,1674621,16,1584951,2,1598649,12,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1674623,14,1,1674705, +16,1582577,2,1,28,1,6,1,10,28,34,63,38,3,26,1674695, +16,1674683,14,109,105,115,115,105,110,103,32,125,0,1674663,1586063,12, +8,1674705,14,1666771,12,8,1674475,14,1310721,2,5,26,2,1606489,12,8, +1584849,1,6,2,1,6,-1,26,5,6,4,10,8,8,1584857,2, +1674775,16,1589535,12,1610135,12,8,15,1589235,12,8,1584857,1,10,3,6, +10,4,8,1,1674799,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +23,28,1310721,4,1310721,2,1835009,40,1674847,16,1966081,1310721,4,1579069,12,1584845, +2,1310721,2,4,3,1,10,28,1310721,2,11,26,4,3,1,10, +28,1310721,2,21,26,4,1648169,12,8,1597071,12,8,1584887,2,1599031,12, +8,1310721,2,5,26,1662195,12,10,3,6,10,4,8,1647757,12,8, +1310721,2,5,26,2,1605077,12,8,1584889,2,1599031,12,8,1584849,1,6, +2,1,6,3,26,5,6,4,10,8,8,1310721,2,3,26,1, +1603891,12,10,3,6,10,4,8,1584851,1,6,2,1,6,3,26, +5,6,4,10,8,8,1467905,1310721,2,3,26,2,26,2,1590069,12, +8,5,1589235,12,8,1310721,2,9,26,1584857,2,10,3,6,10,4, +8,1310721,2,7,26,1606761,12,10,3,6,10,4,8,3,1,10, +28,1310721,2,7,26,2,1670157,12,8,1584891,2,1599031,12,8,1584893,2, +1598497,12,1,6,1,10,28,34,63,38,3,26,1675871,16,1582577,2, +1,28,1,6,1,10,28,34,63,38,3,26,1675265,16,1675253,14, +109,105,115,115,105,110,103,32,125,0,1675233,1586063,12,8,1675871,14, +1584949,2,1598649,12,1675587,16,1597071,12,8,1310721,2,17,26,1,10,3, +6,10,4,8,3,1675475,16,1310721,2,19,26,1665803,12,10,3,6, +10,4,8,1467905,1310721,2,3,26,2,26,2,1590069,12,8,3,1589235, +12,8,1310721,2,19,26,2,1589149,12,8,29,1589235,12,8,1310721,2, +17,26,1589535,12,1310721,2,17,26,2,1588385,12,10,3,6,10,4, +8,17,1589235,12,8,1584899,2,1598801,12,1,6,1,10,28,34,63, +38,3,26,1675471,16,1675475,14,1675305,14,1584915,2,1599031,12,8,1310721,2, +15,26,1589535,12,10,3,6,10,4,8,15,1589235,12,8,1310721,2, +17,26,2,1584837,2,1588737,12,8,1310721,2,7,26,2,1310721,2,9, +26,2,1674347,12,8,1310721,2,15,26,2,1584837,2,1589317,12,8,1675867, +14,1584951,2,1598649,12,1675805,16,1597071,12,8,1584915,2,1599031,12,8,1310721, +2,11,26,2,1,40,3,36,1675699,16,1675691,14,97,32,115,119, +105,116,99,104,32,104,97,115,32,111,110,101,32,100,101,102, +97,117,108,116,0,1675641,1585679,12,8,1310721,2,13,26,1589535,12,10, +3,6,10,4,8,15,1589235,12,8,1310721,2,11,26,1584837,2,10, +3,6,10,4,8,1310721,2,7,26,2,1310721,2,9,26,2,1674347, +12,8,1310721,2,13,26,2,1584837,2,1589317,12,8,1675867,14,1675859,14, +101,120,112,101,99,116,101,100,32,99,97,115,101,32,111,114, +32,100,101,102,97,117,108,116,0,1675809,1586063,12,8,1675165,14,1597071, +12,8,1310721,2,7,26,2,1607393,12,8,1584857,1310721,2,9,26,2, +10,3,6,10,4,8,1310721,2,11,26,2,1,40,3,36,1675981, +16,1310721,2,11,26,2,1589453,12,8,3,1,10,28,3,1,10, +28,1670571,12,8,1676039,14,1310721,2,21,26,1589535,12,10,3,6,10, +4,8,15,1589235,12,8,1310721,2,21,26,2,1310721,2,7,26,2, +1670571,12,8,1310721,2,7,26,2,1607311,12,8,1310721,2,2,1606489,12, +8,1584849,1,6,2,1,6,-1,26,5,6,4,10,8,8,1, +1676103,14,1,1310721,2,23,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1676151,16,1966081,1310721,4,1579069,12,1648169,12,8,1597071,12, +8,1584865,2,1,6,1,10,28,34,63,38,3,26,1676255,16,1676247, +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,1676195,1585679,12,8,1584859, +2,1676351,16,1676343,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,1676267,1585679,12,8,1584901, +2,1598497,12,1676393,16,1,1589149,12,8,1310721,2,1,10,3,6,10, +4,8,1676621,14,1310721,2,1662195,12,10,3,6,10,4,8,1647757,12, +8,1584885,2,1584983,2,28,1,6,1,10,28,34,63,38,3,26, +1676503,16,1676483,14,114,101,116,117,114,110,32,118,97,108,117,101, +0,1676457,1584983,2,1584987,2,1633925,12,8,1676621,14,1584885,2,1676569,16,1584885, +2,1584987,2,1630621,12,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1676571,14,1,1676621,16,1676605, +14,114,101,116,117,114,110,32,118,97,108,117,101,0,1676579,1584885, +2,1584987,2,1633925,12,8,1584901,2,1599031,12,8,1310721,2,2,1621929,12, +8,3,1,1605463,12,8,1584861,1584837,2,1584861,2,1588385,12,10,3,6, +10,4,8,2097153,3,28,1589149,12,8,15,1589235,12,8,1584857,1,10, +3,6,10,4,8,1,1676723,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1676771,16,1966081,1310721,4,1579069, +12,1584853,2,1310721,2,4,1648169,12,8,1597071,12,8,1584853,1,10,3, +6,10,4,8,1667563,12,8,1584853,1310721,2,2,10,3,6,10,4, +8,1,1676843,14,1,1310721,2,3,26,1310721,4,18,1310721,2,21,28, +1310721,4,1310721,2,1835009,40,1676891,16,1966081,1310721,4,1579069,12,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,1584891,2,1599031,12,8,1584893,2,1598497,12,1,6, +1,10,28,34,63,38,3,26,1678951,16,1582577,2,1,28,1,6, +1,10,28,34,63,38,3,26,1677103,16,1677095,14,117,110,116,101, +114,109,105,110,97,116,101,100,32,97,115,109,32,98,108,111, +99,107,0,1677049,1586063,12,8,1582577,2,3,28,1,6,1,10,28, +34,63,38,3,26,1677155,16,1582579,2,1589149,12,8,1597071,12,8,1676981, +14,1582577,2,7,28,1,6,1,10,28,34,63,38,3,26,1677207, +16,1582579,2,1590177,12,8,1597071,12,8,1676981,14,1584917,2,1598497,12,1677325, +16,1597071,12,8,1582577,2,3,28,1,6,1,10,28,34,63,38, +1,10,28,1677305,16,1677297,14,35,32,110,101,101,100,115,32,97, +32,110,117,109,98,101,114,0,1677263,1586063,12,8,1582579,2,1588955,12, +8,1597071,12,8,1676981,14,1584919,2,1598497,12,1677447,16,1597071,12,8,1582577, +2,3,28,1,6,1,10,28,34,63,38,3,26,1677405,16,1582581, +2,1,6,1,10,28,34,63,38,1,10,28,1677407,14,1,1677435, +16,1,1582579,2,28,1589149,12,8,1597071,12,8,1677443,14,29,1589235,12, +8,1676981,14,1584915,2,1598497,12,1677637,16,1597071,12,8,1310721,2,2,129, +40,3,36,1677535,16,1677527,14,116,111,111,32,109,97,110,121,32, +97,115,109,32,108,97,98,101,108,115,0,1677487,1585585,12,8,1310721, +2,13,26,2,1310721,2,2,26,1599321,12,10,3,6,10,4,8, +1310721,2,15,26,2,1310721,2,2,26,1584837,2,10,3,6,10,4, +8,1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8, +1676981,14,1582579,2,1,26,2,1677707,16,1582579,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,1677709,14,1,1677779,16,1310721,2,9,26,1582579,2,1,26, +2,1600613,12,10,3,6,10,4,1,40,3,36,1,6,1,10, +28,34,63,38,1,10,28,1677781,14,1,1677811,16,1310721,2,9,26, +2,1589235,12,8,1597071,12,8,1676981,14,1582577,2,5,28,1,6,1, +10,28,34,63,38,1,10,28,1677891,16,1677883,14,98,97,100,32, +116,111,107,101,110,32,105,110,32,97,115,109,0,1677849,1586063,12, +8,1310721,2,5,26,1582579,2,1603687,12,10,3,6,10,4,8,1310721, +2,5,26,2,1,40,3,36,1678001,16,1472001,1310721,2,5,26,2, +26,3,10,3,6,10,4,8,1467905,1310721,2,5,26,2,26,2, +1590069,12,8,1597071,12,8,1676981,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,1678195,16,1310721,2,13,26, +2,1310721,2,5,26,2,26,2,1582579,2,28,1,6,1,10,28, +34,63,38,3,26,1678157,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,1678051,14,1310721,2,7,26,2,1,40, +3,36,1678257,16,1310721,2,15,26,2,1310721,2,7,26,2,26,2, +1589149,12,8,1597071,12,8,1676981,14,1310721,2,11,26,1582579,2,1587809,12, +10,3,6,10,4,8,1310721,2,11,26,2,1,40,3,36,1678373, +16,1417729,1310721,2,11,26,2,26,2,13,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1678375,14,1,1678415,16,45,1425921,1310721,2,11,26,2,26,2,26,1589235, +12,8,1597071,12,8,1676981,14,1310721,2,11,26,2,1,40,3,36, +1678505,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,1678507,14,1,1678579,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,1678581,14,1,1678617,16,1425921,1310721,2,11, +26,2,26,2,1589149,12,8,1597071,12,8,1676981,14,1310721,2,11,26, +2,1,40,3,36,1678705,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,1678707,14,1,1678737,16,1310721,2,11,26,2, +1589741,12,8,1597071,12,8,1676981,14,1310721,2,3,26,2,501,40,3, +36,1678831,16,1678823,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,1678763,1585585,12,8,1310721,2,17,26,2,1310721,2,3,26, +2,26,1582579,2,10,3,6,10,4,8,1310721,2,19,26,2,1310721, +2,3,26,2,26,1589535,12,10,3,6,10,4,8,1310721,2,3, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1597071,12, +8,1676981,14,1597071,12,8,1310721,2,5,26,1,10,3,6,10,4, +8,1310721,2,5,26,2,1310721,2,3,26,2,40,1679405,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, +1679219,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,1679181,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,1679055,14,1310721,2,7,26,2,1,40, +1679313,16,1310721,2,17,26,2,1310721,2,5,26,2,26,2,1679305,14, +117,110,107,110,111,119,110,32,110,97,109,101,32,105,110,32, +97,115,109,0,1679265,1585849,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, +1589317,12,8,1310721,2,5,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1678979,14,1,1679413,14,1,1310721,2,21,26,1310721,4, +18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1679461,16,1966081,1310721,4, +1579069,12,1597071,12,8,1676857,12,8,1584883,1,10,3,6,10,4,8, +1,1679497,14,1,1310721,2,1,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1679545,16,1966081,1310721,4,1579069,12,1,1310721,2,4, +1,1310721,2,3,26,4,1584891,2,1598497,12,1,6,1,10,28,34, +63,38,3,26,1679631,16,1679623,14,101,120,112,101,99,116,101,100, +32,123,0,1679601,1586063,12,8,1597071,12,8,3,1680053,16,1582577,2,1, +28,1,6,1,10,28,34,63,38,3,26,1679725,16,1679717,14,117, +110,116,101,114,109,105,110,97,116,101,100,32,113,117,111,116, +101,0,1679679,1586063,12,8,1584891,2,1598497,12,1679771,16,1310721,2,3,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1584893,2,1598497, +12,1679855,16,1310721,2,3,26,2,1,6,1,10,28,34,63,38, +3,26,1679821,16,1680053,14,1310721,2,3,26,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1310721,2,2,5401,40,3,36,1679915,16, +1679907,14,113,117,111,116,101,32,116,111,111,32,108,111,110,103, +0,1679877,1585585,12,8,1524225,1310721,2,2,7,30,26,1582577,2,10,3, +6,10,4,8,1524225,1310721,2,2,7,30,3,26,26,1582579,2,10, +3,6,10,4,8,1524225,1310721,2,2,7,30,5,26,26,1582583,2, +10,3,6,10,4,8,1310721,2,1,6,2,1,6,3,26,5, +6,4,10,8,8,1597071,12,8,1679637,14,1597071,12,8,1310721,2,5, +26,1310721,2,2,7,30,3,26,1579923,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,7,30,1574337,12,8, +1310721,2,5,26,2,1680177,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,1835009,40,1680225,16,1966081,1310721,4,1579069,12, +1310721,2,4,1310721,2,2,1,26,2,7,30,3,26,1310721,2,3, +26,4,1310721,2,3,26,2,1579923,12,1310721,2,5,26,4,1310721,2, +5,26,2,1310721,2,2,1310721,2,3,26,2,1574337,12,8,1310721,2, +5,26,2,1680333,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7, +28,1310721,4,1310721,2,1835009,40,1680381,16,1966081,1310721,4,1579069,12,1310721,2, +4,1310721,2,2,1,26,2,7,30,3,26,1310721,2,3,26,4, +1310721,2,3,26,2,1579923,12,1310721,2,5,26,4,1310721,2,5,26, +2,1310721,2,2,1310721,2,3,26,2,1574337,12,8,1310721,2,5,26, +2,1680489,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1680537,16,1966081,1310721,4,1579069,12,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,1680655,16,1310721,2,2,1310721,2,5,26,2,26, +2,1588955,12,8,1310721,2,5,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1680565,14,1,1680663,14,1,1310721,2,7,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1680711,16,1966081,1310721, +4,1579069,12,1597071,12,8,1310721,2,1679511,12,10,3,6,10,4,8, +1310721,2,3,26,1589535,12,10,3,6,10,4,8,15,1589235,12,8, +1310721,2,5,26,1584837,2,10,3,6,10,4,8,1310721,2,7,26, +1310721,2,2,1,26,2,7,30,3,26,10,3,6,10,4,8, +1310721,2,2,1310721,2,7,26,2,1680503,12,8,1310721,2,2,1580623,12, +8,1310721,2,3,26,2,1584837,2,1589317,12,8,1310721,2,5,26,2, +1589149,12,8,1584963,2,1589915,12,8,1584883,3,10,3,6,10,4,8, +1,1680937,14,1,1310721,2,9,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1680985,16,1966081,1310721,4,1579069,12,1310721,2,4,1, +1310721,2,3,26,4,5,1310721,2,2,1,1,1590943,12,8,1597071,12, +8,1582577,2,1,28,1,6,1,10,28,34,63,38,1,10,28, +1681281,16,1310721,2,3,26,2,5401,40,3,36,1681127,16,1681119,14,116, +111,111,32,109,97,110,121,32,116,111,107,101,110,115,0,1681087, +1585585,12,8,1524225,1310721,2,3,26,2,7,30,26,1582577,2,10,3, +6,10,4,8,1524225,1310721,2,3,26,2,7,30,3,26,26,1582579, +2,10,3,6,10,4,8,1524225,1310721,2,3,26,2,7,30,5, +26,26,1582583,2,10,3,6,10,4,8,1310721,2,3,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1597071,12,8,1681027,14, +1592371,12,8,1310721,2,5,26,1310721,2,3,26,2,7,30,3,26, +1579923,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,7,30,1574337,12,8,1310721,2,5,26, +2,1681417,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1681465,16,1966081,1310721,4,1579069,12,1310721,2,4,3, +1310721,2,2,3,3,1590943,12,8,1597071,12,8,1,1681503,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40, +1681551,16,1966081,1310721,4,1579069,12,8181,1310721,2,4,8181,1579923,12,1310721,2, +3,26,4,1,1310721,2,5,26,4,1573227,12,1,6,1,10,28, +34,63,38,3,26,1682109,16,1310721,2,7,26,1573171,12,511,32,10, +3,6,10,4,8,1310721,2,7,26,2,193,28,1,6,1,10, +28,34,63,38,3,26,1681685,16,1682109,14,1310721,2,5,26,2,5, +38,5,26,1310721,2,2,40,3,36,1681873,16,1310721,2,9,26,1310721, +2,2,1310721,2,2,26,13,26,1579923,12,10,3,6,10,4,8, +1310721,2,9,26,2,1310721,2,3,26,2,1310721,2,2,1574337,12,8, +1310721,2,3,26,2,1580623,12,8,1310721,2,3,26,1310721,2,9,26, +2,10,3,6,10,4,8,1310721,2,1310721,2,2,1310721,2,2,26, +13,26,10,3,6,10,4,8,1310721,2,11,26,1310721,2,5,26, +2,5,38,10,3,6,10,4,8,1310721,2,5,26,2,7,32, +1,6,1,10,28,34,63,38,3,26,1681981,16,1310721,2,3,26, +2,1310721,2,11,26,2,26,1,10,3,6,10,4,8,1310721,2, +3,26,2,1310721,2,11,26,2,26,1310721,2,3,26,2,1310721,2, +11,26,2,26,2,1310721,2,7,26,2,1310721,2,5,26,2,7, +32,17,30,48,34,10,3,6,10,4,8,1310721,2,5,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1681587,14,1310721,2, +3,26,2,1310721,2,5,26,2,5,38,26,1310721,2,3,26,2, +1310721,2,5,26,2,5,38,26,2,1574747,1310721,2,5,26,2,7, +32,17,30,26,2,3,28,32,10,3,6,10,4,8,1310721,2, +5,26,2,7,32,1,28,1,6,1,10,28,34,63,38,3, +26,1682287,16,1310721,2,3,26,2,1310721,2,5,26,2,5,38,26, +1,10,3,6,10,4,8,1310721,2,3,26,2,1310721,2,5,26, +2,5,38,3,26,26,1,10,3,6,10,4,8,1310721,2,3, +26,2,1682347,14,1,1310721,2,13,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1682395,16,1966081,1310721,4,1579069,12,1,1310721,2, +4,1582577,2,1,28,1,6,1,10,28,34,63,38,1,10,28, +1682603,16,1585015,2,1598497,12,1682483,16,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1682567,14,1585017,2,1598497,12,1682529,16,1310721, +2,1,6,2,1,6,-1,26,5,6,4,10,8,8,1682567,14, +1585019,2,1598497,12,1682567,16,1310721,2,1310721,2,2,5,28,10,3,6, +10,4,8,1597071,12,8,1310721,2,2,1,10,40,3,36,1682599,16, +1,1682611,14,1682403,14,1,1682611,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,15,28,1310721,4,1310721,2,1835009,40,1682659,16,1966081,1310721,4,1579069, +12,1582579,2,1310721,2,4,1,1310721,2,3,26,4,1,1310721,2,5, +26,4,1,1310721,2,7,26,4,1,1310721,2,9,26,4,1582577,2, +5,28,1,6,1,10,28,34,63,38,1,10,28,1682757,16,1, +1684237,14,1597071,12,8,1585015,2,1598497,12,1682781,16,1682361,12,8,1584887,2, +1598497,12,1,6,1,10,28,34,63,38,3,26,1682819,16,1,1684237, +14,1597071,12,8,1584889,2,1598497,12,1,6,1,10,28,34,63,38, +3,26,1683569,16,1310721,2,3,26,3,10,3,6,10,4,8,1310721, +2,11,26,3,10,3,6,10,4,8,1582577,2,1,28,1,6, +1,10,28,34,63,38,1,10,28,1683475,16,1584887,2,1598497,12,1682985, +16,1310721,2,11,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1683465,14,1584889,2,1598497,12,1683073,16,1310721,2,11,26,1,6, +2,1,6,-1,26,5,6,4,10,8,8,1310721,2,11,26,2, +1,6,1,10,28,34,63,38,3,26,1683069,16,1683475,14,1683465,14, +1310721,2,11,26,2,3,28,1,6,1,10,28,34,63,38,3, +26,1683145,16,1584899,2,1598497,12,1,6,1,10,28,34,63,38,1, +10,28,1683147,14,1,1683305,16,1310721,2,3,26,2,25,10,40,3, +36,1683245,16,1310721,2,5,26,1310721,2,5,26,2,1310721,2,7,26, +2,1310721,2,3,26,2,1310721,2,3,26,2,26,5,28,48,26, +10,3,6,10,4,8,1310721,2,3,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1310721,2,7,26,1,10,3,6,10, +4,8,1683465,14,1310721,2,11,26,2,3,28,1,6,1,10,28, +34,63,38,3,26,1683377,16,1584925,2,1598497,12,1,6,1,10,28, +34,63,38,1,10,28,1683379,14,1,1683465,16,1597071,12,8,1584941,2, +1598649,12,1683427,16,1310721,2,7,26,3,10,3,6,10,4,8,1683461, +14,1584943,2,1598649,12,1683461,16,1310721,2,7,26,5,10,3,6,10, +4,8,1682901,14,1597071,12,8,1682901,14,1310721,2,3,26,2,25,10, +40,3,36,1683569,16,1310721,2,5,26,1310721,2,5,26,2,1310721,2, +7,26,2,1310721,2,3,26,2,1310721,2,3,26,2,26,5,28, +48,26,10,3,6,10,4,8,1597071,12,8,1584905,2,1598801,12,1683807, +16,1582577,2,1,28,1,6,1,10,28,34,63,38,1,10,28, +1683675,16,1584891,2,1598497,12,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1683677,14,1,1683735,16, +1584901,2,1598497,12,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1683737,14,1,1683807,16,1584925,2, +1598497,12,1683797,16,1597071,12,8,1584945,2,1598649,12,1683793,16,1310721,2,9, +26,3,10,3,6,10,4,8,1683587,14,1597071,12,8,1683587,14,1310721, +2,13,26,1310721,2,2,1587809,12,10,3,6,10,4,8,1310721,2, +13,26,2,1,40,1683861,16,3,1683899,14,1310721,2,13,26,2,1582509, +2,40,1,6,1,10,28,34,63,38,1,10,28,1683909,16,3, +1683973,14,1417729,1310721,2,13,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,1683983,16,3,1684025,14,1442305,1310721,2,13,26,2,26,2,3, +32,1,6,1,10,28,34,63,38,1,10,28,1684059,16,1310721,2, +13,26,1310721,2,2,1589617,12,10,3,6,10,4,8,1442305,1310721,2, +13,26,2,26,2,5,32,1,6,1,10,28,34,63,38,3, +26,1684229,16,1434113,1310721,2,13,26,2,26,1310721,2,9,26,2,1310721, +2,3,26,2,26,1310721,2,3,26,2,26,1310721,2,5,26,2, +129,30,26,10,3,6,10,4,8,1442305,1310721,2,13,26,2,26, +1442305,1310721,2,13,26,2,26,2,5,34,513,34,10,3,6,10, +4,8,1,1684237,14,1,1310721,2,15,26,1310721,4,18,1310721,2,11, +28,1310721,4,1310721,2,1835009,40,1684285,16,1966081,1310721,4,1579069,12,1310721,2, +3,26,4,1310721,2,4,1,1310721,2,5,26,4,1585091,2,1310721,2, +7,26,4,1585089,2,1310721,2,9,26,4,1584991,1,6,2,1,6, +3,26,5,6,4,10,8,8,1310721,2,2,1310721,2,3,26,2, +1,1,1590943,12,8,1597071,12,8,1582577,2,1,28,1,6,1,10, +28,34,63,38,1,10,28,1684625,16,1584891,2,1598497,12,1684485,16,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1684615,14,1584893,2,1598497,12,1684535,16,1310721,2,5,26,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1684615,14,1310721,2,5,26,2, +1,10,40,3,36,1684593,16,1584927,2,1598649,12,1,6,1,10,28, +34,63,38,1,10,28,1684595,14,1,1684615,16,1597071,12,8,1682625,12, +8,1684401,14,1597071,12,8,1684401,14,1592371,12,8,1584991,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1585091,1310721,2,7,26,2,10, +3,6,10,4,8,1585089,1310721,2,9,26,2,10,3,6,10,4, +8,1,1684715,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1684763,16,1966081,1310721,4,1579069,12,1681517,12,1310721, +2,4,7,1310721,2,2,1684251,12,8,7,1310721,2,2,1,1,1590943, +12,8,1597071,12,8,1697867,12,8,1582509,2,1697967,12,8,1592371,12,8, +1310721,2,2,1580623,12,8,1,1684853,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1684901,16,1966081,1310721,4, +1579069,12,1548801,1584871,2,49,30,26,1310721,2,4,1584871,2,61,40,3, +36,1685001,16,1684993,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, +1684939,1585585,12,8,1584871,1,6,2,1,6,3,26,5,6,4,10, +8,8,1310721,2,2,1,26,1584845,2,10,3,6,10,4,8,1310721, +2,2,3,26,1584847,2,10,3,6,10,4,8,1310721,2,2,5, +26,1584849,2,10,3,6,10,4,8,1310721,2,2,7,26,1584851,2, +10,3,6,10,4,8,1310721,2,2,9,26,1584853,2,10,3,6, +10,4,8,1310721,2,2,11,26,1584855,2,10,3,6,10,4,8, +1310721,2,2,13,26,1584857,2,10,3,6,10,4,8,1310721,2,2, +15,26,1584859,2,10,3,6,10,4,8,1310721,2,2,17,26,1584861, +2,10,3,6,10,4,8,1310721,2,2,19,26,1584863,2,10,3, +6,10,4,8,1310721,2,2,21,26,1584865,2,10,3,6,10,4, +8,1310721,2,2,23,26,1584867,2,10,3,6,10,4,8,1310721,2, +2,25,26,1584869,2,10,3,6,10,4,8,1310721,2,2,27,26, +1584875,2,10,3,6,10,4,8,1310721,2,2,29,26,1584877,2,10, +3,6,10,4,8,1310721,2,2,31,26,1584879,2,10,3,6,10, +4,8,1310721,2,2,33,26,1584881,2,10,3,6,10,4,8,1310721, +2,2,35,26,1584883,2,10,3,6,10,4,8,1310721,2,2,37, +26,1584873,2,10,3,6,10,4,8,1310721,2,2,39,26,1584885,2, +10,3,6,10,4,8,1310721,2,2,41,26,1585009,2,10,3,6, +10,4,8,1310721,2,2,43,26,1584987,2,10,3,6,10,4,8, +1310721,2,2,45,26,1584993,5,1574337,12,8,1,1685629,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1685677, +16,1966081,1310721,4,1579069,12,1584871,1,6,2,1,6,-1,26,5,6, +4,10,8,8,1310721,2,1548801,1584871,2,49,30,26,10,3,6,10, +4,8,1584845,1310721,2,2,1,26,2,10,3,6,10,4,8,1584847, +1310721,2,2,3,26,2,10,3,6,10,4,8,1584849,1310721,2,2, +5,26,2,10,3,6,10,4,8,1584851,1310721,2,2,7,26,2, +10,3,6,10,4,8,1584853,1310721,2,2,9,26,2,10,3,6, +10,4,8,1584855,1310721,2,2,11,26,2,10,3,6,10,4,8, +1584857,1310721,2,2,13,26,2,10,3,6,10,4,8,1584859,1310721,2, +2,15,26,2,10,3,6,10,4,8,1584861,1310721,2,2,17,26, +2,10,3,6,10,4,8,1584863,1310721,2,2,19,26,2,10,3, +6,10,4,8,1584865,1310721,2,2,21,26,2,10,3,6,10,4, +8,1584867,1310721,2,2,23,26,2,10,3,6,10,4,8,1584869,1310721, +2,2,25,26,2,10,3,6,10,4,8,1584875,1310721,2,2,27, +26,2,10,3,6,10,4,8,1584877,1310721,2,2,29,26,2,10, +3,6,10,4,8,1584879,1310721,2,2,31,26,2,10,3,6,10, +4,8,1584881,1310721,2,2,33,26,2,10,3,6,10,4,8,1584883, +1310721,2,2,35,26,2,10,3,6,10,4,8,1584873,1310721,2,2, +37,26,2,10,3,6,10,4,8,1584885,1310721,2,2,39,26,2, +10,3,6,10,4,8,1585009,1310721,2,2,41,26,2,10,3,6, +10,4,8,1584987,1310721,2,2,43,26,2,10,3,6,10,4,8, +1584993,1310721,2,2,45,26,5,1574337,12,8,1,1686333,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1686381, +16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,1584847,1584845, +2,10,3,6,10,4,8,1584849,3,10,3,6,10,4,8,1584851, +1,10,3,6,10,4,8,1584853,1310721,2,2,1686489,16,1582575,2,1, +6,1,10,28,34,63,38,1,10,28,1686491,14,1,10,3,6, +10,4,8,1584855,1310721,2,3,26,2,10,3,6,10,4,8,1584885, +1,10,3,6,10,4,8,1584857,3,10,3,6,10,4,8,1584859, +1,10,3,6,10,4,8,1584861,1,10,3,6,10,4,8,1584865, +3,10,3,6,10,4,8,1584869,1584867,2,10,3,6,10,4,8, +1584875,1,10,3,6,10,4,8,1584877,1,10,3,6,10,4,8, +1,1686665,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1686713,16,1966081,1310721,4,1579069,12,1310721,1589149,12,8, +3,1589235,12,8,1584863,1589535,12,10,3,6,10,4,8,29,1589235,12, +8,1310721,1589149,12,8,5,1589235,12,8,1310721,1589149,12,8,3,1589235,12, +8,1835009,1589149,12,8,41,1589235,12,8,1310721,2,1589535,12,10,3,6, +10,4,8,17,1589235,12,8,1966081,1589149,12,8,1310721,1589149,12,8,5, +1589235,12,8,1584953,2,1589915,12,8,1310721,2,2,1584837,2,1589317,12,8, +1,1686889,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721, +4,1310721,2,1835009,40,1686937,16,1966081,1310721,4,1579069,12,1,1589149,12,8, +1584861,2,1584837,2,1588737,12,8,1310721,1589149,12,8,3,1589235,12,8,1584851, +2,1589149,12,8,27,1589235,12,8,1310721,1589149,12,8,5,1589235,12,8, +19,1589235,12,8,1584863,2,1584851,2,1589317,12,8,1584865,1,10,3,6, +10,4,8,1584845,1584847,2,10,3,6,10,4,8,1,1687073,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009, +40,1687121,16,1966081,1310721,4,1579069,12,1584891,2,1599031,12,8,1584893,2,1598497, +12,1,6,1,10,28,34,63,38,3,26,1687287,16,1582577,2,1, +28,1,6,1,10,28,34,63,38,3,26,1687277,16,1687269,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,1687199,1586063,12,8,1666771,12,8,1687131,14,1584847,2,1606191,12,8, +1584853,2,1687335,16,1584857,2,1,6,1,10,28,34,63,38,1,10, +28,1687337,14,1,1687455,16,3,3,1605463,12,8,1584855,2,1687455,16,1687447, +14,97,32,45,62,32,46,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,1687363,1586351,12,8,1597071, +12,8,1,1687469,14,1,1310721,2,1,26,1310721,4,18,1310721,2,169, +28,1310721,4,1310721,2,1835009,40,1687517,16,1966081,1310721,4,1579069,12,1310721,2, +4,1,1310721,2,7,26,4,1,1310721,2,9,26,4,1,1310721,2, +13,26,4,1,1310721,2,163,26,4,1,1310721,2,165,26,4,1597071, +12,8,1310721,2,3,26,1599321,12,10,3,6,10,4,8,1585009,1, +10,3,6,10,4,8,1585015,2,1598497,12,1687851,16,1597071,12,8,3, +1687823,16,1585009,2,17,40,3,36,1687731,16,1687723,14,116,111,111,32, +109,97,110,121,32,116,121,112,101,32,112,97,114,97,109,101, +116,101,114,115,0,1687673,1586063,12,8,1584993,1585009,2,26,1599321,12,10, +3,6,10,4,8,1585009,1,6,2,1,6,3,26,5,6,4, +10,8,8,1584899,2,1598801,12,1,6,1,10,28,34,63,38,3, +26,1687819,16,1687823,14,1687647,14,1635147,12,8,1310721,2,165,26,3,10, +3,6,10,4,8,1310721,2,5,26,1310721,2,3,26,2,1587809,12, +10,3,6,10,4,8,1310721,2,5,26,2,1,40,1687909,16,3, +1687947,14,1310721,2,5,26,2,1582509,2,40,1,6,1,10,28,34, +63,38,1,10,28,1687957,16,3,1688021,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,1688031,16,3,1688073,14,1442305, +1310721,2,5,26,2,26,2,3,32,1,6,1,10,28,34,63, +38,1,10,28,1688143,16,1310721,2,5,26,1310721,2,3,26,2,3, +1,1587311,12,10,3,6,10,4,8,1442305,1310721,2,5,26,2,26, +1,10,3,6,10,4,8,1584887,2,1599031,12,8,1584889,2,1598497,12, +1,6,1,10,28,34,63,38,3,26,1689487,16,3,1689487,16,1310721, +2,11,26,1,10,3,6,10,4,8,1310721,2,115,26,1310721,2, +7,26,2,26,1584975,2,10,3,6,10,4,8,1584925,2,1598497,12, +1,6,1,10,28,34,63,38,3,26,1688621,16,1582577,2,9,28, +1,6,1,10,28,34,63,38,3,26,1688431,16,1582579,2,1584911,2, +28,1,6,1,10,28,34,63,38,3,26,1688353,16,3,1688405,14, +1582579,2,1584895,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,1688433,14,1,1688443,16,3,1688595,14,1582577,2,5, +28,1,6,1,10,28,34,63,38,3,26,1688571,16,1582579,2,1584927, +2,28,1,6,1,10,28,34,63,38,3,26,1688515,16,3,1688545, +14,1582579,2,1634911,12,1,6,1,10,28,34,63,38,1,10,28, +1,6,1,10,28,34,63,38,1,10,28,1688573,14,1,1,6, +1,10,28,34,63,38,1,10,28,1,6,1,10,28,34,63, +38,1,10,28,1688623,14,1,1688809,16,1310721,2,115,26,1310721,2,7, +26,2,26,1635249,12,10,3,6,10,4,8,1310721,2,165,26,3, +10,3,6,10,4,8,1310721,2,115,26,1310721,2,7,26,2,26, +2,1629979,12,1688809,16,1688801,14,115,116,114,117,99,116,115,32,97, +110,100,32,97,114,114,97,121,115,32,97,114,101,32,112,97, +115,115,101,100,32,98,121,32,112,111,105,110,116,101,114,0, +1688719,1585679,12,8,1584925,2,1598801,12,1689015,16,1582579,2,1584941,2,28,1, +6,1,10,28,34,63,38,3,26,1688881,16,1310721,2,11,26,3, +10,3,6,10,4,8,1689009,14,1582579,2,1584943,2,28,1,6,1, +10,28,34,63,38,3,26,1688941,16,1310721,2,11,26,5,10,3, +6,10,4,8,1689009,14,1689001,14,97,32,112,97,114,97,109,101, +116,101,114,32,116,97,103,32,105,115,32,46,109,32,111,114, +32,46,100,0,1688945,1586063,12,8,1597071,12,8,1310721,2,19,26,1310721, +2,7,26,2,26,1599321,12,10,3,6,10,4,8,1310721,2,7, +26,2,25,40,3,36,1689109,16,1310721,2,11,26,2,1,6,1, +10,28,34,63,38,1,10,28,1689111,14,1,1689213,16,1689205,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,1689119,1586063,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,1689339,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,48,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,1689447,16,1689439,14,116,111,111,32,109, +97,110,121,32,112,97,114,97,109,101,116,101,114,115,0,1689399, +1586063,12,8,1584899,2,1598801,12,1,6,1,10,28,34,63,38,3, +26,1689483,16,1689487,14,1688185,14,1584889,2,1599031,12,8,1584905,2,1598801,12, +1689713,16,1584925,2,1598497,12,1,6,1,10,28,34,63,38,3,26, +1689587,16,1310721,2,163,26,1635249,12,10,3,6,10,4,8,1310721,2, +165,26,3,10,3,6,10,4,8,1584925,2,1598801,12,1689713,16,1584945, +2,1598649,12,1,6,1,10,28,34,63,38,3,26,1689685,16,1689677, +14,116,104,101,32,114,101,116,117,114,110,32,116,97,103,32, +105,115,32,46,117,0,1689635,1586063,12,8,1597071,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,1689873,16,1442305,1310721,2,5,26,2,26,2,513, +32,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1689875,14,1,1690035,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,1690031,16,1310721,2,3,26,2,1690023,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,1689947,1585849,12,8,1690323,14,1442305,1310721,2,5,26,2,26, +2,9,32,1690137,16,1310721,2,9,26,2,1690079,16,3,1690111,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,1690139,14,1,1690323,16,1310721, +2,3,26,2,1690315,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,1690157,1585849,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,1442305,1310721,2,5, +26,2,26,2,513,32,28,10,3,6,10,4,8,1585009,2,1690481, +16,1442305,1310721,2,5,26,2,26,1442305,1310721,2,5,26,2,26,2, +257,34,10,3,6,10,4,8,1310721,2,165,26,2,1690851,16,1310721, +2,163,26,2,1,6,1,10,28,34,63,38,3,26,1690553,16, +1310721,2,163,26,1584975,2,10,3,6,10,4,8,1310721,2,167,26, +1310721,2,163,26,2,1310721,2,7,26,2,1310721,2,115,26,1310721,2, +15,26,2,1625329,12,10,3,6,10,4,8,1559041,1310721,2,5,26, +2,26,2,1690711,16,1559041,1310721,2,5,26,2,26,2,1310721,2,167, +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,1690713,14,1,1690815,16,1310721,2, +3,26,2,1690807,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,1690731,1585849,12,8,1559041, +1310721,2,5,26,2,26,1310721,2,167,26,2,10,3,6,10,4, +8,1584901,2,1598801,12,1690893,16,1585009,1,10,3,6,10,4,8,1310721, +2,5,26,2,1691783,14,1442305,1310721,2,5,26,2,26,2,3,32, +1690973,16,1310721,2,3,26,2,1690965,14,105,115,32,100,101,102,105, +110,101,100,32,116,119,105,99,101,0,1690931,1585849,12,8,1425921,1310721, +2,5,26,2,26,1584837,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,1584837,2,1588737,12, +8,1450497,1310721,2,5,26,2,26,1,10,3,6,10,4,8,1310721, +2,2,1310721,2,13,26,2,1686347,12,8,1310721,2,165,26,2,1691163, +16,1584885,1310721,2,163,26,2,10,3,6,10,4,8,1686679,12,8, +1310721,2,17,26,1,10,3,6,10,4,8,1310721,2,17,26,2, +1310721,2,7,26,2,40,1691633,16,1310721,2,11,26,1310721,2,19,26, +1310721,2,17,26,2,26,2,1603891,12,10,3,6,10,4,8,1584851, +1,6,2,1,6,3,26,5,6,4,10,8,8,1556993,1310721,2, +11,26,2,26,1310721,2,115,26,1310721,2,17,26,2,26,2,10, +3,6,10,4,8,1584853,2,1691419,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,1691421,14,1,1691453,16, +1469953,1310721,2,11,26,2,26,13,10,3,6,10,4,8,1584853,2, +1691533,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,1691535,14,1,1691595,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,1691191,14,1310721,2,17,26,1310721,2,7,26, +2,10,3,6,10,4,8,1310721,2,17,26,2,1691739,16,1310721,2, +17,26,1,6,2,1,6,-1,26,5,6,4,10,8,8,1310721, +2,17,26,2,1590069,12,8,5,1589235,12,8,1691663,14,1687087,12,8, +1686903,12,8,1585009,1,10,3,6,10,4,8,1310721,2,5,26,2, +1691783,14,1,1310721,2,169,26,1310721,4,18,1310721,2,13,28,1310721,4, +1310721,2,1835009,40,1691831,16,1966081,1310721,4,1579069,12,1310721,2,4,1,1310721, +2,9,26,4,1310721,2,2,1692107,16,1637945,12,8,1310721,2,9,26, +1585011,2,10,3,6,10,4,8,1585013,2,1692001,16,1691993,14,116,97, +103,115,32,103,111,32,111,110,32,108,111,99,97,108,115,32, +97,110,100,32,112,97,114,97,109,101,116,101,114,115,44,32, +110,111,116,32,103,108,111,98,97,108,115,0,1691901,1585679,12,8, +1310721,2,9,26,2,1584983,2,28,1,6,1,10,28,34,63,38, +3,26,1692103,16,1692095,14,97,32,118,97,114,105,97,98,108,101, +32,99,97,110,39,116,32,98,101,32,118,111,105,100,0,1692045, +1585679,12,8,1692113,14,1597071,12,8,3,1693065,16,1310721,2,3,26,1599321, +12,10,3,6,10,4,8,1584895,2,1598801,12,1692441,16,1310721,2,7, +26,1665803,12,10,3,6,10,4,8,1584897,2,1599031,12,8,1310721,2, +11,26,1310721,2,3,26,2,7,1584837,2,1587311,12,10,3,6,10, +4,8,1310721,2,9,26,2,1,6,1,10,28,34,63,38,3, +26,1692287,16,1310721,2,9,26,1584975,2,10,3,6,10,4,8,1559041, +1310721,2,11,26,2,26,1310721,2,9,26,2,1310721,2,7,26,2, +1624809,12,10,3,6,10,4,8,1310721,2,7,26,1559041,1310721,2,11, +26,2,26,2,1628577,12,10,3,6,10,4,8,1310721,2,7,26, +2,1692437,16,1,1588955,12,8,1310721,2,7,26,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1692377,14,1693025,14,1310721,2,9,26, +2,1692495,16,1310721,2,9,26,2,1629979,12,1,6,1,10,28,34, +63,38,1,10,28,1692497,14,1,1692675,16,1310721,2,11,26,1310721,2, +3,26,2,7,1584837,2,1587311,12,10,3,6,10,4,8,1559041,1310721, +2,11,26,2,26,1310721,2,9,26,2,10,3,6,10,4,8, +1310721,2,7,26,1310721,2,9,26,2,1628577,12,10,3,6,10,4, +8,1310721,2,7,26,2,1692671,16,1,1588955,12,8,1310721,2,7,26, +1,6,2,1,6,-1,26,5,6,4,10,8,8,1692611,14,1693025, +14,1310721,2,5,26,1584837,2,10,3,6,10,4,8,1310721,2,11, +26,1310721,2,3,26,2,5,1310721,2,5,26,2,1587311,12,10,3, +6,10,4,8,1310721,2,9,26,2,1692795,16,1559041,1310721,2,11,26, +2,26,1310721,2,9,26,2,10,3,6,10,4,8,1,1588955,12, +8,1584903,2,1598801,12,1693025,16,1582577,2,7,28,1,6,1,10,28, +34,63,38,3,26,1692993,16,1310721,2,5,26,2,1584839,2,26,1584837, +2,10,3,6,10,4,8,1310721,2,7,26,1582579,2,10,3,6, +10,4,8,1310721,2,7,26,2,2,1692975,16,1310721,2,7,26,2, +2,1588955,12,8,1310721,2,7,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1692903,14,1,1588955,12,8,1597071,12,8,1693025,14, +1310721,2,5,26,2,1584839,2,26,1665803,12,10,3,6,10,4,8, +1584899,2,1598801,12,1,6,1,10,28,34,63,38,3,26,1693061,16, +1693065,14,1692113,14,1584901,2,1599031,12,8,1,1693083,14,1,1310721,2,13, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1693131,16, +1966081,1310721,4,1579069,12,1597071,12,8,3,1693231,16,1310721,2,1599321,12,10, +3,6,10,4,8,1584903,2,1599031,12,8,1310721,2,2,9,1665803,12, +1587311,12,8,1584899,2,1598801,12,1,6,1,10,28,34,63,38,3, +26,1693227,16,1693231,14,1693137,14,1584901,2,1599031,12,8,1,1693249,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,43,28,1310721,4,1310721,2,1835009, +40,1693297,16,1966081,1310721,4,1579069,12,1,1310721,2,3,26,4,3,1310721, +2,5,26,4,1,1310721,2,13,26,4,1,1310721,2,15,26,4, +1597071,12,8,1310721,2,1599321,12,10,3,6,10,4,8,1584887,2,1599031, +12,8,1584889,2,1598497,12,1,6,1,10,28,34,63,38,3,26, +1693655,16,3,1693655,16,1310721,2,3,26,2,17,28,1,6,1,10, +28,34,63,38,3,26,1693545,16,1693537,14,97,110,32,101,110,104, +97,110,99,101,109,101,110,116,32,116,97,107,101,115,32,97, +116,32,109,111,115,116,32,56,32,105,110,112,117,116,115,0, +1693461,1586063,12,8,1310721,2,27,26,1310721,2,3,26,2,26,1599321,12, +10,3,6,10,4,8,1310721,2,3,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1584899,2,1598801,12,1,6,1,10,28, +34,63,38,3,26,1693651,16,1693655,14,1693413,14,1584889,2,1599031,12,8, +1584905,2,1598801,12,1693897,16,1582577,2,3,28,1,6,1,10,28,34, +63,38,1,10,28,1693717,16,3,1693747,14,1582579,2,1,40,1,6, +1,10,28,34,63,38,1,10,28,1693757,16,3,1693789,14,1582579,2, +17,10,40,1,6,1,10,28,34,63,38,1,10,28,1693867,16, +1693859,14,101,120,112,101,99,116,101,100,32,116,104,101,32,110, +117,109,98,101,114,32,111,102,32,111,117,116,112,117,116,115, +0,1693797,1586063,12,8,1310721,2,5,26,1582579,2,10,3,6,10,4, +8,1597071,12,8,1310721,2,7,26,1584837,2,10,3,6,10,4,8, +1310721,2,17,26,1,10,3,6,10,4,8,1310721,2,17,26,2, +15,40,1694007,16,1,1588955,12,8,1310721,2,17,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1693943,14,1310721,2,9,26,1584837, +2,10,3,6,10,4,8,1310721,2,17,26,1,10,3,6,10, +4,8,1310721,2,17,26,2,1310721,2,3,26,2,40,1694125,16,1, +1588955,12,8,1310721,2,17,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1694053,14,1310721,2,17,26,1,10,3,6,10,4, +8,1310721,2,17,26,2,1310721,2,3,26,2,40,1694377,16,1310721,2, +9,26,2,1310721,2,17,26,2,26,1584839,2,26,1584837,2,10,3, +6,10,4,8,1310721,2,19,26,1310721,2,27,26,1310721,2,17,26, +2,26,2,10,3,6,10,4,8,1310721,2,19,26,2,2,1694331, +16,1310721,2,19,26,2,2,1588955,12,8,1310721,2,19,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1694259,14,1,1588955,12, +8,1310721,2,17,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1694147,14,1584967,2,1598801,12,1694673,16,1310721,2,11,26,1584837,2, +10,3,6,10,4,8,1582577,2,7,28,1,6,1,10,28,34, +63,38,1,10,28,1694523,16,1694515,14,101,120,112,101,99,116,101, +100,32,116,104,101,32,114,101,99,105,112,101,32,97,115,32, +97,32,115,116,114,105,110,103,0,1694451,1586063,12,8,1582577,2,7, +28,1,6,1,10,28,34,63,38,3,26,1694661,16,1310721,2,19, +26,1582579,2,10,3,6,10,4,8,1310721,2,19,26,2,2,1694651, +16,1310721,2,19,26,2,2,1588955,12,8,1310721,2,19,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1694579,14,1597071,12,8, +1694523,14,1,1588955,12,8,1694839,14,1584969,2,1598801,12,1694785,16,1310721,2, +11,26,1584837,2,10,3,6,10,4,8,1676857,12,8,19,1589235,12, +8,1310721,2,13,26,1584837,2,1310721,2,11,26,2,28,10,3,6, +10,4,8,1310721,2,15,26,3,10,3,6,10,4,8,1694839,14, +1694831,14,101,120,112,101,99,116,101,100,32,109,105,99,114,111, +32,111,114,32,118,109,0,1694789,1586063,12,8,1310721,2,23,26,1582503, +2,10,3,6,10,4,8,1310721,2,23,26,2,1025,40,3,36, +1694969,16,1694961,14,97,108,108,32,53,49,50,32,101,110,104,97, +110,99,101,109,101,110,116,32,115,108,111,116,115,32,97,114, +101,32,116,97,107,101,110,0,1694889,1585585,12,8,1582503,1,6,2, +1,6,3,26,5,6,4,10,8,8,1310721,2,19,26,1310721,2, +7,26,2,1584839,2,26,10,3,6,10,4,8,1310721,2,19,26, +2,1,26,1310721,2,23,26,2,10,3,6,10,4,8,1310721,2, +19,26,2,3,26,1310721,2,15,26,2,10,3,6,10,4,8, +1310721,2,19,26,2,5,26,1310721,2,3,26,2,10,3,6,10, +4,8,1310721,2,19,26,2,7,26,1310721,2,5,26,2,10,3, +6,10,4,8,1310721,2,19,26,2,9,26,1310721,2,11,26,2, +10,3,6,10,4,8,1310721,2,19,26,2,11,26,1310721,2,13, +26,2,10,3,6,10,4,8,1310721,2,19,26,2,13,26,1310721, +2,9,26,2,10,3,6,10,4,8,1310721,2,21,26,1310721,2, +2,13,1310721,2,23,26,2,1587311,12,10,3,6,10,4,8,1434113, +1310721,2,21,26,2,26,1310721,2,3,26,2,1310721,2,5,26,2, +33,30,26,1310721,2,7,26,2,513,30,26,10,3,6,10,4, +8,1584933,2,1598801,12,1695527,16,1310721,2,25,26,1582579,2,1587809,12,10, +3,6,10,4,8,1310721,2,25,26,2,1,40,1695481,16,1310721,2, +25,26,1582579,2,1589617,12,10,3,6,10,4,8,1597071,12,8,1450497, +1310721,2,21,26,2,26,1310721,2,25,26,2,3,26,10,3,6, +10,4,8,1584901,2,1599031,12,8,1584839,2,1,6,1,10,28,34, +63,38,3,26,1695847,16,1310721,2,25,26,1310721,2,7,26,2,1572879, +12,10,3,6,10,4,8,1310721,2,25,26,2,1,40,1695847,16, +1450497,1310721,2,21,26,2,26,2,1,6,1,10,28,34,63,38, +3,26,1695801,16,1310721,2,2,1695793,14,116,104,101,32,101,110,104, +97,110,99,101,109,101,110,116,32,100,105,100,110,39,116,32, +105,110,115,116,97,108,108,32,40,115,101,101,32,105,110,115, +116,97,108,108,39,115,32,99,111,100,101,115,32,105,110,32, +99,111,114,101,46,99,41,0,1695667,1585849,12,8,1442305,1310721,2,21, +26,2,26,1442305,1310721,2,21,26,2,26,2,129,34,10,3,6, +10,4,8,1,1695855,14,1,1310721,2,43,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1695903,16,1966081,1310721,4,1579069,12,1, +1310721,2,4,1582577,2,1,28,1,6,1,10,28,34,63,38,1, +10,28,1696731,16,1584891,2,1598497,12,1695991,16,1310721,2,1,6,2,1, +6,3,26,5,6,4,10,8,8,1696721,14,1584893,2,1598497,12,1696069, +16,1310721,2,1,6,2,1,6,-1,26,5,6,4,10,8,8, +1310721,2,2,1,40,1696065,16,1310721,2,1,10,3,6,10,4,8, +1696721,14,1310721,2,2,1,6,1,10,28,34,63,38,3,26,1696153, +16,1582577,2,5,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1696155,14,1,1696711,16,1582579, +2,1584927,2,28,1,6,1,10,28,34,63,38,3,26,1696199,16, +3,1696251,14,1582579,2,1584929,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1696261,16,3, +1696313,14,1582579,2,1584931,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1696323,16,3,1696375, +14,1582579,2,1585031,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1696385,16,3,1696437,14, +1582579,2,1585033,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1696447,16,3,1696499,14,1582579, +2,1584965,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1696509,16,3,1696561,14,1582579,2, +1585035,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1696571,16,3,1696623,14,1582579,2,1584937, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1696633,16,3,1696685,14,1582579,2,1584939,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,1696713,14,1,1696721,16,1696731,14,1597071,12,8,1695911,14,1585091,1,10, +3,6,10,4,8,1,1696755,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,1835009,40,1696803,16,1966081,1310721,4,1579069, +12,3,1310721,2,4,1,1310721,2,3,26,4,1585091,2,1696839,16,1695869, +12,1697853,14,1584937,2,1598649,12,1696909,16,1597071,12,8,1584901,2,1598801,12, +1696891,16,1582575,1,10,3,6,10,4,8,1,1697853,14,1310721,2,1, +10,3,6,10,4,8,1584939,2,1598649,12,1696949,16,1597071,12,8,1310721, +2,3,26,3,10,3,6,10,4,8,1584927,2,1598649,12,1697235,16, +1310721,2,5,26,1310721,2,2,1687483,12,10,3,6,10,4,8,1310721, +2,3,26,2,1697229,16,1584839,2,1697131,16,1697123,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,1697017,1585679,12,8,1310721,2,7,26,1409537,1310721,2,5,26,2,26, +2,11,1425921,1310721,2,5,26,2,26,2,1587311,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,1697853,14,1310721,2,2,1,6,1,10, +28,34,63,38,3,26,1697271,16,3,1697303,14,1310721,2,3,26,2, +1,6,1,10,28,34,63,38,1,10,28,1697349,16,1697335,14,101, +120,112,101,99,116,101,100,32,102,110,0,1697311,1586063,12,8,1, +1697853,14,1584929,2,1598649,12,1697371,16,1,1691797,12,1697853,14,1585031,2,1598649, +12,1697395,16,1638319,12,8,1,1697853,14,1585033,2,1598649,12,1697415,16,1640225, +12,1697853,14,1585035,2,1598649,12,1697435,16,1640345,12,1697853,14,1584965,2,1598649, +12,1697455,16,1693263,12,1697853,14,1584931,2,1598649,12,1697475,16,1693097,12,1697853, +14,1582577,2,5,28,1,6,1,10,28,34,63,38,3,26,1697705, +16,1310721,2,5,26,1582579,2,1587809,12,10,3,6,10,4,8,1310721, +2,5,26,2,1,40,3,36,1697623,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,1697625,14,1,1697675,16,1442305,1310721, +2,5,26,2,26,2,65,32,1,6,1,10,28,34,63,38, +1,10,28,1697677,14,1,1697705,16,1310721,2,5,26,2,1,1647877,12, +8,1,1697853,14,1637143,12,1697723,16,3,1691797,12,1697853,14,1697837,14,101, +120,112,101,99,116,101,100,32,102,110,44,32,108,101,116,44, +32,99,111,110,115,116,44,32,115,116,114,117,99,116,44,32, +116,121,112,101,32,111,114,32,97,32,100,101,99,108,97,114, +97,116,105,111,110,0,1697727,1586063,12,8,1,1697853,14,1,1310721,2, +9,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1697901, +16,1966081,1310721,4,1579069,12,1582577,2,1,28,1,6,1,10,28,34, +63,38,1,10,28,1697945,16,1696769,12,8,1697901,14,1,1697953,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1698001,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2,1310721,2, +3,26,4,1585091,1,10,3,6,10,4,8,1310721,2,3,26,2, +1582507,2,40,1698371,16,1417729,1310721,2,3,26,2,26,2,3,28,1, +6,1,10,28,34,63,38,3,26,1698169,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,1698171,14,1,1698217,16,1450497, +1310721,2,3,26,2,26,2,1,6,1,10,28,34,63,38,1, +10,28,1698219,14,1,1698333,16,1582583,1425921,1310721,2,3,26,2,26,2, +10,3,6,10,4,8,1409537,1310721,2,3,26,2,26,2,1698325,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,1698273,1585849,12,8,1310721,2, +3,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1698039, +14,1585089,2,1698385,16,1585397,12,8,1,1698393,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1698441,16,1966081, +1310721,4,1579069,12,1310721,2,3,26,4,1310721,2,4,3,1,10,28, +1310721,2,5,26,4,1,1310721,2,7,26,4,1582507,2,1310721,2,9, +26,4,1684867,12,8,1584865,2,1698547,16,1310721,2,5,26,1589535,12,10, +3,6,10,4,8,15,1589235,12,8,1310721,2,3,26,2,1698575,16, +3,1310721,2,2,1684251,12,8,3,1310721,2,2,1,1,1590943,12,8, +1597071,12,8,1310721,2,3,26,2,1698623,16,1697867,12,8,1698777,14,1310721, +2,7,26,1584837,2,10,3,6,10,4,8,3,1,1686347,12,8, +1686679,12,8,1582577,2,1,28,1,6,1,10,28,34,63,38,1, +10,28,1698707,16,1666771,12,8,1698663,14,1584847,2,1606191,12,8,1584853,2, +1698755,16,1584857,2,1,6,1,10,28,34,63,38,1,10,28,1698757, +14,1,1698771,16,3,3,1605463,12,8,1686903,12,8,1592371,12,8,1310721, +2,9,26,2,1697967,12,8,1310721,2,5,26,2,1,40,3,36, +1698841,16,1310721,2,5,26,2,1584837,2,1589317,12,8,1584837,2,1584843,2, +10,40,1698875,16,1584843,1584837,2,10,3,6,10,4,8,1685643,12,8, +1310721,2,7,26,2,1698897,14,1,1310721,2,11,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1698945,16,1966081,1310721,4,1579069,12, +1310721,2,4,1310721,2,2,1,1698407,12,1698969,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1699017,16,1966081, +1310721,4,1579069,12,1310721,2,4,1310721,2,2,3,1698407,12,8,1,1699045, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1699093,16,1966081,1310721,4,1579069,12,1310721,2,4,1310721,2,2, +1,1698407,12,1310721,2,3,26,4,1310721,2,3,26,2,1,6,12, +10,8,1699147,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28, +1310721,4,1310721,2,1835009,40,1699195,16,1966081,1310721,4,1579069,12,1310721,2,4, +1310721,2,2,1680951,12,1310721,2,3,26,4,1310721,2,3,26,2,1699059, +12,1310721,2,5,26,4,1310721,2,3,26,2,1580623,12,8,1310721,2, +5,26,2,1699277,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7, +28,1310721,4,1310721,2,1835009,40,1699325,16,1966081,1310721,4,1579069,12,1310721,2, +4,1310721,2,2,1310721,2,3,26,4,1310721,2,3,26,2,1582507,2, +40,1699745,16,1417729,1310721,2,3,26,2,26,2,3,40,3,36,1699447, +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,1699449,14,1,1699459,16,3,1699521, +14,1417729,1310721,2,3,26,2,26,2,13,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1699707,16,1417729,1310721,2,3,26,2,26,2,1588955,12,8,1425921,1310721,2, +3,26,2,26,2,1588955,12,8,1434113,1310721,2,3,26,2,26,2, +1588955,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,1699699,16,1310721,2,5, +26,2,2,1588955,12,8,1310721,2,5,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1699627,14,1,1588955,12,8,1310721,2,3, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1699347,14, +1,1588955,12,8,1,1699761,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,1835009,40,1699809,16,1966081,1310721,4,1579069,12, +1310721,2,4,1310721,2,2,2,1700157,16,1310721,2,5,26,1310721,2,2, +7,26,1586793,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,1587311, +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,2,1,26,2, +13,28,1,6,1,10,28,34,63,38,3,26,1700107,16,1310721,2, +2,3,26,2,1582503,2,40,3,36,1700085,16,1582503,1310721,2,2,3, +26,2,3,26,10,3,6,10,4,8,1310721,2,2,5,26,2, +17,38,1572879,12,8,1310721,2,1310721,2,2,7,26,1310721,2,2,7, +26,1573885,12,26,3,26,10,3,6,10,4,8,1699815,14,1,1700165, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,21,28,1310721,4,1310721, +2,1835009,40,1700213,16,1966081,1310721,4,1579069,12,1310721,2,3,26,4,1310721, +2,4,1584837,2,1310721,2,5,26,4,1584839,2,1310721,2,7,26,4, +1584841,2,1310721,2,9,26,4,1582509,2,1310721,2,11,26,4,1582511,2, +1310721,2,13,26,4,1582507,2,1310721,2,15,26,4,1582503,2,1310721,2, +17,26,4,1582509,1582507,2,10,3,6,10,4,8,1582511,1582507,2,10, +3,6,10,4,8,1582503,1,10,3,6,10,4,8,1584837,1310721,2, +2,10,3,6,10,4,8,1584839,1310721,2,3,26,2,1310721,2,2, +28,10,3,6,10,4,8,1584841,1310721,2,2,393217,26,10,3,6, +10,4,8,1966081,1589149,12,8,1310721,1589149,12,8,5,1589235,12,8,1584955, +2,1589617,12,1589741,12,8,15,1589235,12,8,1,1588955,12,8,1,1588955, +12,8,1684729,12,8,1310721,2,3,26,2,11,26,1584837,2,10,3, +6,10,4,8,1582509,2,1699291,12,8,1310721,2,3,26,2,13,26, +1584837,2,10,3,6,10,4,8,1310721,2,19,26,1584837,2,1310721,2, +2,28,10,3,6,10,4,8,1310721,2,15,26,2,1588157,12,8, +1582509,1310721,2,11,26,2,10,3,6,10,4,8,1582511,1310721,2,13, +26,2,10,3,6,10,4,8,1584837,1310721,2,5,26,2,10,3, +6,10,4,8,1584839,1310721,2,7,26,2,10,3,6,10,4,8, +1584841,1310721,2,9,26,2,10,3,6,10,4,8,1582503,1310721,2,17, +26,2,10,3,6,10,4,8,1310721,2,19,26,2,1700801,14,1, +1310721,2,21,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009, +40,1700849,16,1966081,1310721,4,1579069,12,1,1584843,2,1581139,12,8,1584839,2, +1,6,1,10,28,34,63,38,3,26,1700927,16,1584837,2,1584843,2, +10,40,1,6,1,10,28,34,63,38,1,10,28,1700929,14,1, +1700947,16,1584843,2,1584837,2,1581139,12,8,1572865,1572865,13,26,2,1581139,12, +8,1540609,1540609,2049,26,1581139,12,8,1310721,2,1966081,1581139,12,8,2064385,2097121, +1581139,12,8,1,1701007,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +1,28,1310721,4,1310721,2,1835009,40,1701055,16,1966081,1310721,4,1579069,12,1582505, +1327617,10,3,6,10,4,8,1311233,1,16385,1574549,12,8,1582507,1,10, +3,6,10,4,8,1582513,1,10,3,6,10,4,8,1582515,1,10, +3,6,10,4,8,1582517,1,10,3,6,10,4,8,1582519,1,10, +3,6,10,4,8,1582521,1,10,3,6,10,4,8,1582523,1,10, +3,6,10,4,8,1582525,1,10,3,6,10,4,8,1584867,1,10, +3,6,10,4,8,1584871,1,10,3,6,10,4,8,1584873,1,10, +3,6,10,4,8,1584845,1,10,3,6,10,4,8,1584847,1,10, +3,6,10,4,8,1584887,1701301,14,40,0,1701297,1586793,12,10,3,6, +10,4,8,1584889,1701329,14,41,0,1701325,1586793,12,10,3,6,10,4, +8,1584891,1701357,14,123,0,1701353,1586793,12,10,3,6,10,4,8,1584893, +1701385,14,125,0,1701381,1586793,12,10,3,6,10,4,8,1584895,1701413,14, +91,0,1701409,1586793,12,10,3,6,10,4,8,1584897,1701441,14,93,0, +1701437,1586793,12,10,3,6,10,4,8,1584899,1701469,14,44,0,1701465,1586793, +12,10,3,6,10,4,8,1584901,1701497,14,59,0,1701493,1586793,12,10, +3,6,10,4,8,1584903,1701525,14,61,0,1701521,1586793,12,10,3,6, +10,4,8,1584905,1701555,14,45,62,0,1701549,1586793,12,10,3,6,10, +4,8,1584907,1701585,14,43,43,0,1701579,1586793,12,10,3,6,10,4, +8,1584909,1701615,14,45,45,0,1701609,1586793,12,10,3,6,10,4,8, +1584911,1701643,14,42,0,1701639,1586793,12,10,3,6,10,4,8,1584913,1701671, +14,38,0,1701667,1586793,12,10,3,6,10,4,8,1584915,1701699,14,58, +0,1701695,1586793,12,10,3,6,10,4,8,1584917,1701727,14,35,0,1701723, +1586793,12,10,3,6,10,4,8,1584919,1701755,14,45,0,1701751,1586793,12, +10,3,6,10,4,8,1584925,1701783,14,46,0,1701779,1586793,12,10,3, +6,10,4,8,1584947,1701811,14,63,0,1701807,1586793,12,10,3,6,10, +4,8,1584949,1701845,14,99,97,115,101,0,1701835,1586793,12,10,3,6, +10,4,8,1584951,1701885,14,100,101,102,97,117,108,116,0,1701869,1586793, +12,10,3,6,10,4,8,1584921,1701915,14,38,38,0,1701909,1586793,12, +10,3,6,10,4,8,1584923,1701945,14,124,124,0,1701939,1586793,12,10, +3,6,10,4,8,1584927,1701975,14,102,110,0,1701969,1586793,12,10,3, +6,10,4,8,1584929,1702007,14,108,101,116,0,1701999,1586793,12,10,3, +6,10,4,8,1584931,1702043,14,99,111,110,115,116,0,1702031,1586793,12, +10,3,6,10,4,8,1584933,1702077,14,101,108,115,101,0,1702067,1586793, +12,10,3,6,10,4,8,1584935,1702107,14,97,115,0,1702101,1586793,12, +10,3,6,10,4,8,1584937,1702151,14,117,110,99,104,101,99,107, +101,100,0,1702131,1586793,12,10,3,6,10,4,8,1584939,1702195,14,105, +109,109,101,100,105,97,116,101,0,1702175,1586793,12,10,3,6,10, +4,8,1584941,1702223,14,109,0,1702219,1586793,12,10,3,6,10,4,8, +1584943,1702251,14,100,0,1702247,1586793,12,10,3,6,10,4,8,1584945,1702279, +14,117,0,1702275,1586793,12,10,3,6,10,4,8,1584955,1702315,14,115, +116,97,114,116,0,1702303,1586793,12,10,3,6,10,4,8,1584957,1702349, +14,109,97,105,110,0,1702339,1586793,12,10,3,6,10,4,8,1584959, +1702383,14,102,114,101,101,0,1702373,1586793,12,10,3,6,10,4,8, +1584961,1702415,14,111,119,110,0,1702407,1586793,12,10,3,6,10,4,8, +1584963,1702449,14,113,110,101,119,0,1702439,1586793,12,10,3,6,10,4, +8,1584953,1702503,14,102,114,97,109,101,95,111,118,101,114,102,108, +111,119,0,1702473,1586793,12,10,3,6,10,4,8,1584965,1702543,14,101, +110,104,97,110,99,101,0,1702527,1586793,12,10,3,6,10,4,8, +1584967,1702579,14,109,105,99,114,111,0,1702567,1586793,12,10,3,6,10, +4,8,1584969,1702609,14,118,109,0,1702603,1586793,12,10,3,6,10,4, +8,1,1702635,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28, +1310721,4,1310721,2,1835009,40,1702683,16,1966081,1310721,4,1579069,12,1702691,14,33, +0,1702687,1702739,14,48,32,36,32,48,32,126,32,45,32,124,32, +51,49,32,62,32,49,32,43,0,1702697,1603187,12,8,1702757,14,33, +33,0,1702751,1702809,14,48,32,36,32,48,32,126,32,45,32,124, +32,51,49,32,62,32,48,32,126,32,45,0,1702763,1603187,12,8, +1702825,14,126,0,1702821,1702841,14,45,49,32,94,0,1702831,1603187,12,8, +1702857,14,45,0,1702853,1702875,14,48,32,126,32,45,0,1702863,1603187,12, +8,1702891,14,42,0,1702887,21,1702903,14,42,0,1702899,1602147,12,8,1702919, +14,47,0,1702915,21,1702937,14,105,100,105,118,0,1702927,1602147,12,8, +1702953,14,37,0,1702949,21,1702971,14,105,109,111,100,0,1702961,1602147,12, +8,1702987,14,43,0,1702983,19,1702999,14,43,0,1702995,1602147,12,8,1703015, +14,45,0,1703011,19,1703027,14,45,0,1703023,1602147,12,8,1703045,14,60, +60,0,1703039,17,1703063,14,105,115,104,108,0,1703053,1602147,12,8,1703081, +14,62,62,0,1703075,17,1703093,14,62,0,1703089,1602147,12,8,1703109,14, +60,0,1703105,15,1703121,14,60,0,1703117,1602147,12,8,1703137,14,62,0, +1703133,15,1703153,14,126,32,60,0,1703145,1602147,12,8,1703171,14,60,61, +0,1703165,15,1703195,14,126,32,60,32,49,32,94,0,1703179,1602147,12, +8,1703213,14,62,61,0,1703207,15,1703233,14,60,32,49,32,94,0, +1703221,1602147,12,8,1703251,14,61,61,0,1703245,13,1703305,14,45,32,48, +32,36,32,48,32,126,32,45,32,124,32,51,49,32,62,32, +49,32,43,0,1703259,1602147,12,8,1703323,14,33,61,0,1703317,13,1703381, +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,1703331,1602147,12,8,1703397,14, +38,0,1703393,11,1703409,14,38,0,1703405,1602147,12,8,1703425,14,94,0, +1703421,9,1703437,14,94,0,1703433,1602147,12,8,1703453,14,124,0,1703449,7, +1703465,14,124,0,1703461,1602147,12,8,1703483,14,38,38,0,1703477,3,1, +10,28,1,1602147,12,8,1703511,14,124,124,0,1703505,5,1,10,28, +1,1602147,12,8,1584903,2,1601319,12,8,1584905,2,1601319,12,8,1584907,2, +1601319,12,8,1584909,2,1601319,12,8,1703581,14,108,101,116,0,1703573,1668993, +17,1603521,12,8,1703603,14,105,102,0,1703597,1669065,17,1603521,12,8,1703631, +14,119,104,105,108,101,0,1703619,1671631,17,1603521,12,8,1703655,14,102, +111,114,0,1703647,1672243,17,1603521,12,8,1703685,14,115,119,105,116,99, +104,0,1703671,1674813,17,1603521,12,8,1703713,14,98,114,101,97,107,0, +1703701,1673347,17,1603521,12,8,1703747,14,99,111,110,116,105,110,117,101, +0,1703729,1673773,17,1603521,12,8,1703777,14,114,101,116,117,114,110,0, +1703763,1676117,17,1603521,12,8,1703813,14,117,110,99,104,101,99,107,101, +100,0,1703793,1676737,17,1603521,12,8,1703837,14,97,115,109,0,1703829,1679427, +17,33,34,1603521,12,8,1703869,14,113,117,111,116,101,0,1703857,1680677, +33,1603521,12,8,1703899,14,115,105,122,101,111,102,0,1703885,1641141,33, +1603521,12,8,1703929,14,116,121,112,101,111,102,0,1703915,1641257,33,1603521, +12,8,1,1703949,14,1,1310721,2,1,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1703997,16,1966081,1310721,4,1579069,12,1577079,12, +8,1701021,12,8,1572865,11,26,2,1699775,12,8,1702649,12,8,1641369,12, +8,1584837,1,10,3,6,10,4,8,1584839,1,10,3,6,10,4, +8,1584841,524289,10,3,6,10,4,8,1584843,1,10,3,6,10,4, +8,1582509,1582507,2,10,3,6,10,4,8,1582511,1,10,3,6,10, +4,8,1684729,12,8,1584837,2,1584843,2,10,40,1704173,16,1584843,1584837,2, +10,3,6,10,4,8,1310721,2,1584957,2,1587809,12,10,3,6,10, +4,8,1310721,2,2,1,40,3,36,1704277,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,1704279,14,1,1704325,16,1442305,1310721,2, +2,26,2,3,32,1,6,1,10,28,34,63,38,1,10,28, +1704327,14,1,1704385,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, +1573283,12,8,1,1704399,14,1,1310721,2,5,26,1310721,4,18,1,851981, +0,115,116,97,114,116,0,1,786439,2,105,110,115,116,97,108, +108,0,1,786550,2,112,117,116,99,0,1,786585,0,103,101,116, +99,0,1,786613,0,101,111,102,0,1,786641,0,104,97,108,116, +0,1,786670,2,112,117,116,115,0,1,786751,2,112,117,116,110, +0,1,786942,2,115,116,114,108,101,110,0,1,787014,4,115,116, +114,101,113,0,1,787168,6,119,99,111,112,121,0,1,787274,6, +119,102,105,108,108,0,1,787406,4,122,117,100,105,118,0,1, +787637,4,122,100,105,118,0,1,787825,4,122,109,111,100,0,1, +787920,4,122,115,104,108,0,1,788005,2,116,111,112,115,105,122, +101,0,1,788181,4,102,112,117,115,104,0,1,788305,4,102,117, +110,108,105,110,107,0,1,788418,4,109,107,98,108,111,99,107, +0,1,788539,0,104,101,97,112,95,105,110,105,116,0,1,788770, +2,98,97,108,108,111,99,0,1,789007,2,98,102,114,101,101, +0,1,789405,2,105,115,111,98,106,0,1,789534,0,102,114,97, +109,101,95,111,118,101,114,102,108,111,119,0,1,789597,0,111, +111,109,0,1,789658,5,110,101,119,95,116,0,1,789961,3,110, +101,119,0,1,789997,2,111,115,105,122,101,0,1,790058,2,116, +121,112,101,111,102,95,111,98,106,0,1,790117,2,114,101,108, +101,97,115,101,0,1,790311,130,102,114,101,101,0,1,790355,4, +111,119,110,0,1,790423,2,109,97,114,107,0,1,790569,4,109, +97,114,107,114,97,110,103,101,0,1,790640,0,100,114,97,105, +110,0,1,850407,0,103,99,95,114,111,111,116,115,0,1,790722, +0,103,99,0,1,791040,0,108,105,118,101,95,111,98,106,101, +99,116,115,0,1,791136,0,108,97,114,103,101,115,116,95,102, +114,101,101,0,1,792546,0,101,114,114,97,116,0,1,792618,0, +101,114,114,101,110,100,0,1,792698,0,103,105,118,101,117,112, +0,1,792792,2,102,97,116,97,108,0,1,792839,2,115,101,114, +114,0,1,792924,4,115,101,114,114,110,0,1,793031,2,100,105, +101,0,1,793098,4,100,105,101,110,0,1,793175,2,99,101,114, +114,0,1,793234,4,99,101,114,114,110,0,1,793306,2,104,97, +115,104,115,0,1,793396,2,105,110,116,101,114,110,0,1,793655, +6,97,100,100,115,121,109,0,1,793904,2,108,111,111,107,117, +112,0,1,794078,2,112,111,112,115,121,109,115,0,1,794155,2, +108,111,111,107,117,112,115,0,1,794192,4,102,105,120,110,101, +119,0,1,794368,4,102,105,120,97,108,108,0,1,794477,2,101, +109,105,116,0,1,794574,2,108,105,116,0,1,794617,2,111,112, +0,1,794658,4,115,101,116,108,105,116,0,1,794726,2,106,109, +112,0,1,794767,0,104,111,108,101,0,1,794808,2,102,119,100, +102,110,0,1,794870,2,102,110,114,101,102,0,1,794957,2,99, +97,108,108,110,97,109,101,0,1,795034,2,108,97,100,100,114, +0,1,795088,2,115,116,114,108,105,116,0,1,795194,0,110,101, +120,116,99,104,0,1,795471,8,115,114,99,95,112,117,115,104, +0,1,796185,0,115,114,99,95,112,111,112,0,1,796526,2,105, +115,111,112,99,104,0,1,796637,4,111,112,112,114,101,102,105, +120,0,1,796880,2,105,115,100,105,103,0,1,796941,2,105,115, +97,108,0,1,797080,2,104,101,120,118,0,1,797212,0,101,115, +99,99,104,0,1,797386,2,111,112,108,101,120,0,1,797531,0, +108,101,120,0,1,798535,0,110,101,120,116,0,1,798734,2,112, +101,101,107,97,116,0,1,798965,0,112,101,101,107,0,1,798995, +0,110,101,120,116,48,0,1,799248,2,105,115,95,111,112,0, +1,799324,2,105,115,95,105,100,0,1,799400,2,97,99,99,101, +112,116,0,1,799515,2,101,120,112,101,99,116,0,1,799660,0, +110,97,109,101,0,1,799737,2,115,101,113,97,115,109,0,1, +800306,2,109,110,101,109,105,100,120,0,1,800408,4,101,109,105, +116,115,101,113,0,1,800659,2,97,100,100,107,111,112,0,1, +800779,2,98,105,110,102,105,110,100,0,1,800877,2,117,110,102, +105,110,100,0,1,800975,2,97,115,103,102,105,110,100,0,1, +801073,6,97,100,100,95,98,105,110,111,112,0,1,801593,4,97, +100,100,95,117,110,111,112,0,1,801760,6,97,100,100,95,107, +119,0,1,801843,2,102,105,110,100,108,111,99,0,1,801945,2, +110,101,119,108,111,99,0,1,802176,2,108,114,111,111,116,0, +1,802245,2,116,114,97,99,107,101,100,0,1,802294,2,116,111, +117,99,104,0,1,802538,2,112,108,97,105,110,117,115,101,0, +1,802678,2,102,114,101,101,118,97,114,0,1,802731,4,101,120, +105,116,95,118,97,114,115,0,1,803095,2,117,110,117,115,101, +100,95,99,104,101,99,107,0,1,803244,2,98,108,111,99,107, +95,99,108,111,115,101,0,1,803380,0,115,110,97,112,95,112, +117,115,104,0,1,803655,2,115,110,97,112,95,112,111,112,0, +1,803696,2,115,110,97,112,95,114,101,115,116,111,114,101,0, +1,803915,2,101,109,112,116,121,0,1,803991,2,115,110,97,112, +95,99,109,112,0,1,804396,2,115,116,97,116,101,110,97,109, +101,0,1,804614,6,109,101,114,103,101,95,101,114,114,0,1, +804880,4,106,115,116,0,1,804955,4,106,111,119,0,1,805011,4, +106,104,109,0,1,805067,2,101,120,105,116,95,114,101,99,0, +1,805363,2,106,97,100,100,0,1,805467,6,106,115,97,109,101, +0,1,805727,4,106,111,105,110,0,1,806519,6,102,105,120,117, +112,115,0,1,806766,2,98,97,99,107,101,100,103,101,0,1, +807557,12,106,111,105,110,50,0,1,807844,4,114,101,99,97,115, +116,0,1,808380,4,97,114,103,99,104,101,99,107,0,1,809146, +2,101,109,105,116,111,119,110,0,1,809195,6,97,115,115,105, +103,110,99,104,101,99,107,0,1,810964,2,114,101,116,99,104, +101,99,107,0,1,811455,2,104,97,110,100,117,112,0,1,811813, +2,100,105,115,99,97,114,100,0,1,811936,2,116,97,108,108, +111,99,0,1,812043,8,116,110,101,119,0,1,812217,2,116,112, +116,114,0,1,812404,4,116,97,114,114,0,1,812664,8,116,102, +110,0,1,813125,4,116,118,97,114,0,1,813321,6,116,105,110, +115,116,0,1,813752,2,116,114,101,115,111,108,118,101,0,1, +814288,2,116,115,122,0,1,814374,4,115,117,98,115,116,0,1, +814873,2,105,115,110,117,109,0,1,814989,2,105,115,97,103,103, +0,1,815071,2,105,115,112,116,114,0,1,815153,2,100,101,99, +97,121,0,1,815216,2,116,101,108,101,109,0,1,815310,4,99, +111,109,112,97,116,0,1,815795,6,117,110,105,102,121,0,1, +816340,2,116,112,114,105,110,116,0,1,816962,6,116,99,101,114, +114,0,1,817162,6,116,99,110,101,101,100,0,1,817357,2,116, +112,102,105,110,100,0,1,817455,2,105,115,116,121,112,101,110, +97,109,101,0,1,817573,0,99,108,111,115,101,97,110,103,108, +101,0,1,817624,0,112,116,121,112,101,0,1,818571,0,116,115, +116,97,114,116,0,1,818972,0,100,116,121,112,101,0,1,819159, +0,107,119,95,115,116,114,117,99,116,0,1,820112,0,107,119, +95,116,121,112,101,0,1,820172,0,107,119,95,116,121,112,101, +99,104,101,99,107,0,1,820279,4,116,102,105,110,100,102,105, +101,108,100,0,1,820403,0,116,121,112,101,97,114,103,0,1, +820570,0,107,119,95,115,105,122,101,111,102,0,1,820628,0,107, +119,95,116,121,112,101,111,102,0,1,820684,0,116,121,112,101, +115,95,105,110,105,116,0,1,821266,2,105,115,110,117,109,111, +112,0,1,821359,6,98,105,110,116,121,112,101,0,1,822752,2, +116,107,105,110,100,0,1,822788,2,116,115,105,122,101,0,1, +822823,2,116,110,97,109,101,0,1,822859,2,116,108,101,110,0, +1,822895,2,116,110,102,105,101,108,100,115,0,1,822937,4,116, +102,110,97,109,101,0,1,822993,4,116,102,116,121,112,101,0, +1,823051,4,116,102,111,102,102,0,1,823109,2,116,114,101,116, +0,1,823145,2,116,110,112,97,114,97,109,115,0,1,823181,4, +116,112,97,114,97,109,0,1,823228,4,116,112,97,114,97,109, +116,97,103,0,1,823285,2,116,114,101,116,117,0,1,823323,2, +116,110,97,114,103,115,0,1,823418,4,116,97,114,103,0,1, +823468,2,115,105,103,111,102,0,1,823779,2,115,105,103,111,102, +115,0,1,823878,0,114,118,97,108,0,1,823938,4,107,119,99, +97,108,108,0,1,824084,0,115,116,109,116,111,110,108,121,0, +1,824162,6,97,114,103,115,0,1,824435,0,110,101,119,116,121, +112,101,100,0,1,824605,2,99,97,108,108,0,1,825172,2,101, +110,104,99,97,108,108,0,1,825541,0,112,114,105,109,97,114, +121,0,1,826961,4,105,110,99,100,101,99,0,1,827385,2,102, +105,101,108,100,0,1,828061,0,112,111,115,116,102,105,120,0, +1,829055,0,117,110,97,114,121,0,1,829894,2,98,105,110,0, +1,830399,0,115,116,111,114,101,107,101,101,112,0,1,830447,2, +116,101,114,110,97,114,121,0,1,831097,0,101,120,112,114,0, +1,831870,0,115,116,109,116,115,116,97,114,116,0,1,832117,0, +98,108,111,99,107,101,120,112,114,0,1,832493,0,99,112,114, +105,109,0,1,832901,0,99,101,120,112,114,0,1,833258,0,114, +101,115,121,110,99,0,1,833385,0,115,116,109,116,0,1,833653, +0,98,108,111,99,107,0,1,833781,0,115,117,98,115,116,109, +116,0,1,833861,2,108,111,99,97,108,100,101,99,108,0,1, +834496,0,107,119,95,118,97,114,0,1,834532,0,107,119,95,105, +102,0,1,835078,4,108,111,111,112,95,112,117,115,104,0,1, +835285,4,108,111,111,112,95,101,110,100,0,1,835815,0,107,119, +95,119,104,105,108,101,0,1,836121,0,107,119,95,102,111,114, +0,1,836673,0,107,119,95,98,114,101,97,107,0,1,836886,0, +107,119,95,99,111,110,116,105,110,117,101,0,1,837173,4,99, +97,115,101,98,111,100,121,0,1,837406,0,107,119,95,115,119, +105,116,99,104,0,1,838058,0,107,119,95,114,101,116,117,114, +110,0,1,838368,0,107,119,95,117,110,99,104,101,99,107,101, +100,0,1,838428,0,97,115,109,98,108,111,99,107,0,1,839713, +0,107,119,95,97,115,109,0,1,839755,1,103,114,97,98,0, +1,840095,3,113,110,101,119,0,1,840173,67,113,100,117,112,0, +1,840251,68,119,99,111,112,121,116,111,0,1,840338,0,107,119, +95,113,117,111,116,101,0,1,840475,3,116,111,107,101,110,115, +0,1,840715,130,102,101,101,100,0,1,840758,0,114,101,97,100, +115,114,99,0,1,841180,0,112,115,107,105,112,97,110,103,108, +101,0,1,841312,0,112,114,101,115,99,97,110,95,102,110,0, +1,842125,4,112,114,101,115,99,97,110,0,1,842364,0,117,110, +105,116,95,115,116,100,105,110,0,1,842433,0,99,116,120,95, +112,117,115,104,0,1,842821,0,99,116,120,95,112,111,112,0, +1,843173,4,102,110,95,98,101,103,105,110,0,1,843339,0,112, +114,111,108,111,103,117,101,0,1,843451,0,101,112,105,108,111, +103,117,101,0,1,843543,0,98,111,100,121,0,1,843741,2,102, +110,100,101,102,0,1,845898,2,103,100,101,99,108,0,1,846548, +0,103,99,111,110,115,116,0,1,846631,0,101,110,104,100,101, +102,0,1,847934,0,116,111,112,115,121,110,99,0,1,848384,0, +116,111,112,105,116,101,109,0,1,848933,0,117,110,105,116,95, +116,111,112,0,1,848983,2,117,110,105,116,95,101,110,100,0, +1,849203,4,99,111,109,112,105,108,101,95,108,105,115,116,0, +1,849455,2,99,111,109,112,105,108,101,0,1,849491,2,108,111, +97,100,0,1,849529,2,101,118,97,108,0,1,849580,2,101,118, +97,108,115,0,1,849645,2,98,108,111,98,95,101,109,105,116, +0,1,849887,2,98,108,111,98,95,108,111,97,100,0,1,850089, +4,98,117,105,108,100,95,105,109,97,103,101,0,1,850510,0, +122,99,95,105,110,105,116,0,1,851324,0,122,99,95,116,97, +98,108,101,115,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,6,0,201337106,105,100,105,118,0,6,1,201343762,105,109,111, +100,0,6,2,201350418,105,115,104,108,0,3,787373,0,112,111,119, +50,0,2,787405,0,122,114,101,109,0,4,6,0,72,68,82, +0,2,787969,0,104,98,117,109,112,0,3,787970,0,102,114,101, +101,108,0,2,788002,0,103,99,95,114,117,110,115,0,2,788003, +0,103,99,95,102,114,101,101,100,0,2,788004,0,103,99,95, +97,117,116,111,0,2,789006,0,102,101,110,100,0,2,790419,0, +109,115,95,116,111,112,0,2,790420,0,109,115,95,111,118,101, +114,0,2,790421,0,103,99,95,108,111,0,2,790422,0,103,99, +95,104,105,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,6,0,75,95, +69,78,72,0,4,7,0,75,95,84,89,80,69,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,64,0,70,95,70, +65,76,76,66,65,67,75,0,4,128,0,70,95,71,69,78, +0,4,256,0,70,95,80,82,69,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,20,0,79,95,76,84,0,4,22,0,88,79,80,48,0, +4,-2,0,83,69,81,82,69,70,0,2,791251,0,110,101,110, +104,0,2,791252,0,112,111,111,108,116,111,112,0,2,791253,0, +110,115,121,109,0,2,791254,0,117,98,97,115,101,0,2,791255, +0,118,105,115,108,111,0,2,791256,0,110,102,105,120,117,0, +2,791257,0,102,105,120,102,114,101,101,0,2,791258,0,110,98, +105,110,0,2,791259,0,110,117,110,0,2,791260,0,110,97,115, +103,0,2,791261,0,110,107,111,112,0,2,791262,0,115,101,113, +116,111,112,0,2,791263,0,109,110,101,109,0,2,791287,0,99, +104,101,99,107,95,111,110,0,2,791288,0,116,107,0,2,791289, +0,116,118,0,2,791290,0,116,103,108,117,101,0,2,791291,0, +116,108,105,110,101,0,2,791292,0,108,105,110,101,0,2,791293, +0,99,104,0,2,791294,0,99,104,107,105,110,100,0,2,791295, +0,99,104,112,116,114,0,2,791296,0,99,104,98,97,115,101, +0,2,791297,0,113,100,111,110,101,0,2,791298,0,105,115,112, +0,3,791299,0,116,98,117,102,0,2,792399,0,112,107,95,116, +107,0,2,792400,0,112,107,95,116,118,0,2,792401,0,112,113, +95,110,0,3,792402,0,112,113,95,116,107,0,3,792406,0,112, +113,95,116,118,0,3,792410,0,112,113,95,103,108,0,3,792414, +0,112,113,95,108,110,0,2,792418,0,104,101,114,101,0,2, +792419,0,104,100,101,108,116,97,0,2,792420,0,104,108,105,109, +105,116,0,2,792421,0,112,116,111,112,0,2,792422,0,110,108, +111,99,0,2,792423,0,108,98,97,115,101,0,2,792424,0,102, +100,101,112,116,104,0,2,792425,0,102,115,108,111,116,115,0, +2,792426,0,102,99,104,107,0,2,792427,0,102,114,101,116,0, +2,792428,0,108,105,118,101,0,2,792429,0,98,120,100,101,112, +116,104,0,2,792430,0,101,112,105,99,104,97,105,110,0,2, +792431,0,102,102,114,97,109,101,0,2,792432,0,105,110,102,110, +0,2,792433,0,108,115,112,0,2,792434,0,108,111,111,112,98, +97,115,101,0,2,792435,0,99,116,120,115,112,0,2,792436,0, +115,110,97,112,116,111,112,0,2,792437,0,108,118,0,2,792438, +0,108,118,107,0,2,792439,0,108,118,105,0,2,792440,0,107, +119,95,101,120,112,114,0,2,792441,0,120,99,108,115,0,2, +792442,0,102,116,121,0,2,792443,0,115,95,108,112,0,2,792444, +0,115,95,114,112,0,2,792445,0,115,95,108,98,0,2,792446, +0,115,95,114,98,0,2,792447,0,115,95,108,107,0,2,792448, +0,115,95,114,107,0,2,792449,0,115,95,99,111,109,109,97, +0,2,792450,0,115,95,115,101,109,105,0,2,792451,0,115,95, +101,113,0,2,792452,0,115,95,97,114,114,111,119,0,2,792453, +0,115,95,105,110,99,0,2,792454,0,115,95,100,101,99,0, +2,792455,0,115,95,115,116,97,114,0,2,792456,0,115,95,97, +109,112,0,2,792457,0,115,95,99,111,108,111,110,0,2,792458, +0,115,95,104,97,115,104,0,2,792459,0,115,95,109,105,110, +117,115,0,2,792460,0,115,95,97,110,100,97,110,100,0,2, +792461,0,115,95,111,114,111,114,0,2,792462,0,115,95,100,111, +116,0,2,792463,0,115,95,102,110,0,2,792464,0,115,95,118, +97,114,0,2,792465,0,115,95,99,111,110,115,116,0,2,792466, +0,115,95,101,108,115,101,0,2,792467,0,115,95,97,115,0, +2,792468,0,115,95,117,110,99,104,101,99,107,101,100,0,2, +792469,0,115,95,105,109,109,101,100,105,97,116,101,0,2,792470, +0,115,95,109,0,2,792471,0,115,95,100,0,2,792472,0,115, +95,117,0,2,792473,0,115,95,113,0,2,792474,0,115,95,99, +97,115,101,0,2,792475,0,115,95,100,101,102,97,117,108,116, +0,2,792476,0,115,95,102,111,118,102,0,2,792477,0,115,95, +115,116,97,114,116,0,2,792478,0,115,95,109,97,105,110,0, +2,792479,0,115,95,102,114,101,101,0,2,792480,0,115,95,111, +119,110,0,2,792481,0,115,95,113,110,101,119,0,2,792482,0, +115,95,101,110,104,97,110,99,101,0,2,792483,0,115,95,109, +105,99,114,111,0,2,792484,0,115,95,118,109,0,4,0,0, +84,89,95,87,79,82,68,0,4,1,0,84,89,95,73,78, +84,0,4,2,0,84,89,95,67,72,65,82,0,4,3,0, +84,89,95,66,79,79,76,0,4,4,0,84,89,95,86,79, +73,68,0,4,5,0,84,89,95,80,84,82,0,4,6,0, +84,89,95,65,82,82,0,4,7,0,84,89,95,70,78,0, +4,8,0,84,89,95,83,84,82,85,67,84,0,4,9,0, +84,89,95,86,65,82,0,4,10,0,84,89,95,71,69,78, +0,4,638976,0,82,95,84,89,0,4,655360,0,82,95,84,89, +69,78,68,0,4,1024,0,78,84,76,0,4,778496,0,108,116, +121,112,101,0,4,779008,0,108,116,97,103,0,4,779520,0,115, +116,121,112,101,0,2,792485,0,116,121,116,111,112,0,2,792486, +0,110,116,108,0,2,792487,0,116,119,111,114,100,0,2,792488, +0,116,105,110,116,0,2,792489,0,116,99,104,97,114,0,2, +792490,0,116,98,111,111,108,0,2,792491,0,116,118,111,105,100, +0,2,792492,0,116,99,95,111,110,0,2,792493,0,120,116,121, +0,2,792494,0,120,122,101,114,111,0,2,792495,0,100,114,121, +0,3,792496,0,116,112,110,0,2,792504,0,110,116,112,0,2, +792505,0,100,116,121,0,2,792506,0,100,116,97,103,0,2,792507, +0,115,95,108,116,0,2,792508,0,115,95,103,116,0,2,792509, +0,115,95,115,104,114,0,2,792510,0,115,95,108,101,0,2, +792511,0,115,95,103,101,0,2,792512,0,115,95,101,113,101,113, +0,2,792513,0,115,95,110,101,0,2,792514,0,115,95,112,108, +117,115,0,2,792515,0,115,95,115,116,114,117,99,116,0,2, +792516,0,115,95,116,121,112,101,0,2,792517,0,115,95,116,121, +112,101,99,104,101,99,107,0,2,792518,0,115,95,111,110,0, +2,792519,0,115,95,111,102,102,0,2,792520,0,115,95,110,101, +119,0,2,792521,0,115,95,110,101,119,95,116,0,3,792522,0, +110,117,109,111,112,115,0,2,792534,0,110,110,117,109,111,112, +115,0,3,792535,0,103,98,105,110,100,0,2,792543,0,110,103, +98,105,110,100,0,2,792544,0,110,101,114,114,0,2,792545,0, +112,97,110,105,99,0,4,783616,0,82,95,69,88,73,84,0, +4,786176,0,82,95,69,88,73,84,69,78,68,0,2,804814,0, +101,120,116,111,112,0,3,804815,0,106,112,115,0,2,804879,0, +110,106,112,115,0,0 +}; +#define GLEN 71014 diff --git a/docs/history/13-gap-fixes/code/io_linux.c b/docs/history/13-gap-fixes/code/io_linux.c new file mode 100644 index 0000000..7ea34e0 --- /dev/null +++ b/docs/history/13-gap-fixes/code/io_linux.c @@ -0,0 +1,6 @@ +#include +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/13-gap-fixes/code/mkgenome.c b/docs/history/13-gap-fixes/code/mkgenome.c new file mode 100644 index 0000000..8fb2cc5 --- /dev/null +++ b/docs/history/13-gap-fixes/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 +#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/13-gap-fixes/code/src/compiler.zc b/docs/history/13-gap-fixes/code/src/compiler.zc new file mode 100644 index 0000000..c6fa3cc --- /dev/null +++ b/docs/history/13-gap-fixes/code/src/compiler.zc @@ -0,0 +1,2638 @@ +// ============================================================================ +// 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, 32 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, 8 words per loop or switch +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, K_ENH = 6, K_TYPE = 7; +const F_DEF = 1, F_SIG = 2, F_UNTYPED = 4, F_STMT = 8, F_EXPR = 16, F_TOP = 32, F_FALLBACK = 64, F_GEN = 128, F_PRE = 256; +// 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, O_LT = 20; +const XOP0 = 22; // first enhancement opcode +const SEQREF = -2; // in an operator sequence: the next word names a symbol + +// ---- state ---- +let nenh, pooltop, nsym, ubase, vislo, nfixu, fixfree; +let nbin, nun, nasg, nkop, seqtop; +let mnem = "q@!$_~cjzr,?.+-*&|^><%"; +let check_on = 1; // set to 0 to switch the analyzer off for what follows +let tk, tv, tglue, tline, line = 1, ch, chkind, chptr, chbase, qdone, isp = -1; +let tbuf[1100]; +let pk_tk, pk_tv, pq_n, pq_tk[4], pq_tv[4], pq_gl[4], pq_ln[4]; // up to 4 tokens of lookahead +let here, hdelta, hlimit, ptop; +let nloc, lbase, fdepth, fslots, fchk, fret, live, bxdepth, epichain, fframe, infn; +let lsp, loopbase, ctxsp, snaptop; +let lv, lvk, lvi, kw_expr, xcls, fty; +// interned spellings the parser compares against +let s_lp, s_rp, s_lb, s_rb, s_lk, s_rk, s_comma, s_semi, s_eq, s_arrow, s_inc, s_dec; +let s_star, s_amp, s_colon, s_hash, s_minus, s_andand, s_oror; +let s_dot, s_fn, s_var, s_const, s_else, s_as, s_unchecked, s_immediate, s_m, s_d, s_u; +let s_q, s_case, s_default, s_fovf, s_start, s_main, s_free, s_own, s_qnew, s_enhance, s_micro, s_vm; + +// ---- types: kinds, tables and parser state (see the types section) ---- +const TY_WORD = 0, TY_INT = 1, TY_CHAR = 2, TY_BOOL = 3, TY_VOID = 4, TY_PTR = 5, TY_ARR = 6; +const TY_FN = 7, TY_STRUCT = 8, TY_VAR = 9, TY_GEN = 10; +const R_TY = 0x9C000, R_TYEND = 0xA0000, NTL = 1024; // the first NTL words list every record +const ltype = 0xBE100, ltag = 0xBE300, stype = 0xBE500; // type per local, declared tag per local, type per symbol +let tytop, ntl, tword, tint, tchar, tbool, tvoid; +let tc_on; // the optional typechecker, off unless a program says typecheck on; +let xty, xzero, dry; // type of the last expression, was it a literal 0, and dry runs (typeof) +let tpn[8], ntp; // type parameters in scope +let dty, dtag; // result of dtype() +let s_lt, s_gt, s_shr, s_le, s_ge, s_eqeq, s_ne, s_plus, s_struct, s_type, s_typecheck, s_on, s_off, s_new, s_new_t; +let numops[12], nnumops; +let gbind[8], ngbind; // explicit type arguments for the next call: f(...) + +// ---- errors ---- +// the compiler reports up to 20 errors before it stops. a syntax error +// (die) skips the token it happened on and sets panic, which skips ahead to +// the next ; or } (or the next top-level item) and keeps quiet until then. +// other errors (serr) just report: the parse is still in step. +let nerr, panic; +fn errat() { puts("zc: line "); putn(tline); puts(": "); nerr++; return 0; } +fn errend() { putc(10); if (nerr >= 20) { puts("zc: too many errors, stopping\n"); halt(); } return 0; } +fn giveup() { puts("zc: "); putn(nerr); if (nerr == 1) puts(" error\n"); else puts(" errors\n"); halt(); return 0; } +fn fatal(msg) { errat(); puts(msg); putc(10); halt(); return 0; } +fn serr(msg) { if (!panic && !dry) { errat(); puts(msg); errend(); } return 0; } +fn serrn(name, msg) { if (!panic && !dry) { errat(); puts(name); puts(": "); puts(msg); errend(); } return 0; } +fn die(msg) { serr(msg); panic = 1; if (tk == T_EOF) giveup(); next(); return 0; } +fn dien(name, msg) { serrn(name, msg); panic = 1; if (tk == T_EOF) giveup(); next(); return 0; } +// analyzer errors only count in checked, reachable code +fn cerr(msg) { if (fchk && live) serr(msg); return 0; } +fn cerrn(i, msg) { if (fchk && live) serrn(lname[i], msg); return 0; } + +// ---- interning ---- +fn hashs(s) { let h = 0; while (*s) { h = h * 31 + *s; s++; } return h & (IHN - 1); } +fn intern(s) +{ + let 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) fatal("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) +{ + let i = nsym; + if (nsym >= NS) fatal("symbol table full"); + nsym++; + sname[i] = name; skind[i] = kind; sval[i] = val; ssig[i] = 0; sflag[i] = F_DEF; sfix[i] = 0; stype[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) +{ + let i = name[-1] - 1; + while (i >= 0) { + if (i >= vislo || skind[i] == K_KW || skind[i] == K_TYPE) 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) +{ + let i = fixfree; + if (i) fixfree = fnext[i]; + else { nfixu++; i = nfixu; if (i >= NF) fatal("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) +{ + let 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 (dry) return 0; if (here >= hlimit) fatal("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) { if (dry) return 0; *(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() { let a = here; lit(MW - 1); return a; } +fn fwdfn(name) { let s = addsym(name, K_FN, tline); sflag[s] = 0; return s; } // the line of the first use, until it's defined +fn fnref(s) +{ + if (sflag[s] & F_DEF) { lit(sval[s]); return 0; } + if (dry) 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) { let 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) +{ + let 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 12 saved line +// 13 saved token line 14 saved lookahead count 15..30 saved lookahead 31 saved char buffer +fn nextch() +{ + if (chkind == 0) { + if (qdone || eof()) { ch = -1; return 0; } + ch = getc() & 255; + if (ch == 96) { qdone = 1; ch = -1; return 0; } // a backtick ends the source + } else if (chkind == 3) { + ch = (chbase[chptr >> 2] >> ((chptr & 3) * 8)) & 255; + if (ch) chptr++; else ch = -1; + } else { + ch = *chptr & 255; + if (ch) chptr++; else ch = -1; + } + if (ch == 10) line++; + return 0; +} +fn src_push(kind, obj, trans, owned) +{ + let f, i; + isp++; + if (isp >= 32) fatal("sources nested too deeply"); + f = R_SRC + isp * 32; + 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; + f[12] = line; f[13] = tline; f[14] = pq_n; f[31] = chbase; + i = 0; while (i < pq_n) { f[15 + i * 4] = pq_tk[i]; f[16 + i * 4] = pq_tv[i]; f[17 + i * 4] = pq_gl[i]; f[18 + i * 4] = pq_ln[i]; i++; } + pq_n = 0; + if (kind == 1) f[3] = obj[0]; + if (kind == 0) { chkind = 0; qdone = 0; line = 1; nextch(); } + if (kind == 2) { chkind = 2; chptr = obj; line = 1; nextch(); } + if (kind == 3) { chkind = 3; chbase = obj; chptr = 0; line = 1; nextch(); } + return 0; +} +fn src_pop() +{ + let f = R_SRC + isp * 32, i = 0; + tk = f[5]; tv = f[6]; tglue = f[7]; ch = f[8]; chkind = f[9]; chptr = f[10]; + line = f[12]; tline = f[13]; pq_n = f[14]; chbase = f[31]; + while (i < pq_n) { pq_tk[i] = f[15 + i * 4]; pq_tv[i] = f[16 + i * 4]; pq_gl[i] = f[17 + i * 4]; pq_ln[i] = f[18 + i * 4]; i++; } + isp--; + if (f[11]) free(f[1]); + return 0; +} +fn isopch(c) +{ + let 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) +{ + let 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() +{ + let 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() +{ + let n = 0, v, dg; + 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 ((dg = hexv(ch)) >= 0) { v = v * 16 + dg; 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; +} +// one token of lookahead: peek() fills pk_*, next() takes it first +fn next() +{ + let i = 1; + if (pq_n) { + tk = pq_tk[0]; tv = pq_tv[0]; tglue = pq_gl[0]; tline = pq_ln[0]; + while (i < pq_n) { pq_tk[i - 1] = pq_tk[i]; pq_tv[i - 1] = pq_tv[i]; pq_gl[i - 1] = pq_gl[i]; pq_ln[i - 1] = pq_ln[i]; i++; } + pq_n--; + return 0; + } + return next0(); +} +// the k-th token after the current one (k from 0 to 3), into pk_tk and pk_tv +fn peekat(k) +{ + let a, b, c, e; + while (pq_n <= k) { + a = tk; b = tv; c = tglue; e = tline; + next0(); + pq_tk[pq_n] = tk; pq_tv[pq_n] = tv; pq_gl[pq_n] = tglue; pq_ln[pq_n] = tline; pq_n++; + tk = a; tv = b; tglue = c; tline = e; + } + pk_tk = pq_tk[k]; pk_tv = pq_tv[k]; + return 0; +} +fn peek() { return peekat(0); } +fn next0() +{ + let f, q, i; + f = R_SRC + isp * 32; + if (f[0] != 1) { lex(); return 0; } + i = f[2]; + if (i < f[3]) { q = f[1]; tk = q[1 + i * 3]; tv = q[2 + i * 3]; tline = q[3 + i * 3]; 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)) { if (!panic && !dry) { errat(); puts("expected "); puts(s); errend(); } panic = 1; if (tk == T_EOF) giveup(); } return 0; } +fn name() +{ + let 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) +{ + let 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) { let i = 0; while (mnem[i]) { if (mnem[i] == c) return i; i++; } return -1; } +fn emitseq(a, n) +{ + let 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 if (skind[s] == K_ENH) op(XOP0 + sval[s]); else lit(sval[s]); + a = a + 2; + } else { emit(R_SEQ[a]); a++; } + } + return 0; +} +fn addkop(p) { let i = 0; while (i < nkop) { if (kops[i] == p) return 0; i++; } kops[nkop] = p; nkop++; return 0; } +fn binfind(p) { let i = nbin; while (i) { i--; if (bname[i] == p) return i; } return -1; } +fn unfind(p) { let i = nun; while (i) { i--; if (uname[i] == p) return i; } return -1; } +fn asgfind(p) { let 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) +{ + let 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) +{ + let 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) { let 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) { let i = nloc; while (i > lbase) { i--; if (lname[i] == n) return i; } return -1; } +fn newloc(n) +{ + let i = nloc; + if (nloc >= NL) fatal("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; ltype[i] = tword; ltag[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) +{ + let 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) +{ + let 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]) serrn(lname[from], "m object is never used"); from++; } + return 0; +} +fn block_close(save) +{ + let 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() +{ + let 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) fatal("nesting too deep for the analyzer"); + return b; +} +fn snap_pop(b) { snaptop = b; return 0; } +fn snap_restore(b) +{ + let 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) +{ + let 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 || panic || dry) return 0; + errat(); puts(lname[i]); puts(": "); puts(what); + puts(" (one path leaves it "); puts(statename(sa)); puts(", another "); puts(statename(lstate[i])); puts(")"); + errend(); + return 0; +} +// after an if: the current state is the else path, sa is the then path + +// ---- joins ---- +// where control flow comes back together (after an if, a loop, a switch or +// ?:) every variable has to agree across the paths that reach the join. one +// exception: a variable that became d, or was given away, on some path is dead +// after the join, and the paths where it's still alive free it on the way in +// (fixups). u objects and borrows don't get this treatment: a u object still +// has to leave, and a borrow never changes. +const R_EXIT = 0xBF500, R_EXITEND = 0xBFF00; // exit records: the states at each break +let extop, jps[64], njps; // the paths being joined: [lbase, nloc, triples] +fn jst(p, i) { if (i >= p[1]) return S_PLAIN; return p[2 + 3 * (i - p[0])]; } +fn jow(p, i) { return p[3 + 3 * (i - p[0])]; } +fn jhm(p, i) { return p[4 + 3 * (i - p[0])]; } +// the states at a break, with the jump to patch: [site] then a snapshot +fn exit_rec(site) +{ + let p = R_EXIT + extop, i = lbase, q; + if (extop + 3 + 3 * (nloc - lbase) >= R_EXITEND - R_EXIT) fatal("too many breaks for the analyzer"); + p[0] = site; p[1] = lbase; p[2] = nloc; + q = p + 3; + while (i < nloc) { q[0] = lstate[i]; q[1] = lowner[i]; q[2] = lhome[i]; q = q + 3; i++; } + extop = q - R_EXIT; + return p; +} +fn jadd(p) { if (njps >= 64) fatal("too many paths for the analyzer"); jps[njps] = p; njps++; return 0; } +fn jsame(p, q, i) +{ + let s = jst(p, i), t = jst(q, i); + if (empty(s) && empty(t)) return 1; + return s == t && jhm(p, i) == jhm(q, i) && (s != S_CHILD || jow(p, i) == jow(q, i)); +} +// join the paths in jps over the locals [lbase, n0) into the current states +fn join(n0, what) +{ + let i = lbase, j, p, s, s0, dead, okdead, bad; + if (!njps) return 0; + while (i < n0) { + p = jps[0]; s0 = jst(p, i); + dead = 0; okdead = 1; bad = -1; + j = 0; + while (j < njps) { + s = jst(jps[j], i); + if (s == S_DEAD || s == S_D) dead = 1; + if (s == S_U || s == S_BORROW) okdead = 0; + if (!jsame(p, jps[j], i)) bad = j; + j++; + } + lstate[i] = s0; lowner[i] = jow(p, i); lhome[i] = jhm(p, i); + if (bad < 0) { + if (empty(s0)) { j = 0; while (j < njps) { if (jst(jps[j], i) == S_DEAD) lstate[i] = S_DEAD; j++; } } + } else if (dead && okdead) lstate[i] = S_DEAD; + else if (fchk && !panic && !dry) { + errat(); puts(lname[i]); puts(": "); puts(what); + puts(" (one path leaves it "); puts(statename(s0)); puts(", another "); puts(statename(jst(jps[bad], i))); puts(")"); + errend(); + } + i++; + } + return 0; +} +// on path p: count (and with doit, emit) the frees for what the join made dead but p still owns +fn fixups(p, n0, doit) +{ + let i = lbase, n = 0, s; + if (!fchk) return 0; + while (i < n0) { + s = jst(p, i); + if (lstate[i] == S_DEAD && (s == S_M || s == S_D)) { n++; if (doit) freevar(i); } + i++; + } + return n; +} +// a jump back to the top of a loop: whatever the loop owns has to be as it was +fn backedge(s0) +{ + let p = R_SNAP + s0, i = p[0], e = p[1], s; + if (!fchk || !live) return 0; + if (e > nloc) e = nloc; + while (i < e) { + s = lstate[i]; + if (empty(s) && empty(jst(p, i))) { if (jst(p, i) == S_DEAD) lstate[i] = S_DEAD; } + else if (s != jst(p, i) || lhome[i] != jhm(p, i) || (s == S_CHILD && lowner[i] != jow(p, i))) { + if (s == S_DEAD || s == S_D) cerrn(i, "is given away inside a loop that comes back around to it; give it away on a path that leaves the loop"); + else if (!panic && !dry) { + errat(); puts(lname[i]); puts(": changes state inside a loop; each pass has to leave it as it found it (it went from "); + puts(statename(jst(p, i))); puts(" to "); puts(statename(s)); puts(")"); errend(); + } + } + i++; + } + return 0; +} +// joins two paths that end at the same point, like the branches of if/else: +// path a jumped (through the hole at ja) and path b falls through to here +fn join2(sa, livea, ja, livebv, n0, what) +{ + let sb, nt, cj; + sb = snap_push(); + njps = 0; if (livea) jadd(R_SNAP + sa); if (livebv) jadd(R_SNAP + sb); + join(n0, what); + if (livebv) fixups(R_SNAP + sb, n0, 1); + nt = 0; if (livea) nt = fixups(R_SNAP + sa, n0, 0); + if (nt) { cj = hole(); op(O_JMP); setlit(ja, here); fixups(R_SNAP + sa, n0, 1); setlit(cj, here); } + else setlit(ja, here); + live = livea || livebv; + return 0; +} + +// ---- analyzer rules for the places values flow ---- +// recast: x as u / x as d / x as m +fn recast(c, t) +{ + let 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) +{ + let 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 <= 1) { // untagged parameters are m: a lend + 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 d*x to give it away"); + else if (st == S_U) cerrn(i, "is u; write d*x 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) +{ + let 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; if (ltag[i]) lstate[i] = ltag[i]; 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; if (ltag[i]) lstate[i] = ltag[i]; + 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_U) cerrn(j, "is u; it has to leave through the block above, not into a borrowed object"); + else { lstate[j] = S_DEAD; lused[j] = 1; emitown(i); } // storing it gives it away + } 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) +{ + let 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 u*x'"); + } + 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) +{ + let 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; +} + +// ---- types ---- +// types are a compiler primitive: records in the type area, hash-consed so +// the same type is always the same pointer and comparing types is comparing +// words. untyped code is typed word, which goes with anything. the records +// stay in memory after compiling, so programs can inspect them. +// t[0] kind t[1] size in words t[2] name t[3] n t[4] a t[5] b t[6] c t[7..] extra +// ptr: a = element arr: a = element, n = length +// fn: a = return type, n = parameter count, b = signature (u m d tags), extra = parameter types +// struct: n = field count (-1 until laid out), a = fields (name, type, offset), +// b = generic template, c = type arguments [n, t1, t2 ...] +// var: a type parameter, n = its index +// gen: a generic struct: n = parameter count, a = fields (name, type), b = field count, c = parameter names + + +fn talloc(n) { let p = tytop; if (tytop + n >= R_TYEND) fatal("the type area is full"); tytop = tytop + n; wfill(p, 0, n); return p; } +fn tnew(kind, size, nm, extra) +{ + let t = talloc(7 + extra); + t[0] = kind; t[1] = size; t[2] = nm; + if (ntl >= NTL) fatal("too many types"); + R_TY[ntl] = t; ntl++; + return t; +} +fn tptr(e) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_PTR && t[4] == e) return t; i++; } + t = tnew(TY_PTR, 1, 0, 0); t[4] = e; + return t; +} +fn tarr(e, n) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_ARR && t[4] == e && t[3] == n) return t; i++; } + t = tnew(TY_ARR, n * tsz(e), 0, 0); t[4] = e; t[3] = n; + return t; +} +fn tfn(ret, np, ps, sig) +{ + let i = 0, j, t; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_FN && t[4] == ret && t[3] == np && t[5] == sig) { + j = 0; while (j < np && t[7 + j] == ps[j]) j++; + if (j == np) return t; + } + i++; + } + t = tnew(TY_FN, 1, 0, np); t[4] = ret; t[3] = np; t[5] = sig; + wcopy(t + 7, ps, np); + return t; +} +fn tvar(i, nm) +{ + let k = 0, t; + while (k < ntl) { t = R_TY[k]; if (t[0] == TY_VAR && t[3] == i) return t; k++; } + t = tnew(TY_VAR, 1, nm, 0); t[3] = i; + return t; +} +fn tinst(g, args, n) +{ + let i = 0, j, t, v; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_STRUCT && t[5] == g) { + v = t[6]; j = 0; while (j < n && v[1 + j] == args[j]) j++; + if (j == n) return t; + } + i++; + } + v = talloc(n + 1); v[0] = n; wcopy(v + 1, args, n); + t = tnew(TY_STRUCT, 0, g[2], 0); t[3] = -1; t[5] = g; t[6] = v; + return t; +} +// lay out a generic instance on first use +fn tresolve(t) +{ + let g, f, n, i, fs, off = 0, ft, bs[8]; + if (t[0] != TY_STRUCT || t[3] >= 0) return t; + if (t[3] == -2) { serr("a struct can't contain itself by value"); t[3] = 0; return t; } + t[3] = -2; + g = t[5]; n = g[5]; f = g[4]; + wfill(bs, 0, 8); wcopy(bs, t[6] + 1, t[6][0]); + fs = talloc(n * 3 + 1); + i = 0; + while (i < n) { + ft = subst(f[i + i + 1], bs); + fs[i * 3] = f[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = n; + return t; +} +fn tsz(t) { if (t[0] == TY_STRUCT && t[3] < 0) tresolve(t); return t[1]; } +// replace type parameters with what they were bound to (unbound ones become word) +fn subst(t, bs) +{ + let k = t[0], i, n, v[24], vec; + if (k == TY_VAR) { if (bs[t[3]]) return bs[t[3]]; return tword; } + if (k == TY_PTR) return tptr(subst(t[4], bs)); + if (k == TY_ARR) return tarr(subst(t[4], bs), t[3]); + if (k == TY_FN) { n = t[3]; i = 0; while (i < n) { v[i] = subst(t[7 + i], bs); i++; } return tfn(subst(t[4], bs), n, v, t[5]); } + if (k == TY_STRUCT && t[5]) { vec = t[6]; n = vec[0]; i = 0; while (i < n) { v[i] = subst(vec[1 + i], bs); i++; } return tinst(t[5], v, n); } + return t; +} +fn isnum(t) { return t[0] == TY_INT || t[0] == TY_CHAR || t[0] == TY_BOOL; } +fn isagg(t) { return t[0] == TY_ARR || t[0] == TY_STRUCT; } +fn isptr(t) { return t[0] == TY_PTR || t[0] == TY_ARR; } +fn decay(t) { if (t[0] == TY_ARR) return tptr(t[4]); return t; } +fn telem(t) { if (t[0] == TY_PTR || t[0] == TY_ARR) return t[4]; return tword; } +// can a value of type src go where dst is expected? +fn compat(dst, src) +{ + if (dst == src || dst == tword || src == tword) return 1; + if (isnum(dst) && isnum(src)) return 1; + src = decay(src); + if (dst[0] == TY_PTR && src[0] == TY_PTR) { + if (dst[4] == tword || src[4] == tword || dst[4] == tvoid || src[4] == tvoid) return 1; + return dst[4] == src[4]; + } + if ((dst[0] == TY_PTR || dst[0] == TY_FN) && xzero) return 1; // a literal 0 is a null pointer + return dst == src; +} +fn unify(p, a, bs) +{ + let i, n, pv, av; + if (p[0] == TY_VAR) { i = p[3]; if (!bs[i]) { bs[i] = a; return 1; } return compat(bs[i], a); } + a = decay(a); + if (p[0] == TY_PTR && a[0] == TY_PTR) { if (a[4] == tword) return 1; return unify(p[4], a[4], bs); } + if (p[0] == TY_STRUCT && p[5] && a[0] == TY_STRUCT && a[5] == p[5]) { + pv = p[6]; av = a[6]; n = pv[0]; i = 0; + while (i < n) { if (!unify(pv[1 + i], av[1 + i], bs)) return 0; i++; } + return 1; + } + return compat(p, a); +} +fn tprint(t) +{ + let k = t[0], i, v; + if (k == TY_PTR) { putc('*'); return tprint(t[4]); } + if (k == TY_ARR) { putc('['); putn(t[3]); putc(']'); return tprint(t[4]); } + if (k == TY_FN) { + puts("fn("); + i = 0; + while (i < t[3]) { + if (i) puts(", "); + tprint(t[7 + i]); + if (i < 12 && tparamtag(t, i) == 1) puts(".m"); + if (i < 12 && tparamtag(t, i) == 2) puts(".d"); + i++; + } + putc(')'); + if (t[4] != tword || (t[5] & 1)) { puts(" -> "); if (t[4] != tword) tprint(t[4]); if (t[5] & 1) puts(".u"); } + return 0; + } + if (t[2]) puts(t[2]); else puts("?"); + if (k == TY_STRUCT && t[5]) { + v = t[6]; putc('<'); + i = 0; while (i < v[0]) { if (i) puts(", "); tprint(v[1 + i]); i++; } + putc('>'); + } + return 0; +} +fn tcerr(what, want, got) +{ + if (!tc_on || !live || dry || panic) return 0; + errat(); puts("type error: "); puts(what); + puts(": expected "); tprint(want); puts(", got "); tprint(got); + errend(); + return 0; +} +fn tcneed(ok, what, got) +{ + if (ok || !tc_on || !live || dry || panic) return 0; + errat(); puts("type error: "); puts(what); puts(", got "); tprint(got); + errend(); + return 0; +} +fn tpfind(n) { let i = ntp; while (i) { i--; if (tpn[i] == n) return i; } return -1; } +fn istypename(n) +{ + let s; + if (tpfind(n) >= 0) return 1; + if (findloc(n) >= 0) return 0; + s = lookup(n); + return s >= 0 && skind[s] == K_TYPE; +} +// the closing > of a type argument list; splits >> in two +fn closeangle() +{ + if (is_op(s_shr)) { tv = s_gt; return 0; } + expect(s_gt); + return 0; +} +fn ptype() +{ + let n, s, t, np = 0, ps[24], ret, args[8], na = 0, i; + if (accept(s_star)) return tptr(ptype()); + if (accept(s_lk)) { n = cexpr(); expect(s_rk); t = ptype(); if (n < 0) serr("a negative array length"); return tarr(t, n); } + if (is_id(s_fn)) { + next(); expect(s_lp); + if (!is_op(s_rp)) { while (1) { if (np >= 24) die("too many parameters"); ps[np] = ptype(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + ret = tword; + i = 0; + if (accept(s_arrow)) { if (!is_op(s_dot)) ret = ptype(); if (accept(s_dot)) { if (!is_id(s_u)) die("the return tag is .u"); next(); i = 1; } } + return tfn(ret, np, ps, i + np + np); + } + if (tk != T_ID) { die("expected a type"); return tword; } + n = tv; + i = tpfind(n); + if (i >= 0) { next(); return tvar(i, n); } + s = lookup(n); + if (s < 0 || skind[s] != K_TYPE) { dien(n, "isn't a type"); return tword; } + next(); + t = sval[s]; + if (t[0] != TY_GEN) return t; + expect(s_lt); + while (1) { + if (na >= 8) die("too many type arguments"); + args[na] = ptype(); + if (tsz(args[na]) != 1) serr("type arguments have to be one word (a pointer, a number, or a parameter)"); + na++; + if (!accept(s_comma)) break; + } + closeangle(); + if (na != t[3]) serrn(n, "wrong number of type arguments"); + return tinst(t, args, na); +} +// does a declaration start here? (a type, or a bare .tag) +fn tstart() +{ + let k; + if (tk == T_OP) { + if (tv == s_lk || tv == s_dot) return 1; + if (tv == s_star) { // *T name, **T name ...: look past the stars + k = 0; + while (k < 3) { peekat(k); if (!(pk_tk == T_OP && pk_tv == s_star)) break; k++; } + peekat(k); + return (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) || (pk_tk == T_OP && pk_tv == s_lk); + } + return 0; + } + if (tk != T_ID) return 0; + return tv == s_fn || istypename(tv); +} +// [type] [.tag] +fn dtype() +{ + dty = 0; dtag = 0; + if (!is_op(s_dot)) dty = ptype(); + if (accept(s_dot)) { + if (tv == s_m) dtag = S_M; else if (tv == s_u) dtag = S_U; else if (tv == s_d) dtag = S_D; else die("a tag is .u, .m or .d"); + next(); + } + return 0; +} +// struct name { type field, ... } or struct name { ... } +fn kw_struct() +{ + let n, t, s, nf = 0, buf = R_QBUF, i, fs, off = 0, gen = 0, ft; + next(); + n = name(); + if (is_op(s_lt)) { // generic + next(); ntp = 0; + while (1) { if (ntp >= 8) die("too many type parameters"); tpn[ntp] = name(); ntp++; if (!accept(s_comma)) break; } + closeangle(); + gen = 1; + t = tnew(TY_GEN, 0, n, 0); t[3] = ntp; + fs = talloc(ntp); wcopy(fs, tpn, ntp); t[6] = fs; + } else { t = tnew(TY_STRUCT, 0, n, 0); t[3] = -2; } // -2 while its fields are read + s = addsym(n, K_TYPE, t); + expect(s_lb); + while (!is_op(s_rb)) { + ft = ptype(); + while (1) { + if (nf >= 1000) fatal("too many fields"); + buf[nf + nf] = name(); buf[nf + nf + 1] = ft; nf++; + if (!accept(s_comma)) break; + } + expect(s_semi); + } + next(); + if (gen) { + fs = talloc(nf + nf); wcopy(fs, buf, nf + nf); + t[4] = fs; t[5] = nf; + ntp = 0; + } else { + fs = talloc(nf * 3 + 1); + i = 0; + while (i < nf) { + ft = buf[i + i + 1]; + if (ft == t) { serr("a struct can't contain itself by value; use a pointer"); ft = tword; } + fs[i * 3] = buf[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = nf; + } + accept(s_semi); + return s; +} +// type name = T; +fn kw_type() { let n; next(); n = name(); expect(s_eq); addsym(n, K_TYPE, ptype()); expect(s_semi); return 0; } +// typecheck on; / typecheck off; +fn kw_typecheck() +{ + next(); + if (is_id(s_on)) tc_on = 1; else if (is_id(s_off)) tc_on = 0; else die("typecheck on or typecheck off"); + next(); expect(s_semi); + return 0; +} +// the field of a struct type, or -1 +fn tfindfield(t, n) { let i = 0; tresolve(t); while (i < t[3]) { if (t[4][i * 3] == n) return i; i++; } return -1; } +// sizeof(T or expr), typeof(T or expr): the expression form is compiled dry, so it never runs +fn typearg() +{ + let t, sb, c; + expect(s_lp); + if (tstart() && !is_op(s_dot)) t = ptype(); + else { + sb = snap_push(); dry++; + c = expr(); rval(); + t = xty; + dry--; snap_restore(sb); snap_pop(sb); + } + expect(s_rp); + return t; +} +fn kw_sizeof() { let t; next(); t = typearg(); lit(tsz(t)); xty = tint; return 0; } +fn kw_typeof() { let t; next(); t = typearg(); lit(t); xty = tword; return 0; } +fn types_init() +{ + tytop = R_TY + NTL; ntl = 0; + tword = tnew(TY_WORD, 1, intern("word"), 0); + tint = tnew(TY_INT, 1, intern("int"), 0); + tchar = tnew(TY_CHAR, 1, intern("char"), 0); + tbool = tnew(TY_BOOL, 1, intern("bool"), 0); + tvoid = tnew(TY_VOID, 0, intern("void"), 0); + addsym(tword[2], K_TYPE, tword); addsym(tint[2], K_TYPE, tint); addsym(tchar[2], K_TYPE, tchar); + addsym(tbool[2], K_TYPE, tbool); addsym(tvoid[2], K_TYPE, tvoid); + s_lt = intern("<"); s_gt = intern(">"); s_shr = intern(">>"); s_le = intern("<="); s_ge = intern(">="); + s_eqeq = intern("=="); s_ne = intern("!="); s_plus = intern("+"); + s_struct = intern("struct"); s_type = intern("type"); s_typecheck = intern("typecheck"); + s_on = intern("on"); s_off = intern("off"); s_new = intern("new"); s_new_t = intern("new_t"); + numops[0] = intern("*"); numops[1] = intern("/"); numops[2] = intern("%"); numops[3] = intern("&"); + numops[4] = intern("|"); numops[5] = intern("^"); numops[6] = intern("<<"); numops[7] = s_shr; nnumops = 8; + return 0; +} +fn isnumop(o) { let i = 0; while (i < nnumops) { if (numops[i] == o) return 1; i++; } return 0; } +// the type of a binary operation, checking it when the typechecker is on +fn bintype(b, lt, rt) +{ + let o = bname[b]; + lt = decay(lt); rt = decay(rt); + if (blen[b] < 0) { tcneed(!isagg(lt) && !isagg(rt), "&& and || need scalars", lt); return tbool; } + if (o == s_eqeq || o == s_ne) { if (!compat(lt, rt) && !compat(rt, lt)) tcerr("comparison", lt, rt); return tbool; } + if (o == s_lt || o == s_gt || o == s_le || o == s_ge) { + if (!(lt == tword || rt == tword || (isnum(lt) && isnum(rt)) || (lt[0] == TY_PTR && rt[0] == TY_PTR))) tcerr("comparison", lt, rt); + return tbool; + } + if (o == s_plus) { + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (rt[0] == TY_PTR && isnum(lt)) return rt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("+", lt, rt); return tword; + } + if (o == s_minus) { + if (lt[0] == TY_PTR && rt[0] == TY_PTR) return tint; + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("-", lt, rt); return tword; + } + if (isnumop(o)) { + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + if (isnum(lt)) lt = rt; + tcneed(0, "arithmetic needs numbers", lt); return tword; + } + return tword; // operators a program added +} + +// ---- reflection ---- +// for programs (and parse words) looking at types at runtime +fn tkind(t) { return t[0]; } +fn tsize(t) { return tsz(t); } +fn tname(t) { return t[2]; } +fn tlen(t) { return t[3]; } +fn tnfields(t) { tresolve(t); return t[3]; } +fn tfname(t, i) { tresolve(t); return t[4][i * 3]; } +fn tftype(t, i) { tresolve(t); return t[4][i * 3 + 1]; } +fn tfoff(t, i) { tresolve(t); return t[4][i * 3 + 2]; } +fn tret(t) { return t[4]; } +fn tnparams(t) { return t[3]; } +fn tparam(t, i) { return t[7 + i]; } +fn tparamtag(t, i) { return ((t[5] >> 6) >> (i + i)) & 3; } // 0 untagged (m), 1 .m, 2 .d +fn tretu(t) { return t[5] & 1; } +fn tnargs(t) { if (t[0] != TY_STRUCT || !t[5]) return 0; return t[6][0]; } +fn targ(t, i) { return t[6][1 + i]; } +// the type of a function, by address. untyped functions get one made from their signature +fn sigof(f) +{ + let i = nsym, s = -1, ws[24], n, k; + while (i) { i--; if (skind[i] == K_FN && sval[i] == f && (sflag[i] & F_DEF)) { s = i; break; } } + if (s < 0) return 0; + if (stype[s]) return stype[s]; + n = (ssig[s] >> 1) & 31; k = 0; + while (k < n) { ws[k] = tword; k++; } + return tfn(tword, n, ws, ssig[s]); +} +fn sigofs(nm) { let s = lookups(nm); if (s < 0 || skind[s] != K_FN) return 0; return sigof(sval[s]); } + +// ---- expressions ---- +// every expression leaves its value on the stack, returns its analyzer class, +// and sets xty to its type. lv means the stack holds an address that hasn't +// been loaded yet; structs and arrays are never loaded, their address is +// their value. +fn rval() { if (lv) { if (!isagg(xty)) op(O_LD); lv = 0; } return 0; } +fn kwcall(s, e) +{ + let f = sval[s], old = kw_expr, c; + kw_expr = e; xcls = C_PLAIN; xty = tword; xzero = 0; + f(); + kw_expr = old; + c = xcls; + lv = 0; lvk = LV_NONE; + return c; +} +fn stmtonly() { if (kw_expr) serr("this can't be used inside an expression"); return 0; } +// the arguments of a call. ft is the callee's type (or 0), bs the generic bindings +fn args(tags, ft, bs) +{ + let np = 0, c, pt; + expect(s_lp); + if (!is_op(s_rp)) { + while (1) { + c = expr(); rval(); + argcheck(c, (tags >> (np + np)) & 3); + if (ft && np < ft[3]) { pt = ft[7 + np]; if (!unify(pt, xty, bs)) tcerr("argument", subst(pt, bs), xty); } + np++; + if (!accept(s_comma)) break; + } + } + expect(s_rp); + return np; +} +// new(T) and new(T, count): a typed object, its type stamped into the header +fn newtyped() +{ + let t, c; + t = ptype(); + if (accept(s_comma)) { + c = expr(); rval(); plainuse(c); + if (tsz(t) != 1) { lit(tsz(t)); op(15); } + lit(tarr(t, 0)); + } else { lit(tsz(t)); lit(t); } + expect(s_rp); + callname(s_new_t); + lv = 0; lvk = LV_NONE; xty = tptr(t); xzero = 0; + return C_FRESH; +} +fn call(s) +{ + let np, tags = 0, ret = 0, ft = stype[s], bs[8]; + if (sname[s] == s_new && skind[s] == K_FN) { + peek(); + if (pk_tk == T_OP && (pk_tv == s_star || pk_tv == s_lk)) { next(); return newtyped(); } + if (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) { next(); return newtyped(); } + } + if (sflag[s] & F_SIG) { tags = ssig[s] >> 6; ret = ssig[s] & 1; } + else sflag[s] = sflag[s] | F_UNTYPED; + wfill(bs, 0, 8); + if (ngbind) { wcopy(bs, gbind, ngbind); ngbind = 0; } + np = args(tags, ft, bs); + if ((sflag[s] & F_SIG) && np != ((ssig[s] >> 1) & 31)) serrn(sname[s], "wrong number of arguments"); + fnref(s); op(O_CALL); + lv = 0; lvk = LV_NONE; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + if (ret) return C_FRESH; + return C_PLAIN; +} +// an enhancement used like a function: the arguments, then its one opcode +fn enhcall(s) +{ + let nin = ssig[s] & 15, nout = (ssig[s] >> 4) & 15, n = 0, c; + expect(s_lp); + if (!is_op(s_rp)) { while (1) { c = expr(); rval(); plainuse(c); n++; if (!accept(s_comma)) break; } } + expect(s_rp); + if (n != nin) serrn(sname[s], "wrong number of inputs"); + lv = 0; lvk = LV_NONE; xty = tword; xzero = 0; + if (sflag[s] & F_FALLBACK) { fnref(sfix[s] - 1); op(O_CALL); return C_PLAIN; } + op(XOP0 + sval[s]); + if (nout == 0) lit(0); + if (nout > 1) serrn(sname[s], "leaves several values; use it from asm"); + return C_PLAIN; +} +fn primary() +{ + let n, i, s, c; + lv = 0; lvk = LV_NONE; xzero = 0; + if (tk == T_NUM) { lit(tv); xzero = tv == 0; xty = tint; next(); return C_PLAIN; } + if (tk == T_STR) { strlit(tv); next(); xty = tptr(tchar); 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"); lit(0); xty = tword; return C_PLAIN; + } + if (tk != T_ID) { die("expected an expression"); lit(0); xty = tword; return C_PLAIN; } + n = tv; + i = findloc(n); + if (i >= 0) { + next(); + if (!fchk && tracked(i)) serrn(n, "is tracked by the analyzer and can't be used in unchecked code"); + laddr(lslot[i]); + xty = ltype[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); + } + if (s >= 0 && skind[s] == K_TYPE) { dien(n, "is a type, not a value"); lit(0); xty = tword; return C_PLAIN; } + next(); + xty = tword; + if (s >= 0 && skind[s] == K_CONST) { lit(sval[s]); xty = tint; xzero = sval[s] == 0; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GVAR) { lit(sval[s]); if (stype[s]) xty = stype[s]; lv = 1; lvk = LV_GLOBAL; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GARR) { lit(sval[s]); if (stype[s]) xty = stype[s]; return C_PLAIN; } + if (s >= 0 && skind[s] == K_ENH) return enhcall(s); + if (s < 0) s = fwdfn(n); + if (is_op(s_lt) && (sflag[s] & F_GEN)) { // f(...) + next(); ngbind = 0; + while (1) { if (ngbind >= 8) die("too many type arguments"); gbind[ngbind] = ptype(); ngbind++; if (!accept(s_comma)) break; } + closeangle(); + if (!is_op(s_lp)) die("expected ( after the type arguments"); + } + if (is_op(s_lp)) return call(s); + fnref(s); + if (stype[s]) xty = stype[s]; + return C_PLAIN; +} +// ++ and -- on the address at the top of the stack +fn incdec(post, dlt) +{ + 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"); + tcneed(isnum(xty) || xty[0] == TY_PTR || xty == tword, "++ and -- need a number or a pointer", xty); + lv = 0; lvk = LV_NONE; xzero = 0; + lit(0); op(O_PICK); op(O_LD); + if (post) { lit(0); op(O_PICK); lit(dlt); op(O_ADD); lit(2); op(O_PICK); op(O_ST); } + else { lit(dlt); 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; +} +// p.x and p->x: a field of a struct, or of the struct a pointer points at +fn field(c) +{ + let n, st, i, b = -1; + next(); + n = name(); + rval(); + if (c == C_FRESH) cerr("use a field of a new object only after binding it to a name"); + else if (c >= C_VAR) { touch(c - C_VAR); b = c - C_VAR; } + st = xty; + if (st[0] == TY_PTR) st = st[4]; + if (st[0] != TY_STRUCT) { + if (!panic && !dry) { errat(); putc('.'); puts(n); puts(": that's a "); tprint(xty); puts(", not a struct or a pointer to one"); errend(); } + xty = tword; lv = 1; lvk = LV_OTHER; return C_PLAIN; + } + i = tfindfield(st, n); + if (i < 0) { + if (!panic && !dry) { errat(); tprint(st); puts(" has no field "); puts(n); errend(); } + xty = tword; lv = 1; lvk = LV_OTHER; return C_PLAIN; + } + if (st[4][i * 3 + 2]) { lit(st[4][i * 3 + 2]); op(O_ADD); } + xty = st[4][i * 3 + 1]; + lv = 1; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + return C_PLAIN; +} +fn postfix() +{ + let c = primary(), b, n, t, et, ft, bs[8]; + while (1) { + if (tk == T_ID && tv == s_as) { // e as T: same bits, another type + next(); t = ptype(); rval(); xty = 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; } + tcneed(isptr(xty) || xty == tword, "only pointers and arrays can be indexed", xty); + et = telem(xty); + c = expr(); rval(); plainuse(c); + tcneed(isnum(xty) || xty == tword, "an index has to be a number", xty); + expect(s_rk); + if (tsz(et) != 1) { lit(tsz(et)); op(15); } + op(O_ADD); + lv = 1; xty = et; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + c = C_PLAIN; + continue; + } + if (tv == s_dot || tv == s_arrow) { c = field(c); continue; } + if (tv == s_lp) { // call through a value + rval(); plainuse(c); + ft = 0; + if (xty[0] == TY_FN) ft = xty; + else tcneed(xty == tword, "only functions can be called", xty); + wfill(bs, 0, 8); + n = args(0, ft, bs); + lit(n); op(O_PICK); op(O_CALL); op(O_SWAP); op(O_DROP); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + 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() +{ + let c, un, t; + if (tk == T_ID && (tv == s_u || tv == s_m || tv == s_d)) { // u*x, d*x, m*x: recast + t = S_M; if (tv == s_u) t = S_U; if (tv == s_d) t = S_D; + next(); expect(s_star); + c = unary(); rval(); + lvk = LV_NONE; + return recast(c, t); + } + if (tk == T_OP) { + if (tv == s_star) { + next(); c = unary(); rval(); plainuse(c); + tcneed(xty[0] == TY_PTR || xty == tword, "only pointers can be dereferenced", xty); + xty = telem(xty); + lv = 1; lvk = LV_OTHER; xzero = 0; + return C_PLAIN; + } + if (tv == s_amp) { + next(); c = unary(); + if (!lv && !isagg(xty)) die("& needs something addressable"); + if (c >= C_VAR) touch(c - C_VAR); + lv = 0; lvk = LV_NONE; xzero = 0; + xty = tptr(xty); + return C_PLAIN; + } + if (tv == s_inc) { next(); unary(); return incdec(0, 1); } + if (tv == s_dec) { next(); unary(); return incdec(0, -1); } + un = unfind(tv); + if (un >= 0) { + next(); c = unary(); rval(); plainuse(c); + emitseq(useq[un], ulen[un]); + if (un <= 1) xty = tbool; + else if (xty != tword) { tcneed(isnum(xty), "this operator needs a number", xty); xty = tint; } + lv = 0; lvk = LV_NONE; xzero = 0; + return C_PLAIN; + } + } + return postfix(); +} +fn bin(minp) +{ + let c = unary(), b, p, a, j, lt; + while (tk == T_OP) { + b = binfind(tv); + if (b < 0) return c; + p = bprec[b]; + if (p < minp) return c; + next(); rval(); plainuse(c); + lt = xty; + 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]); + } + xty = bintype(b, lt, xty); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; + } + 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; } +// c ? a : b +fn ternary(c) +{ + let a, b, s0, sa, livea, live0 = live, n0 = nloc, ca, cb, ta; + rval(); plainuse(c); + next(); + a = hole(); op(O_JZ); + s0 = snap_push(); + ca = expr(); rval(); ta = xty; + if (ca != C_FRESH) plainuse(ca); + livea = live; sa = snap_push(); + b = hole(); op(O_JMP); + expect(s_colon); + setlit(a, here); + snap_restore(s0); live = live0; + cb = expr(); rval(); + if (cb != C_FRESH) plainuse(cb); + join2(sa, livea, b, live, n0, "ends the two sides of ?: in different states"); + snap_pop(s0); + if (!compat(ta, xty) && !compat(xty, ta)) tcerr("the two sides of ?:", ta, xty); + if (ta != tword) xty = ta; + lv = 0; lvk = LV_NONE; xzero = 0; + if (ca == C_FRESH && cb == C_FRESH) return C_FRESH; + if (ca == C_FRESH || cb == C_FRESH) cerr("both sides of ?: have to be new objects, or neither"); + return C_PLAIN; +} +fn expr() +{ + let c = bin(1), k, i, a, rc, lt; + if (tk != T_OP) return c; + if (tv == s_q) return ternary(c); + if (tv == s_eq) { + if (!lv) die("this can't be assigned to"); + k = lvk; i = lvi; lt = xty; + if (isagg(lt)) serr("a whole struct or array can't be assigned; assign its fields"); + next(); + rc = expr(); rval(); + if (!compat(lt, xty)) tcerr("assignment", lt, xty); + storekeep(); + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + 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"); + lt = xty; + next(); + lit(0); op(O_PICK); op(O_LD); + lv = 0; + rc = expr(); rval(); plainuse(rc); + emitseq(bseq[abin[a]], blen[abin[a]]); + k = bintype(abin[a], lt, xty); + if (!compat(lt, k)) tcerr("compound assignment", lt, k); + storekeep(); + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + return C_PLAIN; + } + return c; +} +// does the current token start a statement rather than an expression? +fn stmtstart() +{ + let s; + if (tk == T_OP) return tv == s_semi || tv == s_lb || tstart(); + if (tk != T_ID || findloc(tv) >= 0) return 0; + if (tstart()) return 1; + 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() +{ + let save = nloc, c = C_PLAIN, tail = 0, t = tint; + 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; t = xty; + } + next(); + if (tail) c = handup(c); else lit(0); + block_close(save); + fdepth--; bxdepth--; + lv = 0; lvk = LV_NONE; xty = t; xzero = 0; + return c; +} + +// ---- constant expressions ---- +fn cprim() +{ + let 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() +{ + let 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 ---- +// after a syntax error: skip to the end of the statement +fn resync() +{ + while (tk != T_EOF && !is_op(s_semi) && !is_op(s_rb)) next(); + if (is_op(s_semi)) next(); + panic = 0; + return 0; +} +fn stmt() +{ + let s, c; + if (panic) return resync(); + 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 (tstart()) { localdecl(1); 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() +{ + let save = nloc; + expect(s_lb); + fdepth++; + while (!is_op(s_rb)) { if (tk == T_EOF) die("missing }"); stmt(); } + block_close(save); // before the }, so its line is the one reported + next(); + fdepth--; + return 0; +} +// the body of if/while/for: its own block, even without braces +fn substmt() +{ + let save = nloc; + if (is_op(s_lb)) return block(); + fdepth++; + stmt(); + block_close(save); + fdepth--; + return 0; +} +// let a = e, b[10]; or, typed: int a = 1, b; *node.m p = new(node); .u r; +// let infers pointer, struct and function types from the initializer and +// keeps numbers as plain words. +fn localdecl(typed) +{ + let n, i, c, k, t = 0, tg = 0; + if (typed) { dtype(); t = dty; tg = dtag; if (t == tvoid) serr("a variable can't be void"); } + while (1) { + n = name(); + i = newloc(n); + ltag[i] = tg; + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + if (!t) t = tword; + larr[i] = 1; ltype[i] = tarr(t, k); fslots = fslots + tsz(ltype[i]); + } else if (t && isagg(t)) { larr[i] = 1; ltype[i] = t; fslots = fslots + tsz(t); } + else { fslots++; if (t) ltype[i] = t; } + if (accept(s_eq)) { + if (larr[i]) serr("an array or a struct can't be initialized with ="); + c = expr(); rval(); laddr(lslot[i]); op(O_ST); + if (t) { if (!compat(t, xty)) tcerr("initializer", t, xty); } + else if (!isnum(xty)) ltype[i] = xty; + assigncheck(LV_LOCAL, i, c); + } + if (!accept(s_comma)) break; + } + expect(s_semi); + return 0; +} +fn kw_var() { stmtonly(); next(); return localdecl(0); } +fn kw_if() +{ + let a, b, c, s0, sa, live0, livea, n0 = nloc, nt, cj; + 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(); + join2(sa, livea, b, live, n0, "ends the branches of an if in different states"); + } else { + // the path that skips the then branch still has the states from before it + njps = 0; if (livea) jadd(R_SNAP + sa); if (live0) jadd(R_SNAP + s0); + join(n0, "ends the branches of an if in different states"); + if (livea) fixups(R_SNAP + sa, n0, 1); + nt = 0; if (live0) nt = fixups(R_SNAP + s0, n0, 0); + if (nt) { cj = hole(); op(O_JMP); setlit(a, here); fixups(R_SNAP + s0, n0, 1); setlit(cj, here); } + else setlit(a, here); + live = livea || live0; + } + snap_pop(s0); + return 0; +} +// loop frame: 0 continue target 1 break chain 2 depth 3 snapshot 4 block-expression depth +// loop frame: 0 continue target (-1 for a switch) 2 depth 3 snapshot at the top +// 4 block-expression depth 5 locals at the start 6 its first exit record +fn loop_push(cont, s0) +{ + let f = R_LOOP + lsp * 8; + if (lsp >= 60) fatal("loops nested too deeply"); + f[0] = cont; f[1] = 0; f[2] = fdepth; f[3] = s0; f[4] = bxdepth; f[5] = nloc; f[6] = extop; + lsp++; + return 0; +} +// the end of a loop or switch: join its exits (the fall-out path sc through +// the jump at a, if there is one, and every break) and lay out each path's +// fixups on its way to the end +fn loop_end(a, sc) +{ + let f, p, e, n0, outs = 0; + lsp--; + f = R_LOOP + lsp * 8; + n0 = f[5]; + njps = 0; + if (sc >= 0) jadd(R_SNAP + sc); + p = R_EXIT + f[6]; e = R_EXIT + extop; + while (p < e) { jadd(p + 1); p = p + 3 + 3 * (p[2] - p[1]); } + join(n0, "leaves the loop in different states on different paths"); + live = njps > 0; + p = R_EXIT + f[6]; + while (p < e) { + if (fixups(p + 1, n0, 0)) { setlit(p[0], here); fixups(p + 1, n0, 1); outs = fixnew(hole(), outs); op(O_JMP); } + else outs = fixnew(p[0], outs); + p = p + 3 + 3 * (p[2] - p[1]); + } + if (a >= 0) setlit(a, here); + if (sc >= 0) fixups(R_SNAP + sc, n0, 1); + fixall(outs, here); + extop = f[6]; + return 0; +} +fn kw_while() +{ + let c0 = here, a, s0, sc = -1, c, inf = 0; + stmtonly(); + next(); + s0 = snap_push(); + expect(s_lp); + if (tk == T_NUM && tv) { peek(); if (pk_tk == T_OP && pk_tv == s_rp) inf = 1; } // while (1): no way out but break + c = expr(); rval(); plainuse(c); expect(s_rp); + a = hole(); op(O_JZ); + if (!inf && live) sc = snap_push(); + loop_push(c0, s0); + substmt(); + backedge(s0); + jmp(c0); + loop_end(a, sc); + snap_pop(s0); + return 0; +} +fn kw_for() +{ + let save = nloc, s0, sc = -1, c0, a, b, st, c, inf = 0; + stmtonly(); + next(); + expect(s_lp); + fdepth++; + if (is_id(s_var)) kw_var(); + else if (tstart()) localdecl(1); + 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)) { + if (tk == T_NUM && tv) { peek(); if (pk_tk == T_OP && pk_tv == s_semi) inf = 1; } + c = expr(); rval(); plainuse(c); + } else { lit(1); inf = 1; } + expect(s_semi); + a = hole(); op(O_JZ); + if (!inf && live) sc = snap_push(); + b = hole(); op(O_JMP); + st = here; + if (!is_op(s_rp)) { c = expr(); rval(); op(O_DROP); discard(c); } + expect(s_rp); + jmp(c0); + setlit(b, here); + loop_push(st, s0); + substmt(); + backedge(s0); + jmp(st); + loop_end(a, sc); + snap_pop(s0); + block_close(save); + fdepth--; + return 0; +} +fn kw_break() +{ + let f; + stmtonly(); + next(); expect(s_semi); + if (lsp <= loopbase) { serr("break outside a loop or a switch"); return 0; } + f = R_LOOP + (lsp - 1) * 8; + if (f[4] != bxdepth) { serr("break can't leave a block expression"); return 0; } + exit_vars(f[2] + 1, 0); + if (live) exit_rec(hole()); else hole(); + op(O_JMP); + live = 0; + return 0; +} +fn kw_continue() +{ + let j = lsp - 1, f; + stmtonly(); + next(); expect(s_semi); + while (j >= loopbase && R_LOOP[j * 8] == -1) j--; // past any switch + if (j < loopbase) { serr("continue outside a loop"); return 0; } + f = R_LOOP + j * 8; + if (f[4] != bxdepth) { serr("continue can't leave a block expression"); return 0; } + backedge(f[3]); + exit_vars(f[2] + 1, 0); + jmp(f[0]); + live = 0; + return 0; +} +// switch (e) { case 1, 2: ... case 'x': ... default: ... } +// cases don't fall through: each one ends where the next begins, and break +// leaves the switch early. case labels are constants. +fn casebody(s0, live0) +{ + let save = nloc; + snap_restore(s0); live = live0; + fdepth++; + while (!is_op(s_rb) && !is_id(s_case) && !is_id(s_default)) { if (tk == T_EOF) { die("missing }"); break; } stmt(); } + block_close(save); + fdepth--; + if (live) { exit_rec(hole()); op(O_JMP); } // the end of a case leaves the switch + live = 0; + return 0; +} +fn kw_switch() +{ + let save = nloc, tmp, c, s0, live0, defent = -1, skip, nxt, bj, v, a = -1; + stmtonly(); + next(); + expect(s_lp); c = expr(); rval(); plainuse(c); expect(s_rp); + fdepth++; + tmp = newloc(0); fslots++; // a hidden local holds the value + laddr(lslot[tmp]); op(O_ST); + live0 = live; + s0 = snap_push(); + loop_push(-1, s0); + expect(s_lb); + while (!is_op(s_rb)) { + if (tk == T_EOF) { die("missing }"); break; } + if (is_id(s_case)) { + next(); + bj = 0; + while (1) { + v = cexpr(); + laddr(lslot[tmp]); op(O_LD); lit(v); op(O_SUB); + bj = fixnew(hole(), bj); op(O_JZ); + if (!accept(s_comma)) break; + } + expect(s_colon); + nxt = hole(); op(O_JMP); + fixall(bj, here); + casebody(s0, live0); + setlit(nxt, here); + } else if (is_id(s_default)) { + next(); expect(s_colon); + if (defent >= 0) serr("a switch has one default"); + skip = hole(); op(O_JMP); // only reached when nothing matched + defent = here; + casebody(s0, live0); + setlit(skip, here); + } else die("expected case or default"); + } + next(); + snap_restore(s0); live = live0; + if (defent >= 0) { jmp(defent); loop_end(-1, -1); } + else { a = hole(); op(O_JMP); loop_end(a, s0); } // nothing matched: out with the states from the top + snap_pop(s0); + block_close(save); + fdepth--; + return 0; +} +fn kw_return() +{ + let c; + stmtonly(); + next(); + if (!infn) serr("return outside a function"); + if (bxdepth) serr("return can't leave a block expression"); + if (is_op(s_semi)) { lit(0); c = C_PLAIN; } + else { + c = expr(); rval(); + if (fty == tvoid) tcerr("return value", tvoid, xty); + else if (fty && !compat(fty, xty)) tcerr("return value", fty, xty); + } + 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() +{ + let 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() +{ + let 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) fatal("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_ENH) { op(XOP0 + sval[s]); next(); continue; } + 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) fatal("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) serrn(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, line for each token. names, +// strings and operators are interned pointers. +fn grab() -> .u +{ + let 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 >= 2700) fatal("quote too long"); + R_QBUF[n * 3] = tk; R_QBUF[n * 3 + 1] = tv; R_QBUF[n * 3 + 2] = tline; n++; + next(); + } + next(); + q = new(n * 3 + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n * 3); + return u*q; +} +unchecked fn qnew(src) -> .u { let n = src[0] * 3 + 1, q = new(n); wcopy(q, src, n); return q; } +fn qdup(.m q) -> .u { let n = q[0] * 3 + 1, r = new(n); wcopy(r, q, n); return u*r; } +fn wcopyto(.m q, n) { let i = 0; while (i < n) { emit(q[i]); i++; } return 0; } +fn kw_quote() +{ + let q, j, a, n; + next(); + q = grab(); + j = hole(); op(O_JMP); + a = here; + n = q[0] * 3 + 1; + wcopyto(q, n); + free(d*q); + 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 +{ + let n = 0, q; + src_push(2, s, 0, 0); + next(); + while (tk != T_EOF) { + if (n >= 2700) fatal("too many tokens"); + R_QBUF[n * 3] = tk; R_QBUF[n * 3 + 1] = tv; R_QBUF[n * 3 + 2] = tline; n++; + next(); + } + src_pop(); + q = new(n * 3 + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n * 3); + return u*q; +} +// 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; } + +// ---- reading a unit and scanning it for signatures ---- +// a unit from stdin is read whole first (4 chars to a word), then scanned +// once for fn signatures, so a function's tags are known before its first +// call even when it's defined further down. +unchecked fn readsrc() +{ + let cap = 4090, b = new(4090), n = 0, c, nb, w; + while (!eof()) { + c = getc() & 255; + if (c == 96) break; + if ((n >> 2) + 2 >= cap) { nb = new(cap + cap + 6); wcopy(nb, b, cap); free(b); b = nb; cap = cap + cap + 6; } + w = n >> 2; + if (!(n & 3)) b[w] = 0; + b[w] = b[w] | (c << ((n & 3) * 8)); + n++; + } + b[n >> 2] = b[n >> 2] & (pow2[(n & 3) * 8] - 1); // the 0 at the end + if ((n & 3) == 0) b[n >> 2] = 0; + b[(n >> 2) + 1] = 0; + return b; +} +// skip a <...> group (type parameters) +fn pskipangle() +{ + let dp = 0; + while (tk != T_EOF) { + if (is_op(s_lt)) dp++; + else if (is_op(s_gt)) dp--; + else if (is_op(s_shr)) dp = dp - 2; + next(); + if (dp <= 0) return 0; + } + return 0; +} +// at the name after fn: read the signature's tags and record them +fn prescan_fn() +{ + let n = tv, np = 0, tags = 0, t = 0, ret = 0, dp, s; + if (tk != T_ID) return 0; + next(); + if (is_op(s_lt)) pskipangle(); + if (!is_op(s_lp)) return 0; + next(); + if (!is_op(s_rp)) { + np = 1; dp = 1; + while (tk != T_EOF) { + if (is_op(s_lp)) dp++; + else if (is_op(s_rp)) { dp--; if (!dp) break; } + else if (dp == 1 && is_op(s_comma)) { if (np <= 12) tags = tags + (t << (np + np - 2)); np++; t = 0; } + else if (dp == 1 && is_op(s_dot)) { next(); if (is_id(s_m)) t = 1; else if (is_id(s_d)) t = 2; continue; } + next(); + } + if (np <= 12) tags = tags + (t << (np + np - 2)); + } + next(); + if (accept(s_arrow)) { + while (tk != T_EOF && !is_op(s_lb) && !is_op(s_semi)) { + if (is_op(s_dot)) { next(); if (is_id(s_u)) ret = 1; continue; } + next(); + } + } + s = lookup(n); + if (s < 0 || s < ubase || skind[s] != K_FN || (sflag[s] & F_DEF)) s = fwdfn(n); + if (!(sflag[s] & F_SIG)) { ssig[s] = ret + np + np + tags * 64; sflag[s] = sflag[s] | F_SIG | F_PRE; } + return 0; +} +fn prescan(kind, obj) +{ + let depth = 0, sp = panic, sn = nerr; + dry++; + src_push(kind, obj, 0, 0); + next(); + while (tk != T_EOF) { + if (is_op(s_lb)) depth++; + else if (is_op(s_rb)) depth--; + else if (depth <= 0 && is_id(s_fn)) { next(); prescan_fn(); continue; } + next(); + } + src_pop(); + dry--; panic = sp; nerr = sn; + return 0; +} +// compile a whole unit from stdin +fn unit_stdin() +{ + let src = readsrc(); + prescan(3, src); + src_push(3, src, 0, 0); + next(); + unit_top(); + unit_end(ubase); + src_pop(); + free(src); + 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() +{ + let f = R_CTX + ctxsp * 24; + if (ctxsp >= 30) fatal("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; + f[19] = fty; f[20] = ntp; f[21] = xty; wcopy(f + 22, tpn, 2); + return 0; +} +fn ctx_pop() +{ + let 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]; + fty = f[19]; ntp = f[20]; xty = f[21]; wcopy(tpn, f + 22, 2); + return 0; +} + +// ---- functions and the top level ---- +fn fn_begin(chk, ret) +{ + lbase = nloc; fdepth = 1; fslots = 0; fchk = chk && check_on; fret = ret; fty = 0; + live = 1; bxdepth = 0; epichain = 0; infn = 1; loopbase = lsp; lv = 0; lvk = LV_NONE; + return 0; +} +// fp -= frame size, then check the frame stack: past FBOT, reset fp and stop +fn prologue() +{ + let k; + lit(ZFP); op(O_LD); fframe = hole(); op(O_SUB); lit(ZFP); op(O_ST); + lit(ZFP); op(O_LD); lit(FBOT); op(O_LT); k = hole(); op(O_JZ); + lit(FTOP); lit(ZFP); op(O_ST); callname(s_fovf); + setlit(k, here); + 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(); } + unused_check(lbase); + if (fchk && live) { exit_vars(1, 1); if (fret) cerr("a -> .u function has to end with a return"); } + next(); + return 0; +} +// fn name(int a, *node.m n, .d x, b) -> *list.u { ... } +fn fndef(chk) +{ + let n, s, np = 0, tags = 0, t, ret = 0, sig, i, pn[24], pt[24], pty[24], rty = 0, typed = 0, ft; + next(); + n = name(); + ntp = 0; + if (is_op(s_lt)) { // type parameters + next(); + while (1) { if (ntp >= 8) die("too many type parameters"); tpn[ntp] = name(); ntp++; if (!accept(s_comma)) break; } + closeangle(); + typed = 1; + } + 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; + pty[np] = tword; + if (!is_op(s_dot) && ((tk == T_OP && (tv == s_star || tv == s_lk)) || (tk == T_ID && (tv == s_fn || istypename(tv))))) { + pty[np] = ptype(); typed = 1; + if (isagg(pty[np])) serr("structs and arrays are passed by pointer"); + } + if (accept(s_dot)) { // .m lends, .d takes over + if (tv == s_m) t = 1; else if (tv == s_d) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + 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_op(s_dot)) { rty = ptype(); typed = 1; } + if (accept(s_dot)) { if (!is_id(s_u)) die("the return tag is .u"); next(); ret = 1; } + } + sig = ret + np + np + tags * 64; + if ((sflag[s] & F_SIG) && !(sflag[s] & F_PRE)) { if (ssig[s] != sig) serrn(n, "doesn't match its earlier declaration"); } + else if ((sflag[s] & F_UNTYPED) && (tags || ret)) serrn(n, "was called before its tags were declared; put a prototype above the first call"); + ssig[s] = sig; + sflag[s] = (sflag[s] | F_SIG) - (sflag[s] & F_PRE); + if (ntp) sflag[s] = sflag[s] | F_GEN; + if (typed) { + if (!rty) rty = tword; + ft = tfn(rty, np, pty, sig); + if (stype[s] && stype[s] != ft) serrn(n, "doesn't match its earlier declaration"); + stype[s] = ft; + } + if (accept(s_semi)) { ntp = 0; return s; } + if (sflag[s] & F_DEF) serrn(n, "is defined twice"); + sval[s] = here; + sflag[s] = sflag[s] | F_DEF; + fixall(sfix[s], here); sfix[s] = 0; + fn_begin(chk, ret); + if (typed) fty = rty; + prologue(); + i = 0; + while (i < np) { + t = newloc(pn[i]); fslots++; + ltype[t] = pty[i]; + 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(); + ntp = 0; + return s; +} +// let g = 1, buf[10]; int g = 3; [10]int buf; point origin; +fn gdecl(typed) +{ + let n, a, k, t = 0, s; + if (typed) { dtype(); t = dty; if (dtag) serr("tags go on locals and parameters, not globals"); if (t == tvoid) serr("a variable can't be void"); } + else next(); + while (1) { + n = name(); + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + s = addsym(n, K_GARR, here); + if (!t) t = tword; + stype[s] = tarr(t, k); + k = tsz(stype[s]); + while (k) { emit(0); k--; } + } else if (t && isagg(t)) { + s = addsym(n, K_GARR, here); stype[s] = t; + k = tsz(t); + while (k) { emit(0); k--; } + } else { + a = here; + s = addsym(n, K_GVAR, a); + if (t) stype[s] = t; + 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() +{ + let n; + next(); + while (1) { n = name(); expect(s_eq); addsym(n, K_CONST, cexpr()); if (!accept(s_comma)) break; } + expect(s_semi); + return 0; +} +// enhance name(a, b) [-> n] micro "recipe" [else fn]; +// enhance name(a, b) [-> n] vm { asm } [else fn]; +// lays out the descriptor the install opcode reads, and wires it in right +// away (an image wires its own in when it boots). +fn enhdef() +{ + let n, np = 0, nout = 1, dsc, na, pay, len = 0, kind = 0, i, p, s, slot, r, pn[8]; + next(); + n = name(); + expect(s_lp); + if (!is_op(s_rp)) { while (1) { if (np == 8) die("an enhancement takes at most 8 inputs"); pn[np] = name(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + if (accept(s_arrow)) { if (tk != T_NUM || tv < 0 || tv > 8) die("expected the number of outputs"); nout = tv; next(); } + dsc = here; i = 0; while (i < 7) { emit(0); i++; } + na = here; i = 0; while (i < np) { emit(0); i++; } + i = 0; + while (i < np) { *(na + i + hdelta) = here; p = pn[i]; while (*p) { emit(*p); p++; } emit(0); i++; } + if (accept(s_micro)) { + pay = here; + if (tk != T_STR) die("expected the recipe as a string"); + while (tk == T_STR) { p = tv; while (*p) { emit(*p); p++; } next(); } + emit(0); + } else if (accept(s_vm)) { pay = here; asmblock(); op(O_RET); len = here - pay; kind = 1; } + else die("expected micro or vm"); + slot = nenh; + if (slot >= 512) fatal("all 512 enhancement slots are taken"); + nenh++; + p = dsc + hdelta; + p[0] = slot; p[1] = kind; p[2] = np; p[3] = nout; p[4] = pay; p[5] = len; p[6] = na; + s = addsym(n, K_ENH, slot); + ssig[s] = np + nout * 16 + dsc * 256; + if (accept(s_else)) { r = lookup(tv); if (r < 0) r = fwdfn(tv); next(); sfix[s] = r + 1; } + expect(s_semi); + if (!hdelta) { + r = install(dsc); + if (r < 0) { + if (!sfix[s]) serrn(n, "the enhancement didn't install (see install's codes in core.c)"); + sflag[s] = sflag[s] | F_FALLBACK; + } + } + return 0; +} +// after a syntax error at the top level: skip to something that starts a declaration +fn topsync() +{ + let depth = 0; + while (tk != T_EOF) { + if (is_op(s_lb)) depth++; + else if (is_op(s_rb)) { depth--; if (depth < 0) depth = 0; } + else if (!depth && tk == T_ID && (tv == s_fn || tv == s_var || tv == s_const || tv == s_struct || tv == s_type + || tv == s_enhance || tv == s_typecheck || tv == s_unchecked || tv == s_immediate)) break; + next(); + } + panic = 0; + return 0; +} +fn topitem() +{ + let chk = 1, imm = 0, s, k; + if (panic) return topsync(); + 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) serr("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"); return 0; } + if (is_id(s_var)) return gdecl(0); + if (is_id(s_struct)) { kw_struct(); return 0; } + if (is_id(s_type)) return kw_type(); + if (is_id(s_typecheck)) return kw_typecheck(); + if (is_id(s_enhance)) return enhdef(); + 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; } + } + if (tstart()) return gdecl(1); + die("expected fn, let, const, struct, type or a declaration"); + return 0; +} +fn unit_top() { while (tk != T_EOF) topitem(); return 0; } +fn unit_end(from) +{ + let i = from; + panic = 0; + while (i < nsym) { + if (skind[i] == K_FN && !(sflag[i] & F_DEF) && sfix[i]) { tline = sval[i]; serrn(sname[i], "is used but never defined"); } + i++; + } + if (nerr) giveup(); + 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(q, top) +{ + let hop = -1, entry = 0, from = nsym; + ctx_push(); + if (infn) { hop = hole(); op(O_JMP); } + if (top) prescan(1, q); + 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(q) { return compile_list(q, 0); } +fn load(q) { compile_list(q, 1); return 0; } +fn eval(q) { let f = compile_list(q, 0); return f(); } +fn evals(s) { let q = tokens(s), r = eval(q); free(d*q); 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) +{ + let i = from, p; + while (i < nsym) { + if ((skind[i] >= K_FN && skind[i] <= K_CONST) || skind[i] == K_ENH) { + 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) +{ + let 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; + if (p[0] == K_ENH) { if (p[1] >= nenh) nenh = p[1] + 1; install(p[2] >> 8); } + 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) +{ + let sh = here, sd = hdelta, sl = hlimit, sub = ubase, svl = vislo, sns = nsym, sen = nenh, n; + ubase = nsym; vislo = nsym; nenh = 0; + 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); + unit_stdin(); + *(dst + 5) = here; + blob_emit(ubase); + *(dst + 6) = here; + n = here - org; + popsyms(sns); + ubase = sub; vislo = svl; here = sh; hdelta = sd; hlimit = sl; nenh = sen; + 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 + 1024); + 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_dot = intern("."); s_q = intern("?"); s_case = intern("case"); s_default = intern("default"); s_andand = intern("&&"); s_oror = intern("||"); + s_fn = intern("fn"); s_var = intern("let"); 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"); s_fovf = intern("frame_overflow"); + s_enhance = intern("enhance"); s_micro = intern("micro"); s_vm = intern("vm"); + 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, "idiv"); // native divide, wired in by rt.zc + add_binop("%", 10, "imod"); + add_binop("+", 9, "+"); // 3 + add_binop("-", 9, "-"); // 4 + add_binop("<<", 8, "ishl"); // 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("let", 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("switch", kw_switch, 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); + add_kw("sizeof", kw_sizeof, F_EXPR); + add_kw("typeof", kw_typeof, F_EXPR); + return 0; +} +fn start() +{ + let s, f; + heap_init(); + zc_init(); + blob_load(GORG[5]); + zc_tables(); + types_init(); + here = 0; hdelta = 0; hlimit = HEAP_LO; ptop = 0; + ubase = nsym; vislo = 0; + unit_stdin(); + 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/13-gap-fixes/code/src/rt.zc b/docs/history/13-gap-fixes/code/src/rt.zc new file mode 100644 index 0000000..55b8976 --- /dev/null +++ b/docs/history/13-gap-fixes/code/src/rt.zc @@ -0,0 +1,240 @@ +// ============================================================================ +// 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; + +// ---- virtual enhancements ---- +// install(desc) wires a custom opcode into the cpu (the % opcode). these three +// give the language native division and left shift (zdiv, zmod and zshl +// below are the same thing done in software). they come first, since the +// compiler resolves / % and << to them by name. +fn install(desc) { return asm { desc @ % }; } +enhance idiv(a, b) micro "a = sdiv a b"; +enhance imod(a, b) micro "a = srem a b"; +enhance ishl(a, b) micro "a = shl a b"; + +// ---- 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(s) { let i = 0; while (s[i]) { putc(s[i]); i++; } return 0; } +fn putn(n) +{ + let 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(s) { let n = 0; while (s[n]) n++; return n; } +fn streq(a, b) { let i = 0; while (a[i] && a[i] == b[i]) i++; return a[i] == b[i]; } +fn wcopy(dst, src, n) { let i = 0; while (i < n) { dst[i] = src[i]; i++; } return 0; } +fn wfill(dst, v, n) { let i = 0; while (i < n) { dst[i] = v; i++; } return 0; } + +// ---- arithmetic the hardware doesn't have ---- +let pow2[32]; +let zrem; +fn zudiv(n, dv) +{ + let q = 0, r = 0, i = 30; + if (n < dv) { zrem = n; return 0; } + while (i >= 0) { + r = r + r + ((n >> i) & 1); + q = q + q; + if (r >= dv) { r = r - dv; q++; } + i--; + } + zrem = r; + return q; +} +fn zdiv(a, b) +{ + let 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) { let neg = a < 0; if (b == 0) return a; zdiv(a, b); if (neg) return 0 - zrem; return zrem; } +fn zshl(a, b) { return a * pow2[b & 31]; } + +// ---- heap ---- +// a buddy allocator. the heap is cut into aligned power-of-two chunks, every +// block is a power of two words, and a freed block merges with its buddy +// (the other half of the block they were split from) whenever that one is +// free too, so freed space can be reused at any size. every block has a 6 +// word header before the pointer the program sees: +// p[-6] block size p[-5] size class p[-4] flags (0 free, 1 live, 3 marked) +// p[-3] p ^ MAGIC p[-2] owner (the container that owns it, or 0) +// p[-1] its type (a type record from new(T), or 0 from new(n)) +// free blocks sit on a doubly linked list per class, linked through p[0], p[1]. +const HDR = 6; +let hbump, freel[32], gc_runs, gc_freed, gc_auto = 1; + +// the size of the top-level chunk holding heap offset off +fn topsize(off) +{ + let h = HEAP_HI - HEAP_LO, base = 0, sz; + while (h) { + sz = 1; + while (sz + sz <= h) sz = sz + sz; + if (off < base + sz) return sz; + base = base + sz; h = h - sz; + } + return 0; +} +fn fpush(b, k) { b[2] = 0; b[6] = freel[k]; b[7] = 0; if (freel[k]) freel[k][7] = b; freel[k] = b; return 0; } +fn funlink(b, k) +{ + if (b[7]) b[7][6] = b[6]; else freel[k] = b[6]; + if (b[6]) b[6][7] = b[7]; + return 0; +} +fn mkblock(b, k) { b[0] = pow2[k]; b[1] = k; b[2] = 0; b[3] = 0; b[4] = 0; b[5] = 0; return b; } +fn heap_init() +{ + let i = 1, b = HEAP_LO, sz, k; + pow2[0] = 1; + while (i < 32) { pow2[i] = pow2[i - 1] + pow2[i - 1]; i++; } + hbump = HEAP_HI; + wfill(freel, 0, 32); + while (b < HEAP_HI) { + sz = topsize(b - HEAP_LO); k = 0; + while (pow2[k] < sz) k++; + fpush(mkblock(b, k), k); + b = b + sz; + } + return 0; +} +// a free block of class k, split down from a bigger one if needed; 0 if none +fn balloc(k) +{ + let j = k, b, h; + while (j < 32 && !freel[j]) j++; + if (j >= 32) return 0; + b = freel[j]; + funlink(b, j); + while (j > k) { j--; h = b + pow2[j]; fpush(mkblock(h, j), j); } + mkblock(b, k); + return b; +} +let fend; // end of the block bfree last made, for the sweep +// put block b back, merging it with its buddy as long as it can +fn bfree(b) +{ + let k = b[1], sz = pow2[k], off, bud; + while (1) { + off = b - HEAP_LO; + if (sz >= topsize(off)) break; + bud = HEAP_LO + (off ^ sz); + if (bud[2] != 0 || bud[1] != k || bud[0] != sz) break; + funlink(bud, k); + if (bud < b) { b[0] = 0; b[3] = 0; b = bud; } // the upper header is inside the merged block now + else { bud[0] = 0; bud[3] = 0; } + k++; sz = sz + sz; + mkblock(b, k); + } + fpush(mkblock(b, k), k); + fend = b + sz; + return 0; +} +fn isobj(x) { return x >= HEAP_LO + HDR && x < hbump && x[-3] == (x ^ MAGIC) && (x[-4] & 1); } + +// every prologue checks the frame stack; on overflow it resets the frame +// pointer (so this can run at all) and stops +fn frame_overflow() { puts("zy: frame stack overflow\n"); halt(); return 0; } +fn oom() { puts("zc: out of heap memory\n"); halt(); return 0; } +// n words typed t +unchecked fn new_t(n, t) -> .u +{ + let need = n + HDR, k = 3, b, p; + if (n < 0) need = HDR; + while (pow2[k] < need) k++; + b = balloc(k); + if (!b && gc_auto) { gc(); b = balloc(k); } + if (!b) oom(); + p = b + HDR; + b[2] = 1; b[3] = p ^ MAGIC; b[4] = 0; b[5] = t; + wfill(p, 0, pow2[k] - HDR); + return p; +} +unchecked fn new(n) -> .u { return new_t(n, 0); } +fn osize(p) { if (!isobj(p)) return 0; return p[-6] - HDR; } +fn typeof_obj(p) { if (!isobj(p)) return 0; return p[-1]; } + +// frees p and, recursively, every object p owns +fn release(p) +{ + let b = p - HDR, n = b[0] - HDR, i = 0, w; + b[2] = 0; + while (i < n) { w = p[i]; if (isobj(w) && w[-2] == p) release(w); i++; } + bfree(b); + return 0; +} +unchecked fn free(.d p) { if (isobj(p)) release(p); return 0; } +fn own(c, p) { if (isobj(c)) c[-2] = 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. +let ms_top, ms_over, gc_lo, gc_hi; +fn mark(w) +{ + if (!isobj(w) || (w[-4] & 2)) return 0; + w[-4] = w[-4] | 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() +{ + let p; + while (ms_top) { ms_top--; p = MARK0[ms_top]; markrange(p, p + p[-6] - HDR); } + return 0; +} +fn gc_roots(); +unchecked fn gc() +{ + let 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 < HEAP_HI) { if (b[2] == 3) markrange(b + HDR, b + b[0]); b = b + b[0]; drain(); } + } + b = HEAP_LO; + while (b < HEAP_HI) { + sz = b[0]; + if (b[2] == 1) { bfree(b); n++; b = fend; } // merging may swallow what follows + 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() { let b = HEAP_LO, n = 0; while (b < HEAP_HI) { if (b[2] & 1) n++; b = b + b[0]; } return n; } +// the biggest block that's free right now, in words +fn largest_free() { let k = 31; while (k > 0 && !freel[k]) k--; if (!freel[k]) return 0; return pow2[k]; } diff --git a/docs/history/13-gap-fixes/code/test.sh b/docs/history/13-gap-fixes/code/test.sh new file mode 100755 index 0000000..e28182d --- /dev/null +++ b/docs/history/13-gap-fixes/code/test.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# full check: bootstraps the compiler from zc0, verifies the fixpoint, then runs +# the examples and tests on the portable interpreter (host), the arm64 jit under +# qemu, and the llvm backend. needs gcc; the jit half needs aarch64-linux-gnu-gcc +# and qemu-aarch64, the llvm half needs llvm-config and libLLVM (each is skipped +# if 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 < examples/typed.zc | tr '\n' '/')" "last: 4/point is 2 words: x int, y int/vec<*point> is 3 words: len int, cap int, items **point/push is fn(*vec, T.d) -> bool/the heap says v is a vec, and v.items[0] is a point/" "$l typed example" + chk "$($vm < examples/wiring.zc)" "16 1234 25 4/9" "$l enhancement example" + 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" + chk "$($vm < tests/types.zc | tr '\n' '/')" "12 5 2 15 56 42 7 14 3/rect *rect *list fn(int) -> *list.u fn(*list) -> T fn(word.d)/a:point@0 b:point@2 tag:int@4 /point 1 1/" "$l types, generics, reflection" + chk "$($vm < tests/typeok.zc)" "14" "$l a program the typechecker accepts" + chk "$($vm < tests/typeoff.zc)" "6" "$l the typechecker is off by default" + chk "$($vm < tests/enhance.zc)" "100 0 343 3,2 5 -2 0" "$l virtual enhancements" + chk "$($vm < tests/joins.zc)" "0 0 5 80 8 3 9 0" "$l joins free what one path gave away; switch, ?:, no prototypes" + chk "$($vm < tests/buddy.zc)" "131072 262144 1 0" "$l buddy allocator merges freed blocks" + chk "$($vm < tests/borrowmove.zc)" "6" "$l storing into a borrowed object moves it" + chk "$($vm < tests/manyerrors.zc | tr '\n' '/')" "zc: line 3: expected an expression/zc: line 4: x: m object is never used/zc: line 5: type error: initializer: expected *char, got int/zc: line 6: expected ;/zc: 4 errors/" "$l several errors in one run" + chk "$($vm < tests/overflow_return.zc 2>&1)" "zy: return stack overflow" "$l return stack overflow is caught" + chk "$($vm < tests/overflow_data.zc 2>&1)" "zy: data stack overflow" "$l data stack overflow is caught" + chk "$($vm < tests/overflow_frame.zc 2>&1)" "zy: frame stack overflow" "$l frame stack overflow is caught" + local r; r=$(tests/runerr.sh "$vm" tests/errors | tail -1) + chk "$r" "rejected: $(ls tests/errors/*.zc | wc -l) passed, 0 failed" "$l analyzer rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/typeerrors | tail -1) + chk "$r" "rejected: $(ls tests/typeerrors/*.zc | wc -l) passed, 0 failed" "$l typechecker 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 +if command -v llvm-config >/dev/null; then + gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c -o $T/zyl $(llvm-config --ldflags --libs) || exit 1 + run $T/zyl "llvm" + printf '#!/bin/sh\nZYHOT=1 exec %s "$@"\n' $T/zyl > $T/llall; chmod +x $T/llall + chk "$($T/llall < tests/types.zc | md5sum)" "$($T/zy < tests/types.zc | md5sum)" "llvm compiling every block agrees" + selfc $T/zyl $T/gl.bin; cmp -s $T/g1.bin $T/gl.bin && chk 1 1 "llvm self-compile matches" || chk 0 1 "llvm self-compile matches" +else echo "skip llvm (no llvm-config)"; fi +echo "$ok passed, $bad failed"; [ $bad = 0 ] diff --git a/docs/history/13-gap-fixes/code/tests/basics.zc b/docs/history/13-gap-fixes/code/tests/basics.zc new file mode 100644 index 0000000..c1f1faf --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/basics.zc @@ -0,0 +1,22 @@ +let table[10]; +let 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() +{ + let i, s = 0, a[5]; + for (i = 0; i < N; i++) table[i] = i * i; + for (let 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); + let b = { let 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); + let x = asm { 2 3 + }; + putn(x); putc(10); + asm { 'o' . 'k' . 10 . } + return 0; +} diff --git a/docs/history/13-gap-fixes/code/tests/borrowmove.zc b/docs/history/13-gap-fixes/code/tests/borrowmove.zc new file mode 100644 index 0000000..43f27b2 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/borrowmove.zc @@ -0,0 +1,2 @@ +fn put(.m box, int v) { *int c = new(int); *c = v; box[0] = c; return 0; } +fn main() { let b = new(1); put(b, 6); putn(*(b[0] as *int)); putc(10); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/buddy.zc b/docs/history/13-gap-fixes/code/tests/buddy.zc new file mode 100644 index 0000000..2000598 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/buddy.zc @@ -0,0 +1,15 @@ +// the buddy allocator: 20000 small blocks, freed, merge back into one big one +let keep[20000]; +fn main() +{ + let i = 0, p; + while (i < 20000) { keep[i] = new(2); i++; } // 20000 8-word blocks + putn(largest_free()); putc(' '); + i = 0; while (i < 20000) { free(keep[i]); i++; } + putn(largest_free()); putc(' '); + p = new(200000); // only possible if the small blocks merged back + putn(osize(p) >= 200000); putc(' '); + free(d*p); + putn(live_objects()); putc(10); + return 0; +} diff --git a/docs/history/13-gap-fixes/code/tests/enhance.zc b/docs/history/13-gap-fixes/code/tests/enhance.zc new file mode 100644 index 0000000..6acc742 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/enhance.zc @@ -0,0 +1,29 @@ +// custom opcodes: recipes, lifted vm code, several outputs, and a fallback +enhance clampadd(a, b) micro "a = add a b; a = min a 100; a = max a 0"; +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance divmod(a, b) -> 2 micro "r2 = sdiv a b" "\n r1 = srem a b\n r0 = r2"; +enhance div7(a) micro "a = sdiv a 7"; +enhance urem10(a) micro "a = urem a 10"; +enhance hi(a, b) micro "a = mulhu a b"; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // i/o can't be lifted, so calls use the fallback +fn soft_noisy(x) { return x + 1; } +let qq, rr, seed = 7; +fn rnd() { seed = seed * 1103515245 + 12345; return seed ^ (seed >> 11); } +fn main() +{ + let i = 0, a, bad = 0; + putn(clampadd(70, 50)); putc(' '); putn(clampadd(-50, 2)); putc(' '); putn(cube(7)); putc(' '); + asm { 17 5 divmod rr ! qq ! } + putn(qq); putc(','); putn(rr); putc(' '); + putn(noisy(4)); putc(' '); + putn(hi(-1, -1)); putc(' '); + while (i < 5000) { + a = rnd(); + if (div7(a) != zdiv(a, 7)) bad++; + if (urem10(a) < 0 || urem10(a) > 9) bad++; + if (a / (i + 1) != zdiv(a, i + 1)) bad++; + i++; + } + putn(bad); putc(10); + return 0; +} diff --git a/docs/history/13-gap-fixes/code/tests/errors/back_to_m.zc b/docs/history/13-gap-fixes/code/tests/errors/back_to_m.zc new file mode 100644 index 0000000..b8c160f --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/back_to_m.zc @@ -0,0 +1,2 @@ +// expect: x: can't be recast back to m +fn main() { let x = new(3); d*x; m*x; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/borrow_escape.zc b/docs/history/13-gap-fixes/code/tests/errors/borrow_escape.zc new file mode 100644 index 0000000..ce24480 --- /dev/null +++ b/docs/history/13-gap-fixes/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() { let x = new(1); f(x); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/branch_mismatch.zc b/docs/history/13-gap-fixes/code/tests/errors/branch_mismatch.zc new file mode 100644 index 0000000..bd19968 --- /dev/null +++ b/docs/history/13-gap-fixes/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() { let x = new(1); if (x[0]) take(d*x); else u*x; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/child_dies.zc b/docs/history/13-gap-fixes/code/tests/errors/child_dies.zc new file mode 100644 index 0000000..67caca9 --- /dev/null +++ b/docs/history/13-gap-fixes/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() { let p = new(2), c = new(1); p[0] = c; take(d*p); return c[0]; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/child_recast.zc b/docs/history/13-gap-fixes/code/tests/errors/child_recast.zc new file mode 100644 index 0000000..c9ccd62 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/child_recast.zc @@ -0,0 +1,2 @@ +// expect: c: belongs to a container; recast the container instead +fn main() { let p = new(2), c = new(1); p[0] = c; d*c; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/copy_owned.zc b/docs/history/13-gap-fixes/code/tests/errors/copy_owned.zc new file mode 100644 index 0000000..862c7ef --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/copy_owned.zc @@ -0,0 +1,2 @@ +// expect: x: is an owned object and can't be copied +fn main() { let x = new(1); let y = x; return y[0]; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/d_into_block.zc b/docs/history/13-gap-fixes/code/tests/errors/d_into_block.zc new file mode 100644 index 0000000..2d7f526 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/d_into_block.zc @@ -0,0 +1,2 @@ +// expect: x: used after it was given away +fn main() { let x = new(1); d*x; { x[0] = 5; } return x[0]; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/d_kept.zc b/docs/history/13-gap-fixes/code/tests/errors/d_kept.zc new file mode 100644 index 0000000..dcbfb86 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/d_kept.zc @@ -0,0 +1,2 @@ +// expect: x: d object was never given away +fn main() { let x = new(3); d*x; x[0] = 1; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/discard_u.zc b/docs/history/13-gap-fixes/code/tests/errors/discard_u.zc new file mode 100644 index 0000000..dd76e94 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/discard_u.zc @@ -0,0 +1,3 @@ +// expect: can't be thrown away +fn mk() -> .u { let p = new(1); return u*p; } +fn main() { mk(); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/give_m.zc b/docs/history/13-gap-fixes/code/tests/errors/give_m.zc new file mode 100644 index 0000000..cd67896 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/give_m.zc @@ -0,0 +1,3 @@ +// expect: x: is m; write d*x +fn take(.d p) { return p[0]; } +fn main() { let x = new(3); take(x); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/global_store.zc b/docs/history/13-gap-fixes/code/tests/errors/global_store.zc new file mode 100644 index 0000000..dc0e546 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/global_store.zc @@ -0,0 +1,3 @@ +// expect: x: must be d to be stored in a global +let g; +fn main() { let x = new(1); g = x; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/leak_overwrite.zc b/docs/history/13-gap-fixes/code/tests/errors/leak_overwrite.zc new file mode 100644 index 0000000..d19b5fd --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/leak_overwrite.zc @@ -0,0 +1,2 @@ +// expect: x: still owns an object +fn main() { let x = new(1); x = new(2); return x[0]; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/lend_d.zc b/docs/history/13-gap-fixes/code/tests/errors/lend_d.zc new file mode 100644 index 0000000..55ac7e0 --- /dev/null +++ b/docs/history/13-gap-fixes/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() { let x = new(3); d*x; look(x); take(x); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/loop_move.zc b/docs/history/13-gap-fixes/code/tests/errors/loop_move.zc new file mode 100644 index 0000000..df3c94a --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/loop_move.zc @@ -0,0 +1,3 @@ +// expect: x: is given away inside a loop that comes back around to it +fn take(.d p) { return p[0]; } +fn main() { let x = new(1); let i = 0; d*x; while (i < 3) { take(x); i++; } return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/plain_return.zc b/docs/history/13-gap-fixes/code/tests/errors/plain_return.zc new file mode 100644 index 0000000..4540714 --- /dev/null +++ b/docs/history/13-gap-fixes/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/13-gap-fixes/code/tests/errors/return_m.zc b/docs/history/13-gap-fixes/code/tests/errors/return_m.zc new file mode 100644 index 0000000..1acc4be --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/return_m.zc @@ -0,0 +1,3 @@ +// expect: x: has to be u to be returned +fn mk() -> .u { let x = new(1); return x; } +fn main() { let y = mk(); return y[0]; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/tag_mismatch.zc b/docs/history/13-gap-fixes/code/tests/errors/tag_mismatch.zc new file mode 100644 index 0000000..079f249 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/tag_mismatch.zc @@ -0,0 +1,2 @@ +// expect: c: its tag doesn't match its container's +fn main() { let p = new(2), c = new(1); u*p; p[0] = c; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/u_dropped.zc b/docs/history/13-gap-fixes/code/tests/errors/u_dropped.zc new file mode 100644 index 0000000..e1ca68a --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/u_dropped.zc @@ -0,0 +1,2 @@ +// expect: x: u object must leave this block +fn main() { let x = new(3); u*x; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/u_skip_level.zc b/docs/history/13-gap-fixes/code/tests/errors/u_skip_level.zc new file mode 100644 index 0000000..6caeeb3 --- /dev/null +++ b/docs/history/13-gap-fixes/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() { let r; { { let t = new(1); u*t; r = t; } } return r[0]; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/unchecked_touch.zc b/docs/history/13-gap-fixes/code/tests/errors/unchecked_touch.zc new file mode 100644 index 0000000..141639d --- /dev/null +++ b/docs/history/13-gap-fixes/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() { let x = new(1); unchecked { x[0] = 1; } return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/unused.zc b/docs/history/13-gap-fixes/code/tests/errors/unused.zc new file mode 100644 index 0000000..64aff1f --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/errors/unused.zc @@ -0,0 +1,2 @@ +// expect: x: m object is never used +fn main() { let x = new(3); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/errors/use_after_give.zc b/docs/history/13-gap-fixes/code/tests/errors/use_after_give.zc new file mode 100644 index 0000000..8a10922 --- /dev/null +++ b/docs/history/13-gap-fixes/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() { let x = new(3); take(d*x); return x[0]; } diff --git a/docs/history/13-gap-fixes/code/tests/gc.zc b/docs/history/13-gap-fixes/code/tests/gc.zc new file mode 100644 index 0000000..41f14a0 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/gc.zc @@ -0,0 +1,20 @@ +let keep; +unchecked fn churn(n) +{ + let i = 0, p; + while (i < n) { p = new(10); p[0] = i; if (i % 100 == 0) keep = p; i++; } + return 0; +} +fn main() +{ + let 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/13-gap-fixes/code/tests/joins.zc b/docs/history/13-gap-fixes/code/tests/joins.zc new file mode 100644 index 0000000..a272e08 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/joins.zc @@ -0,0 +1,32 @@ +// joins: something given away on one path is dead afterwards, and the paths +// that still own it free it on the way in. nothing here leaks. +fn take(.d p) { return p[0]; } +fn later(.d p); // not needed any more, but still allowed +fn mk(int v) -> *int.u { *int p = new(int); *p = v; return u*p; } +fn count(int n) { let s = 0; switch (n % 4) { case 0: s = 10; case 1, 2: s = 20; break; default: s = 30; } return s; } +fn main() +{ + let base = live_objects(), i = 0, hits = 0, k; + while (i < 50) { + let x = mk(i); + if (i % 3 == 0) take(d*x); // else: freed here by the fixup + i++; + } + putn(live_objects() - base); putc(' '); + // give away and break: fine now; the normal exit frees it + i = 0; + let y = mk(7); + while (i < 10) { if (i == 4) { take(d*y); break; } i++; } + putn(live_objects() - base); putc(' '); + let z = mk(5); + while (1) { if (z[0] == 5) { hits = take(d*z); break; } } + putn(hits); putc(' '); + putn(count(0) + count(1) + count(2) + count(3)); putc(' '); + k = i > 3 ? i * 2 : 0 - 1; + putn(k); putc(' '); + putn(forward(new(int))); putc(' '); // tagged and defined below: the prescan knows .d + **int pp; *int q = new(int); *q = 9; pp = &q; putn(**pp); free(d*q); putc(' '); + putn(live_objects() - base); putc(10); + return 0; +} +fn forward(*int.d p) { return 3 + *p; } diff --git a/docs/history/13-gap-fixes/code/tests/manyerrors.zc b/docs/history/13-gap-fixes/code/tests/manyerrors.zc new file mode 100644 index 0000000..7c9febf --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/manyerrors.zc @@ -0,0 +1,6 @@ +// several errors in one run: a syntax error, an analyzer error, a type error +typecheck on; +fn f() { let a = ; return 0; } +fn g() { let x = new(3); return 0; } +fn h() -> int { *char s = 5; return 1; } +fn main() { return 0 } diff --git a/docs/history/13-gap-fixes/code/tests/meta.zc b/docs/history/13-gap-fixes/code/tests/meta.zc new file mode 100644 index 0000000..bc89454 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/meta.zc @@ -0,0 +1,46 @@ +fn ipow(a, b) { let 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() +{ + let 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() +{ + let n, body, i = 0; + next(); n = tv; next(); + body = grab(); + while (i < n) { feed(qdup(body)); i++; } + free(d*body); + 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); + let q = quote { putn(40 + 2); putc(10); return 7; }; + putn(q[0]); putc(' '); + putn(eval(q)); putc(10); + let f = compile(q); + putn(f()); putc(10); + free(d*q); + let defs = quote { fn sq(x) { return x * x; } }; + load(defs); + free(d*defs); + putn(evals("return sq(12);")); putc(10); + return 0; +} diff --git a/docs/history/13-gap-fixes/code/tests/misc.zc b/docs/history/13-gap-fixes/code/tests/misc.zc new file mode 100644 index 0000000..25fc53b --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/misc.zc @@ -0,0 +1,30 @@ +// ct { ... } runs a block while compiling and leaves its result as a constant +immediate fn ct() +{ + let q, v; + next(); + q = grab(); + v = eval(q); + free(d*q); + 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 { let 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() { let p = new(3); p[0] = 'o'; p[1] = 'k'; return p; } diff --git a/docs/history/13-gap-fixes/code/tests/overflow_data.zc b/docs/history/13-gap-fixes/code/tests/overflow_data.zc new file mode 100644 index 0000000..3042f0a --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/overflow_data.zc @@ -0,0 +1 @@ +fn main() { while (1) asm { 1 } return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/overflow_frame.zc b/docs/history/13-gap-fixes/code/tests/overflow_frame.zc new file mode 100644 index 0000000..3897bf4 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/overflow_frame.zc @@ -0,0 +1,2 @@ +fn big(n) { let a[500]; a[0] = n; return big(n + 1) + a[0]; } +fn main() { return big(0); } diff --git a/docs/history/13-gap-fixes/code/tests/overflow_return.zc b/docs/history/13-gap-fixes/code/tests/overflow_return.zc new file mode 100644 index 0000000..9d5c622 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/overflow_return.zc @@ -0,0 +1,2 @@ +fn deep(n) { return deep(n + 1) + 1; } +fn main() { return deep(0); } diff --git a/docs/history/13-gap-fixes/code/tests/runerr.sh b/docs/history/13-gap-fixes/code/tests/runerr.sh new file mode 100755 index 0000000..23ea054 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/runerr.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# runs every .zc in a folder (tests/errors by default) and checks the compiler +# rejects it with the message on its first line: // expect: ... +vm=${1:-zy}; dir=${2:-$(dirname "$0")/errors}; pass=0; fail=0 +for f in "$dir"/*.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 "rejected: $pass passed, $fail failed" diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/arg.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/arg.zc new file mode 100644 index 0000000..b762c19 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/arg.zc @@ -0,0 +1,5 @@ +// expect: type error: argument: expected *point, got *int +typecheck on; +struct point { int x, y; }; +fn f(*point p) -> int { return p.x; } +fn main() { *int q = new(int); f(q); free(d*q); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/arith.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/arith.zc new file mode 100644 index 0000000..76e3111 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/arith.zc @@ -0,0 +1,3 @@ +// expect: type error: arithmetic needs numbers, got *int +typecheck on; +fn main() { *int p = 0; int x = p * 2; return x; } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/assign.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/assign.zc new file mode 100644 index 0000000..8b8a888 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/assign.zc @@ -0,0 +1,3 @@ +// expect: type error: initializer: expected *char, got int +typecheck on; +fn main() { *char s = 5; return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/call.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/call.zc new file mode 100644 index 0000000..7b03dbf --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/call.zc @@ -0,0 +1,3 @@ +// expect: type error: only functions can be called, got int +typecheck on; +fn main() { int k = 3; return k(1); } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/deref.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/deref.zc new file mode 100644 index 0000000..ed030f5 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/deref.zc @@ -0,0 +1,3 @@ +// expect: type error: only pointers can be dereferenced, got int +typecheck on; +fn main() { int x = 3; return *x; } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/field.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/field.zc new file mode 100644 index 0000000..ba03697 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/field.zc @@ -0,0 +1,3 @@ +// expect: point has no field z +struct point { int x, y; }; +fn main() { point p; return p.z; } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/generic.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/generic.zc new file mode 100644 index 0000000..4a502ce --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/generic.zc @@ -0,0 +1,4 @@ +// expect: type error: argument: expected int, got *char +typecheck on; +fn same(T a, T b) -> T { return a; } +fn main() { return same(1, "x"); } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/notstruct.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/notstruct.zc new file mode 100644 index 0000000..0dff6bd --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/notstruct.zc @@ -0,0 +1,2 @@ +// expect: .x: that's a int, not a struct or a pointer to one +fn main() { int n = 1; return n.x; } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/ret.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/ret.zc new file mode 100644 index 0000000..cedd534 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/ret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected bool, got *char +typecheck on; +fn f() -> bool { return "no"; } +fn main() { return f(); } diff --git a/docs/history/13-gap-fixes/code/tests/typeerrors/voidret.zc b/docs/history/13-gap-fixes/code/tests/typeerrors/voidret.zc new file mode 100644 index 0000000..a897290 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeerrors/voidret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected void, got int +typecheck on; +fn f() -> void { return 3; } +fn main() { f(); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/typeoff.zc b/docs/history/13-gap-fixes/code/tests/typeoff.zc new file mode 100644 index 0000000..e44e450 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeoff.zc @@ -0,0 +1,2 @@ +// the typechecker is off unless asked for: this mismatch compiles and runs +fn main() { *char s = 5; putn(s as int + 1); putc(10); return 0; } diff --git a/docs/history/13-gap-fixes/code/tests/typeok.zc b/docs/history/13-gap-fixes/code/tests/typeok.zc new file mode 100644 index 0000000..3cdee0c --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/typeok.zc @@ -0,0 +1,22 @@ +// passes the typechecker: words mix with everything, literal 0 is null, +// arrays decay to pointers, generic calls bind their parameters +typecheck on; +struct pair { A a; B b; }; +fn mk(A x, B y) -> *pair.u { *pair p = new(pair); p.a = x; p.b = y; return u*p; } +fn left(*pair p) -> A { return p.a; } +fn strlen2(*char s) -> int { int n = 0; while (s[n]) n++; return n; } +fn main() -> int +{ + *pair p = mk(3, "four"); + int a = left(p); + *char s = p.b; + [8]char buf; + *char q = buf; + *int nothing = 0; + let w = 5; + int mixed = w + 1; + q[0] = 'h'; q[1] = 0; + putn(a + strlen2(s) + strlen2(buf) + mixed); putc(10); + free(d*p); + return 0; +} diff --git a/docs/history/13-gap-fixes/code/tests/types.zc b/docs/history/13-gap-fixes/code/tests/types.zc new file mode 100644 index 0000000..ccbbd26 --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/types.zc @@ -0,0 +1,57 @@ +struct point { int x, y; }; +struct rect { point a, b; int tag; }; +struct list { int len; *T items; }; +struct node { int v; *node next; }; +type num = int; + +int counter = 5; +[4]int squares; +point origin; + +fn area(*rect r) -> int { return (r.b.x - r.a.x) * (r.b.y - r.a.y); } +fn mklist(int cap) -> *list.u +{ + *list l = new(list); + l.len = 0; + l.items = new(T, cap) as *T; + return u*l; +} +fn first(*list l) -> T { return l.items[0]; } +fn sum(*node n) -> int { int s = 0; while (n) { s += n.v; n = n.next; } return s; } + +fn main() +{ + rect r; + r.a.x = 1; r.a.y = 2; r.b.x = 4; r.b.y = 6; + putn(area(&r)); putc(' '); + putn(sizeof(rect)); putc(' '); putn(sizeof(point)); putc(' '); putn(sizeof([3]rect)); putc(' '); + let p = new(point); // let infers *point + p.x = 7; p->y = 8; + putn(p.x * p.y); putc(' '); + free(d*p); + *list l = mklist(4); + l.items[0] = 42; l.len = 1; + putn(first(l)); putc(' '); + free(d*l); + *node a = new(node), b = new(node); + a.v = 3; b.v = 4; a.next = b; + putn(sum(a)); putc(' '); + free(d*a); // b went with it: a.next = b made a its owner + [3]point pts; + pts[2].y = 9; + putn(pts[2].y + counter); putc(' '); + num k = 3; + putn(k); putc(10); + + // reflection + tprint(typeof(r)); putc(' '); tprint(typeof(&r)); putc(' '); tprint(typeof(l)); putc(' '); + tprint(sigof(mklist)); putc(' '); tprint(sigof(first)); putc(' '); tprint(sigofs("free")); putc(10); + let t = typeof(r), i = 0; + while (i < tnfields(t)) { puts(tfname(t, i)); putc(':'); tprint(tftype(t, i)); putc('@'); putn(tfoff(t, i)); putc(' '); i++; } + putc(10); + *point q = new(point); + tprint(typeof_obj(q)); putc(' '); putn(typeof_obj(q) == typeof(point)); putc(' '); putn(tkind(typeof_obj(q)) == TY_STRUCT); + free(d*q); + putc(10); + return 0; +} diff --git a/docs/history/13-gap-fixes/code/tests/umd.zc b/docs/history/13-gap-fixes/code/tests/umd.zc new file mode 100644 index 0000000..ee463bf --- /dev/null +++ b/docs/history/13-gap-fixes/code/tests/umd.zc @@ -0,0 +1,52 @@ +// lists as [len, items...], items owned by the list +fn mklist(n) -> .u +{ + let l = new(n + 1); + l[0] = 0; + return u*l; +} +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn sum(.m l) { let s = 0, i = 1; while (i <= l[0]) { s += l[i][0]; i++; } return s; } +fn box(v) -> .u { let b = new(1); b[0] = v; return u*b; } +fn consume(.d b) { return b[0]; } + +fn main() +{ + let base = live_objects(); + { + let l = mklist(8); // u from mklist arrives m*here + let i = 0; + while (i < 5) { + let b = box(i * 10); // m in the loop body + d*b; // 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 + let outer; + { + let t = box(7); + u*t; + outer = t; + } + let v = { let w = box(8); u*w }; + putn(outer[0] + v[0]); putc(' '); + + // d given away to a callee + let g = box(99); + putn(consume(d*g)); putc(' '); + + // containers: child takes its parent's tag + let 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/13-gap-fixes/code/tools/build.zc b/docs/history/13-gap-fixes/code/tools/build.zc new file mode 100644 index 0000000..a38e97f --- /dev/null +++ b/docs/history/13-gap-fixes/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() +{ + let 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/13-gap-fixes/code/zc0.c b/docs/history/13-gap-fixes/code/zc0.c new file mode 100644 index 0000000..4df587e --- /dev/null +++ b/docs/history/13-gap-fixes/code/zc0.c @@ -0,0 +1,460 @@ +/* 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 +#include +#include +#include + +#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, K_KW, K_ENH }; +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, ""); 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 if (tk == T_ID && (!strcmp(ts, "u") || !strcmp(ts, "m") || !strcmp(ts, "d"))) { next(); expect("*"); unary(); } /* u*x: a recast, no code */ + 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("let") || 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("let") || 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 (accept(".")) { /* .m name, .d name */ + if (is("m")) t = 1; else if (is("d")) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + if (np < 12) tags += t << (2 * np); + strcpy(pn[np++], ident()); + } while (accept(",")); + expect(")"); + } + if (accept("->")) { expect("."); if (strcmp(ident(), "u")) die("the return tag is -> .u"); 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; +} +/* enhance name(params) [-> n] micro "recipe"; or ... vm { asm }; + emits the install descriptor; the booted genome installs it */ +static int nenh; +static void enhdef(void) +{ + char *n = ident(), pn[8][64]; int np = 0, nout = 1, d, na, pay, len = 0, i, j; Sym *s; + expect("("); + if (!accept(")")) { do { if (np == 8) die("at most 8 inputs"); strcpy(pn[np++], ident()); } while (accept(",")); expect(")"); } + if (accept("->")) { nout = tv; next(); } + d = here; for (i = 0; i < 7; i++) emit(0); + na = here; for (i = 0; i < np; i++) emit(0); + for (i = 0; i < np; i++) { img[na + i - GORG] = here; for (j = 0; pn[i][j]; j++) emit((unsigned char)pn[i][j]); emit(0); } + if (accept("micro")) { pay = here; while (tk == T_STR) { for (j = 0; ts[j]; j++) emit((unsigned char)ts[j]); next(); } emit(0); } + else if (accept("vm")) { pay = here; asmblock(); op(O_RET); len = here - pay; img[d + 1 - GORG] = 1; } + else die("expected micro or vm"); + img[d - GORG] = nenh; img[d + 2 - GORG] = np; img[d + 3 - GORG] = nout; + img[d + 4 - GORG] = pay; img[d + 5 - GORG] = len; img[d + 6 - GORG] = na; + s = add(n, K_ENH, nenh++); s->sig = np + nout * 16 + d * 256; + expect(";"); +} +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("enhance")) { enhdef(); continue; } + if (accept("let") || 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; +} diff --git a/docs/history/13-gap-fixes/notes.md b/docs/history/13-gap-fixes/notes.md new file mode 100644 index 0000000..f7e5ab5 --- /dev/null +++ b/docs/history/13-gap-fixes/notes.md @@ -0,0 +1,48 @@ +# gap fixes + +code/ next to this file is the tree at the end of this stage. + +## message 13 + +> gaps +> 1. when there's a var state change to d, mark that var as dead by default for any other scope that can access it afterwards. u is fine since it just returns +> 2. any suggestions for a cheap fix? +> 3. it's fine, rare occurrence (probably?), suggest a fix +> 4. fix that +> 5. suggest a fix +> 6. fix +> 7. fix + +**summary:** the numbers followed the gap list from my previous chat message. here's what each one got. + +**1. joins.** a variable that became d, or was given away, on any path is dead after the join, and fixup code frees it on the paths that still own it. a loop's exit state is the join of its breaks and its normal exit. giving something away on a path that loops back is still an error. u and borrows don't get the dead treatment. + +**2, 3 and 5.** suggestions only, now under open ends: a quarantine on reuse plus "borrowed from" marks on pointer-typed values for aliases, a stack-depth opcode for the collector, and page-indexed invalidation plus per-slot install tracking for the jit. + +**4. heap.** a buddy allocator. + +**6. stack checks.** all three stacks are checked: data and return at every block exit on all backends, and frames in every prologue. + +**7. the small stuff.** error recovery with up to 20 reported errors, line numbers carried in token lists, a signature prescan over the whole unit so prototypes are optional, storing into a borrowed object moving the object automatically, `?:`, and go-style `switch`. on the side, a 4-token lookahead fixed `**` declarations. + +## message 14 + +> how costly is it if we add a counter to each block to see how many times it runs, then run the optimizer on it if it's a hot path? + +> continue + +**summary:** answered without building anything. about 4 instructions per block entry while a block is being counted, and nothing once its optimized translation replaces it. the optimizing pass would reuse the enhancement lifter, optimizer and register allocator. lifting whole blocks would need jz side exits and barriers at calls and i/o. compiling a block that way takes microseconds, against milliseconds for llvm, and keeping values in registers instead of the memory stack likely gives 2 to 4x on tight loops. it's listed under open ends. then the gap fixes continued. + +## working notes + +the join rule from message 1 needed a place to put frees, because the merged state is only known after the last path has compiled. for if/else, the then branch already jumps over the else, so that jump now lands on a small fixup block after the else when it has frees to do, and on the join otherwise. if without else does its then-fixups inline, since the skip path's state (the state before the branch) is known in advance. loops record the states at every break in an exit record, and after the loop each break gets its own fixup stub, or a direct jump when it has nothing to free. the normal exit's fixups come last and fall into the end. switch is built on the same loop frames, with continue skipping past them to the real loop. + +error recovery without exceptions: the vm can't unwind its own stacks, so a syntax error returns normally and sets panic. the error consumes the token it happened on, which guarantees every loop makes progress, and statement and top-level parsing skip ahead until panic clears. the risky part was code after an error that used a bad lookup result (sval[-1] and the like), which on the jit would read outside memory. those spots return safe defaults now. + +the prescan reads the whole unit first, packed 4 chars to a word (a char per word would have needed 400k words of heap for the compiler's own source), then lexes it once with the analyzer and errors muted. signatures it finds are marked as prescanned, so a real definition quietly overrides a wrong guess. + +bugs on the way: deleting a one-line function with a "find the next closing brace" helper also deleted the function after it. the variable d bit again in new code, since u, m and d are reserved. and a rename helper turned die into sdie when it was supposed to produce serr. + +the buddy heap: freed blocks merge with their buddy while it's free, the same size, and inside the same top-level chunk. the sweep walks the heap by block sizes, and a merge can swallow the block that comes next, so the sweep continues from the end of the merged block. a merge also clears the absorbed header, so no stale header can look like a free block later. + +numbers: the genome is 71014 words. the per-prologue frame check costs about 12 words per function, which accounts for most of the growth. diff --git a/docs/history/15-o3/code/README.md b/docs/history/15-o3/code/README.md new file mode 100644 index 0000000..e4859f2 --- /dev/null +++ b/docs/history/15-o3/code/README.md @@ -0,0 +1,511 @@ +# 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, compiled through llvm on other hosts if you build with it, or interpreted. 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, and 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. types are a compiler primitive, with structs, generics, reflection and an optional typechecker. a program can also wire up to 512 custom opcodes into the cpu (virtual enhancements), which the jits inline as native code. and code marked `o3` skips the stack machine: the core compiles it as a whole region, with its variables in registers. + +this folder has the latest code. `history/` is the scrapbook: notes for every stage, plus frozen code from the stages that still have it. + +## files + +`core.c` is the native core and the only native code at runtime: the arm64 jit, the llvm backend (behind `-DZYLLVM`), the portable interpreter, the enhancement unit (recipe parser, vm-code lifter, optimizer and lowering) and the o3 region compiler. `src/rt.zc` is the runtime (i/o, the native division enhancements, 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` 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 the small ones (hello, factorial, echo, self-patching code, an owning list, a repl, a typed program, an enhancement demo) and some bigger proofs of concept: + +- `mandel.zc`: the mandelbrot set in 16.16 fixed point, with the fixed-point multiply wired in as a custom opcode. +- `bf.zc`: a brainfuck compiler. it turns brainfuck into zc source, has the resident compiler compile it, and runs it (native code on the jit). it takes a program after a backtick, or runs hello world. +- `dump.zc`: prints any heap struct, nested ones included, with no printing code, by walking its type through reflection. +- `tree.zc`: a binary search tree whose nodes own their children. there's no `free` anywhere, and the live object count drops back to 0 when the root's block ends. +- `lang.zc`: grows the language while it compiles: a `|>` pipe operator (one table entry, since on a stack machine it's just `call`), `unless`, an `assert` that knows its source line, and `times n { }`. +- `staged.zc`: writes a polynomial as source with its coefficients baked in, compiles it while running, and finds it by name. +- `quine.zc`: prints its own source. +- `life.zc`: conway's life on a typed 2d board, with a glider wrapping around a torus. +- `primes.zc`: an o3 sieve over a fixed array, the primes gathered into a growable one, then twin primes and the widest gap. + +`tests/` has feature tests, `tests/errors/` (programs the lifetime analyzer has to reject), `tests/typeerrors/` (programs the typechecker has to reject) and `tests/langerrors/` (o3 and array misuse). each of those starts with the message it expects, and `tests/runerr.sh` runs a folder of them. `test.sh` does the whole bootstrap and runs everything on all three backends. `bench.sh` times o3 against plain code on each backend. `history/` is the scrapbook. + +## build + +``` +cc -O2 core.c io_linux.c -o zy # io_linux.c provides Q, G and J +./zy `). `ZYNOLLVM=1` turns the llvm tier off. with `ZYTRACE=1`, `ZYO3DUMP=1` also prints every o3 block's micro-ops. + +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, on every backend. + +## zc, the language + +it reads like c. underneath every value is a 32 bit word and memory is word addressed, so `p + 1` is the next word whatever `p` points at, and strings are one char per word with a 0 at the end. types are optional: untyped code is typed `word`, which goes with anything. + +``` +const N = 10; +[N]int table; // a global array +int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +fn main() { + for (int i = 0; i < N; i++) table[i] = fib(i); + let sq = { let t = table[5]; t * t }; // a block is an expression too, its last line is its value + let x = asm { 2 3 + }; // raw vm code, leaves one value + putn(sq + x); putc(10); + return 0; +} +``` + +declarations are c-style, type first: `int a = 1, b;`, `*node p = new(node);`, `[4]char buf;`, `point origin;`. `let` declares without a type: it infers pointer, struct and function types from the initializer and keeps numbers as plain words, and `let a[10];` is an untyped array. statements are declarations, `if`/`else`, `while`, `for`, `switch`, `break`, `continue`, `return`, `{ }` blocks, `asm { }` and expressions. `switch (e) { case 1, 2: ... default: ... }` takes constant labels, and its cases don't fall through: each ends where the next begins, and `break` leaves early. operators are c's with c's precedence, including `c ? a : b`, plus `p.x` and `p->x` (the same thing: `.` goes through a pointer on its own), `e as T` to change a type without changing the bits, and the casts below. comparisons and `&& ||` give 0 or 1. `/`, `%` and `<<` compile to native enhancement opcodes. character literals, `0x` hex and the usual escapes are there. + +functions are declared like c, return type first: `int f(int x)`, `*node.u make()`, `.u grab()` (a tag on its own), `void log(*char s)`. `fn f(a, b)` is the untyped form, returning a word. a generic function puts its type parameters in front, ` T first(*list l)`. function types are written the same way, `int(int, *char)`, and `fn(int)` for one that returns a word. the earlier `fn f(...) -> T` spelling is gone. + +arrays come in three kinds. `[n]T` has its size in the type and lives in place. `[]T` is a growable array: a small handle object that owns its items, made with `new([]T)` or `new([]T, n)`, indexed with a bounds check, and changed with `push(a, x)`, `pop(a)` and `resize(a, n)`. `len(a)` works on both (for `[n]T` it's the constant) and `cap(a)` gives the room before the next grow. `fixed []T` is a `[]T` that can't change size: `new(fixed []T, n)` needs the length, and `push`, `pop` and `resize` on it are compile errors. a `fixed []T` can't be passed where a `[]T` is expected, the other way round is fine, and a constant index outside a `[n]T` is caught at compile time. the items belong to the array, so freeing it frees them, and objects stored into a `[]*T` are its children like any container's. + +a unit is read whole and scanned for function signatures before it compiles, so calls can come before definitions, tags included, and prototypes are optional. `main` runs after the whole program has compiled. every function returns one word, 0 if it falls off the end. + +builtins from the runtime: `putc`, `getc`, `eof`, `puts`, `putn`, `halt`, `strlen`, `streq`, `wcopy`, `wfill`, `new`, `new_t`, `new_raw`, `free`, `gc`, `isobj`, `osize`, `typeof_obj`, `live_objects`, `install`, `zdiv`, `zmod`, `zshl`. + +## memory model: u, m and d + +`new(n)` or `new(T)` gives back a fresh object. 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. a tag is written after the type, `*node.u p`, or alone, `.d x`. `u`, `m` and `d` are reserved words. + +**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, 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. the first time it's handed to a lower scope its life here is over: passing it to a `.d` parameter, 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. it has to leave this block for the one above, where it arrives as m. it leaves through `return` (the function's return type has to carry `.u`, like `*node.u make()` or just `.u make()`), as the value of a block expression, or by assignment to a variable of the directly enclosing block. letting it fall out of scope, or throwing away a u result, is an error. + +recasting is multiplication by the tag: `u*x`, `d*x`, `m*x`. it 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 declaration can carry a tag too, `.u r;`, and then whatever lands in it gets that tag. + +parameters: an untagged parameter is m from the caller's side, a lend, and the callee sees a plain word. `.m` makes it a checked borrow: the callee can read and write it but can't free it, return it, recast it or store it anywhere. `.d` hands the object over, and it arrives as m. + +``` +*int.u box(int v) { *int b = new(int); *b = v; return u*b; } +fn add(*list l, *int.d item) { l.items[l.len] = d*item; l.len++; return 0; } +``` + +containers own what you store in them. `p[i] = c` or `p.f = 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 gives the child away: it's dead here afterwards, and the caller's object owns it. 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 `d*`, and the mark-sweep collector takes it over. a fresh object can go straight in. + +where paths join (after an `if`, a loop, a `switch` or `?:`) every variable has to be in the same state on every path that reaches the join, with one exception. a variable that became d, or was given away, on some path is dead afterwards, and the compiler frees it on the paths where it's still alive, on their way in. a loop's exit state is the join of its `break`s and its normal exit, so giving something away and breaking is fine. what a loop can't do is give something away on a path that comes back around to the top, since the next pass would use it dead. a u object doesn't get the dead treatment: it still has to leave. + +### the analyzer + +it runs inside the compiler on every function, including code compiled at runtime by `eval` and friends, and reports each violation with a line number and the variable's name. the compiler keeps going after errors, up to 20: a syntax error skips to the next `;` or `}` (or the next top-level declaration), and analyzer and type errors just get reported, since the parse is still in step. a unit with errors doesn't run. `tests/errors/` has one small program per rule. 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 what it allocates belongs to the collector, and checked variables can't be touched from inside an unchecked block. + +## types + +types are a compiler primitive. the compiler keeps them as records in a type area at 0x9C000, hash-consed so the same type is always the same pointer. they stay in memory after compiling, so programs and parse words can look at them. + +``` +struct point { int x, y; }; +struct list { int len; *T items; }; +type num = int; + T first(*list l) { return l.items[0]; } + *list.u mk(int cap) { *list l = new(list); l.items = new(T, cap); return u*l; } +... +*list<*point> ps = mk<*point>(8); // explicit type arguments, or inferred from the arguments +``` + +the kinds are `word`, `int`, `char`, `bool`, `void`, pointers `*T`, arrays `[n]T`, `[]T` and `fixed []T`, function types `int(int, *char)`, structs, generic structs and generic functions. structs and arrays live in place (in a frame, a global or inside another struct), and their value is their address, so they're passed around by pointer. `sizeof` counts words. type arguments have to be one word (a number, a pointer or another parameter), so a generic function is compiled once and works for every instance. indexing scales by the element's size, while plain pointer arithmetic stays in words, like b. `new(T)` and `new(T, n)` stamp the type into the object's header. + +### reflection + +`typeof(e)` and `typeof(T)` give a type record and `sizeof(...)` its size. both work on any expression, which is compiled dry and never runs. at runtime: `tkind(t)` (one of the `TY_` constants), `tsize`, `tname`, `tlen`, `tnfields`, `tfname(t, i)`, `tftype`, `tfoff`, `tret`, `tnparams`, `tparam`, `tparamtag` (the u/m/d tag of a parameter), `tretu`, `tnargs` and `targ` for generic instances, and `tprint(t)`. `sigof(f)` gives the type of a function by address (untyped ones get a signature built from their arity and tags), `sigofs("name")` by name, and `typeof_obj(p)` reads the type stamped on a heap object. + +### the typechecker + +off by default. `typecheck on;` turns it on for what follows and `typecheck off;` turns it back off (a parse word can flip `tc_on`). it checks initializers, assignments, arguments (unifying generic parameters), return values, arithmetic, comparisons, dereferencing, indexing and calls. `word` matches anything, numbers mix with each other, a literal 0 is a null pointer, and arrays decay to pointers. it stops at the first error, printing what it expected and what it got. `tests/typeerrors/` has one per rule. some things are checked whatever the setting, because the compiler needs them to generate code: field names, and field access on something that isn't a struct. + +## virtual enhancements + +the cpu has room for 512 custom opcodes (22 to 533), and opcode 21 (`%` in asm) installs one at runtime. it's the closest a soft cpu gets to rewiring itself. an enhancement takes up to 8 inputs off the data stack and leaves up to 8 outputs, and it's written one of two ways: + +``` +enhance clamp(x, lo, hi) micro "x = max x lo; x = min x hi"; +enhance 2 divmod(a, b) micro "r2 = sdiv a b; r1 = srem a b; r0 = r2"; // the number is how many outputs +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // can't be lifted (it does i/o), so calls use the fallback +``` + +a micro recipe works on registers `r0`..`r15`, which the inputs arrive in (also under the parameter names), and the outputs leave from `r0` up. the micro-ops are `li mov add sub mul sdiv udiv srem urem and or xor shl shr sar neg not lt ltu eq ne min max minu maxu mulhs mulhu clz abs sel ld st`. a `vm` body is straight-line vm code that gets lifted by running it symbolically. both turn into ssa, and the core's optimizer folds constants, simplifies algebra, removes common subexpressions and dead code, and turns division by a constant into a multiply-high sequence (`ZYTRACE=1` prints the result). the arm64 jit then inlines the code at every use with registers allocated, the llvm backend inlines it as ir, and the interpreter runs the optimized list. if something doesn't fit in registers, the jit calls the interpreter for that op. when literals feed an enhancement's last inputs (`x / 7` is `x 7 idiv`), the arm64 jit specializes that use on them: the literals become constants, the optimizer runs again, and `x / 7` turns into a multiply-high and two shifts instead of a divide. + +an enhancement is called like a function when it has one output, or by name from asm. `enhance` installs at compile time, so the wiring is there before `main` runs, and a parse word can use it right away. an image installs its own enhancements when it boots, from its symbol table. that's how `/`, `%` and `<<` work: `rt.zc` declares `idiv`, `imod` and `ishl` as one-instruction recipes. `install(desc)` is the raw interface, and its descriptor format is documented in `core.c`. stores done by an enhancement don't invalidate compiled code, so use them for data. + +this replaces my first plan for enhancements, which compiled c or llvm ir sources at runtime. part of that reply got stopped by a safety check, and once it turned out llvm was meant for portability, it moved into the backend below instead. + +## o3 + +`o3` marks code for the optimizing tier. it goes on a function, a block or a single variable: + +``` +o3 int sum(fixed []int a) { int s = 0; for (int i = 0; i < len(a); i++) s += a[i]; return s; } +fn main() { + o3 int hits = 0; // one o3 variable + o3 { for (int i = 0; i < 1000; i++) if (i % 7 == 3) hits++; } + ... +} +``` + +what it gives up, as asked: variables declared in o3 code must be typed (`let` and untyped parameters are errors), they have no address (`&x` and naming one from `asm` are errors), `new` in o3 code returns raw memory with no type stamp and no zero fill (`new_raw`), and an o3 function skips the frame stack check in its prologue. what it gets: the compiler hands each o3 function body and each o3 block to the core as a region (install kind 2: the range of vm words plus the frame slots of up to 7 typed variables, picked in declaration order), and the core compiles the region right away. + +inside the core, a region is cut into basic blocks at jump targets, branch fallthroughs and call return points. each block is lifted to ssa the way enhancements are: the vm stack becomes values, and only what's still on it at the end of the block is written to memory. the frame pointer and the promoted slots become variables that live in registers across the whole region, so `i++` on an o3 int is one add. enhancements are spliced into the block, so `/`, `%` and `<<` become one instruction or a magic-number sequence. every block then goes through the same optimizer (folding, algebra, cse, dce, division by constants). in o3 code `a[i]` on a `[]T` is compiled inline with its bounds check (`outside(i, len)`, one enhancement), and `len(a)` is a load. + +the backends: on arm64 the region becomes one piece of native code. variables sit in w0..w7, block values in w8..w14 and w26..w28, constants are folded into instructions where they fit, loads from a fixed address are one `ldr`, and blocks branch to each other directly with no dispatch and no stack checks. on the llvm build the region becomes one function, with the variables in allocas that mem2reg turns into ssa across blocks, and it goes through llvm's O3 pipeline. on the plain interpreter, a small region interpreter runs the optimized blocks with the variables in locals. + +calls, returns, jumps out of the region, i/o, `install`, a store to the frame pointer and anything else a block can't lift all leave the region: the variables are written back to the frame first, so outside code sees ordinary memory. a call's return point is an entry, which loads them again. stores inside a region still check the coverage map, so writing to compiled code works, and a store into the region's own code drops it (it lifts again at its next entry). to keep variable addresses from waiting on the stack across a branch, assignment to an o3 variable in o3 code evaluates the value first and the address after. the lifter refuses a block that would leave such an address on the stack, rather than miscompile it. single o3 variables outside o3 code are reached through `lfa(k)`, an enhancement for `fp + k`, which the arm64 jit specializes into a load and an add. + +`bench.sh` runs four kernels from `tests/bench.zc` with and without `o3`. milliseconds per run, start-up and compile time removed (arm64 is under qemu on an x86 host, so only its ratios mean much): + +``` +backend kernel plain ms o3 ms speedup +interp collatz 309.63 209.87 1.5x +interp sieve 45.58 15.95 2.8x +interp digits 191.32 92.29 2.1x +interp fib 6.70 5.50 1.2x +llvm collatz 27.69 3.48 7.9x +llvm sieve 17.32 0.17 101.9x +llvm digits 24.72 1.60 15.4x +llvm fib 1.82 0.84 2.2x +arm64 (qemu) collatz 327.33 16.78 19.5x +arm64 (qemu) sieve 90.23 3.85 23.4x +arm64 (qemu) digits 147.67 3.46 42.7x +arm64 (qemu) fib 22.62 5.73 3.9x +``` + +fib is the weak one, since every call leaves the region and comes back through the dispatcher. llvm's sieve number is llvm's loop optimizations doing their work on a region with no stack traffic left in it. + +## the llvm backend + +a tiered jit for hosts the arm64 backend doesn't cover. the interpreter counts how often each block start gets reached, and a hot block is translated to llvm ir using the same block rules as the arm64 jit: it ends at call, jump, ret or halt, keeps going past a jz, and literal targets are fused. the ir goes through the O2 pipeline and gets compiled by orc's lljit. stores into compiled words drop the blocks covering them, like on arm64. it pays off for long-running code: a loop-and-recursion benchmark runs about 3.3x faster than the interpreter. short bursty work like the self-compile is slower, since compile time dominates there. `ZYHOT=1` compiles every block, which is a good stress test, and the test suite runs that way too. + +## the heap + +0x40000 to 0x9BFFF, managed by a buddy allocator. the heap is split into aligned power-of-two chunks, every block is a power of two words, and a freed block merges with its buddy whenever that one is free too, so freed space can be reused at any size. (stage 15 fixed a bug here: `release` marked a container free before freeing its children, so a child whose buddy was the container merged into it while the container was still being freed, and corrupted a free list. growable arrays hit it every time, since a handle and its items are often buddies.) allocation finds the smallest free block that fits and splits it down. free blocks sit on a doubly linked list per class, so taking a buddy off its list during a merge is constant time. checked code frees deterministically. under that runs a mark-sweep collector, conservative and non-moving, which handles globals, unchecked code and anything given to it. it runs on `gc()`, which returns how many objects it freed, or when an allocation doesn't fit. the sweep frees through the same merging path. + +## code as data + +the compiler is in memory with your program and every name in it is callable. + +`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, enhancement names emit their opcode, and other names push the address of a variable or function. + +`quote { ... }` is a token list as a fresh object: `[n, kind, value, line, kind, value, line, ...]`, so errors inside a macro expansion point at the line the tokens came from, where names, strings and operators are interned pointers (`intern("while")` gets one). `tokens(s)` makes one from a string, and `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)` runs `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()`, `peek()` and `peekat(k)` (up to 4 tokens ahead), `tk`/`tv` (current token kind and value), `expect`, `accept`, `expr()`, `stmt()`, `substmt()`, `ptype()`, `emit`, `lit`, `op`, `hole`/`setlit` for jumps, and `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` partway through a 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 both. `mnem` is the asm mnemonic table, `q@!$_~cjzr,?.+-*&|^><%`, and can be rewritten. + +## the bootstrap + +`zc0.c` compiles the subset `compiler.zc` uses (no analyzer, types, quote, parse words or block expressions, but it does lay out `enhance` declarations) into a first genome. that genome compiles `compiler.zc` again on the vm. that's where the real compiler, the analyzer and native division first meet their own source, and `compiler.zc` passes its own lifetime checks. the result compiles itself into identical words, on all three backends, and that's the `genome.h` that ships (78217 words). an image build (`build_image(org, dst)`) compiles with only the image's own names visible (plus keywords and builtin types), writes code meant for one address into another, and appends a symbol table so the booted genome knows its own names and enhancements. + +## the instruction set + +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 21 % install +2 ! store 7 j jump 12 . out (G) 17 | or 22..533 enhancements +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, `c` and `j` take their target from the stack, and `%` is `(descriptor -- status)`. there's still no div or mod in the base set, because a divider can't finish in one cycle in hardware. an enhancement can add one. + +## memory map and abi + +memory is 1m (1048576) words. it could grow until the host runs out (literals already reach 1g words), but that would mean reserving the jit tables with mmap instead of static arrays, and 1m is plenty for now. + +``` +0x00000.. the program: code, with globals between functions +0x40000..0x9BFFF heap +0x9C000..0x9FFFF type records +0xA0000 frame pointer word +0xA0100..0xBFFFF 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. heap objects have a 6 word header: size, size class, flags, a check word, owner, type. + +## 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, install hook, enhancement fallback). o3 regions also use x26..x28, which the entry stub saves. + +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 dispatch stub that checks both stack pointers against their limits (kept in x24 and x25), bounds-checks the target, loads `tab[t]`, and branches straight to it when it's already compiled. otherwise it returns to c, which compiles the block and re-enters. enhancements are inlined: inputs load from the data stack into w0..w15, the optimized micro-ops run in registers with x16 and x17 as scratch, and the outputs go back. an install calls into c and then returns to the loop, which flushes every translation, since code built before the install may have inlined the old version. a flush drops o3 regions too, and they lift again on their next entry. when the loop reaches an o3 entry point, it compiles the region (or reuses it) instead of translating a block. + +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. + +the stacks are checked. the data and return stacks are checked at every block exit on all three backends, so the cost is a couple of compares per block rather than per push. a block pushes at most about 1024 words, which the data stack limit leaves room for. overflowing either one stops the cpu with `zy: data stack overflow` or `zy: return stack overflow`. the frame stack is checked in every function prologue, which resets the frame pointer and stops with `zy: frame stack overflow`. + +platform: the darwin path uses `MAP_JIT`, `pthread_jit_write_protect_np` and `sys_icache_invalidate`. linux uses rwx mmap and `__builtin___clear_cache`. only linux arm64 has actually been run, under qemu. the darwin path follows apple's documented recipe but hasn't been tested, and under the hardened runtime it also needs the allow-jit entitlement. every host shares the same semantics: shift counts wrap at 32, stores outside memory are ignored, loads outside memory read 0, and jumping outside memory or to an unwired opcode halts. + +## test results + +`test.sh` passes all 125 checks on x86-64 linux: the fixpoint, an up-to-date `genome.h`, and then every example and feature test on the interpreter, on the arm64 jit under qemu, and on the llvm backend, all with identical output. it also covers joins and fixup frees (with a leak count), `switch` and `?:`, the buddy allocator, several errors in one run, all three stack overflows, growable and fixed arrays, and `tests/o3.zc` (loops, recursion, calls inside loops, `switch`, `&& ||`, structs through pointers, arrays, division by constants, and a function with more variables than registers), whose output matches the same file with `o3` taken out. it checks that every o3 region in that test lifts, and gets compiled on the jit and on llvm, that the o3 bounds check fires, and that all 22 programs in `tests/errors/`, all 10 in `tests/typeerrors/` and all 8 in `tests/langerrors/` get rejected with the expected message on each backend, that llvm agrees when it compiles every block, and that the self-compile matches byte for byte on all three. separately, 80000 random divisions through enhancements matched the software routine, covering divide by zero, INT_MIN/-1, negatives and the magic-number path for constants. + +## open ends + +fixed in stage 13 (details in `history/13-gap-fixes`): branch and loop joins, free lists that never merged (now a buddy allocator), missing stack checks, stopping at the first error, macro line numbers, required prototypes, `d*` for storing into borrowed objects, `**` declarations, and `?:` and `switch`. still open: + +**untracked aliases.** the analyzer only follows bare variable names, so `let q = p + 0;` or `let c = list[1];` is a plain word nobody tracks, and it dangles once the owner is freed. two cheap fixes, and they combine well. at runtime: don't reuse a freed block right away. `free` would put it on a quarantine list, and the collector's next sweep only releases quarantined blocks that no word points at. the conservative mark already finds such words, so that's maybe 30 lines in rt.zc. a stale alias then reads a dead but intact block, and a second free through it is a no-op, because the header's flags say free. at compile time: now that there are types, a pointer-typed value computed from a tracked variable (`p + k`, `p.field`, `p[i]` when the element is a pointer) can carry a "borrowed from p" mark into the local it's stored in. using that local after `p` dies becomes an error. that's the same machinery children already use. + +**the conservative collector.** it scans the whole data stack region, because the vm can't read its own stack pointer, and stale words keep garbage alive a little longer. the fix is one base opcode that pushes the data stack depth, which is trivial in hardware since the register already exists. then the collector scans only the live part. zeroing a frame in the prologue would do the same for the frame stack, at a few words per call. + +**coarse invalidation.** a store to a covered word rescans every block, and an install flushes everything. three fixes, in order of payoff. first, index blocks by page (say 64 words): a covered store only looks at the blocks touching its page, and dropping a block only rebuilds the coverage bytes for that block. second, record which enhancement slots each translation inlines, so an install only drops those. third, on llvm, give each block its own resource tracker, so dropped code actually gets freed. + +**automatic tiering.** o3 is the explicit version of what you asked about in message 14. doing it without the keyword means a run counter per block (about 4 instructions per block entry) and, for a hot loop, finding its region and its variables without the compiler's help. the hard part is the variables: o3 can keep them in registers because the compiler promises nothing takes their address, and code without that promise would need the lifter to prove it. + +**o3's own gaps.** calls always leave the region through the dispatcher, so call-heavy code gains least (fib above). a direct call from one compiled region into another, with the variables spilled only for the slots the callee can't see, would fix most of that. only 7 variables get registers, picked by declaration order rather than by use. a fixed array's length and items pointer can't change, so o3 code could load them once per region instead of at every index, and doesn't yet. the core's own optimizer works one block at a time (no loop-invariant motion or cross-block cse); llvm does that on its build. regions aren't built into images, so `rt.zc` and the compiler can't use o3. and o3 code that rewrites its own region sees the change at the next entry, not right away. + +**generics are erased.** a generic function is compiled once, so the type stamped by `new(T)` inside it says `T`, and type arguments have to be one word. + +**the rest.** the prescan only knows tags, not types, so a call to a typed function that's defined further down gets `word` as its result type until the definition shows up. the llvm backend compiles one module per block, so it warms up slowly. stores done by enhancements don't invalidate compiled code. a parse word that changes the syntax can confuse the prescan. it only records signatures, though, and a real definition always overrides what the prescan guessed. + +--- + +## 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 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/`. + +### 11 + +> progress report? +> add types please :) +> mostly as a compiler primitive though, plus type-inspection via reflection +> and a small optional typechecker (default off) +> oh and keep the stuff you write as a history scrapbook +> if it helps, add a path to the hardware which is called "virtual enhancements", and allows up to 512 custom operations to be compiled down via jit into hardware-level speeds and interoped directly into a fast path in the vm to become essentially custom wiring. useful for division and other stuff as a dynamic runtime path + +my answers to the clarifying questions, exactly: + +> types: words + structs + generics +> +> reflection: runtime type of heap objects, function signatures, typeof at compile time +> +> how an enhancement is defined: either actual C or llvm ir code or vm code or micro-ops passed through an optimizer. since for example, micro-ops and vm code are not sufficient for optimizing things like division +> +> scrapbook: notes + code snapshots + +**summary:** the progress report said the previous round was finished and shipped. i then laid out a plan where the core would compile c or llvm ir enhancement sources at runtime with the host toolchain and load the result. part of that reply was stopped by a safety check before it finished, so i stopped and checked in instead of building it. + +### 12 + +> also make the umd syntax like `type.u name`, and casting is multiplication `u*name` +> ideally i'd prefer memory to be unlimited words growing until system oom, but 1m is fine +> core.c plain interp is also nice +> zc0.c own file is fine +> i mentioned llvm for portability to non-arm targets +> yes, d object semantic that was intended +> u object hands up one block and becomes an m, that's fine. the code can make it a u or a d or whatever +> explain your gaps more +> +> wait why safety check? what's wrong with that + +my answers to the clarifying questions, exactly: + +> declarations: c-style, var -> let +> +> tags on untyped values and the names u, m, d: names reserved, bare .u allowed, untype is m by default +> +> llvm: llvm jit backend (Recommended) + +**summary:** on the safety check: nothing was wrong with the request. my best guess was that it tripped on the plan for a program inside the vm handing source text to the system compiler and loading the result into the running process, since that pattern also shows up in malware. with llvm meant for portability, that path wasn't needed. the gaps got the longer explanations that are now under open ends above. then the round itself: + +**syntax.** declarations are c-style (`int x`, `*node.m p`), `let` replaces `var` for untyped and inferred declarations, tags are `.u .m .d` after the type or on their own, recasts are `u*x` / `d*x` / `m*x`, `u m d` are reserved, and an untagged parameter counts as an m lend. + +**types.** a compiler primitive: hash-consed records with structs, generic structs and functions, fixed arrays, function types, `typeof`/`sizeof`, `as` casts and a reflection api, with object headers carrying their type. the typechecker is off by default and turned on with `typecheck on;`. + +**virtual enhancements.** opcode 21 installs, 22 to 533 are the slots. micro-op recipes and lifted vm code go through an optimizer in the core (folding, cse, dce, multiply-high division by constants) and get inlined by both jits. the language's own `/ % <<` now run on them. + +**backends.** a tiered llvm backend (`-DZYLLVM`) for non-arm hosts. + +**bootstrap and history.** it still reaches its fixpoint on all three backends. `history/` holds notes for every stage and code from stages 7, 10 and this one (in 11-types-enhancements). + +### 13 + +> gaps +> 1. when there's a var state change to d, mark that var as dead by default for any other scope that can access it afterwards. u is fine since it just returns +> 2. any suggestions for a cheap fix? +> 3. it's fine, rare occurrence (probably?), suggest a fix +> 4. fix that +> 5. suggest a fix +> 6. fix +> 7. fix + +**summary:** the numbers followed the gap list from my previous chat message. here's what each one got. + +**1. joins.** a variable that became d, or was given away, on any path is dead after the join, and fixup code frees it on the paths that still own it. a loop's exit state is the join of its breaks and its normal exit. giving something away on a path that loops back is still an error. u and borrows don't get the dead treatment. + +**2, 3 and 5.** suggestions only, now under open ends: a quarantine on reuse plus "borrowed from" marks on pointer-typed values for aliases, a stack-depth opcode for the collector, and page-indexed invalidation plus per-slot install tracking for the jit. + +**4. heap.** a buddy allocator. + +**6. stack checks.** all three stacks are checked: data and return at every block exit on all backends, and frames in every prologue. + +**7. the small stuff.** error recovery with up to 20 reported errors, line numbers carried in token lists, a signature prescan over the whole unit so prototypes are optional, storing into a borrowed object moving the object automatically, `?:`, and go-style `switch`. on the side, a 4-token lookahead fixed `**` declarations. + +### 14 + +> how costly is it if we add a counter to each block to see how many times it runs, then run the optimizer on it if it's a hot path? + +> continue + +**summary:** answered without building anything. about 4 instructions per block entry while a block is being counted, and nothing once its optimized translation replaces it. the optimizing pass would reuse the enhancement lifter, optimizer and register allocator. lifting whole blocks would need jz side exits and barriers at calls and i/o. compiling a block that way takes microseconds, against milliseconds for llvm, and keeping values in registers instead of the memory stack likely gives 2 to 4x on tight loops. it's listed under open ends. then the gap fixes continued. + +### 15 + +> write some really cool examples for this language + +> no, wdym building a fresh vm?? just pocs 😭 we already have a compiler and everything + +**summary:** my progress note had said "building a fresh vm", which only meant compiling core.c into a binary to run the examples. eight proofs of concept went into `examples/`: mandel, bf, dump, tree, lang, staged, quine and life, each described under files above and checked by `test.sh` on all three backends. + +### 16 + +> add opt keywords, for example `optim` (or o3, i prefer o3 as the keyword) will cause any vars in a scope to not assign heap type metadata, compiles with opt level o3 and is immediately compiled down to native, and when used with variables they must be always typed and it reduces the perf cost for accessing or modifying them, etc etc. add a `fixed` keyword which says that an array has a fixed size and cannot be resized, etc + +my answers to the clarifying questions, exactly: + +> where o3 goes: functions, blocks and single vars +> +> how far o3 goes: real optimizing tier (Recommended) +> +> what o3 code may give up: type stamps on objects, zero-filling new objects, the address of o3 vars, stack and frame checks, also i don't like the -> return type syntax. please replace it with the c-like syntax +> +> arrays: add growable arrays too (Recommended) + +**summary:** three things changed. + +**return types.** functions are declared c-style now, `int f(int x)`, `*node.u make()`, ` T first(*list l)`, with fn types written `int(int, *char)`. `->` is gone from the compiler, zc0, the tests and the examples. + +**arrays.** `[]T` grows (`push`, `pop`, `resize`, `len`, `cap`), and `fixed []T` can't change size after `new(fixed []T, n)`. both are bounds-checked. `[n]T` stays as it was, plus a compile-time check for constant indexes. + +**o3.** on functions, blocks and single variables, with the trade-offs you picked, and a real optimizing tier in the core, described in the o3 section above. it compiles at install time on arm64 and llvm and has a region interpreter for the plain build. measured gains are 1.5 to 2.8x on the interpreter, 8 to 100x on llvm and 20 to 43x on arm64 (under qemu) for loop-heavy kernels, and much less for call-heavy ones. on the way, the arm64 jit learned to specialize an enhancement on literal inputs, so `x / 7` is a multiply-high everywhere, not only in o3 code. tests for arrays and o3 turned up an old heap bug: freeing a container could merge one of its children into it while it was still being freed, which corrupted a free list. growable arrays hit it every time. it's fixed. diff --git a/docs/history/15-o3/code/bench.sh b/docs/history/15-o3/code/bench.sh new file mode 100755 index 0000000..c5e5a83 --- /dev/null +++ b/docs/history/15-o3/code/bench.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# o3 against plain code: each kernel in tests/bench.zc on each backend, with +# the time to start up and compile (the 'z' run) taken off. needs bc. +cd "$(dirname "$0")"; T=$(mktemp -d); trap 'rm -rf $T' EXIT +gcc -O2 -w -DJTYPE=int core.c io_linux.c -o $T/zy +vms=("$T/zy"); names=("interp") +if command -v llvm-config >/dev/null; then + gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c -o $T/zyl $(llvm-config --ldflags --libs) && { vms+=("$T/zyl"); names+=("llvm"); } +fi +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 && { vms+=("qemu-aarch64 $T/zyj"); names+=("arm64 (qemu)"); } +fi +# seconds per run of kernel $2 on vm $1: the slope between $3 runs and 1 run, +# best of three each, so starting up and compiling cancel out +t(){ local s e; s=$(date +%s.%N); (cat tests/bench.zc; printf '`'$2$3) | $1 >/dev/null; e=$(date +%s.%N); echo "$e - $s" | bc; } +best(){ local b=999 x i; for i in 1 2 3; do x=$(t "$1" $2 $3); b=$(echo "if ($x < $b) $x else $b" | bc); done; echo $b; } +per(){ echo "scale=5; ($(best "$1" $2 $3) - $(best "$1" $2 1)) / ($3 - 1)" | bc; } +printf "%-14s %-8s %10s %10s %8s\n" backend kernel "plain ms" "o3 ms" speedup +for i in "${!vms[@]}"; do + n=41; [ "${names[$i]}" = interp ] && n=5 + for k in "collatz a b" "sieve c d" "digits e f" "fib g h"; do + set -- $k + p=$(per "${vms[$i]}" $2 5); o=$(per "${vms[$i]}" $3 $n) + printf "%-14s %-8s %10.2f %10.2f %7.1fx\n" "${names[$i]}" $1 $(echo "$p * 1000" | bc) $(echo "$o * 1000" | bc) $(echo "scale=2; $p / $o" | bc) + done +done diff --git a/docs/history/15-o3/code/core.c b/docs/history/15-o3/code/core.c new file mode 100644 index 0000000..4e74c93 --- /dev/null +++ b/docs/history/15-o3/code/core.c @@ -0,0 +1,2019 @@ +/* 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 +#include +#include +#if defined(__aarch64__) && !defined(ZYINTERP) +#define ZYJIT 1 +#include +#ifdef __APPLE__ +#include +#include +#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 DSLIM (0xFC000 + 1100) /* data stack overflows below this (a block pushes at most ~1024) */ +#define RSLIM (0xF8000 - 8) /* return stack overflows above this */ +/* why the cpu stopped, when it wasn't a halt */ +static int stopped(int p) +{ + if (p == MW + 1) { fprintf(stderr, "zy: data stack overflow\n"); return 2; } + if (p == MW + 2) { fprintf(stderr, "zy: return stack overflow\n"); return 2; } + return 0; +} +#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; + +/* ---- virtual enhancements ---- + up to 512 custom opcodes (22 .. 533), wired in at runtime by the install + opcode (21). an enhancement is a short program over native micro-ops, + written either as a recipe (text) or as straight-line vm code that gets + lifted. both become ssa, go through the optimizer below, and then run in + the interpreter or get inlined by the jit as native code. */ +#define NENH 512 +#define XOP0 22 +enum { U_LI, U_MOV, U_ADD, U_SUB, U_MUL, U_SDIV, U_UDIV, U_SREM, U_UREM, U_AND, U_OR, U_XOR, + U_SHL, U_SHR, U_SAR, U_NEG, U_NOT, U_LT, U_LTU, U_EQ, U_NE, U_MIN, U_MAX, U_MINU, U_MAXU, + U_MULHS, U_MULHU, U_CLZ, U_ABS, U_SEL, U_LD, U_ST, U_N }; +static const char *unames[U_N] = { "li", "mov", "add", "sub", "mul", "sdiv", "udiv", "srem", "urem", + "and", "or", "xor", "shl", "shr", "sar", "neg", "not", "lt", "ltu", "eq", "ne", "min", "max", + "minu", "maxu", "mulhs", "mulhu", "clz", "abs", "sel", "ld", "st" }; +static const signed char uarity[U_N] = { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2 }; +typedef struct { int op, d, a, b, c, imm; } Uop; /* ssa: d is a fresh value, a b c are values */ +typedef struct { + int live, kind, nin, nout, n, nv, out[8]; + Uop *u; + signed char *reg; /* physical register per value, for the jit; 0 if it didn't fit */ +} Enh; +static Enh enh[NENH]; +static int need_flush; + +#define MAXUOP 4096 +static Uop ub[MAXUOP]; static int un, unv, uerr; /* the program being built */ +static int unew(int op, int a, int b, int c, int imm) +{ + Uop *u; + if (un >= MAXUOP) { uerr = -5; return 0; } + u = &ub[un++]; u->op = op; u->d = unv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + return u->d; +} +static int mread(int a) { return (unsigned)a < MW ? m[a] : 0; } + +/* recipe text: one statement per line or per ';' + r0 = sdiv r0 r1 dst = op operands, operands are rN, parameter names or numbers + r2 = r0 a copy, or a number + st r1 r0 memory[r1] = r0 + inputs arrive in r0.. (and under the parameter names), outputs leave from r0.. */ +static int parse_recipe(int src, int names, int nin, int nout, int *out) +{ + int cur[16], i, p = src, n, k, op, args[3], na, dst, isst; + char tok[8][32]; int nt; + for (i = 0; i < 16; i++) cur[i] = i < nin ? i : -1; + for (;;) { + /* read one statement into tokens */ + nt = 0; + for (;;) { + int c = mread(p); + while (c == ' ' || c == '\t' || c == '\r') c = mread(++p); + if (!c || c == '\n' || c == ';') break; + if (c == '=') { if (nt < 8) strcpy(tok[nt++], "="); p++; continue; } + n = 0; + while (c && c != ' ' && c != '\t' && c != '\n' && c != ';' && c != '=' && c != '\r') { if (n < 31) tok[nt < 8 ? nt : 7][n++] = (char)c; c = mread(++p); } + if (nt < 8) tok[nt++][n] = 0; + } + if (nt) { + isst = !strcmp(tok[0], "st"); + if (!isst && (nt < 3 || strcmp(tok[1], "="))) return -2; + /* destination register */ + dst = -1; + if (!isst) { + if (tok[0][0] == 'r' && tok[0][1] >= '0' && tok[0][1] <= '9') dst = atoi(tok[0] + 1); + else for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)tok[0][j]) j++; + if (!mread(s + j) && !tok[0][j]) dst = i; + } + if (dst < 0 || dst > 15) return -2; + } + k = isst ? 1 : 2; /* first token after "=" (or after st) */ + op = -1; + if (!isst && nt > 3) { for (i = 0; i < U_N; i++) if (!strcmp(tok[k], unames[i])) op = i; if (op < 0) return -2; k++; } + if (isst) op = U_ST; + na = 0; + for (; k < nt; k++) { + char *t = tok[k], *e; int v = -1; + if (na >= 3) return -2; + if (t[0] == 'r' && t[1] >= '0' && t[1] <= '9') { int r = atoi(t + 1); if (r > 15) return -2; if (cur[r] < 0) cur[r] = unew(U_LI, 0, 0, 0, 0); v = cur[r]; } + else if ((t[0] >= '0' && t[0] <= '9') || t[0] == '-') { long x = strtol(t, &e, 0); if (*e) return -2; v = unew(U_LI, 0, 0, 0, (int)x); } + else { + for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)t[j]) j++; + if (!mread(s + j) && !t[j]) v = cur[i] < 0 ? (cur[i] = unew(U_LI, 0, 0, 0, 0)) : cur[i]; + } + if (v < 0) return -2; + } + args[na++] = v; + } + if (op < 0) { /* x = y */ + if (na != 1) return -2; + cur[dst] = args[0]; + } else { + if (na != (op == U_LI ? 0 : uarity[op])) { + if (!(op == U_LI && na == 1)) return -2; + } + if (op == U_LI) cur[dst] = args[0]; + else if (op == U_ST) unew(U_ST, args[0], args[1], 0, 0); + else cur[dst] = unew(op, args[0], na > 1 ? args[1] : 0, na > 2 ? args[2] : 0, 0); + } + if (uerr) return uerr; + } + if (!mread(p)) break; + p++; + } + for (i = 0; i < nout; i++) { if (cur[i] < 0) cur[i] = unew(U_LI, 0, 0, 0, 0); out[i] = cur[i]; } + return uerr; +} + +/* straight-line vm code from addr up to its ret, run symbolically */ +static int lift_vm(int a, int len, int nin, int nout, int *out) +{ + int st[256], sp = 0, i, w, k, x, y; + for (i = 0; i < nin; i++) st[sp++] = i; + for (i = 0; i < len; i++) { + w = mread(a + i); + if (w & 1) { if (sp >= 256) return -4; st[sp++] = unew(U_LI, 0, 0, 0, w >> 1); continue; } + k = w / 2; + if (k == 9) break; + switch (k) { + case 1: if (sp < 1) return -4; st[sp - 1] = unew(U_LD, st[sp - 1], 0, 0, 0); break; + case 2: if (sp < 2) return -4; unew(U_ST, st[sp - 1], st[sp - 2], 0, 0); sp -= 2; break; + case 3: /* pick needs a constant index */ + if (sp < 1) return -4; + x = st[sp - 1]; + if (x < nin) return -4; + { int j; for (j = 0; j < un && ub[j].d != x; j++); if (j == un || ub[j].op != U_LI) return -4; y = ub[j].imm; } + if (y < 0 || y >= sp - 1) return -4; + st[sp - 1] = st[sp - 2 - y]; + break; + case 4: if (sp < 1) return -4; sp--; break; + case 5: if (sp < 2) return -4; x = st[sp - 1]; st[sp - 1] = st[sp - 2]; st[sp - 2] = x; break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: { + static const int map[] = { U_ADD, U_SUB, U_MUL, U_AND, U_OR, U_XOR, U_SAR, U_LT }; + if (sp < 2) return -4; + x = st[sp - 1]; y = st[sp - 2]; sp -= 2; + st[sp++] = unew(map[k - 13], y, x, 0, 0); + break; } + default: return -4; /* control flow, i/o and other enhancements don't lift */ + } + if (uerr) return uerr; + } + if (sp != nout) return -4; + for (i = 0; i < nout; i++) out[i] = st[i]; + return uerr; +} + +/* ---- the optimizer ---- + one forward pass of copy propagation, constant folding, algebraic + simplification, division by constants (the multiply-high trick) and + common subexpression elimination, then dead code removal. */ +static int ev(int op, int a, int b, int c) +{ + unsigned ua = (unsigned)a, ub_ = (unsigned)b; + switch (op) { + case U_ADD: return (int)(ua + ub_); + case U_SUB: return (int)(ua - ub_); + case U_MUL: return (int)(ua * ub_); + case U_SDIV: return b == 0 ? 0 : (a == (int)0x80000000 && b == -1) ? a : a / b; + case U_UDIV: return b == 0 ? 0 : (int)(ua / ub_); + case U_SREM: return b == 0 ? a : (a == (int)0x80000000 && b == -1) ? 0 : a % b; + case U_UREM: return b == 0 ? a : (int)(ua % ub_); + case U_AND: return a & b; + case U_OR: return a | b; + case U_XOR: return a ^ b; + case U_SHL: return (int)(ua << (b & 31)); + case U_SHR: return (int)(ua >> (b & 31)); + case U_SAR: return a >> (b & 31); + case U_NEG: return (int)(0u - ua); + case U_NOT: return ~a; + case U_LT: return a < b; + case U_LTU: return ua < ub_; + case U_EQ: return a == b; + case U_NE: return a != b; + case U_MIN: return a < b ? a : b; + case U_MAX: return a > b ? a : b; + case U_MINU: return ua < ub_ ? a : b; + case U_MAXU: return ua > ub_ ? a : b; + case U_MULHS: return (int)(((long long)a * (long long)b) >> 32); + case U_MULHU: return (int)(((unsigned long long)ua * ub_) >> 32); + case U_CLZ: { int n = 0; if (!ua) return 32; while (!(ua & 0x80000000u)) { ua <<= 1; n++; } return n; } + case U_ABS: return a < 0 ? (int)(0u - ua) : a; + case U_SEL: return a ? b : c; + } + return 0; +} +static void smagic(int d, int *mul, int *sh) /* hacker's delight, signed */ +{ + const unsigned two31 = 0x80000000u; + unsigned ad = d < 0 ? 0u - (unsigned)d : (unsigned)d, t = two31 + ((unsigned)d >> 31); + unsigned anc = t - 1 - t % ad, q1 = two31 / anc, r1 = two31 - q1 * anc, q2 = two31 / ad, r2 = two31 - q2 * ad, delta; + int p = 31; + do { + p++; + q1 *= 2; r1 *= 2; if (r1 >= anc) { q1++; r1 -= anc; } + q2 *= 2; r2 *= 2; if (r2 >= ad) { q2++; r2 -= ad; } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + *mul = (int)(q2 + 1); if (d < 0) *mul = -*mul; + *sh = p - 32; +} +static void umagic(unsigned d, unsigned *mul, int *add, int *sh) /* hacker's delight, unsigned */ +{ + unsigned nc = 0xFFFFFFFFu - (0u - d) % d, q1, r1, q2, r2, delta; + int p = 31; + *add = 0; + q1 = 0x80000000u / nc; r1 = 0x80000000u - q1 * nc; + q2 = 0x7FFFFFFFu / d; r2 = 0x7FFFFFFFu - q2 * d; + do { + p++; + if (r1 >= nc - r1) { q1 = 2 * q1 + 1; r1 = 2 * r1 - nc; } else { q1 = 2 * q1; r1 = 2 * r1; } + if (r2 + 1 >= d - r2) { if (q2 >= 0x7FFFFFFFu) *add = 1; q2 = 2 * q2 + 1; r2 = 2 * r2 + 1 - d; } + else { if (q2 >= 0x80000000u) *add = 1; q2 = 2 * q2; r2 = 2 * r2 + 1; } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + *mul = q2 + 1; *sh = p - 32; +} + +static Uop ob[MAXUOP]; static int on, onv; +static int *omap, *isk, *kv; /* old value -> new value; constness of new values */ +static int pure(int op) { return op != U_LD && op != U_ST; } +static int ispow2(unsigned x) { return x && !(x & (x - 1)); } +static int lg2(unsigned x) { int n = 0; while (x > 1) { x >>= 1; n++; } return n; } +static int oe(int op, int a, int b, int c, int imm); +static int K(int v) { return oe(U_LI, 0, 0, 0, v); } +static int raw(int op, int a, int b, int c, int imm) +{ + Uop *u; int i; + if (pure(op)) /* cse */ + for (i = 0; i < on; i++) { + u = &ob[i]; + if (u->op == op && u->a == a && u->b == b && u->c == c && u->imm == imm) return u->d; + } + if (on >= MAXUOP) { uerr = -5; return 0; } + u = &ob[on++]; u->op = op; u->d = onv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + isk[u->d] = op == U_LI; kv[u->d] = imm; + return u->d; +} +static int sdivk(int a, int d) /* a / d for a constant d, no divide instruction */ +{ + int mul, sh, q, t; + if (d == 1) return a; + if (d == -1) return oe(U_NEG, a, 0, 0, 0); + if (d == (int)0x80000000) return oe(U_EQ, a, K(d), 0, 0); + if (ispow2((unsigned)(d < 0 ? -d : d))) { + int k = lg2((unsigned)(d < 0 ? -d : d)); + t = oe(U_SAR, a, K(31), 0, 0); + t = oe(U_SHR, t, K(32 - k), 0, 0); + q = oe(U_SAR, oe(U_ADD, a, t, 0, 0), K(k), 0, 0); + return d < 0 ? oe(U_NEG, q, 0, 0, 0) : q; + } + smagic(d, &mul, &sh); + q = oe(U_MULHS, a, K(mul), 0, 0); + if (d > 0 && mul < 0) q = oe(U_ADD, q, a, 0, 0); + if (d < 0 && mul > 0) q = oe(U_SUB, q, a, 0, 0); + if (sh) q = oe(U_SAR, q, K(sh), 0, 0); + return oe(U_ADD, q, oe(U_SHR, q, K(31), 0, 0), 0, 0); +} +static int udivk(int a, unsigned d) +{ + unsigned mul; int add, sh, t; + if (d == 1) return a; + if (ispow2(d)) return oe(U_SHR, a, K(lg2(d)), 0, 0); + if (d > 0x80000000u) return oe(U_XOR, oe(U_LTU, a, K((int)d), 0, 0), K(1), 0, 0); /* a >= d */ + umagic(d, &mul, &add, &sh); + t = oe(U_MULHU, a, K((int)mul), 0, 0); + if (!add) return sh ? oe(U_SHR, t, K(sh), 0, 0) : t; + t = oe(U_ADD, oe(U_SHR, oe(U_SUB, a, t, 0, 0), K(1), 0, 0), t, 0, 0); + return sh > 1 ? oe(U_SHR, t, K(sh - 1), 0, 0) : t; +} +static int oe(int op, int a, int b, int c, int imm) +{ + int ka, kb, A, B; + if (op == U_LI) return raw(U_LI, 0, 0, 0, imm); + if (op == U_MOV) return a; + if (op == U_LD || op == U_ST) return raw(op, a, b, 0, 0); + ka = isk[a]; kb = uarity[op] > 1 && isk[b]; + A = kv[a]; B = kv[b]; + /* everything constant: fold */ + if (ka && (uarity[op] < 2 || kb) && (uarity[op] < 3 || isk[c])) return K(ev(op, A, B, kv[c])); + /* constants go right for commutative ops */ + if (ka && !kb && (op == U_ADD || op == U_MUL || op == U_AND || op == U_OR || op == U_XOR || op == U_EQ || op == U_NE || + op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU || op == U_MULHS || op == U_MULHU)) { + int t = a; a = b; b = t; kb = 1; B = A; ka = 0; + } + if (op == U_SEL && ka) return A ? b : c; + if (op == U_SEL && b == c) return b; + if (kb) switch (op) { + case U_ADD: case U_SUB: case U_OR: case U_XOR: case U_SHL: case U_SHR: case U_SAR: + if (!B || (op >= U_SHL && op <= U_SAR && !(B & 31))) return a; + break; + case U_MUL: + if (B == 0) return K(0); + if (B == 1) return a; + if (B == -1) return oe(U_NEG, a, 0, 0, 0); + if (ispow2((unsigned)B)) return oe(U_SHL, a, K(lg2((unsigned)B)), 0, 0); + break; + case U_AND: if (B == 0) return K(0); if (B == -1) return a; break; + case U_SDIV: if (B == 0) return K(0); return sdivk(a, B); + case U_SREM: if (B == 0) return a; if (B == 1 || B == -1) return K(0); + return oe(U_SUB, a, oe(U_MUL, sdivk(a, B), b, 0, 0), 0, 0); + case U_UDIV: if (B == 0) return K(0); return udivk(a, (unsigned)B); + case U_UREM: if (B == 0) return a; + if (ispow2((unsigned)B)) return oe(U_AND, a, K(B - 1), 0, 0); + return oe(U_SUB, a, oe(U_MUL, udivk(a, (unsigned)B), b, 0, 0), 0, 0); + } + if (a == b && uarity[op] == 2) { + if (op == U_SUB || op == U_XOR || op == U_LT || op == U_LTU || op == U_NE) return K(0); + if (op == U_AND || op == U_OR || op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU) return a; + if (op == U_EQ) return K(1); + } + return raw(op, a, b, c, 0); +} +/* runs the optimizer over ub[0..un) with nin inputs; leaves the result in e */ +static int optimize(Enh *e, int nin, int *out, int nout) +{ + int i, *live, n = 0; + static int omap_[MAXUOP + 16], isk_[MAXUOP * 4], kv_[MAXUOP * 4]; + omap = omap_; isk = isk_; kv = kv_; + on = 0; onv = nin; + for (i = 0; i < nin; i++) { omap[i] = i; isk[i] = 0; } + for (i = 0; i < un && !uerr; i++) { + Uop *u = &ub[i]; + int a = uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD ? omap[u->a] : 0; + int b = uarity[u->op] > 1 || u->op == U_ST ? omap[u->b] : 0; + int c = uarity[u->op] > 2 ? omap[u->c] : 0; + if (u->op == U_ST) oe(U_ST, a, b, 0, 0); + else omap[u->d] = oe(u->op, a, b, c, u->imm); + } + if (uerr) return uerr; + /* dead code: outputs and stores are live */ + live = calloc(onv + 1, sizeof *live); + for (i = 0; i < nout; i++) { e->out[i] = omap[out[i]]; live[e->out[i]] = 1; } + for (i = on; i--;) { + Uop *u = &ob[i]; + if (u->op != U_ST && !live[u->d]) { u->op = -1; continue; } + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) live[u->a] = 1; + if (uarity[u->op] > 1 || u->op == U_ST) live[u->b] = 1; + if (uarity[u->op] > 2) live[u->c] = 1; + } + free(live); + e->u = malloc((on + 1) * sizeof(Uop)); + for (i = 0; i < on; i++) if (ob[i].op >= 0) e->u[n++] = ob[i]; + e->n = n; e->nv = onv; e->nin = nin; e->nout = nout; + return 0; +} +/* run an installed enhancement on a downward-growing stack; returns the new top */ +static int *xexec(Enh *e, int *sp) +{ + int vb[256], *v = e->nv <= 256 ? vb : malloc(e->nv * sizeof(int)), i, j; + for (j = 0; j < e->nin; j++) v[j] = sp[e->nin - 1 - j]; + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + switch (u->op) { + case U_LI: v[u->d] = u->imm; break; + case U_LD: v[u->d] = mread(v[u->a]); break; + case U_ST: if ((unsigned)v[u->a] < MW) m[v[u->a]] = v[u->b]; break; + default: v[u->d] = ev(u->op, v[u->a], v[u->b], v[u->c]); + } + } + sp += e->nin - e->nout; + for (j = 0; j < e->nout; j++) sp[e->nout - 1 - j] = v[e->out[j]]; + if (v != vb) free(v); + return sp; +} +static void xdump(int slot, Enh *e) +{ + int i; + fprintf(stderr, "enh %d: %d in, %d out, %d ops\n", slot, e->nin, e->nout, e->n); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (u->op == U_ST) fprintf(stderr, " st v%d v%d\n", u->a, u->b); + else if (u->op == U_LI) fprintf(stderr, " v%d = %d\n", u->d, u->imm); + else { fprintf(stderr, " v%d = %s v%d", u->d, unames[u->op], u->a); if (uarity[u->op] > 1) fprintf(stderr, " v%d", u->b); if (uarity[u->op] > 2) fprintf(stderr, " v%d", u->c); fprintf(stderr, "\n"); } + } + for (i = 0; i < e->nout; i++) fprintf(stderr, " out%d = v%d\n", i, e->out[i]); +} +/* registers for the jit: values live in w0..w15, straight-line linear scan. + if they don't fit, reg stays 0 and the jit calls the interpreter instead. */ +static void regalloc(Enh *e) +{ + int *last = malloc(e->nv * sizeof(int)), i, j, k, fr = 0xffff; + signed char *r = malloc(e->nv); + for (i = 0; i < e->nv; i++) { last[i] = -2; r[i] = -1; } + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) last[u->a] = i; + if (uarity[u->op] > 1 || u->op == U_ST) last[u->b] = i; + if (uarity[u->op] > 2) last[u->c] = i; + } + for (i = 0; i < e->nout; i++) last[e->out[i]] = e->n; +#define TAKE(v) do { for (k = 0; k < 16 && !(fr >> k & 1); k++); if (k == 16) goto fail; fr &= ~(1 << k); r[v] = (signed char)k; } while (0) + for (j = 0; j < e->nin; j++) if (last[j] >= -1 && last[j] != -2) TAKE(j); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; int ops[3], no = 0; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) ops[no++] = u->a; + if (uarity[u->op] > 1 || u->op == U_ST) ops[no++] = u->b; + if (uarity[u->op] > 2) ops[no++] = u->c; + for (j = 0; j < no; j++) if (last[ops[j]] == i && r[ops[j]] >= 0 && (fr >> r[ops[j]] & 1) == 0) fr |= 1 << r[ops[j]]; + if (u->op != U_ST) TAKE(u->d); + if (u->op != U_ST && last[u->d] == -2) fr |= 1 << r[u->d]; /* never used */ + } +#undef TAKE + free(last); e->reg = r; return; +fail: + free(last); free(r); e->reg = 0; +} +/* the install opcode. descriptor: slot, kind (0 recipe, 1 vm code), inputs, + outputs, payload address, payload length, parameter names (or 0). kind 2 + is an o3 region (below). + returns 0, or -1 bad descriptor, -2 recipe syntax, -4 code doesn't lift, + -5 too big. */ +static int o3install(int d); +static int install(int d) +{ + int slot = mread(d), kind = mread(d + 1), nin = mread(d + 2), nout = mread(d + 3); + int pay = mread(d + 4), len = mread(d + 5), names = mread(d + 6), out[8], r; + Enh ne; + if (kind == 2) return o3install(d); + if ((unsigned)slot >= NENH || (unsigned)nin > 8 || (unsigned)nout > 8 || (kind != 0 && kind != 1)) return -1; + un = 0; unv = nin; uerr = 0; + r = kind == 0 ? parse_recipe(pay, names, nin, nout, out) : lift_vm(pay, len, nin, nout, out); + if (r) { if (trace) fprintf(stderr, "enh %d: install failed (%d)\n", slot, r); return r; } + memset(&ne, 0, sizeof ne); + if ((r = optimize(&ne, nin, out, nout))) return r; + ne.kind = kind; ne.live = 1; + regalloc(&ne); + if (enh[slot].live) { free(enh[slot].u); free(enh[slot].reg); } + enh[slot] = ne; + need_flush = 1; + if (trace) xdump(slot, &enh[slot]); + return 0; +} + +/* ---- o3: optimized regions ---- + o3 code comes from the compiler as a region: a range [lo, hi) of vm words + plus up to 7 frame slots that nothing takes the address of (install kind 2: + [-, 2, lo, hi, n, slots...]). the region is cut into basic blocks. each + block is lifted to ssa: the vm stack is tracked symbolically, so only what + is left on it at the end of the block touches memory, the slots live in + registers across blocks (VGET reads one at block entry, the block's end + says what each one holds now), the frame pointer is var 0, and enhancements + are spliced in. every block then goes through the optimizer above. a + backend compiles the whole region at once: arm64, llvm at O3, or the + region interpreter below. the region is entered at lo and at the return + points of its calls. calls, returns, jumps out, and anything a block can't + lift leave it: the slots go back to the frame first, so the code outside + sees the usual memory. stores to its own code drop it; it lifts again on + its next entry. */ +#define ZFP 0xA0000 /* the frame pointer word */ +#define U_VGET U_N /* a var at block entry; imm = var */ +#define U_SLD (U_N + 1) /* the stack word at offset imm from the top at block entry */ +#define RMAXV 8 +#define RMAXE 256 +enum { T_BR, T_CBR, T_JMP, T_CALL, T_RET }; +typedef struct { + int a, n, nv, delta, nso, term, cv, s1, s2, x1, x2; + int vs[RMAXV]; /* each var's value at the end, -1 if unchanged */ + int *so; /* stack words to write at the end: offset, value */ + Uop *u; +} RB; +typedef struct { + int idx, lo, hi, nv, slot[RMAXV], lifted, dead, nonat, nb, ne, maxnv; + int ent[RMAXE], entb[RMAXE]; + RB *b; + void *nat, *stub[RMAXE]; /* the backend's code */ +} Rg; +#define MAXRG 4096 +static Rg *rgs[MAXRG]; +static int nrg; +static unsigned short o3ent[MW]; /* region + 1 at an entry point */ +static unsigned char o3ei[MW]; /* which of its entries */ +static void rforget(Rg *R); /* the backend drops its code */ +static void rmark(Rg *R); /* the backend watches the region's words */ +static void rcompile(Rg *R, int eager); + +static int nargs(int op) { return op >= U_N ? 0 : uarity[op]; } +static void rclear(Rg *R) +{ + int b; + rforget(R); + for (b = 0; b < R->nb; b++) { free(R->b[b].u); free(R->b[b].so); } + free(R->b); R->b = 0; R->nb = 0; R->lifted = 0; +} +static void rdrop_all(void) { int j; for (j = 0; j < nrg; j++) if (rgs[j]->lifted) rclear(rgs[j]); } + +/* lifting one block */ +static Rg *R_; +static unsigned char *lead_; +static int *bidx_, *wl_, nw_; +static int lv_[RMAXV], lw_[RMAXV]; +#define SB 1100 +static int skv[2 * SB], stp, slo, shi; +static unsigned char skk[2 * SB]; +static int afp[MAXUOP * 4 + 16]; /* value -> 1 + its offset from fp, if it is fp + k */ +static int emap[MAXUOP * 4 + 16]; + +static int rvar(int v) +{ + if (lv_[v] < 0) { lv_[v] = raw(U_VGET, 0, 0, 0, v); if (!v) afp[lv_[v]] = 1; } + return lv_[v]; +} +static int slotvar(int off) { int v; for (v = 1; v < R_->nv; v++) if (R_->slot[v] == off) return v; return 0; } +static int rbin(int op, int x, int y, int z) +{ + int r = oe(op, x, y, z, 0); + if (op == U_ADD && !afp[r]) { + if (afp[x] && isk[y]) afp[r] = afp[x] + kv[y]; + else if (afp[y] && isk[x]) afp[r] = afp[y] + kv[x]; + } + return r; +} +static int rld(int a) +{ + int v; + if (isk[a] && kv[a] == ZFP) return rvar(0); + if (afp[a] && (v = slotvar(afp[a] - 1))) return rvar(v); + return oe(U_LD, a, 0, 0, 0); +} +static int rst(int a, int b) +{ + int v; + if (isk[a] && kv[a] == ZFP) return 0; /* moving the frame: not in here */ + if (afp[a] && (v = slotvar(afp[a] - 1))) { lv_[v] = b; lw_[v] = 1; return 1; } + oe(U_ST, a, b, 0, 0); + return 1; +} +static int sget(int o) +{ + if (o < -SB || o >= SB) { uerr = -6; return 0; } + if (!skk[o + SB]) { + if (o < 0) { uerr = -6; return 0; } + skv[o + SB] = raw(U_SLD, 0, 0, 0, o); skk[o + SB] = 1; + } + if (o < slo) slo = o; + if (o >= shi) shi = o + 1; + return skv[o + SB]; +} +static void sset(int o, int v) +{ + if (o < -SB || o >= SB) { uerr = -6; return; } + skv[o + SB] = v; skk[o + SB] = 1; + if (o < slo) slo = o; + if (o >= shi) shi = o + 1; +} +static int spop(void) { return sget(stp++); } +static void spush(int v) { sset(--stp, v); } +static int rblk(int t) { return t >= R_->lo && t < R_->hi && lead_[t - R_->lo] ? bidx_[t - R_->lo] : -1; } +/* an enhancement, spliced into the block */ +static int rsplice(Enh *e) +{ + int i, j; + for (j = e->nin; j--;) emap[j] = spop(); + for (i = 0; i < e->n && !uerr; i++) { + Uop *u = &e->u[i]; + int na = nargs(u->op), a = na > 0 ? emap[u->a] : 0, b = na > 1 ? emap[u->b] : 0, c = na > 2 ? emap[u->c] : 0; + if (u->op == U_LI) emap[u->d] = K(u->imm); + else if (u->op == U_LD) emap[u->d] = rld(a); + else if (u->op == U_ST) { if (!rst(a, b)) uerr = -4; } + else emap[u->d] = rbin(u->op, a, b, c); + } + for (j = 0; j < e->nout; j++) spush(emap[e->out[j]]); + return uerr; +} +static int lift_block(int bi) +{ + static const int map[] = { U_ADD, U_SUB, U_MUL, U_AND, U_OR, U_XOR, U_SAR, U_LT }; + RB *B = &R_->b[bi]; + int i = B->a, w, k, x, y, t, j, o, n = 0, *live; + on = 0; onv = 0; uerr = 0; + memset(afp, 0, sizeof afp); memset(skk, 0, sizeof skk); + stp = slo = shi = 0; + for (j = 0; j < RMAXV; j++) { lv_[j] = -1; lw_[j] = 0; } + B->term = T_JMP; B->cv = -1; B->s1 = B->s2 = -1; B->x1 = B->x2 = 0; + for (;;) { + if (uerr) return uerr; + if (i != B->a && (t = rblk(i)) >= 0) { B->term = T_BR; B->s1 = t; goto done; } + if (i < R_->lo || i >= R_->hi) goto leave_at; + w = m[i]; + if (w & 1) { spush(K(w >> 1)); i++; continue; } + k = w / 2; + switch (k) { + case 0: B->cv = K(-1); goto done; /* halt */ + case 1: x = spop(); spush(rld(x)); break; + case 2: + x = sget(stp); + if (isk[x] && kv[x] == ZFP) goto leave_at; + x = spop(); y = spop(); rst(x, y); + break; + case 3: /* pick: a constant depth */ + x = sget(stp); + if (!isk[x] || kv[x] < 0 || kv[x] > 1024) goto leave_at; + stp++; spush(sget(stp + kv[x])); + break; + case 4: stp++; break; + case 5: x = sget(stp); y = sget(stp + 1); sset(stp, y); sset(stp + 1, x); break; + case 6: B->cv = spop(); B->term = T_CALL; B->x2 = i + 1; goto done; + case 7: + x = spop(); + if (isk[x] && (t = rblk(kv[x])) >= 0) { B->term = T_BR; B->s1 = t; } + else B->cv = x; + goto done; + case 8: + x = sget(stp); + if (!isk[x]) goto leave_at; + stp++; y = spop(); + if (isk[y]) { /* a known condition */ + if (kv[y]) { i++; continue; } + if ((t = rblk(kv[x])) >= 0) { B->term = T_BR; B->s1 = t; } else B->cv = K(kv[x]); + goto done; + } + B->term = T_CBR; B->cv = y; + B->x1 = kv[x]; B->s1 = rblk(kv[x]); + B->x2 = i + 1; B->s2 = rblk(i + 1); + goto done; + case 9: B->term = T_RET; goto done; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + x = spop(); y = spop(); spush(rbin(map[k - 13], y, x, 0)); + break; + default: + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { if (rsplice(&enh[k - XOP0])) return uerr; break; } + goto leave_at; /* i/o, install, unwired: done the usual way */ + } + i++; + } +leave_at: + B->term = T_JMP; B->cv = K(i); +done: + if (uerr) return uerr; + B->delta = stp; + B->so = malloc((shi - slo + 1) * 2 * sizeof(int)); + B->nso = 0; + for (o = stp > slo ? stp : slo; o < shi; o++) + if (skk[o + SB]) { + x = skv[o + SB]; + if (ob[x].op == U_SLD && ob[x].imm == o) continue; /* still the word that was there */ + if (afp[x] && slotvar(afp[x] - 1)) return -7; /* a register var's address can't wait in memory */ + B->so[2 * B->nso] = o; B->so[2 * B->nso + 1] = x; B->nso++; + } + for (j = 0; j < RMAXV; j++) B->vs[j] = -1; + for (j = 1; j < R_->nv; j++) + if (lw_[j] && !(ob[lv_[j]].op == U_VGET && ob[lv_[j]].imm == j)) B->vs[j] = lv_[j]; + /* dead code: what the block leaves behind and its stores are live */ + live = calloc(onv + 1, sizeof *live); + for (j = 0; j < B->nso; j++) live[B->so[2 * j + 1]] = 1; + for (j = 1; j < R_->nv; j++) if (B->vs[j] >= 0) live[B->vs[j]] = 1; + if (B->term == T_CBR || B->term == T_JMP || B->term == T_CALL) live[B->cv] = 1; + for (i = on; i--;) { + Uop *u = &ob[i]; + if (u->op != U_ST && !live[u->d]) { u->op = -1; continue; } + k = nargs(u->op); + if (k > 0) live[u->a] = 1; + if (k > 1) live[u->b] = 1; + if (k > 2) live[u->c] = 1; + } + free(live); + B->u = malloc((on + 1) * sizeof(Uop)); + for (i = 0; i < on; i++) if (ob[i].op >= 0) B->u[n++] = ob[i]; + B->n = n; B->nv = onv; + if (onv > R_->maxnv) R_->maxnv = onv; + return 0; +} +static void addl(int x, int en) +{ + int e; + if (x < R_->lo || x >= R_->hi) return; + if (!lead_[x - R_->lo]) { lead_[x - R_->lo] = 1; wl_[nw_++] = x; } + if (en) { for (e = 0; e < R_->ne && R_->ent[e] != x; e++); if (e == R_->ne && e < RMAXE) R_->ent[R_->ne++] = x; } +} +/* blocks, then each one lifted and optimized */ +static int rlift(Rg *R) +{ + int n = R->hi - R->lo, L, i, w, k, t, b, e, r = 0, cnt; + if (R->lifted) rclear(R); + R_ = R; + lead_ = calloc(n, 1); bidx_ = malloc(n * sizeof(int)); wl_ = malloc(n * sizeof(int)); nw_ = 0; + R->ne = 0; + addl(R->lo, 1); + while (nw_) { + L = wl_[--nw_]; + for (i = L, cnt = 0;;) { + if (i >= R->hi || (i != L && lead_[i - R->lo])) break; + if (cnt++ >= 1000) { addl(i, 0); break; } + w = m[i]; + if (w & 1) { + if (i + 1 < R->hi && !(m[i + 1] & 1) && (k = m[i + 1] / 2) >= 6 && k <= 8) { + t = w >> 1; + if (k == 6) addl(i + 2, 1); /* a call comes back here */ + else if (k == 7) addl(t, 0); + else { addl(t, 0); addl(i + 2, 0); } + break; + } + i++; + continue; + } + k = w / 2; + if (k == 6) { addl(i + 1, 1); break; } + if (k == 8) { addl(i + 1, 0); break; } + if (k == 0 || k == 7 || k == 9) break; + i++; + } + } + for (i = 0, b = 0; i < n; i++) if (lead_[i]) bidx_[i] = b++; + R->nb = b; R->b = calloc(b, sizeof(RB)); R->maxnv = 0; + for (i = 0; i < n; i++) if (lead_[i]) R->b[bidx_[i]].a = R->lo + i; + for (b = 0; b < R->nb && !r; b++) r = lift_block(b); + for (e = 0; e < R->ne; e++) R->entb[e] = bidx_[R->ent[e] - R->lo]; + free(lead_); free(bidx_); free(wl_); + if (r) { + if (trace) fprintf(stderr, "o3: %d..%d doesn't lift (%d)\n", R->lo, R->hi - 1, r); + R->lifted = 1; rclear(R); return r; + } + for (e = 0; e < R->ne; e++) { o3ent[R->ent[e]] = R->idx + 1; o3ei[R->ent[e]] = e; } + R->lifted = 1; + rmark(R); + if (trace) { + int ops = 0; + for (b = 0; b < R->nb; b++) ops += R->b[b].n; + fprintf(stderr, "o3: %d..%d: %d blocks, %d entries, %d vars, %d micro-ops\n", R->lo, R->hi - 1, R->nb, R->ne, R->nv - 1, ops); + if (getenv("ZYO3DUMP")) + for (b = 0; b < R->nb; b++) { + RB *B = &R->b[b]; + fprintf(stderr, " b%d @%d: %d ops, sp %+d, term %d cv v%d s %d/%d x %d/%d\n", b, B->a, B->n, B->delta, B->term, B->cv, B->s1, B->s2, B->x1, B->x2); + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + if (u->op == U_ST) fprintf(stderr, " st v%d v%d\n", u->a, u->b); + else if (u->op == U_LI) fprintf(stderr, " v%d = %d\n", u->d, u->imm); + else if (u->op == U_VGET) fprintf(stderr, " v%d = var%d\n", u->d, u->imm); + else if (u->op == U_SLD) fprintf(stderr, " v%d = s[%d]\n", u->d, u->imm); + else { fprintf(stderr, " v%d = %s v%d", u->d, unames[u->op], u->a); if (nargs(u->op) > 1) fprintf(stderr, " v%d", u->b); if (nargs(u->op) > 2) fprintf(stderr, " v%d", u->c); fprintf(stderr, "\n"); } + } + for (i = 0; i < B->nso; i++) fprintf(stderr, " s[%d] = v%d\n", B->so[2 * i], B->so[2 * i + 1]); + for (i = 1; i < R->nv; i++) if (B->vs[i] >= 0) fprintf(stderr, " var%d = v%d\n", i, B->vs[i]); + } + } + return 0; +} +/* install kind 2 */ +static int o3install(int d) +{ + int lo = mread(d + 2), hi = mread(d + 3), n = mread(d + 4), i, r; + Rg *R; + if (lo <= 0 || hi <= lo || hi > MW || hi - lo > 1000000 || (unsigned)n > 7 || nrg >= MAXRG) return -1; + R = calloc(1, sizeof *R); + R->idx = nrg; rgs[nrg++] = R; + R->lo = lo; R->hi = hi; R->nv = n + 1; + for (i = 0; i < n; i++) { R->slot[i + 1] = mread(d + 5 + i); if ((unsigned)R->slot[i + 1] >= 4096) { R->dead = 1; return -1; } } + if ((r = rlift(R))) { R->dead = 1; return r; } + rcompile(R, 1); + return 0; +} +/* the region entered at p, lifted again if it has to be, or 0 */ +static Rg *rat(int p) +{ + Rg *R = rgs[o3ent[p] - 1]; + if (R->dead) { o3ent[p] = 0; return 0; } + if (!R->lifted && rlift(R)) { R->dead = 1; o3ent[p] = 0; return 0; } + if (o3ei[p] >= R->ne || R->ent[o3ei[p]] != p) { o3ent[p] = 0; return 0; } + return R; +} + +#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[13]; /* m, s, r, tab, cov, Q, G, &J, store hook, install, enhancement fallback, stack limits */ + +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(0xa9b97bfd); /* stp x29, x30, [sp, #-112]! */ + 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(0xa90467f8); /* stp x24, x25, [sp, #64] */ + E(0xa9056ffa); /* stp x26, x27, [sp, #80] */ + E(0xf90033fc); /* str x28, [sp, #96] */ + E(0xaa0003f7); /* mov x23, x0 */ + ldrx_u(M, ST, 0); + ldrx_u(24, ST, 88); ldrx_u(25, ST, 96); /* x24, x25: the stack limits, as addresses */ + 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(0xa94467f8); /* ldp x24, x25, [sp, #64] */ + E(0xa9456ffa); /* ldp x26, x27, [sp, #80] */ + E(0xf94033fc); /* ldr x28, [sp, #96] */ + E(0xa8c77bfd); /* ldp x29, x30, [sp], #112 */ + E(0xd65f03c0); /* ret */ + { + unsigned *ovd = cp, *ovr; + li(W0, MW + 1); b_to(x_exit); /* data stack overflow */ + ovr = cp; + li(W0, MW + 2); b_to(x_exit); /* return stack overflow */ + x_disp = cp; /* w0 = target: check the stacks, chain through tab[] or fall back to c */ + E(0xeb18029f); /* cmp x20, x24 */ + E(0x54000003 | ((ovd - cp) & 0x7ffff) << 5); /* b.lo data overflow */ + E(0xeb1902bf); /* cmp x21, x25 */ + E(0x54000002 | ((ovr - cp) & 0x7ffff) << 5); /* b.hs return overflow */ + } + 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; + rdrop_all(); + 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 < nrg; j++) + if (rgs[j]->lifted && rgs[j]->lo <= a && a < rgs[j]->hi) { + if (trace) fprintf(stderr, "o3: dropped %d..%d (a store to %d)\n", rgs[j]->lo, rgs[j]->hi - 1, a); + rclear(rgs[j]); + memset(cov, 0, sizeof cov); + 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; + for (j = 0; j < nrg; j++) if (rgs[j]->lifted) rmark(rgs[j]); + 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); +} + +/* one micro-op, operands in registers. tmp is a scratch register for the + remainders; x16 and x17 are scratch too. */ +static void emit_uop(int op, int d, int a, int b, int c, int tmp) +{ + switch (op) { + case U_ADD: op3(0x0b000000, d, a, b); break; + case U_SUB: op3(0x4b000000, d, a, b); break; + case U_MUL: op3(0x1b007c00, d, a, b); break; + case U_SDIV: op3(0x1ac00c00, d, a, b); break; + case U_UDIV: op3(0x1ac00800, d, a, b); break; + case U_SREM: op3(0x1ac00c00, tmp, a, b); E(0x1b008000 | b << 16 | a << 10 | tmp << 5 | d); break; /* msub */ + case U_UREM: op3(0x1ac00800, tmp, a, b); E(0x1b008000 | b << 16 | a << 10 | tmp << 5 | d); break; + case U_AND: op3(0x0a000000, d, a, b); break; + case U_OR: op3(0x2a000000, d, a, b); break; + case U_XOR: op3(0x4a000000, d, a, b); break; + case U_SHL: op3(0x1ac02000, d, a, b); break; + case U_SHR: op3(0x1ac02400, d, a, b); break; + case U_SAR: op3(0x1ac02800, d, a, b); break; + case U_NEG: E(0x4b0003e0 | a << 16 | d); break; + case U_NOT: E(0x2a2003e0 | a << 16 | d); break; + case U_LT: E(0x6b00001f | b << 16 | a << 5); E(0x1a9fa7e0 | d); break; /* cmp; cset lt */ + case U_LTU: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f27e0 | d); break; /* cset lo */ + case U_EQ: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f17e0 | d); break; + case U_NE: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f07e0 | d); break; + case U_MIN: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 11 << 12 | a << 5 | d); break; + case U_MAX: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 12 << 12 | a << 5 | d); break; + case U_MINU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 3 << 12 | a << 5 | d); break; + case U_MAXU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 8 << 12 | a << 5 | d); break; + case U_MULHS: E(0x9b207c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; /* smull; lsr #32 */ + case U_MULHU: E(0x9ba07c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; + case U_CLZ: E(0x5ac01000 | a << 5 | d); break; + case U_ABS: E(0x7100001f | a << 5); E(0x5a800400 | a << 16 | 10 << 12 | a << 5 | d); break; /* cmp #0; cneg */ + case U_SEL: E(0x7100001f | a << 5); E(0x1a800000 | c << 16 | 1 << 12 | b << 5 | d); break; /* csel ne */ + case U_LD: /* out of range reads 0, like the interpreter */ + E(0x52800011); E(0x7144001f | a << 5); E(0x54000042); ldr_rr(17, M, a, UXTW); movw(d, 17); + break; + case U_ST: E(0x7144001f | a << 5); E(0x54000042); str_rr(b, M, a, UXTW); break; + } +} +/* an enhancement, inlined: inputs from the data stack into w0..w15, the + optimized micro-ops, outputs back. constants are made where they're used, + or folded into the instruction (a fixed address, a small addend). */ +static int ekc[MAXUOP * 4 + 16], ekv[MAXUOP * 4 + 16]; +static void emit_enh_e(Enh *e, int s) +{ + signed char *r = e->reg; + int i, j, delta, na; + if (!r) { /* didn't fit in registers: x0 = data stack, w1 = slot, call the interpreter */ + E(0xaa1403e0); li(W1, s); ldrx_u(X11, ST, 80); blr(X11); E(0xaa0003f4); + return; + } + for (i = 0; i < e->nv; i++) ekc[i] = 0; + for (i = 0; i < e->n; i++) if (e->u[i].op == U_LI) { ekc[e->u[i].d] = 1; ekv[e->u[i].d] = e->u[i].imm; } +#define EOP(x) (ekc[x] ? (li(r[x], ekv[x]), r[x]) : r[x]) + for (j = 0; j < e->nin; j++) if (r[j] >= 0) ldr_u(r[j], SP, 4 * (e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + int d = u->op == U_ST ? 0 : r[u->d], a = 0, b = 0, c = 0; + if (u->op == U_LI) continue; + if (u->op == U_LD && ekc[u->a] && (unsigned)ekv[u->a] < MW) { + if (ekv[u->a] < 4096) ldr_u(d, M, ekv[u->a] * 4); else ldr_rr(d, M, EOP(u->a), UXTW); + continue; + } + if ((u->op == U_ADD || u->op == U_SUB) && ekc[u->b] && ekv[u->b] >= 0 && ekv[u->b] < 4096) { + E((u->op == U_ADD ? 0x11000000 : 0x51000000) | ekv[u->b] << 10 | EOP(u->a) << 5 | d); + continue; + } + na = nargs(u->op); + if (na > 0) a = EOP(u->a); + if (na > 1) b = EOP(u->b); + if (na > 2) c = EOP(u->c); + emit_uop(u->op, d, a, b, c, 16); + } + delta = 4 * (e->nin - e->nout); + if (delta > 0) E(0x91000294 | delta << 10); + if (delta < 0) E(0xd1000294 | (-delta) << 10); + for (j = 0; j < e->nout; j++) str_u(EOP(e->out[j]), SP, 4 * (e->nout - 1 - j)); +#undef EOP +} +static void emit_enh(int s) { emit_enh_e(&enh[s], s); } +/* lit .. lit xop: the enhancement specialized on the literals that feed its + last inputs, so the optimizer sees them as constants (x / 7 becomes a + multiply, lfa(k) a load and an add). 0 if it worked. */ +static int spec_enh(int s, int *ks, int nk, Enh *te) +{ + Enh *e = &enh[s]; + int nin = e->nin - nk, i, j, out[8], na; + static int mp[MAXUOP * 4 + 16]; + if (e->nv > MAXUOP * 4) return -1; + un = 0; unv = nin; uerr = 0; + for (j = 0; j < nin; j++) mp[j] = j; + for (j = 0; j < nk; j++) mp[nin + j] = unew(U_LI, 0, 0, 0, ks[j]); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + na = nargs(u->op); + j = unew(u->op, na > 0 ? mp[u->a] : 0, na > 1 ? mp[u->b] : 0, na > 2 ? mp[u->c] : 0, u->imm); + if (u->op != U_ST) mp[u->d] = j; + } + for (j = 0; j < e->nout; j++) out[j] = mp[e->out[j]]; + memset(te, 0, sizeof *te); + if (uerr || optimize(te, nin, out, e->nout)) return -1; + regalloc(te); + if (!te->reg) { free(te->u); return -1; } + return 0; +} + +/* ---- o3 regions on arm64 ---- + vars live in w0..w7 (w0 is the frame pointer), block values in w8..w14, + w26..w28 and the homes of unused vars. constants have no register: they + are made in a scratch register where they're used (w16, w17, w15), or + folded into the instruction. x15..x17 are scratch. */ +static signed char rreg[MAXUOP * 4 + 16]; +static unsigned char rk[MAXUOP * 4 + 16], rhome[MAXUOP * 4 + 16]; +static int rkv[MAXUOP * 4 + 16], rlast[MAXUOP * 4 + 16]; +static unsigned **rfa; static int *rfb, rnf; /* branches to blocks, fixed up at the end */ + +static void rforget(Rg *R) +{ + int e; + if (R->nat) for (e = 0; e < R->ne; e++) if (tab[R->ent[e]] == R->stub[e]) tab[R->ent[e]] = 0; + R->nat = 0; +} +static void rmark(Rg *R) { int x; for (x = R->lo; x < R->hi; x++) cov[x] = 1; } +static int ralloc(Rg *R, RB *B) +{ + int i, j, k, n = B->n; + unsigned fr = 0x7f00u | 0x1c000000u; /* w8..w14, w26..w28 */ + for (j = R->nv; j < 8; j++) fr |= 1u << j; + for (i = 0; i < B->nv; i++) { rlast[i] = -2; rk[i] = 0; rhome[i] = 0; rreg[i] = -1; } + for (i = 0; i < n; i++) { + Uop *u = &B->u[i]; int na = nargs(u->op); + if (na > 0) rlast[u->a] = i; + if (na > 1) rlast[u->b] = i; + if (na > 2) rlast[u->c] = i; + } + for (j = 0; j < B->nso; j++) rlast[B->so[2 * j + 1]] = n; + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) rlast[B->vs[j]] = n; + if (B->term == T_CBR || B->term == T_JMP || B->term == T_CALL) rlast[B->cv] = n; + for (i = 0; i < n; i++) { + Uop *u = &B->u[i]; int na = nargs(u->op), ops[3], d = u->d; + ops[0] = u->a; ops[1] = u->b; ops[2] = u->c; + for (j = 0; j < na; j++) { int x = ops[j]; if (rlast[x] == i && rreg[x] >= 0 && !rhome[x]) fr |= 1u << rreg[x]; } + if (u->op == U_ST) continue; + if (u->op == U_LI) { rk[d] = 1; rkv[d] = u->imm; continue; } + if (u->op == U_VGET) { rreg[d] = (signed char)u->imm; rhome[d] = 1; continue; } + for (k = 0; k < 32 && !(fr >> k & 1); k++); + if (k == 32) return -1; + fr &= ~(1u << k); rreg[d] = (signed char)k; + if (rlast[d] == -2) fr |= 1u << k; + } + return 0; +} +static int ropr(int x, int s) { if (rk[x]) { li(s, rkv[x]); return s; } return rreg[x]; } +/* w t <-> the data stack word o places from the top at block entry */ +static void rsw(int t, int o, int store) +{ + int by = o * 4; + if (by >= 0 && by < 16384) { if (store) str_u(t, SP, by); else ldr_u(t, SP, by); } + else if (by >= -256 && by < 256) E((store ? 0xb8000000u : 0xb8400000u) | (unsigned)(by & 0x1ff) << 12 | SP << 5 | t); /* stur, ldur */ + else { li(16, by); addx_ext(16, SP, 16, SXTW); if (store) str_u(t, 16, 0); else ldr_u(t, 16, 0); } +} +static void addsp(int by) +{ + if (by > 0 && by < 4096) E(0x91000294 | by << 10); + else if (by < 0 && -by < 4096) E(0xd1000294 | (-by) << 10); + else if (by) { li(16, by); addx_ext(SP, SP, 16, SXTW); } +} +static void rspill(Rg *R) +{ + int v; + for (v = 1; v < R->nv; v++) { E(0x11000000 | R->slot[v] << 10 | 16); str_rr(v, M, 16, UXTW); } /* add w16, w0, #slot */ +} +static void rload(Rg *R) +{ + int v; + li(16, ZFP); ldr_rr(0, M, 16, UXTW); + for (v = 1; v < R->nv; v++) { E(0x11000000 | R->slot[v] << 10 | 16); ldr_rr(v, M, 16, UXTW); } +} +static void rexitk(Rg *R, int t) { rspill(R); li(W0, t); b_to(x_disp); } +static void rbranch(int b) { rfa[rnf] = cp; rfb[rnf++] = b; E(0x14000000); } +/* m[a] = v, checked like the jit's own stores: a word some translation covers goes through hook */ +static void rstore(int a, int v) +{ + unsigned *p1, *p2, *p3; + int j; + E(0x7144001f | a << 5); /* cmp wa, #MW */ + p1 = cp; E(0x54000002); /* b.hs done */ + ldrx_u(15, ST, 32); + E(0x38604800 | a << 16 | 15 << 5 | 15); /* ldrb w15, [x15, wa, uxtw] */ + p2 = cp; E(0x35000000 | 15); /* cbnz w15, slow */ + str_rr(v, M, a, UXTW); + p3 = cp; E(0x14000000); + cb_fix(p2, cp); + E(0xd10203ff); /* sub sp, sp, #128 */ + for (j = 0; j < 16; j += 2) E(0xa9000000 | (j / 2 * 2) << 15 | (j + 1) << 10 | 31 << 5 | j); /* stp xj, xj+1, [sp, #8j] */ + movw(15, a); movw(1, v); movw(0, 15); + ldrx_u(16, ST, 64); blr(16); + for (j = 0; j < 16; j += 2) E(0xa9400000 | (j / 2 * 2) << 15 | (j + 1) << 10 | 31 << 5 | j); + E(0x910203ff); /* add sp, sp, #128 */ + cb_fix(p1, cp); + *p3 |= (cp - p3) & 0x3ffffff; +} +static void rpmove(Rg *R, RB *B) +{ + int dst[RMAXV], src[RMAXV], n = 0, j, k, x; + for (j = 1; j < R->nv; j++) + if (B->vs[j] >= 0 && !rk[B->vs[j]] && rreg[B->vs[j]] != j) { dst[n] = j; src[n] = rreg[B->vs[j]]; n++; } + while (n) { + for (j = 0; j < n; j++) { for (k = 0; k < n && src[k] != dst[j]; k++); if (k == n) break; } + if (j < n) { movw(dst[j], src[j]); n--; dst[j] = dst[n]; src[j] = src[n]; continue; } + x = src[0]; movw(16, x); /* a cycle: park one */ + for (k = 0; k < n; k++) if (src[k] == x) src[k] = 16; + } + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0 && rk[B->vs[j]]) li(j, rkv[B->vs[j]]); +} +static void emit_uop(int op, int d, int a, int b, int c, int tmp); +static int remit(Rg *R, int bi) +{ + RB *B = &R->b[bi]; + int i, j, d, a, b, c; + unsigned *p; + if (ralloc(R, B)) return -1; + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + switch (u->op) { + case U_LI: case U_VGET: continue; + case U_SLD: rsw(rreg[u->d], u->imm, 0); continue; + case U_LD: + if (rk[u->a] && (unsigned)rkv[u->a] < MW) { /* a fixed address */ + if (rkv[u->a] < 4096) ldr_u(rreg[u->d], M, rkv[u->a] * 4); + else { li(16, rkv[u->a]); ldr_rr(rreg[u->d], M, 16, UXTW); } + continue; + } + break; + case U_ST: a = ropr(u->a, 16); rstore(a, ropr(u->b, 17)); continue; + case U_ADD: case U_SUB: + if (rk[u->b] && rkv[u->b] >= 0 && rkv[u->b] < 4096) { + E((u->op == U_ADD ? 0x11000000 : 0x51000000) | rkv[u->b] << 10 | ropr(u->a, 16) << 5 | rreg[u->d]); + continue; + } + break; + } + d = rreg[u->d]; + a = nargs(u->op) > 0 ? ropr(u->a, 16) : 0; + b = nargs(u->op) > 1 ? ropr(u->b, 17) : 0; + c = nargs(u->op) > 2 ? ropr(u->c, 15) : 0; + emit_uop(u->op, d, a, b, c, 15); + } + for (j = 0; j < B->nso; j++) rsw(ropr(B->so[2 * j + 1], 17), B->so[2 * j], 1); + if (B->term == T_CBR || B->term == T_JMP || B->term == T_CALL) { + if (rk[B->cv]) li(17, rkv[B->cv]); else movw(17, rreg[B->cv]); + } + addsp(B->delta * 4); + rpmove(R, B); + switch (B->term) { + case T_BR: rbranch(B->s1); break; + case T_CBR: + if (B->s1 >= 0) { rfa[rnf] = cp; rfb[rnf++] = B->s1; E(0x34000000 | 17); } /* cbz w17, taken */ + else { p = cp; E(0x35000000 | 17); rexitk(R, B->x1); cb_fix(p, cp); } + if (B->s2 >= 0) rbranch(B->s2); else rexitk(R, B->x2); + break; + case T_CALL: rspill(R); li(16, B->x2); str_post(16, RP, 4); movw(W0, 17); b_to(x_disp); break; + case T_RET: rspill(R); ldr_pre(W0, RP, -4); b_to(x_disp); break; + default: rspill(R); movw(W0, 17); b_to(x_disp); + } + return 0; +} +/* the whole region: entry stubs that load the vars, then the blocks */ +static int rjit(Rg *R, int wr) +{ + unsigned *start = cp, **lab; + int b, e, j, bad = 0; + long need = (long)(R->hi - R->lo) * 96 + (long)R->ne * 32 + 4096; + if (need > (code + CODEW) - cp) return -1; + if (wr) jitwrite(1); + lab = malloc((R->nb + 1) * sizeof *lab); + rfa = malloc((2 * R->nb + R->ne + 4) * sizeof *rfa); rfb = malloc((2 * R->nb + R->ne + 4) * sizeof *rfb); rnf = 0; + for (e = 0; e < R->ne; e++) { R->stub[e] = cp; rload(R); rbranch(R->entb[e]); } + for (b = 0; b < R->nb && !bad; b++) { lab[b] = cp; bad = remit(R, b); } + if (!bad) { + for (j = 0; j < rnf; j++) { + unsigned *at = rfa[j], *to = lab[rfb[j]]; + if ((*at & 0xfc000000u) == 0x14000000u) *at |= (to - at) & 0x3ffffff; else cb_fix(at, to); + } + R->nat = start; + for (e = 0; e < R->ne; e++) tab[R->ent[e]] = R->stub[e]; + syncicache(start, cp); + if (trace) fprintf(stderr, "o3: %d..%d -> %ld bytes of arm64\n", R->lo, R->hi - 1, (long)((char *)cp - (char *)start)); + } else { + cp = start; + if (trace) fprintf(stderr, "o3: %d..%d: a block needs too many registers\n", R->lo, R->hi - 1); + } + free(lab); free(rfa); free(rfb); + if (wr) jitwrite(0); + return bad; +} +static void rcompile(Rg *R, int eager) +{ + if (R->nat || R->nonat) return; + if (rjit(R, eager) && cp - code < CODEW / 2) R->nonat = 1; /* registers, not space: give up on it */ +} + +static int inst_hook(int d) { return install(d); } +static long xrun(long sp, int slot) { return (long)xexec(&enh[slot], (int *)sp); } + +static void *translate(int p) +{ + unsigned *start; + int i = p, n = 0, w, k, t; + if (cp - code > CODEW - 65536 || nbl >= MAXB) flush(); + if (o3ent[p]) { /* an o3 region starts here */ + Rg *R = rat(p); + if (R) { rcompile(R, 0); if (R->nat && tab[p]) return tab[p]; } + } + 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) { + int L = 0, x, s, nk, ks[8], j; + Enh te; + while (L < 8 && i + L < MW && (m[i + L] & 1)) L++; + x = i + L < MW ? m[i + L] : 1; + if (!(x & 1) && (s = x / 2 - XOP0) >= 0 && s < NENH && enh[s].live && enh[s].nin) { + nk = L < enh[s].nin ? L : enh[s].nin; + for (j = 0; j < nk; j++) ks[j] = m[i + L - nk + j] >> 1; + if (!spec_enh(s, ks, nk, &te)) { + for (j = 0; j < L - nk; j++) { li(X9, m[i + j] >> 1); str_pre(X9, SP, -4); } + for (j = 0; j <= L; j++) cov[i + j] = 1; + emit_enh_e(&te, s); + free(te.u); free(te.reg); + i += L + 1; n += L; + continue; + } + } + 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; } + if (k == 21) { /* install: call into c, then return to it so it can flush */ + ldr_u(W0, SP, 0); ldrx_u(X11, ST, 72); blr(X11); str_u(W0, SP, 0); + li(W0, i + 1); b_to(x_exit); i++; break; + } + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { emit_enh(k - XOP0); i++; continue; } + if (k > 20) { E(0x12800000); b_to(x_exit); i++; break; } /* not wired: halt */ + 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). */ +#ifdef ZYLLVM +/* ---- llvm backend ---- + a tiered jit for hosts the arm64 backend doesn't cover. the interpreter + counts how often each block start is reached; a hot block is translated to + llvm ir (same block rules as the arm64 jit: it ends at call, jump, ret or + halt, and keeps going past a jz), optimized at O2 and compiled with orc. + enhancements are inlined as ir. stores into compiled words drop the blocks + that cover them, so self-modifying code still works. */ +#include +#include +#include +#include +#include +#include +static int HOT = 5000; /* runs before a block gets compiled: ZYHOT */ +static const char *lpasses = "default"; /* ZYPASSES */ +#define LMAXB 65536 +typedef int (*Blk)(int *mem, int *regs); +static Blk lt[MW]; /* address -> compiled block */ +static unsigned short hot[MW]; +static unsigned char lcov[MW]; /* 1 if a compiled block covers the word */ +static struct { int a, b; } lbl[LMAXB]; +static int nlbl, llvm_ok, nblocks; +static LLVMOrcLLJITRef jit; +static LLVMOrcThreadSafeContextRef tsc; +static LLVMContextRef ctx; +static LLVMTypeRef i8t, i32t, i64t, ptrt, i1t; +static LLVMBuilderRef bd; +static LLVMValueRef fn_, vm_, vregs, vs, vr; /* function, memory, regs, s and r slots */ +static LLVMModuleRef mod_; + +static unsigned char rcov[MW]; /* 1 on the words of a lifted o3 region */ +static int rdrop(int a); +static void ldrop_all(void) +{ + rdrop_all(); memset(rcov, 0, sizeof rcov); + memset(lt, 0, sizeof lt); memset(lcov, 0, sizeof lcov); memset(hot, 0, sizeof hot); nlbl = 0; + if (trace) fprintf(stderr, "llvm: dropped every block\n"); +} +/* a store to a word some block covers: write it, drop those blocks */ +static int lhook(int a, int v) +{ + int j, x, hit = 0; + if (m[a] == v) return 0; + m[a] = v; + for (j = 0; j < nlbl; j++) + if (lbl[j].a >= 0 && lbl[j].a <= a && a < lbl[j].b) { + lt[lbl[j].a] = 0; hot[lbl[j].a] = 0; + if (trace) fprintf(stderr, "llvm: dropped %d..%d\n", lbl[j].a, lbl[j].b - 1); + lbl[j].a = -1; hit = 1; + } + if (rcov[a] && rdrop(a)) hit = 1; + if (hit) { + memset(lcov, 0, sizeof lcov); + for (j = 0; j < nlbl; j++) if (lbl[j].a >= 0) for (x = lbl[j].a; x < lbl[j].b; x++) lcov[x] = 1; + for (j = 0; j < nrg; j++) if (rgs[j]->lifted) for (x = rgs[j]->lo; x < rgs[j]->hi; x++) lcov[x] = 1; + } + return hit; +} +static int linstall(int d) { return install(d); } + +static LLVMValueRef K32(int v) { return LLVMConstInt(i32t, (unsigned)v, 0); } +static LLVMValueRef cptr(void *p) { return LLVMConstIntToPtr(LLVMConstInt(i64t, (unsigned long long)(size_t)p, 0), ptrt); } +static LLVMValueRef mslot(LLVMValueRef idx) { return LLVMBuildGEP2(bd, i32t, vm_, &idx, 1, ""); } +static LLVMValueRef ld(LLVMValueRef idx) { return LLVMBuildLoad2(bd, i32t, mslot(idx), ""); } +static void st(LLVMValueRef idx, LLVMValueRef v) { LLVMBuildStore(bd, v, mslot(idx)); } +static LLVMValueRef gets(void) { return LLVMBuildLoad2(bd, i32t, vs, ""); } +static void sets(LLVMValueRef v) { LLVMBuildStore(bd, v, vs); } +static LLVMValueRef add(LLVMValueRef a, int k) { return LLVMBuildAdd(bd, a, K32(k), ""); } +/* a load that reads 0 outside memory */ +static LLVMValueRef safeld(LLVMValueRef a) +{ + LLVMValueRef in = LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""); + LLVMValueRef v = ld(LLVMBuildSelect(bd, in, a, K32(0), "")); + return LLVMBuildSelect(bd, in, v, K32(0), ""); +} +static void push(LLVMValueRef v) { LLVMValueRef s = add(gets(), -1); sets(s); st(s, v); } +/* leave the block: write s and r back, return the next vm address */ +static void leave(LLVMValueRef next) +{ + LLVMValueRef r0 = K32(0), r1 = K32(1); + LLVMBuildStore(bd, gets(), LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, vr, ""), LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, "")); + LLVMBuildRet(bd, next); +} +static LLVMBasicBlockRef newbb(void) { return LLVMAppendBasicBlockInContext(ctx, fn_, ""); } +static LLVMValueRef callp(void *f, LLVMTypeRef ret, LLVMTypeRef *at, int n, LLVMValueRef *args) +{ + LLVMTypeRef ft = LLVMFunctionType(ret, at, (unsigned)n, 0); + return LLVMBuildCall2(bd, ft, cptr(f), args, (unsigned)n, ""); +} +/* one micro-op as ir: the same semantics as ev() */ +static LLVMValueRef ir_op(int op, LLVMValueRef a, LLVMValueRef b, LLVMValueRef c) +{ + LLVMValueRef z = K32(0), q, d, t, c1, c2, r = 0; + LLVMTypeRef i64 = i64t; + switch (op) { + case U_ADD: r = LLVMBuildAdd(bd, a, b, ""); break; + case U_SUB: r = LLVMBuildSub(bd, a, b, ""); break; + case U_MUL: r = LLVMBuildMul(bd, a, b, ""); break; + case U_SDIV: case U_SREM: /* /0 and INT_MIN/-1 are defined, like the cpu */ + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + c2 = LLVMBuildAnd(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32((int)0x80000000), ""), LLVMBuildICmp(bd, LLVMIntEQ, b, K32(-1), ""), ""); + d = LLVMBuildSelect(bd, LLVMBuildOr(bd, c1, c2, ""), K32(1), b, ""); + if (op == U_SDIV) { q = LLVMBuildSDiv(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, z, q, ""); } + else { q = LLVMBuildSRem(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, a, LLVMBuildSelect(bd, c2, z, q, ""), ""); } + break; + case U_UDIV: case U_UREM: + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + d = LLVMBuildSelect(bd, c1, K32(1), b, ""); + if (op == U_UDIV) r = LLVMBuildSelect(bd, c1, z, LLVMBuildUDiv(bd, a, d, ""), ""); + else r = LLVMBuildSelect(bd, c1, a, LLVMBuildURem(bd, a, d, ""), ""); + break; + case U_AND: r = LLVMBuildAnd(bd, a, b, ""); break; + case U_OR: r = LLVMBuildOr(bd, a, b, ""); break; + case U_XOR: r = LLVMBuildXor(bd, a, b, ""); break; + case U_SHL: r = LLVMBuildShl(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SHR: r = LLVMBuildLShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SAR: r = LLVMBuildAShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_NEG: r = LLVMBuildSub(bd, z, a, ""); break; + case U_NOT: r = LLVMBuildNot(bd, a, ""); break; + case U_LT: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), i32t, ""); break; + case U_LTU: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), i32t, ""); break; + case U_EQ: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, b, ""), i32t, ""); break; + case U_NE: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntNE, a, b, ""), i32t, ""); break; + case U_MIN: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), a, b, ""); break; + case U_MAX: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSGT, a, b, ""), a, b, ""); break; + case U_MINU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), a, b, ""); break; + case U_MAXU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntUGT, a, b, ""), a, b, ""); break; + case U_MULHS: case U_MULHU: { + LLVMValueRef x = op == U_MULHS ? LLVMBuildSExt(bd, a, i64, "") : LLVMBuildZExt(bd, a, i64, ""); + LLVMValueRef y = op == U_MULHS ? LLVMBuildSExt(bd, b, i64, "") : LLVMBuildZExt(bd, b, i64, ""); + r = LLVMBuildTrunc(bd, LLVMBuildLShr(bd, LLVMBuildMul(bd, x, y, ""), LLVMConstInt(i64, 32, 0), ""), i32t, ""); + break; } + case U_CLZ: { + unsigned id = LLVMLookupIntrinsicID("llvm.ctlz", 9); + LLVMValueRef f = LLVMGetIntrinsicDeclaration(mod_, id, &i32t, 1), args[2]; + args[0] = a; args[1] = LLVMConstInt(i1t, 0, 0); + r = LLVMBuildCall2(bd, LLVMIntrinsicGetType(ctx, id, &i32t, 1), f, args, 2, ""); + break; } + case U_ABS: t = LLVMBuildICmp(bd, LLVMIntSLT, a, z, ""); r = LLVMBuildSelect(bd, t, LLVMBuildSub(bd, z, a, ""), a, ""); break; + case U_SEL: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntNE, a, z, ""), b, c, ""); break; + } + return r; +} +/* an enhancement as ir */ +static void ir_enh(Enh *e) +{ + LLVMValueRef *v = calloc(e->nv + 1, sizeof *v), s = gets(); + int i, j; + for (j = 0; j < e->nin; j++) v[j] = ld(add(s, e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + LLVMValueRef a = u->op == U_LI ? 0 : v[u->a], b = uarity[u->op] > 1 || u->op == U_ST ? v[u->b] : 0, c = uarity[u->op] > 2 ? v[u->c] : 0, r = 0; + switch (u->op) { + case U_LI: r = K32(u->imm); break; + case U_LD: r = safeld(a); break; + case U_ST: { + LLVMBasicBlockRef yes = newbb(), done = newbb(); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), yes, done); + LLVMPositionBuilderAtEnd(bd, yes); st(a, b); LLVMBuildBr(bd, done); + LLVMPositionBuilderAtEnd(bd, done); + break; } + default: r = ir_op(u->op, a, b, c); + } + if (u->op != U_ST) v[u->d] = r; + } + s = add(s, e->nin - e->nout); sets(s); + for (j = 0; j < e->nout; j++) st(add(s, e->nout - 1 - j), v[e->out[j]]); + free(v); +} +static void llvm_init(void) +{ + LLVMErrorRef err; + if (getenv("ZYHOT")) HOT = atoi(getenv("ZYHOT")); + if (HOT < 1) HOT = 1; + if (HOT > 65000) HOT = 65000; + if (getenv("ZYPASSES")) lpasses = getenv("ZYPASSES"); + LLVMInitializeNativeTarget(); LLVMInitializeNativeAsmPrinter(); + if ((err = LLVMOrcCreateLLJIT(&jit, 0))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return; } + tsc = LLVMOrcCreateNewThreadSafeContext(); + ctx = LLVMOrcThreadSafeContextGetContext(tsc); + i1t = LLVMInt1TypeInContext(ctx); i8t = LLVMInt8TypeInContext(ctx); i32t = LLVMInt32TypeInContext(ctx); + i64t = LLVMInt64TypeInContext(ctx); ptrt = LLVMPointerTypeInContext(ctx, 0); + bd = LLVMCreateBuilderInContext(ctx); + llvm_ok = 1; +} +/* compile the block at p; 0 if it couldn't be */ +static Blk lcompile(int p) +{ + char name[32]; LLVMTypeRef pt[2], ft; LLVMValueRef s, a, b, v, r, args[2]; LLVMTypeRef at[2]; + LLVMOrcExecutorAddress addr; LLVMErrorRef err; LLVMPassBuilderOptionsRef po; + int i = p, n = 0, w, k, t, done = 0; + if (!llvm_ok || nlbl >= LMAXB) return 0; + sprintf(name, "b%d_%d", p, nblocks++); + mod_ = LLVMModuleCreateWithNameInContext(name, ctx); + pt[0] = ptrt; pt[1] = ptrt; + ft = LLVMFunctionType(i32t, pt, 2, 0); + fn_ = LLVMAddFunction(mod_, name, ft); + vm_ = LLVMGetParam(fn_, 0); vregs = LLVMGetParam(fn_, 1); + LLVMPositionBuilderAtEnd(bd, newbb()); + vs = LLVMBuildAlloca(bd, i32t, "s"); vr = LLVMBuildAlloca(bd, i32t, "r"); + { LLVMValueRef r0 = K32(0), r1 = K32(1); + sets(LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, ""), "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, ""), ""), vr); } + while (!done) { + if (i >= MW) { leave(K32(MW)); break; } + if (n++ >= 1024) { leave(K32(i)); break; } + w = m[i]; + lcov[i] = 1; + if (w & 1) { + /* a literal followed by call, jump or jz: a known target */ + if (i + 1 < MW && !(m[i + 1] & 1) && (k = m[i + 1] / 2) >= 6 && k <= 8) { + t = w >> 1; lcov[i + 1] = 1; + if (k == 8) { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + s = gets(); a = ld(s); sets(add(s, 1)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(K32(t)); + LLVMPositionBuilderAtEnd(bd, go); + i += 2; continue; + } + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 2)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(K32(t)); i += 2; break; + } + push(K32(w >> 1)); i++; continue; + } + k = w / 2; + s = gets(); + switch (k) { + case 0: leave(K32(MW)); done = 1; break; + case 1: st(s, safeld(ld(s))); break; + case 2: { + LLVMBasicBlockRef in = newbb(), cv = newbb(), plain = newbb(), out = newbb(), quit = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), in, out); + LLVMPositionBuilderAtEnd(bd, in); + v = LLVMBuildLoad2(bd, i8t, LLVMBuildGEP2(bd, i8t, cptr(lcov), &a, 1, ""), ""); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, LLVMConstInt(i8t, 0, 0), ""), cv, plain); + LLVMPositionBuilderAtEnd(bd, plain); st(a, b); LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, cv); + at[0] = i32t; at[1] = i32t; args[0] = a; args[1] = b; + v = callp((void *)lhook, i32t, at, 2, args); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, K32(0), ""), quit, out); + LLVMPositionBuilderAtEnd(bd, quit); leave(K32(i + 1)); /* a block died: back to the loop */ + LLVMPositionBuilderAtEnd(bd, out); + break; } + case 3: a = ld(s); st(s, safeld(LLVMBuildAdd(bd, add(s, 1), a, ""))); break; + case 4: sets(add(s, 1)); break; + case 5: a = ld(s); b = ld(add(s, 1)); st(s, b); st(add(s, 1), a); break; + case 6: case 7: + a = ld(s); sets(add(s, 1)); + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 1)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(a); done = 1; break; + case 8: { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, b, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(a); + LLVMPositionBuilderAtEnd(bd, go); + break; } + case 9: + r = add(LLVMBuildLoad2(bd, i32t, vr, ""), -1); LLVMBuildStore(bd, r, vr); + leave(ld(r)); done = 1; break; + case 10: v = callp((void *)Q, i8t, 0, 0, 0); push(LLVMBuildSExt(bd, v, i32t, "")); break; + case 11: + if (sizeof J == 1) push(LLVMBuildZExt(bd, LLVMBuildLoad2(bd, i8t, cptr(&J), ""), i32t, "")); + else push(LLVMBuildLoad2(bd, i32t, cptr(&J), "")); + break; + case 12: at[0] = i8t; args[0] = LLVMBuildTrunc(bd, ld(s), i8t, ""); callp((void *)G, LLVMVoidTypeInContext(ctx), at, 1, args); sets(add(s, 1)); break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + a = ld(s); b = ld(add(s, 1)); s = add(s, 1); sets(s); + switch (k) { + case 13: v = LLVMBuildAdd(bd, b, a, ""); break; + case 14: v = LLVMBuildSub(bd, b, a, ""); break; + case 15: v = LLVMBuildMul(bd, b, a, ""); break; + case 16: v = LLVMBuildAnd(bd, b, a, ""); break; + case 17: v = LLVMBuildOr(bd, b, a, ""); break; + case 18: v = LLVMBuildXor(bd, b, a, ""); break; + case 19: v = LLVMBuildAShr(bd, b, LLVMBuildAnd(bd, a, K32(31), ""), ""); break; + default: v = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, b, a, ""), i32t, ""); + } + st(s, v); break; + case 21: /* install: then back to the loop, which drops every block */ + at[0] = i32t; args[0] = ld(s); + st(s, callp((void *)linstall, i32t, at, 1, args)); + leave(K32(i + 1)); done = 1; break; + default: + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { ir_enh(&enh[k - XOP0]); break; } + leave(K32(MW)); done = 1; /* not wired: halt */ + } + i++; + } + lbl[nlbl].a = p; lbl[nlbl++].b = i; + po = LLVMCreatePassBuilderOptions(); + if ((err = LLVMRunPasses(mod_, lpasses, 0, po))) { LLVMConsumeError(err); } + LLVMDisposePassBuilderOptions(po); + if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, LLVMOrcLLJITGetMainJITDylib(jit), LLVMOrcCreateNewThreadSafeModule(mod_, tsc)))) { + char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; + } + if ((err = LLVMOrcLLJITLookup(jit, &addr, name))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; } + if (trace) fprintf(stderr, "llvm: %d..%d compiled\n", p, i - 1); + return (Blk)(size_t)addr; +} +#endif + +/* ---- o3 regions without the arm64 jit: compiled by llvm, or run here ---- */ +#ifndef ZYLLVM +static unsigned char rcov[MW]; /* 1 on the words of a lifted region */ +#endif +static int rvals[MAXUOP * 4 + 16]; +static int rdrop(int a) /* a store landed on region code: drop those regions */ +{ + int j, x, hit = 0; + for (j = 0; j < nrg; j++) + if (rgs[j]->lifted && rgs[j]->lo <= a && a < rgs[j]->hi) { + if (trace) fprintf(stderr, "o3: dropped %d..%d (a store to %d: %d)\n", rgs[j]->lo, rgs[j]->hi - 1, a, m[a]); + rclear(rgs[j]); hit = 1; + } + if (hit) { + memset(rcov, 0, sizeof rcov); + for (j = 0; j < nrg; j++) if (rgs[j]->lifted) for (x = rgs[j]->lo; x < rgs[j]->hi; x++) rcov[x] = 1; + } + return hit; +} +#ifdef ZYLLVM +static int lhook(int a, int v); +#define RSTORE(a, b) do { if ((unsigned)(a) < MW) { if (lcov[a]) lhook(a, b); else m[a] = b; } } while (0) +#else +#define RSTORE(a, b) do { if ((unsigned)(a) < MW) { m[a] = b; if (rcov[a]) rdrop(a); } } while (0) +#endif +/* the region interpreter: ssa values in an array, vars in locals */ +static int rexec(Rg *R, int e, int *ps, int *pr) +{ + int var[RMAXV], nv2[RMAXV], *v = rvals, s = *ps, r = *pr, b = R->entb[e], fp, j, i, t, o; + var[0] = fp = mread(ZFP); + for (j = 1; j < R->nv; j++) var[j] = mread(fp + R->slot[j]); + for (;;) { + RB *B = &R->b[b]; + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + switch (u->op) { + case U_LI: v[u->d] = u->imm; break; + case U_VGET: v[u->d] = var[u->imm]; break; + case U_SLD: v[u->d] = mread(s + u->imm); break; + case U_LD: v[u->d] = mread(v[u->a]); break; + case U_ST: RSTORE(v[u->a], v[u->b]); break; + default: v[u->d] = ev(u->op, v[u->a], v[u->b], v[u->c]); + } + } + for (j = 0; j < B->nso; j++) { o = s + B->so[2 * j]; if ((unsigned)o < MW) m[o] = v[B->so[2 * j + 1]]; } + s += B->delta; + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) nv2[j] = v[B->vs[j]]; + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) var[j] = nv2[j]; + if (B->term == T_BR) { b = B->s1; continue; } + if (B->term == T_CBR) { + if (!v[B->cv]) { if (B->s1 >= 0) { b = B->s1; continue; } t = B->x1; } + else { if (B->s2 >= 0) { b = B->s2; continue; } t = B->x2; } + } else if (B->term == T_JMP) t = v[B->cv]; + else if (B->term == T_CALL) { m[r++] = B->x2; t = v[B->cv]; } + else t = m[--r]; + break; + } + for (j = 1; j < R->nv; j++) if ((unsigned)(fp + R->slot[j]) < MW) m[fp + R->slot[j]] = var[j]; + *ps = s; *pr = r; + return t; +} +#ifndef ZYLLVM +static void rforget(Rg *R) { (void)R; } +static void rmark(Rg *R) { int x; for (x = R->lo; x < R->hi; x++) rcov[x] = 1; } +static void rcompile(Rg *R, int eager) { (void)R; (void)eager; } +#endif +#ifdef ZYLLVM + +/* ---- o3 regions in llvm: one function per region, vars in allocas (so + mem2reg makes them ssa across blocks), each block's micro-ops as ir, then + the O3 pipeline. f(mem, regs, entry) returns the next vm address. */ +typedef int (*RFn)(int *mem, int *regs, int ent); +static int nregions; +static LLVMValueRef rvv[RMAXV]; +static void rforget(Rg *R) { R->nat = 0; } +static void rmark(Rg *R) { int x; for (x = R->lo; x < R->hi; x++) rcov[x] = lcov[x] = 1; } +static void rspill_ir(Rg *R) +{ + LLVMValueRef fp = LLVMBuildLoad2(bd, i32t, rvv[0], ""); + int j; + for (j = 1; j < R->nv; j++) st(add(fp, R->slot[j]), LLVMBuildLoad2(bd, i32t, rvv[j], "")); +} +static LLVMBasicBlockRef rexit_bb(Rg *R, int t) +{ + LLVMBasicBlockRef here = LLVMGetInsertBlock(bd), x = newbb(); + LLVMPositionBuilderAtEnd(bd, x); + rspill_ir(R); leave(K32(t)); + LLVMPositionBuilderAtEnd(bd, here); + return x; +} +/* m[a] = v, through lhook if some compiled code covers the word */ +static void rstore_ir(LLVMValueRef a, LLVMValueRef b) +{ + LLVMBasicBlockRef in = newbb(), cv = newbb(), plain = newbb(), out = newbb(); + LLVMValueRef v, args[2]; LLVMTypeRef at[2]; + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), in, out); + LLVMPositionBuilderAtEnd(bd, in); + v = LLVMBuildLoad2(bd, i8t, LLVMBuildGEP2(bd, i8t, cptr(lcov), &a, 1, ""), ""); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, LLVMConstInt(i8t, 0, 0), ""), cv, plain); + LLVMPositionBuilderAtEnd(bd, plain); st(a, b); LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, cv); + at[0] = i32t; at[1] = i32t; args[0] = a; args[1] = b; + callp((void *)lhook, i32t, at, 2, args); + LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, out); +} +static void *lregion(Rg *R) +{ + char name[40]; LLVMTypeRef pt[3], ft; LLVMValueRef ent, sw, *val, s0, fp, r; + LLVMBasicBlockRef *bb, eb, dflt; + LLVMOrcExecutorAddress addr; LLVMErrorRef err; LLVMPassBuilderOptionsRef po; + int b, i, j, e; + sprintf(name, "o3_%d_%d", R->lo, nregions++); + mod_ = LLVMModuleCreateWithNameInContext(name, ctx); + pt[0] = ptrt; pt[1] = ptrt; pt[2] = i32t; + ft = LLVMFunctionType(i32t, pt, 3, 0); + fn_ = LLVMAddFunction(mod_, name, ft); + vm_ = LLVMGetParam(fn_, 0); vregs = LLVMGetParam(fn_, 1); ent = LLVMGetParam(fn_, 2); + LLVMPositionBuilderAtEnd(bd, newbb()); + vs = LLVMBuildAlloca(bd, i32t, "s"); vr = LLVMBuildAlloca(bd, i32t, "r"); + for (j = 0; j < R->nv; j++) rvv[j] = LLVMBuildAlloca(bd, i32t, ""); + { LLVMValueRef r0 = K32(0), r1 = K32(1); + sets(LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, ""), "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, ""), ""), vr); } + bb = malloc(R->nb * sizeof *bb); + for (b = 0; b < R->nb; b++) bb[b] = newbb(); + dflt = newbb(); + sw = LLVMBuildSwitch(bd, ent, dflt, (unsigned)R->ne); + for (e = 0; e < R->ne; e++) { + eb = newbb(); + LLVMAddCase(sw, K32(e), eb); + LLVMPositionBuilderAtEnd(bd, eb); + fp = ld(K32(ZFP)); + LLVMBuildStore(bd, fp, rvv[0]); + for (j = 1; j < R->nv; j++) LLVMBuildStore(bd, safeld(add(fp, R->slot[j])), rvv[j]); + LLVMBuildBr(bd, bb[R->entb[e]]); + } + LLVMPositionBuilderAtEnd(bd, dflt); leave(K32(-1)); + val = calloc(R->maxnv + 1, sizeof *val); + for (b = 0; b < R->nb; b++) { + RB *B = &R->b[b]; + LLVMPositionBuilderAtEnd(bd, bb[b]); + s0 = gets(); + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + LLVMValueRef a = nargs(u->op) > 0 ? val[u->a] : 0, x = nargs(u->op) > 1 ? val[u->b] : 0, c = nargs(u->op) > 2 ? val[u->c] : 0; + switch (u->op) { + case U_LI: val[u->d] = K32(u->imm); break; + case U_VGET: val[u->d] = LLVMBuildLoad2(bd, i32t, rvv[u->imm], ""); break; + case U_SLD: val[u->d] = ld(add(s0, u->imm)); break; + case U_LD: val[u->d] = safeld(a); break; + case U_ST: rstore_ir(a, x); break; + default: val[u->d] = ir_op(u->op, a, x, c); + } + } + for (j = 0; j < B->nso; j++) st(add(s0, B->so[2 * j]), val[B->so[2 * j + 1]]); + sets(add(s0, B->delta)); + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) LLVMBuildStore(bd, val[B->vs[j]], rvv[j]); + switch (B->term) { + case T_BR: LLVMBuildBr(bd, bb[B->s1]); break; + case T_CBR: + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, val[B->cv], K32(0), ""), + B->s1 >= 0 ? bb[B->s1] : rexit_bb(R, B->x1), B->s2 >= 0 ? bb[B->s2] : rexit_bb(R, B->x2)); + break; + case T_CALL: + r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(B->x2)); LLVMBuildStore(bd, add(r, 1), vr); + rspill_ir(R); leave(val[B->cv]); + break; + case T_RET: + r = add(LLVMBuildLoad2(bd, i32t, vr, ""), -1); LLVMBuildStore(bd, r, vr); + rspill_ir(R); leave(ld(r)); + break; + default: rspill_ir(R); leave(val[B->cv]); + } + } + free(val); free(bb); + po = LLVMCreatePassBuilderOptions(); + if ((err = LLVMRunPasses(mod_, "default", 0, po))) LLVMConsumeError(err); + LLVMDisposePassBuilderOptions(po); + if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, LLVMOrcLLJITGetMainJITDylib(jit), LLVMOrcCreateNewThreadSafeModule(mod_, tsc)))) { + char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; + } + if ((err = LLVMOrcLLJITLookup(jit, &addr, name))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; } + if (trace) fprintf(stderr, "o3: %d..%d compiled by llvm\n", R->lo, R->hi - 1); + return (void *)(size_t)addr; +} +static void rcompile(Rg *R, int eager) +{ + (void)eager; + if (R->nat || R->nonat || !llvm_ok) return; + if (!(R->nat = lregion(R))) R->nonat = 1; +} +#endif +#define LD(x) ((unsigned)(x) < MW ? m[x] : 0) +static int run(int p) +{ + int s = DS0, r = RS0, w, a, b, xfer = 1; + unsigned long long steps = 0; +#ifdef ZYLLVM + int regs[2]; + if (!getenv("ZYNOLLVM")) llvm_init(); +#endif + while ((unsigned)p < MW) { + if (xfer && (s < DSLIM || r > RSLIM)) { p = s < DSLIM ? MW + 1 : MW + 2; break; } + if (xfer && o3ent[p]) { /* an o3 region */ + Rg *R = rat(p); + if (R) { +#ifdef ZYLLVM + rcompile(R, 0); + if (R->nat) { regs[0] = s; regs[1] = r; p = ((RFn)R->nat)(m, regs, o3ei[p]); s = regs[0]; r = regs[1]; } + else +#endif + p = rexec(R, o3ei[p], &s, &r); + continue; + } + } +#ifdef ZYLLVM + if (xfer && llvm_ok) { /* at a block start: run it compiled, or count it */ + xfer = 0; + if (!lt[p] && hot[p] < 65535 && ++hot[p] == HOT && !(lt[p] = lcompile(p))) hot[p] = 65535; + if (lt[p]) { + regs[0] = s; regs[1] = r; + p = lt[p](m, regs); + s = regs[0]; r = regs[1]; + if (need_flush) { need_flush = 0; ldrop_all(); } + xfer = 1; + continue; + } + } +#endif + 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) { +#ifdef ZYLLVM + if (lcov[a]) lhook(a, b); else +#else + if (rcov[a]) { m[a] = b; rdrop(a); } else +#endif + 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++; xfer = 1; break; + case 7: p = a; s++; xfer = 1; break; + case 8: if (!b) { p = a; xfer = 1; } s += 2; break; + case 9: p = m[--r]; xfer = 1; 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; + case 21: + m[s] = install(a); +#ifdef ZYLLVM + if (need_flush) { need_flush = 0; ldrop_all(); } +#else + if (need_flush) { need_flush = 0; rdrop_all(); memset(rcov, 0, sizeof rcov); } +#endif + break; + default: + if (w / 2 >= XOP0 && w / 2 < XOP0 + NENH && enh[w / 2 - XOP0].live) s = (int)(xexec(&enh[w / 2 - XOP0], m + s) - m); + else p = MW; /* halt: unwired opcodes and the reserved negative ones */ + } + } + if (trace) fprintf(stderr, "interp: %llu steps\n", steps); + return stopped(p); +} +#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; + S[9] = (long)inst_hook; S[10] = (long)xrun; + S[11] = (long)(m + DSLIM); S[12] = (long)(m + RSLIM); + 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); + if (need_flush) { need_flush = 0; jitwrite(1); flush(); jitwrite(0); } + } + return stopped(p); + } +#else + return run(GORG); +#endif + return 0; +} diff --git a/docs/history/15-o3/code/examples/bf.zc b/docs/history/15-o3/code/examples/bf.zc new file mode 100644 index 0000000..384025a --- /dev/null +++ b/docs/history/15-o3/code/examples/bf.zc @@ -0,0 +1,50 @@ +// a brainfuck compiler. it turns a brainfuck program into zc source, hands +// that to the compiler that's sitting in memory, and runs the result, which on +// arm64 means native code. runs of + - < > fold into one statement each. +// give it a program after a backtick, or it runs the hello world below. +let out[30000], n, depth; +fn emit(s) { let i = 0; while (s[i]) { out[n] = s[i]; n++; i++; } return 0; } +fn emitn(int v) { if (v >= 10) emitn(v / 10); out[n] = '0' + v % 10; n++; return 0; } +// how many times does c repeat from s[i] +int run(s, int i, int c) { int k = 0; while (s[i + k] == c) k++; return k; } + +fn translate(s) +{ + int i = 0, k; + n = 0; depth = 0; + emit("let t[30000], p = 0;\n"); + while (s[i]) { + switch (s[i]) { + case '+', '-': + k = run(s, i, s[i]); + emit("t[p] = (t[p] "); emit(s[i] == '+' ? "+ " : "- "); emitn(k); emit(") & 255;\n"); + i = i + k; continue; + case '>', '<': + k = run(s, i, s[i]); + emit("p "); emit(s[i] == '>' ? "+= " : "-= "); emitn(k); emit(";\n"); + i = i + k; continue; + case '[': emit("while (t[p]) {\n"); depth++; + case ']': emit("}\n"); depth--; + case '.': emit("putc(t[p]);\n"); + case ',': emit("t[p] = eof() ? 0 : getc() & 255;\n"); + } + i++; + } + emit("return 0;\n"); + out[n] = 0; + return depth; +} +let hello = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."; +let prog[20000]; +fn main() +{ + let src = hello, k = 0, lines = 0, i = 0; + while (!eof() && k < 19999) { let c = getc(); if (c != 10) { prog[k] = c; k++; } } + prog[k] = 0; + if (k) src = prog; + if (translate(src)) { puts("unbalanced brackets\n"); return 1; } + while (out[i]) { if (out[i] == 10) lines++; i++; } + puts("compiled to "); putn(lines); puts(" lines of zc, running it:\n"); + evals(out); + return 0; +} diff --git a/docs/history/15-o3/code/examples/dump.zc b/docs/history/15-o3/code/examples/dump.zc new file mode 100644 index 0000000..6082213 --- /dev/null +++ b/docs/history/15-o3/code/examples/dump.zc @@ -0,0 +1,32 @@ +// printing any struct with no printing code: the heap knows each object's +// type, and reflection walks its fields +struct person { *char name; int age; }; +struct item { *char name; int count; *person owner; }; + +fn dump(p) +{ + let t = typeof_obj(p), i = 0; + if (!t) { puts("?"); return 0; } + tprint(t); puts(" { "); + while (i < tnfields(t)) { + let ft = tftype(t, i), v = p[tfoff(t, i)]; + if (i) puts(", "); + puts(tfname(t, i)); puts(": "); + if (tkind(ft) == TY_PTR && telem(ft) == typeof(char)) { putc('"'); puts(v); putc('"'); } + else if (tkind(ft) == TY_PTR) { if (v) dump(v); else puts("null"); } + else putn(v); + i++; + } + puts(" }"); + return 0; +} +fn main() +{ + *person ana = new(person); + ana.name = "ana"; ana.age = 30; + *item lamp = new(item); + lamp.name = "lamp"; lamp.count = 3; lamp.owner = ana; + dump(lamp); putc(10); + free(d*lamp); + return 0; +} diff --git a/docs/history/15-o3/code/examples/echo.zc b/docs/history/15-o3/code/examples/echo.zc new file mode 100644 index 0000000..01f28b0 --- /dev/null +++ b/docs/history/15-o3/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/15-o3/code/examples/fact.zc b/docs/history/15-o3/code/examples/fact.zc new file mode 100644 index 0000000..2a218b2 --- /dev/null +++ b/docs/history/15-o3/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/15-o3/code/examples/hello.zc b/docs/history/15-o3/code/examples/hello.zc new file mode 100644 index 0000000..f36a810 --- /dev/null +++ b/docs/history/15-o3/code/examples/hello.zc @@ -0,0 +1 @@ +fn main() { puts("hello, world!\n"); return 0; } diff --git a/docs/history/15-o3/code/examples/lang.zc b/docs/history/15-o3/code/examples/lang.zc new file mode 100644 index 0000000..e4d91c5 --- /dev/null +++ b/docs/history/15-o3/code/examples/lang.zc @@ -0,0 +1,53 @@ +// growing the language from inside a program, while it compiles + +// x |> f calls f(x). on a stack machine that's just "call": the value is +// already on the stack, under f's address. +immediate fn pipe_op() { next(); add_binop("|>", 1, "c"); return 0; } +pipe_op + +// unless (c) stmt +immediate fn unless() +{ + let a; + next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not + a = hole(); op(O_JZ); + substmt(); + setlit(a, here); + return 0; +} +// assert (c): the failure message carries the line it was written on +fn assert_fail(int line) { puts("assertion failed on line "); putn(line); putc(10); halt(); return 0; } +immediate fn assert() +{ + let a, l = tline; + next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not: the jump below skips the failure when it holds + a = hole(); op(O_JZ); + lit(l); callname(intern("assert_fail")); op(O_DROP); + setlit(a, here); + return 0; +} +// times N { body }: the body pasted N times, at compile time +immediate fn times() +{ + let n, b, i = 0; + next(); n = tv; next(); + b = grab(); + while (i < n) { feed(qdup(b)); i++; } + free(d*b); + return 0; +} + +fn double(x) { return x * 2; } +fn inc(x) { return x + 1; } +fn main() +{ + putn(5 |> double |> inc |> double); putc(10); + unless (1 > 2) puts("one isn't bigger than two\n"); + times 3 { putc('*'); } + putc(10); + assert(double(4) == 8); + assert(inc(1) == 3); + return 0; +} diff --git a/docs/history/15-o3/code/examples/life.zc b/docs/history/15-o3/code/examples/life.zc new file mode 100644 index 0000000..a43d660 --- /dev/null +++ b/docs/history/15-o3/code/examples/life.zc @@ -0,0 +1,38 @@ +// conway's life on a 10 x 20 torus, with typed 2d arrays in a struct. +// a glider walks diagonally and wraps around the edges. +const H = 10, W = 20; +struct board { [10][20]int c; }; + +int get(*board b, int y, int x) { return b.c[(y + H) % H][(x + W) % W]; } +fn step(*board from, *board to) +{ + for (int y = 0; y < H; y++) + for (int x = 0; x < W; x++) { + int n = 0; + for (int dy = 0 - 1; dy <= 1; dy++) + for (int dx = 0 - 1; dx <= 1; dx++) + if (dy || dx) n += get(from, y + dy, x + dx); + to.c[y][x] = n == 3 || (n == 2 && from.c[y][x]); + } + return 0; +} +fn show(*board b, int gen) +{ + puts("generation "); putn(gen); putc(10); + for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) putc(b.c[y][x] ? '#' : '.'); putc(10); } + return 0; +} +fn main() +{ + *board a = new(board), b = new(board); + a.c[0][1] = 1; a.c[1][2] = 1; a.c[2][0] = 1; a.c[2][1] = 1; a.c[2][2] = 1; + // two generations a pass, a -> b -> a: owned boards can't be swapped + // through a temporary, since the analyzer can't follow that + for (int g = 0; g <= 40; g += 2) { + if (g % 20 == 0) show(a, g); + step(a, b); + step(b, a); + } + free(d*a); free(d*b); + return 0; +} diff --git a/docs/history/15-o3/code/examples/lists.zc b/docs/history/15-o3/code/examples/lists.zc new file mode 100644 index 0000000..3cf0206 --- /dev/null +++ b/docs/history/15-o3/code/examples/lists.zc @@ -0,0 +1,34 @@ +// ownership in practice: a list owns its boxes. nothing here calls free; +// everything is released at the end of the block that owns it. +.u box(v) { let b = new(1); b[0] = v; return u*b; } +.u mklist(cap) { let l = new(cap + 1); l[0] = 0; return u*l; } +// item m*arrives (it was given down), and goes d*on into the borrowed list +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn show(.m l) +{ + let i = 1; + putc('['); + while (i <= l[0]) { if (i > 1) putc(' '); putn(l[i][0]); i++; } + putc(']'); + return 0; +} +.u squares(n) { + let l = mklist(n), i = 0; + while (i < n) { + let b = box(i * i); + push(l, d*b); + i++; + } + return u*l; +} +fn main() +{ + let before = live_objects(); + { + let 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/15-o3/code/examples/mandel.zc b/docs/history/15-o3/code/examples/mandel.zc new file mode 100644 index 0000000..5810397 --- /dev/null +++ b/docs/history/15-o3/code/examples/mandel.zc @@ -0,0 +1,36 @@ +// the mandelbrot set in 16.16 fixed point. the cpu has no fixed-point +// multiply, so one gets wired in: a 32x32 -> 64 bit multiply, keeping the +// middle 32 bits. the jit inlines it as two native multiplies and a shift. +enhance fmul(a, b) micro + "r2 = mul a b; r3 = mulhs a b" + "; r3 = shl r3 16; r2 = shr r2 16; a = or r3 r2"; + +const ONE = 65536, W = 72, H = 28, MAXIT = 40; +let shades = " .,:;-=+*%#@"; + +int escape(int cx, int cy) { + int x = 0, y = 0, i = 0; + while (i < MAXIT) { + int xx = fmul(x, x), yy = fmul(y, y); + if (xx + yy > 4 * ONE) return i; + y = 2 * fmul(x, y) + cy; + x = xx - yy + cx; + i++; + } + return MAXIT; +} +fn main() +{ + int row = 0; + while (row < H) { + int col = 0, cy = (row * 2400 / (H - 1) - 1200) * ONE / 1000; + while (col < W) { + int cx = (col * 3200 / (W - 1) - 2200) * ONE / 1000, it = escape(cx, cy); + putc(it == MAXIT ? '@' : shades[it * 11 / MAXIT]); + col++; + } + putc(10); + row++; + } + return 0; +} diff --git a/docs/history/15-o3/code/examples/primes.zc b/docs/history/15-o3/code/examples/primes.zc new file mode 100644 index 0000000..26df0b5 --- /dev/null +++ b/docs/history/15-o3/code/examples/primes.zc @@ -0,0 +1,38 @@ +// primes below 60000: an o3 sieve over a fixed array, the primes +// gathered into a growable one, then a few questions asked of them. +// with ZYTRACE=1 the o3 lines show each region being lifted and compiled. + +// marks the composites; f[i] ends up 1 for every prime i +o3 int sieve(fixed []int f) +{ + int n = len(f), c = 0; + for (int i = 2; i < n; i++) f[i] = 1; + for (int i = 2; i * i < n; i++) + if (f[i]) for (int j = i * i; j < n; j += i) f[j] = 0; + for (int i = 2; i < n; i++) c += f[i]; + return c; +} +// the largest gap between neighbours, and where it starts +o3 int gap(fixed []int f, *int at) +{ + int n = len(f), last = 2, best = 0, where = 0; + for (int i = 3; i < n; i++) + if (f[i]) { if (i - last > best) { best = i - last; where = last; } last = i; } + *at = where; + return best; +} +fn main() +{ + fixed []int f = new(fixed []int, 60000); + []int ps = new([]int); + int c = sieve(f), at = 0, twins = 0; + for (int i = 2; i < len(f); i++) if (f[i]) push(ps, i); + o3 { for (int k = 1; k < len(ps); k++) if (ps[k] - ps[k - 1] == 2) twins++; } + puts("primes below 60000: "); putn(c); putc(10); + puts("the last five:"); for (int k = len(ps) - 5; k < len(ps); k++) { putc(' '); putn(ps[k]); } putc(10); + puts("twin pairs: "); putn(twins); putc(10); + int g = gap(f, &at); + puts("widest gap: "); putn(g); puts(", after "); putn(at); putc(10); + free(d*f); free(d*ps); + return 0; +} diff --git a/docs/history/15-o3/code/examples/quine.zc b/docs/history/15-o3/code/examples/quine.zc new file mode 100644 index 0000000..23be8cb --- /dev/null +++ b/docs/history/15-o3/code/examples/quine.zc @@ -0,0 +1 @@ +let s="let s=#;fn main(){let i=0;while(s[i]){if(s[i]==35){putc(34);puts(s);putc(34);}else putc(s[i]);i++;}putc(10);return 0;}";fn main(){let i=0;while(s[i]){if(s[i]==35){putc(34);puts(s);putc(34);}else putc(s[i]);i++;}putc(10);return 0;} diff --git a/docs/history/15-o3/code/examples/repl.zc b/docs/history/15-o3/code/examples/repl.zc new file mode 100644 index 0000000..b7b81b8 --- /dev/null +++ b/docs/history/15-o3/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. +let buf[4000]; +fn readchunk() +{ + let 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() +{ + let 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(d*q); + } + return 0; +} diff --git a/docs/history/15-o3/code/examples/selfpatch.zc b/docs/history/15-o3/code/examples/selfpatch.zc new file mode 100644 index 0000000..074ccec --- /dev/null +++ b/docs/history/15-o3/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() +{ + let 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/15-o3/code/examples/staged.zc b/docs/history/15-o3/code/examples/staged.zc new file mode 100644 index 0000000..5f6342e --- /dev/null +++ b/docs/history/15-o3/code/examples/staged.zc @@ -0,0 +1,35 @@ +// staged code: a program writes a specialized function as source, compiles it +// while running, and calls it. here, polynomials with their coefficients baked +// in as constants, so there's no loop and no array left at runtime. +let buf[2000], n; +fn put(s) { let i = 0; while (s[i]) { buf[n] = s[i]; n++; i++; } return 0; } +fn putnum(int v) { if (v >= 10) putnum(v / 10); buf[n] = '0' + v % 10; n++; return 0; } + +// coefficients c[0] + c[1] x + ... in horner form: ((c3 x + c2) x + c1) x + c0 +fn specialize(*int c, int deg) +{ + n = 0; + put("fn poly(x) { return "); + for (int i = 0; i < deg; i++) put("("); + if (c[deg] < 0) { put("0 - "); putnum(0 - c[deg]); } else putnum(c[deg]); + for (int i = deg - 1; i >= 0; i--) { + put(") * x "); + if (c[i] < 0) { put("- "); putnum(0 - c[i]); } else { put("+ "); putnum(c[i]); } + } + put("; }"); + buf[n] = 0; + return buf; +} +fn main() +{ + [4]int c; + c[0] = 7; c[1] = 0 - 3; c[2] = 0; c[3] = 2; // 2x^3 - 3x + 7 + let src = specialize(c, 3), q = tokens(src); + puts(src); putc(10); + load(q); // compiled now, into the running program + free(d*q); + let f = sval[lookups("poly")]; // and found by name in the compiler's symbol table + for (int x = 0 - 2; x <= 3; x++) { putn(f(x)); putc(' '); } + putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/examples/tree.zc b/docs/history/15-o3/code/examples/tree.zc new file mode 100644 index 0000000..90a01d4 --- /dev/null +++ b/docs/history/15-o3/code/examples/tree.zc @@ -0,0 +1,28 @@ +// a binary search tree where every node owns its children. there's no free +// anywhere: when the root's block ends, the whole tree goes with it. +struct node { int v; *node left, right; }; + +*node.u leaf(int v) { *node n = new(node); n.v = v; return u*n; } +// n is borrowed; storing a new leaf into it makes n the leaf's owner +fn insert(*node.m n, int v) +{ + if (v < n.v) { if (n.left) insert(n.left, v); else n.left = leaf(v); } + else { if (n.right) insert(n.right, v); else n.right = leaf(v); } + return 0; +} +fn walk(*node n) { if (!n) return 0; walk(n.left); putn(n.v); putc(' '); walk(n.right); return 0; } +int height(*node n) { if (!n) return 0; int l = height(n.left), r = height(n.right); return 1 + (l > r ? l : r); } + +fn main() +{ + let before = live_objects(); + { + *node root = leaf(50); + int x = 7; + for (int i = 0; i < 30; i++) { x = (x * 37 + 11) % 100; insert(root, x); } + walk(root); putc(10); + puts("height "); putn(height(root)); puts(", live objects "); putn(live_objects() - before); putc(10); + } + puts("after the block: "); putn(live_objects() - before); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/examples/typed.zc b/docs/history/15-o3/code/examples/typed.zc new file mode 100644 index 0000000..964a150 --- /dev/null +++ b/docs/history/15-o3/code/examples/typed.zc @@ -0,0 +1,44 @@ +// types: structs, a generic container, and looking at it all through reflection +typecheck on; +struct point { int x, y; }; +struct vec { int len, cap; *T items; }; + + *vec.u mkvec(int cap) { + *vec v = new(vec); + v.cap = cap; + v.items = new(T, cap); + return u*v; +} +// x is given away (.d): the vector's memory holds it from now on, and the +// collector looks after it + bool push(*vec v, T.d x) { + if (v.len == v.cap) { free(d*x); return 0; } + v.items[v.len] = d*x; + v.len++; + return 1; +} +fn show(word t) +{ + let i = 0; + tprint(t); puts(" is "); putn(tsize(t)); puts(" words: "); + while (i < tnfields(t)) { if (i) puts(", "); puts(tfname(t, i)); puts(" "); tprint(tftype(t, i)); i++; } + putc(10); + return 0; +} +int main() { + *vec<*point> v = mkvec<*point>(4); + int i = 0; + while (i < 3) { + *point p = new(point); + p.x = i; p.y = i * i; + push(v, d*p); + i++; + } + puts("last: "); putn(v.items[2].y); putc(10); + show(typeof(point)); + show(typeof(*v)); + puts("push is "); tprint(sigof(push)); putc(10); + // generic code is compiled once, so what mkvec stamped is vec + puts("the heap says v is a "); tprint(typeof_obj(v)); puts(", and v.items[0] is a "); tprint(typeof_obj(v.items[0])); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/examples/wiring.zc b/docs/history/15-o3/code/examples/wiring.zc new file mode 100644 index 0000000..d5e64f4 --- /dev/null +++ b/docs/history/15-o3/code/examples/wiring.zc @@ -0,0 +1,19 @@ +// virtual enhancements: custom opcodes wired into the cpu while compiling. +// the recipes run through the core's optimizer; the jit inlines the result. +enhance popcount(x) micro + "r1 = shr x 1; r1 = and r1 0x55555555; x = sub x r1" + "; r1 = shr x 2; r1 = and r1 0x33333333; x = and x 0x33333333; x = add x r1" + "; r1 = shr x 4; x = add x r1; x = and x 0x0f0f0f0f; x = mul x 0x01010101; x = shr x 24"; +enhance div10(x) micro "x = udiv x 10"; // becomes a multiply-high, no divide +enhance hypot2(a, b) vm { 0 $ * ~ 0 $ * + }; // lifted from vm code +enhance 2 minmax(a, b) micro "r2 = min a b; r1 = max a b; r0 = r2"; +let lo, hi; +fn main() +{ + putn(popcount(0xff00ff)); putc(' '); + putn(div10(12345)); putc(' '); + putn(hypot2(3, 4)); putc(' '); + asm { 9 4 minmax hi ! lo ! } + putn(lo); putc('/'); putn(hi); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/genome.h b/docs/history/15-o3/code/genome.h new file mode 100644 index 0000000..adaca4a --- /dev/null +++ b/docs/history/15-o3/code/genome.h @@ -0,0 +1,4893 @@ +#define GORG 786432 +static const int genome[] = { +1966081,1310721,4,1717361,14,858905,864649,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1572913,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,42,1572933, +14,1,1310721,2,3,26,1310721,4,18,0,0,2,1,786486,0,786480, +786482,786484,97,0,98,0,97,32,61,32,115,100,105,118,32,97, +32,98,0,1,0,2,1,786512,0,786506,786508,786510,97,0,98,0, +97,32,61,32,115,114,101,109,32,97,32,98,0,2,0,2, +1,786538,0,786532,786534,786536,97,0,98,0,97,32,61,32,115,104, +108,32,97,32,98,0,3,0,1,1,786560,0,786557,786558,107,0, +114,49,32,61,32,108,100,32,54,53,53,51,54,48,59,32, +107,32,61,32,97,100,100,32,114,49,32,107,0,4,0,2, +1,786602,0,786596,786598,786600,105,0,110,0,105,32,61,32,108,116, +117,32,105,32,110,59,32,105,32,61,32,120,111,114,32,105, +32,49,0,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1573289,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,24,1,1573311,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40, +1573359,16,1966081,1310721,4,1579223,12,20,1573367,14,1,1310721,2,1,26,1310721, +4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1573415,16,1966081,1310721, +4,1579223,12,22,1573423,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +1,28,1310721,4,1310721,2,1835009,40,1573471,16,1966081,1310721,4,1579223,12,0, +1,1573481,14,1,1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1573529,16,1966081,1310721,4,1579223,12,1310721,2,4,1, +1310721,2,3,26,4,1310721,2,2,1310721,2,3,26,2,26,2,1573635, +16,1310721,2,2,1310721,2,3,26,2,26,2,1573255,12,8,1310721,2, +3,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1573547, +14,1,1573643,14,1,1310721,2,5,26,1310721,4,18,1310721,2,29,28, +1310721,4,1310721,2,1835009,40,1573691,16,1966081,1310721,4,1579223,12,1310721,2,4, +1,1310721,2,27,26,4,1310721,2,2,1,40,1573757,16,91,1573255,12, +8,1310721,2,1,1310721,2,2,28,10,3,6,10,4,8,1310721,2, +2,1,40,1573811,16,1573797,14,50,49,52,55,52,56,51,54,52, +56,0,1573775,1573495,12,8,1,1574025,14,3,1573949,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,46,26,10,3,6,10,4,8,1310721,2, +1310721,2,2,21,44,10,3,6,10,4,8,1310721,2,2,1,6, +1,10,28,34,63,38,3,26,1573945,16,1573949,14,1573811,14,1310721,2, +27,26,2,1574017,16,1310721,2,3,26,1310721,2,27,26,1,6,2, +-1,26,1,6,5,6,4,10,8,26,2,1573255,12,8,1573949,14, +1,1574025,14,1,1310721,2,29,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1574073,16,1966081,1310721,4,1579223,12,1310721,2,4,1, +1310721,2,3,26,4,1310721,2,2,1310721,2,3,26,2,26,2,1574153, +16,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1574091,14,1310721,2,3,26,2,1574169,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1574217,16,1966081, +1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1,1310721,2,5, +26,4,1310721,2,2,1310721,2,5,26,2,26,2,1574361,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,1574363,14,1,1574405,16,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1574245,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,1574477,14,1,1310721,2,7,26,1310721,4,18,1310721,2,9, +28,1310721,4,1310721,2,1835009,40,1574525,16,1966081,1310721,4,1579223,12,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,1574681,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,1574563,14,1,1574689,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009, +40,1574737,16,1966081,1310721,4,1579223,12,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,1574879,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,1574775,14,1, +1574887,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,1835009,40,1575001,16,1966081,1310721,4,1579223,12,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,1575101, +16,1574965,1310721,2,2,10,3,6,10,4,8,1,1575415,14,1310721,2, +9,26,2,1,40,3,36,1575375,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,1575337,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,1575101,14,1574965,1310721,2,7,26,2,10,3,6, +10,4,8,1310721,2,5,26,2,1575415,14,1,1310721,2,11,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1575463,16,1966081,1310721, +4,1579223,12,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,1575555,16,1574965,1310721,2,2,10,3,6,10,4,8,1,1575791, +14,1310721,2,2,1,40,1575617,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,1575703,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,1574967,12,10,3,6,10,4,8,1310721, +2,5,26,2,1575775,16,1,1310721,2,7,26,2,28,1575791,14,1310721, +2,7,26,2,1575791,14,1,1310721,2,9,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1575839,16,1966081,1310721,4,1579223,12,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,1,40,1310721,2,5,26, +4,1310721,2,3,26,2,1,28,1,6,1,10,28,34,63,38, +3,26,1575923,16,1310721,2,2,1575981,14,1310721,2,2,1310721,2,3,26, +2,1575429,12,8,1310721,2,5,26,2,1575971,16,1,1574965,2,28,1575981, +14,1574965,2,1575981,14,1,1310721,2,7,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1576029,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1310721,2,2,1574901,1310721,2,3,26,2,63, +32,26,2,30,1576079,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,9,28,1310721,4,1310721,2,1835009,40,1576199,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,524289,28,1310721,2,3,26,4,1,1310721, +2,5,26,4,1310721,2,3,26,2,1576495,16,1310721,2,7,26,3, +10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,7,26,2, +26,1310721,2,3,26,2,10,40,3,36,1576359,16,1310721,2,7,26, +1310721,2,7,26,2,1310721,2,7,26,2,26,10,3,6,10,4, +8,1576269,14,1310721,2,2,1310721,2,5,26,2,1310721,2,7,26,2, +26,40,1576407,16,1310721,2,7,26,2,1576503,14,1310721,2,5,26,1310721, +2,5,26,2,1310721,2,7,26,2,26,10,3,6,10,4,8, +1310721,2,3,26,1310721,2,3,26,2,1310721,2,7,26,2,28,10, +3,6,10,4,8,1576233,14,1,1576503,14,1,1310721,2,9,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1576551,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,5,26, +1,10,3,6,10,4,8,1310721,2,2,13,26,1576095,1310721,2,3, +26,2,26,2,10,3,6,10,4,8,1310721,2,2,15,26,1, +10,3,6,10,4,8,1576095,1310721,2,3,26,2,26,2,1576711,16, +1576095,1310721,2,3,26,2,26,2,15,26,1310721,2,2,10,3,6, +10,4,8,1576095,1310721,2,3,26,2,26,1310721,2,2,10,3,6, +10,4,8,1,1576751,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1576799,16,1966081,1310721,4,1579223,12,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,15,26,2,1576875,16,1310721, +2,2,15,26,2,13,26,1310721,2,2,13,26,2,10,3,6, +10,4,8,1576913,14,1576095,1310721,2,3,26,2,26,1310721,2,2,13, +26,2,10,3,6,10,4,8,1310721,2,2,13,26,2,1576969,16, +1310721,2,2,13,26,2,15,26,1310721,2,2,15,26,2,10,3, +6,10,4,8,1,1576977,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1577025,16,1966081,1310721,4,1579223,12, +1310721,2,3,26,4,1310721,2,4,1310721,2,2,1,26,1574901,1310721,2, +3,26,2,26,2,10,3,6,10,4,8,1310721,2,2,3,26, +1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,2,5,26, +1,10,3,6,10,4,8,1310721,2,2,7,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,1,10,3,6,10,4,8,1310721,2,2,1577219,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2, +1835009,40,1577267,16,1966081,1310721,4,1579223,12,3,1310721,2,4,524289,1310721,2, +3,26,4,1574901,1,26,3,10,3,6,10,4,8,1310721,2,2, +65,40,1577411,16,1574901,1310721,2,2,26,1574901,1310721,2,2,3,28,26, +2,1574901,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,1577307, +14,1576093,1310721,10,3,6,10,4,8,1576095,1,65,1574703,12,8,1310721, +2,3,26,2,1310721,40,1577673,16,1310721,2,5,26,1310721,2,3,26, +2,524289,28,1576165,12,10,3,6,10,4,8,1310721,2,7,26,1, +10,3,6,10,4,8,1574901,1310721,2,7,26,2,26,2,1310721,2, +5,26,2,40,1577587,16,1310721,2,7,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1577517,14,1310721,2,3,26,2,1310721,2, +7,26,2,1576991,12,1310721,2,7,26,2,1576517,12,8,1310721,2,3, +26,1310721,2,3,26,2,1310721,2,5,26,2,26,10,3,6,10, +4,8,1577439,14,1,1577681,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,9,28,1310721,4,1310721,2,1835009,40,1577729,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,1310721,2,3,26,4,1310721,2,3,26,2, +65,40,1577831,16,1576095,1310721,2,3,26,2,26,2,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1577833,14,1,1577875,16,1310721,2,3,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1577751,14,1310721,2,3,26,2,65,40, +3,36,1577903,16,1,1578153,14,1310721,2,5,26,1576095,1310721,2,3,26, +2,26,2,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2, +3,26,2,1576765,12,8,1310721,2,3,26,2,1310721,2,2,10,40, +1578115,16,1310721,2,3,26,1,6,2,1,6,-1,26,5,6,4, +10,8,8,1310721,2,7,26,1310721,2,5,26,2,1574901,1310721,2,3, +26,2,26,2,26,10,3,6,10,4,8,1310721,2,7,26,2, +1310721,2,3,26,2,1576991,12,1310721,2,3,26,2,1576517,12,8,1577965, +14,1310721,2,5,26,2,1310721,2,2,1576991,12,8,1310721,2,5,26, +2,1578153,14,1,1310721,2,9,26,1310721,4,18,0,1310721,2,11,28, +1310721,4,1310721,2,1835009,40,1578203,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,3,26,2,1310721,2,3,26,4,1574901,1310721,2,3,26, +2,26,2,1310721,2,5,26,4,3,1578875,16,1310721,2,7,26,1310721, +2,2,524289,28,10,3,6,10,4,8,1310721,2,5,26,2,1310721, +2,7,26,2,1576165,12,40,3,36,1578331,16,1578875,14,1310721,2,9, +26,524289,1310721,2,7,26,2,1310721,2,5,26,2,36,26,10,3, +6,10,4,8,1310721,2,9,26,2,5,26,2,1,28,1,6, +1,10,28,34,63,38,1,10,28,1578429,16,3,1578501,14,1310721,2, +9,26,2,3,26,2,1310721,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,1578511,16,3,1578583,14,1310721,2,9,26,2,1,26,2,1310721, +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,1578591,16,1578875,14,1310721, +2,9,26,2,1310721,2,3,26,2,1576765,12,8,1310721,2,9,26, +2,1310721,2,2,40,1578717,16,1310721,2,2,1,26,1,10,3,6, +10,4,8,1310721,2,2,7,26,1,10,3,6,10,4,8,1310721, +2,1310721,2,9,26,2,10,3,6,10,4,8,1578773,14,1310721,2, +9,26,2,1,26,1,10,3,6,10,4,8,1310721,2,9,26, +2,7,26,1,10,3,6,10,4,8,1310721,2,3,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1310721,2,5,26,1310721, +2,5,26,2,1310721,2,5,26,2,26,10,3,6,10,4,8, +1310721,2,2,1310721,2,3,26,2,1576991,12,8,1578257,14,1310721,2,2, +1310721,2,3,26,2,1576991,12,1310721,2,3,26,2,1576517,12,8,1578167, +1310721,2,2,1310721,2,5,26,2,26,10,3,6,10,4,8,1, +1578951,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1578999,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2, +2,524289,13,26,40,3,36,1579065,16,1310721,2,2,1576093,2,40,1, +6,1,10,28,34,63,38,1,10,28,1579067,14,1,1579147,16,1310721, +2,2,7,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,1579149,14,1,1579201,16,1310721,2,2,9,1,10,28,26, +2,3,32,1,6,1,10,28,34,63,38,1,10,28,1579203,14, +1,1579209,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721, +4,1310721,2,1835009,40,1579257,16,1966081,1310721,4,1579223,12,1579313,14,122,121, +58,32,102,114,97,109,101,32,115,116,97,99,107,32,111,118, +101,114,102,108,111,119,10,0,1579261,1573495,12,8,1573437,12,8,1, +1579335,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1579383,16,1966081,1310721,4,1579223,12,1579435,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,1579387,1573495,12,8,1573437,12,8,1,1579457,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009, +40,1579505,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,13,26, +1310721,2,3,26,4,7,1310721,2,5,26,4,1310721,2,2,1,40, +1579579,16,1310721,2,3,26,13,10,3,6,10,4,8,1574901,1310721,2, +5,26,2,26,2,1310721,2,3,26,2,40,1579649,16,1310721,2,5, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1579579,14, +1310721,2,7,26,1310721,2,5,26,2,1577695,12,10,3,6,10,4, +8,1310721,2,7,26,2,1,6,1,10,28,34,63,38,3,26, +1579747,16,1576163,2,1,6,1,10,28,34,63,38,1,10,28,1579749, +14,1,1579793,16,1584091,12,8,1310721,2,7,26,1310721,2,5,26,2, +1577695,12,10,3,6,10,4,8,1310721,2,7,26,2,1,6,1, +10,28,34,63,38,3,26,1579833,16,1579349,12,8,1310721,2,9,26, +1310721,2,7,26,2,13,26,10,3,6,10,4,8,1310721,2,7, +26,2,5,26,3,10,3,6,10,4,8,1310721,2,7,26,2, +7,26,1310721,2,9,26,2,1459366445,36,10,3,6,10,4,8,1310721, +2,7,26,2,9,26,1,10,3,6,10,4,8,1310721,2,7, +26,2,11,26,1,10,3,6,10,4,8,1310721,2,9,26,2, +1580007,14,1,1310721,2,11,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1580055,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,1579471,12,1310721,2,5,26,4,1310721,2,5, +26,2,3,1,10,28,26,1310721,2,3,26,2,10,3,6,10, +4,8,1310721,2,5,26,2,1,1310721,2,5,26,2,13,1,10, +28,26,2,13,28,1574703,12,8,1310721,2,5,26,2,1580193,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1580241,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,1580021, +12,1580265,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1580313,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,1578965,12,1,6,1,10,28,34,63,38,3,26,1580359,16, +1,1580387,14,1310721,2,2,13,1,10,28,26,2,13,28,1580387,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1580435,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1578965, +12,1,6,1,10,28,34,63,38,3,26,1580481,16,1,1580505,14, +1310721,2,2,3,1,10,28,26,2,1580505,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1580553,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,13,28,1310721,2,3,26, +4,1310721,2,3,26,2,1,26,2,13,28,1310721,2,5,26,4, +1,1310721,2,7,26,4,1310721,2,3,26,2,5,26,5,10,3, +6,10,4,8,1310721,2,7,26,2,1310721,2,5,26,2,40,1580869, +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,1578965,12,1580809,16,1310721,2, +9,26,2,5,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,1580811,14,1,1580831,16,1310721,2,9,26,2,1580519,12,8,1310721, +2,7,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1580649,14,1310721,2,3,26,2,1578169,12,8,1,1580893,14,1,1310721,2, +11,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1580941, +16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1578965,12,1580973,16, +1310721,2,2,1580519,12,8,1,1580981,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1581029,16,1966081,1310721,4, +1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1578965,12,1581097, +16,1310721,2,2,5,1,10,28,26,1310721,2,3,26,2,10,3, +6,10,4,8,1310721,2,2,1581109,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1581157,16,1966081,1310721,4, +1579223,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,9, +1310721,2,5,26,2,1580021,12,1310721,2,7,26,4,1310721,2,3,26, +2,1310721,2,9,26,4,1310721,2,9,26,2,9,40,1581269,16,1310721, +2,9,26,9,10,3,6,10,4,8,1310721,2,11,26,1310721,2, +9,26,2,1310721,2,2,30,1580207,12,10,3,6,10,4,8,1310721, +2,7,26,2,1,26,1310721,2,3,26,2,10,3,6,10,4, +8,1310721,2,7,26,2,3,26,1310721,2,9,26,2,10,3,6, +10,4,8,1310721,2,7,26,2,5,26,1310721,2,11,26,2,1310721, +2,7,26,2,1580995,12,10,3,6,10,4,8,1310721,2,7,26, +2,7,26,1310721,2,2,10,3,6,10,4,8,1310721,2,7,26, +2,1581481,14,1,1310721,2,13,26,1310721,4,18,1310721,2,17,28,1310721, +4,1310721,2,1835009,40,1581529,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1310721,2,2,3,26,2,1310721,2,5,26,4,1310721, +2,2,5,26,2,1310721,2,9,26,4,1,1310721,2,11,26,4, +1310721,2,3,26,2,1310721,2,5,26,2,10,40,3,36,1581639,16, +1,1582193,14,1310721,2,5,26,2,1310721,2,3,26,2,40,1581711,16, +1310721,2,5,26,1310721,2,5,26,2,1310721,2,5,26,2,26,10, +3,6,10,4,8,1581639,14,1310721,2,7,26,1310721,2,5,26,2, +1310721,2,2,7,26,2,30,1580207,12,10,3,6,10,4,8,1310721, +2,15,26,1310721,2,2,1,26,2,1310721,2,2,7,26,2,30, +10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,9,26,2, +1310721,2,15,26,2,1574491,12,8,1310721,2,11,26,2,1310721,2,15, +26,2,40,1582095,16,1310721,2,13,26,1310721,2,7,26,2,1310721,2, +11,26,2,26,2,10,3,6,10,4,8,1310721,2,13,26,2, +1578965,12,1582009,16,1310721,2,13,26,2,5,1,10,28,26,2,1310721, +2,9,26,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1582011,14,1,1582057,16,1310721, +2,13,26,2,5,1,10,28,26,1310721,2,7,26,2,10,3, +6,10,4,8,1310721,2,11,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1581841,14,1310721,2,2,5,26,1310721,2,7,26, +2,1310721,2,2,1580995,12,10,3,6,10,4,8,1310721,2,2,3, +26,1310721,2,5,26,2,10,3,6,10,4,8,1310721,2,9,26, +2,1580907,12,8,1,1582193,14,1,1310721,2,17,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1582241,16,1966081,1310721,4,1579223,12, +1310721,2,3,26,4,1310721,2,4,1582283,14,122,121,58,32,105,110, +100,101,120,32,0,1582261,1573495,12,8,1310721,2,2,1573657,12,8,1582353, +14,32,111,117,116,32,111,102,32,114,97,110,103,101,32,40, +108,101,110,103,116,104,32,0,1582307,1573495,12,8,1310721,2,3,26, +2,1573657,12,8,1582387,14,41,10,0,1582381,1573495,12,8,1573437,12,8, +1,1582409,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1582457,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1310721,2,3,26,2,1,40,1582497,16,3,1582547,14, +1310721,2,3,26,2,1310721,2,2,1,26,2,40,3,36,1,6, +1,10,28,34,63,38,1,10,28,1582579,16,1310721,2,3,26,2, +1310721,2,2,1,26,2,1582207,12,8,1310721,2,2,5,26,2,1310721, +2,3,26,2,1310721,2,2,7,26,2,30,26,1582623,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40, +1582671,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721, +2,2,1310721,2,2,1,26,2,3,26,1581495,12,8,1310721,2,2, +5,26,2,1310721,2,2,1,26,2,26,1310721,2,3,26,2,10, +3,6,10,4,8,1310721,2,3,26,2,1310721,2,2,5,26,2, +1580995,12,8,1310721,2,2,1,26,1310721,2,2,1,26,2,3,26, +10,3,6,10,4,8,1,1582837,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1582885,16,1966081,1310721,4, +1579223,12,1310721,2,4,1310721,2,2,1,26,2,1,6,1,10,28, +34,63,38,3,26,1582943,16,3,1,10,28,1,1582207,12,8,1310721, +2,2,1,26,1310721,2,2,1,26,2,3,28,10,3,6,10, +4,8,1310721,2,2,5,26,2,1310721,2,2,1,26,2,26,2, +1583015,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1583063,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,1,26,2,1310721,2,2,7,26,2,30, +1310721,2,5,26,4,1310721,2,3,26,2,1,40,1583155,16,1310721,2, +3,26,1,10,3,6,10,4,8,1310721,2,2,1310721,2,3,26, +2,1581495,12,8,1310721,2,3,26,2,1310721,2,2,7,26,2,30, +1310721,2,5,26,2,10,40,1583287,16,1310721,2,2,5,26,2,1310721, +2,5,26,2,26,1,1310721,2,3,26,2,1310721,2,2,7,26, +2,30,1310721,2,5,26,2,28,1574703,12,8,1310721,2,2,1,26, +1310721,2,3,26,2,10,3,6,10,4,8,1,1583327,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1583375,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26,2, +1583399,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1583447,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2, +2,3,26,2,1583471,14,1,1310721,2,3,26,1310721,4,18,0,0, +0,0,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1583527,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,1578965,12,1,6,1,10,28, +34,63,38,3,26,1583573,16,3,1583617,14,1310721,2,2,9,1,10, +28,26,2,5,32,1,6,1,10,28,34,63,38,1,10,28, +1583627,16,1,1583771,14,1310721,2,2,9,1,10,28,26,1310721,2,2, +9,1,10,28,26,2,5,34,10,3,6,10,4,8,1583485,2, +32769,40,1583747,16,2031617,1583485,2,26,1310721,2,2,10,3,6,10,4, +8,1583485,1,6,2,1,6,3,26,5,6,4,10,8,8,1583763, +14,1583487,3,10,3,6,10,4,8,1,1583771,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1583819,16, +1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2, +1310721,2,3,26,2,40,1583905,16,1310721,2,2,2,1583493,12,8,1310721, +2,1,6,2,1,6,3,26,5,6,4,10,8,8,1583835,14, +1,1583913,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1583961,16,1966081,1310721,4,1579223,12,1583485,2,1584069,16, +1583485,1,6,2,1,6,-1,26,5,6,4,10,8,8,1310721,2, +2031617,1583485,2,26,2,10,3,6,10,4,8,1310721,2,2,1310721,2, +2,1310721,2,2,13,1,10,28,26,2,26,13,28,1583785,12,8, +1583961,14,1,1584077,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7, +28,1310721,4,1310721,2,1835009,40,1584125,16,1966081,1310721,4,1579223,12,1,1310721, +2,5,26,4,1583485,1,10,3,6,10,4,8,1583487,1,10,3, +6,10,4,8,1714063,12,8,1583927,12,8,1583487,2,1584363,16,1583487,1, +10,3,6,10,4,8,1310721,2,524289,10,3,6,10,4,8,1310721, +2,2,1310721,40,1584359,16,1310721,2,2,5,26,2,7,28,1,6, +1,10,28,34,63,38,3,26,1584313,16,1310721,2,2,13,26,1310721, +2,2,1310721,2,2,1,26,2,26,1583785,12,8,1310721,2,1310721,2, +2,1310721,2,2,1,26,2,26,10,3,6,10,4,8,1583927,12, +8,1584223,14,1584181,14,1310721,2,524289,10,3,6,10,4,8,1310721,2, +2,1310721,40,1584639,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,1584537,16,1310721,2,2,1578169,12,8,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1310721,2,1578167,2,10,3,6,10,4,8,1584635,14,1310721,2,2,5, +26,2,7,28,1,6,1,10,28,34,63,38,3,26,1584601,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,1584381,14,1576159, +1,6,2,1,6,3,26,5,6,4,10,8,8,1576161,1576161,2, +1310721,2,5,26,2,26,10,3,6,10,4,8,1310721,2,5,26, +2,1584713,14,1,1310721,2,7,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1584761,16,1966081,1310721,4,1579223,12,524289,1310721,2,4, +1,1310721,2,3,26,4,1310721,2,2,1310721,40,1584889,16,1310721,2,2, +5,26,2,3,32,1584849,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,1584781,14,1310721,2,3,26, +2,1584905,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1584953,16,1966081,1310721,4,1579223,12,63,1310721,2,4, +1310721,2,2,1,10,40,1585035,16,1576095,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,1585037,14,1,1585075,16,1310721,2,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1584961,14,1576095,1310721,2,2,26,2,1, +6,1,10,28,34,63,38,3,26,1585117,16,1,1585135,14,1574901,1310721, +2,2,26,2,1585135,14,1,1310721,2,3,26,1310721,4,18,0,0, +0,0,0,0,0,0,0,0,0,0,792587,113,64,33,36,95, +126,99,106,122,114,44,63,46,43,45,42,38,124,94,62,60, +37,0,1,0,0,0,0,1,0,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,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,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,1,28,1310721,4,1310721,2,1835009,40,1588261,16,1966081,1310721,4, +1579223,12,1588285,14,122,99,58,32,108,105,110,101,32,0,1588265,1573495, +12,8,1585229,2,1573657,12,8,1588313,14,58,32,0,1588307,1573495,12,8, +1588223,1,6,2,1,6,3,26,5,6,4,10,8,8,1,1588357, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1588405,16,1966081,1310721,4,1579223,12,21,1573255,12,8,1588223,2, +41,40,3,36,1588509,16,1588495,14,122,99,58,32,116,111,111,32, +109,97,110,121,32,101,114,114,111,114,115,44,32,115,116,111, +112,112,105,110,103,10,0,1588433,1573495,12,8,1573437,12,8,1,1588517, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1588565,16,1966081,1310721,4,1579223,12,1588579,14,122,99,58,32, +0,1588569,1573495,12,8,1588223,2,1573657,12,8,1588223,2,3,28,1,6, +1,10,28,34,63,38,3,26,1588661,16,1588649,14,32,101,114,114, +111,114,10,0,1588633,1573495,12,8,1588691,14,1588683,14,32,101,114,114, +111,114,115,10,0,1588665,1573495,12,8,1573437,12,8,1,1588705,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1588753,16,1966081,1310721,4,1579223,12,1310721,2,4,1588227,12,8,1310721,2, +2,1573495,12,8,21,1573255,12,8,1573437,12,8,1,1588799,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1588847,16,1966081,1310721,4,1579223,12,1310721,2,4,1588225,2,1,6,1,10, +28,34,63,38,3,26,1588931,16,1587637,2,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1588933, +14,1,1588961,16,1588227,12,8,1310721,2,2,1573495,12,8,1588371,12,8, +1,1588969,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1589017,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1588225,2,1,6,1,10,28,34,63,38,3,26, +1589111,16,1587637,2,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1589113,14,1,1589175,16,1588227,12, +8,1310721,2,2,1573495,12,8,1589145,14,58,32,0,1589139,1573495,12,8, +1310721,2,3,26,2,1573495,12,8,1588371,12,8,1,1589183,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1589231,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1588813,12,8, +1588225,3,10,3,6,10,4,8,1585223,2,1,28,1,6,1,10, +28,34,63,38,3,26,1589303,16,1588531,12,8,1601277,12,8,1,1589317, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1589365,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721, +2,4,1310721,2,2,1310721,2,3,26,2,1588983,12,8,1588225,3,10, +3,6,10,4,8,1585223,2,1,28,1,6,1,10,28,34,63, +38,3,26,1589457,16,1588531,12,8,1601277,12,8,1,1589471,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1589519,16,1966081,1310721,4,1579223,12,1310721,2,4,1587499,2,1589563,16,1587503,2, +1,6,1,10,28,34,63,38,1,10,28,1589565,14,1,1589581,16, +1310721,2,2,1588813,12,8,1,1589589,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1589637,16,1966081,1310721,4, +1579223,12,1310721,2,3,26,4,1310721,2,4,1587499,2,1589691,16,1587503,2, +1,6,1,10,28,34,63,38,1,10,28,1589693,14,1,1589725,16, +1466881,1310721,2,2,26,2,1310721,2,3,26,2,1588983,12,8,1,1589733, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1589781,16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2, +3,26,4,1310721,2,2,2,1589889,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,1589799,14, +1310721,2,3,26,2,16385,3,28,32,1589913,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1589961,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,1589747,12,1310721,2,3,26, +4,3,1590151,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,1590067,16,1590151,14,1310721,2,5,26,2,1310721,2, +2,1574183,12,1590105,16,1310721,2,5,26,2,1590431,14,1310721,2,3,26, +1310721,2,3,26,2,3,26,16385,3,28,32,10,3,6,10,4, +8,1589987,14,1310721,2,7,26,1310721,2,2,1574039,12,10,3,6,10, +4,8,1585151,2,1310721,2,7,26,2,26,5,26,1409025,40,3,36, +1590259,16,1590251,14,115,116,114,105,110,103,32,112,111,111,108,32, +102,117,108,108,0,1590217,1588719,12,8,1585151,2,1,26,1,10,3, +6,10,4,8,1310721,2,5,26,1585151,2,3,26,10,3,6,10, +4,8,1310721,2,5,26,2,1310721,2,2,1310721,2,7,26,2,3, +26,1574491,12,8,1585151,1585151,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,1590431,14,1,1310721, +2,9,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40, +1590479,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26, +4,1310721,2,4,1585153,2,1310721,2,7,26,4,1585153,2,8193,40,3, +36,1590583,16,1590575,14,115,121,109,98,111,108,32,116,97,98,108, +101,32,102,117,108,108,0,1590539,1588719,12,8,1585153,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,1559041,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,1590929,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1590977,16,1966081,1310721,4,1579223,12, +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,1591263,16,1310721,2, +3,26,2,1585157,2,40,3,36,1591067,16,3,1591129,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,1591139,16,3,1591201, +14,1417729,1310721,2,3,26,2,26,2,15,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1591219,16,1310721,2,3,26,2,1591277,14,1310721,2,3,26,1458689,1310721,2, +3,26,2,26,2,3,28,10,3,6,10,4,8,1591015,14,3, +1,10,28,1591277,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1591325,16,1966081,1310721,4,1579223,12,1310721,2, +4,1585153,2,1310721,2,2,10,40,1591423,16,1585153,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1409537,1585153,2,26,2,3,1,10, +28,26,1458689,1585153,2,26,2,10,3,6,10,4,8,1591331,14,1, +1591431,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1591479,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2, +2,1589927,12,1590943,12,1591505,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,1835009,40,1591553,16,1966081,1310721,4,1579223,12, +1310721,2,3,26,4,1310721,2,4,1585161,2,1310721,2,5,26,4,1310721, +2,5,26,2,1591631,16,1585161,1491457,1310721,2,5,26,2,26,2,10, +3,6,10,4,8,1591773,14,1585159,1,6,2,1,6,3,26,5, +6,4,10,8,8,1310721,2,5,26,1585159,2,10,3,6,10,4, +8,1310721,2,5,26,2,16385,40,3,36,1591773,16,1591765,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,1591709,1588719,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,1591857,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,1835009,40,1591905,16,1966081,1310721,4,1579223,12, +1310721,2,3,26,4,1310721,2,4,1310721,2,2,1592067,16,1475073,1310721,2, +2,26,2,1310721,2,3,26,2,1592451,12,8,1310721,2,5,26,1491457, +1310721,2,2,26,2,10,3,6,10,4,8,1491457,1310721,2,2,26, +1585161,2,10,3,6,10,4,8,1585161,1310721,2,2,10,3,6,10, +4,8,1310721,2,1310721,2,5,26,2,10,3,6,10,4,8,1591921, +14,1,1592075,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1592123,16,1966081,1310721,4,1579223,12,1310721,2,4, +1587637,2,1592143,16,1,1592269,14,1587483,2,1587487,2,40,3,36,1592205,16, +1592197,14,112,114,111,103,114,97,109,32,116,111,111,32,98,105, +103,0,1592165,1588719,12,8,1587483,2,1587485,2,26,1310721,2,2,10,3, +6,10,4,8,1587483,1,6,2,1,6,3,26,5,6,4,10, +8,8,1,1592269,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1592317,16,1966081,1310721,4,1579223,12,1310721,2, +4,1310721,2,2,1310721,2,2,26,3,26,1592089,12,8,1,1592355,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1592403,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1310721, +2,2,26,1592089,12,8,1,1592437,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1592485,16,1966081,1310721,4, +1579223,12,1310721,2,3,26,4,1310721,2,4,1587637,2,1592515,16,1,1592573, +14,1310721,2,2,1587485,2,26,1310721,2,3,26,2,1310721,2,3,26, +2,26,3,26,10,3,6,10,4,8,1,1592573,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1592621, +16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1592283,12,8,15, +1592369,12,8,1,1592655,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1592703,16,1966081,1310721,4,1579223,12,1587483, +2,1310721,2,4,2097153,3,28,1592283,12,8,1310721,2,2,1592737,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1592785,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,3,1585229, +2,1590445,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,1592861,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1592909, +16,1966081,1310721,4,1579223,12,1310721,2,4,1442305,1310721,2,2,26,2,3, +32,1592959,16,1425921,1310721,2,2,26,2,1592283,12,8,1,1593035,14,1587637, +2,1592973,16,1,1593035,14,1450497,1310721,2,2,26,1587483,2,1450497,1310721,2, +2,26,2,1591519,12,10,3,6,10,4,8,2097153,3,28,1592283,12, +8,1,1593035,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1593083,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,1590943,12,1310721,2,3,26,4,1310721,2,3,26,2,1, +40,1593157,16,1310721,2,3,26,1310721,2,2,1592751,12,10,3,6,10, +4,8,1310721,2,3,26,2,1592875,12,8,13,1592369,12,8,1,1593189, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1593237,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,1592283,12, +8,3,1592369,12,8,1310721,2,2,1593289,16,1310721,2,2,1592283,12,8, +27,1592369,12,8,1,1593297,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1593345,16,1966081,1310721,4,1579223,12, +1310721,2,4,1558017,1310721,2,2,26,2,33,32,1593543,16,1310721,2,3, +26,1587693,2,1590943,12,10,3,6,10,4,8,1310721,2,3,26,2, +1,40,3,36,1593487,16,1417729,1310721,2,3,26,2,26,2,13,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1593489,14,1,1593543,16,1467905,1310721,2,2,26,2, +1592283,12,8,45,1425921,1310721,2,3,26,2,26,2,26,1592369,12,8, +1,1593565,14,1467905,1310721,2,2,26,2,1593203,12,1593565,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1593613, +16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2,3,26,4,1310721, +2,3,26,2,1587723,2,40,1593743,16,1587707,1310721,2,3,26,2,26, +2,1310721,2,2,28,1,6,1,10,28,34,63,38,3,26,1593705, +16,1,1593817,14,1310721,2,3,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1593631,14,1587723,2,15,40,1593809,16,1587707,1587723,2, +26,1310721,2,2,10,3,6,10,4,8,1587723,1,6,2,1,6, +3,26,5,6,4,10,8,8,1,1593817,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1593865,16,1966081, +1310721,4,1579223,12,1310721,2,7,26,4,1310721,2,5,26,4,1310721,2, +3,26,4,1310721,2,4,1587485,2,1593915,16,3,1593959,14,1310721,2,2, +1310721,2,3,26,2,40,3,36,1,6,1,10,28,34,63,38, +1,10,28,1593969,16,1,1594137,14,1588127,1,26,1,10,3,6,10, +4,8,1588127,3,26,5,10,3,6,10,4,8,1588127,5,26,1310721, +2,2,10,3,6,10,4,8,1588127,7,26,1310721,2,3,26,2, +10,3,6,10,4,8,1588127,9,26,1310721,2,7,26,2,10,3, +6,10,4,8,1588127,11,26,1310721,2,5,26,2,1310721,2,7,26, +2,1574491,12,8,1588127,1572879,12,8,1,1594137,14,1,1310721,2,9,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1594185,16,1966081, +1310721,4,1579223,12,1,1310721,2,4,1310721,2,2,1588125,2,40,1594345,16, +1310721,2,3,26,1587725,1310721,2,2,21,30,26,10,3,6,10,4, +8,1310721,2,3,26,2,1,26,2,1310721,2,3,26,2,3,26, +2,1310721,2,3,26,2,7,26,1310721,2,3,26,2,5,26,2, +1593831,12,8,1310721,2,1,6,2,1,6,3,26,5,6,4,10, +8,8,1594193,14,1588125,1,10,3,6,10,4,8,1,1594369,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009, +40,1594417,16,1966081,1310721,4,1579223,12,1310721,2,4,1592669,12,1310721,2,3, +26,4,15,1592369,12,8,1310721,2,5,26,1587483,2,10,3,6,10, +4,8,1310721,2,2,2,1594529,16,1310721,2,2,2,1592089,12,8,1310721, +2,1,6,2,1,6,3,26,5,6,4,10,8,8,1594469,14, +1,1592089,12,8,1310721,2,3,26,2,1587483,2,1592451,12,8,1310721,2, +5,26,2,1592283,12,8,1,1594581,14,1,1310721,2,7,26,1310721,4, +18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1594629,16,1966081,1310721,4, +1579223,12,1585235,2,1,28,1,6,1,10,28,34,63,38,3,26, +1594835,16,1585241,2,1594675,16,3,1594701,14,1573381,12,1,6,1,10,28, +34,63,38,1,10,28,1594733,16,1585233,3,1,10,28,10,3,6, +10,4,8,1,1595135,14,1585233,1573325,12,511,32,10,3,6,10,4, +8,1585233,2,193,28,1,6,1,10,28,34,63,38,3,26,1594831, +16,1585241,3,10,3,6,10,4,8,1585233,3,1,10,28,10,3, +6,10,4,8,1,1595135,14,1595067,14,1585235,2,7,28,1,6,1, +10,28,34,63,38,3,26,1594981,16,1585233,1585239,2,1585237,2,5,38, +26,2,1585237,2,7,32,17,30,38,511,32,10,3,6,10,4, +8,1585233,2,1594955,16,1585237,1,6,2,1,6,3,26,5,6,4, +10,8,8,1594977,14,1585233,3,1,10,28,10,3,6,10,4,8, +1595067,14,1585233,1585237,2,2,511,32,10,3,6,10,4,8,1585233,2, +1595045,16,1585237,1,6,2,1,6,3,26,5,6,4,10,8,8, +1595067,14,1585233,3,1,10,28,10,3,6,10,4,8,1585233,2,21, +28,1,6,1,10,28,34,63,38,3,26,1595127,16,1585231,1,6, +2,1,6,3,26,5,6,4,10,8,8,1,1595135,14,1,1310721, +2,1,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40, +1595183,16,1966081,1310721,4,1579223,12,1310721,2,7,26,4,1310721,2,5,26, +4,1310721,2,3,26,4,1310721,2,4,1585243,1,6,2,1,6,3, +26,5,6,4,10,8,8,1585243,2,65,40,3,36,1595327,16,1595319, +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,1595267,1588719,12,8,1310721, +2,9,26,1540609,1585243,2,65,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,1585223,2,10,3,6,10,4,8, +1310721,2,9,26,2,13,26,1585225,2,10,3,6,10,4,8,1310721, +2,9,26,2,15,26,1585227,2,10,3,6,10,4,8,1310721,2, +9,26,2,17,26,1585233,2,10,3,6,10,4,8,1310721,2,9, +26,2,19,26,1585235,2,10,3,6,10,4,8,1310721,2,9,26, +2,21,26,1585237,2,10,3,6,10,4,8,1310721,2,9,26,2, +25,26,1585231,2,10,3,6,10,4,8,1310721,2,9,26,2,27, +26,1585229,2,10,3,6,10,4,8,1310721,2,9,26,2,29,26, +1587449,2,10,3,6,10,4,8,1310721,2,9,26,2,63,26,1585239, +2,10,3,6,10,4,8,1310721,2,11,26,1,10,3,6,10, +4,8,1310721,2,11,26,2,1587449,2,40,1596167,16,1310721,2,9,26, +2,31,1310721,2,11,26,2,9,30,26,26,1587451,1310721,2,11,26, +2,26,2,10,3,6,10,4,8,1310721,2,9,26,2,33,1310721, +2,11,26,2,9,30,26,26,1587459,1310721,2,11,26,2,26,2, +10,3,6,10,4,8,1310721,2,9,26,2,35,1310721,2,11,26, +2,9,30,26,26,1587467,1310721,2,11,26,2,26,2,10,3,6, +10,4,8,1310721,2,9,26,2,37,1310721,2,11,26,2,9,30, +26,26,1587475,1310721,2,11,26,2,26,2,10,3,6,10,4,8, +1310721,2,11,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1595877,14,1587449,1,10,3,6,10,4,8,1310721,2,2,3,28, +1,6,1,10,28,34,63,38,3,26,1596259,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, +1596347,16,1585235,1,10,3,6,10,4,8,1585241,1,10,3,6,10, +4,8,1585231,3,10,3,6,10,4,8,1594595,12,8,1310721,2,2, +5,28,1,6,1,10,28,34,63,38,3,26,1596443,16,1585235,5, +10,3,6,10,4,8,1585237,1310721,2,3,26,2,10,3,6,10, +4,8,1585231,3,10,3,6,10,4,8,1594595,12,8,1310721,2,2, +7,28,1,6,1,10,28,34,63,38,3,26,1596555,16,1585235,7, +10,3,6,10,4,8,1585239,1310721,2,3,26,2,10,3,6,10, +4,8,1585237,1,10,3,6,10,4,8,1585231,3,10,3,6,10, +4,8,1594595,12,8,1,1596563,14,1,1310721,2,13,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1596611,16,1966081,1310721,4,1579223, +12,1540609,1585243,2,65,30,26,1310721,2,4,1,1310721,2,3,26,4, +1585223,1310721,2,2,11,26,2,10,3,6,10,4,8,1585225,1310721,2, +2,13,26,2,10,3,6,10,4,8,1585227,1310721,2,2,15,26, +2,10,3,6,10,4,8,1585233,1310721,2,2,17,26,2,10,3, +6,10,4,8,1585235,1310721,2,2,19,26,2,10,3,6,10,4, +8,1585237,1310721,2,2,21,26,2,10,3,6,10,4,8,1585231,1310721, +2,2,25,26,2,10,3,6,10,4,8,1585229,1310721,2,2,27, +26,2,10,3,6,10,4,8,1587449,1310721,2,2,29,26,2,10, +3,6,10,4,8,1585239,1310721,2,2,63,26,2,10,3,6,10, +4,8,1310721,2,3,26,2,1587449,2,40,1597175,16,1587451,1310721,2,3, +26,2,26,1310721,2,2,31,1310721,2,3,26,2,9,30,26,26, +2,10,3,6,10,4,8,1587459,1310721,2,3,26,2,26,1310721,2, +2,33,1310721,2,3,26,2,9,30,26,26,2,10,3,6,10, +4,8,1587467,1310721,2,3,26,2,26,1310721,2,2,35,1310721,2,3, +26,2,9,30,26,26,2,10,3,6,10,4,8,1587475,1310721,2, +3,26,2,26,1310721,2,2,37,1310721,2,3,26,2,9,30,26, +26,2,10,3,6,10,4,8,1310721,2,3,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1596901,14,1585243,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1310721,2,2,23,26,2,1597237, +16,1310721,2,2,3,26,2,1580907,12,8,1,1597245,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1597293, +16,1966081,1310721,4,1579223,12,1310721,2,4,1597343,14,43,45,42,47,37, +61,60,62,33,38,124,94,126,63,58,46,64,35,36,0,1597303, +1310721,2,3,26,4,1310721,2,3,26,2,2,1597459,16,1310721,2,3, +26,2,2,1310721,2,2,28,1,6,1,10,28,34,63,38,3, +26,1597421,16,3,1597467,14,1310721,2,3,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1597355,14,1,1597467,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1597515,16, +1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1,1310721,2, +5,26,4,1310721,2,5,26,2,1585169,2,40,1597945,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,1597731,16,1310721,2,7,26,2,1310721,2,9,26,2,26, +2,1585245,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,1597733, +14,1,1597775,16,1310721,2,9,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1597621,14,1310721,2,9,26,2,1310721,2,2,28, +1,6,1,10,28,34,63,38,3,26,1597895,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,1597897,14,1,1597907,16,3,1597953,14,1310721,2,5,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1597543,14,1,1597953,14,1, +1310721,2,11,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1598001,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,97,40, +3,36,1598067,16,1310721,2,2,115,10,40,3,36,1,6,1,10, +28,34,63,38,1,10,28,1598069,14,1,1598075,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1598123,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,195,40,3,36,1598189, +16,1310721,2,2,245,10,40,3,36,1,6,1,10,28,34,63, +38,1,10,28,1598191,14,1,1598201,16,3,1598285,14,1310721,2,2,131, +40,3,36,1598261,16,1310721,2,2,181,10,40,3,36,1,6,1, +10,28,34,63,38,1,10,28,1598263,14,1,1,6,1,10,28, +34,63,38,1,10,28,1598295,16,3,1598347,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,1598353,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1598401,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,1597967,12,1598435,16,1310721,2,2,97,28,1598617, +14,1310721,2,2,195,40,3,36,1598495,16,1310721,2,2,205,10,40, +3,36,1,6,1,10,28,34,63,38,1,10,28,1598497,14,1, +1598519,16,1310721,2,2,195,28,21,26,1598617,14,1310721,2,2,131,40, +3,36,1598579,16,1310721,2,2,141,10,40,3,36,1,6,1,10, +28,34,63,38,1,10,28,1598581,14,1,1598603,16,1310721,2,2,131, +28,21,26,1598617,14,3,1,10,28,1598617,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1598665,16,1966081, +1310721,4,1579223,12,1585233,2,1310721,2,4,1594595,12,8,1310721,2,2,185, +28,1,6,1,10,28,34,63,38,1,10,28,1598727,16,1310721,2, +2,1598965,14,1310721,2,1585233,2,10,3,6,10,4,8,1594595,12,8, +1310721,2,2,221,28,1,6,1,10,28,34,63,38,3,26,1598793, +16,21,1598965,14,1310721,2,2,233,28,1,6,1,10,28,34,63, +38,3,26,1598833,16,19,1598965,14,1310721,2,2,229,28,1,6,1, +10,28,34,63,38,3,26,1598873,16,27,1598965,14,1310721,2,2,97, +28,1,6,1,10,28,34,63,38,3,26,1598913,16,1,1598965,14, +1310721,2,2,203,28,1,6,1,10,28,34,63,38,3,26,1598953, +16,55,1598965,14,1310721,2,2,1598965,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1599013,16,1966081,1310721,4, +1579223,12,1310721,2,4,1585233,2,1,40,3,36,1599069,16,1585233,2,1597259, +12,1,6,1,10,28,34,63,38,1,10,28,1599071,14,1,1599115, +16,1310721,2,2,1585233,2,1597481,12,1,6,1,10,28,34,63,38, +1,10,28,1599117,14,1,1599187,16,1585245,1310721,2,2,26,1585233,2,10, +3,6,10,4,8,1310721,2,1,6,2,1,6,3,26,5,6, +4,10,8,8,1594595,12,8,1599019,14,1585245,1310721,2,2,26,1,10, +3,6,10,4,8,1585223,9,10,3,6,10,4,8,1585225,1585245,1589927, +12,10,3,6,10,4,8,1,1599255,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1599303,16,1966081,1310721, +4,1579223,12,1,1310721,2,4,1585227,3,10,3,6,10,4,8,3, +1599979,16,1585233,2,65,28,1,6,1,10,28,34,63,38,3,26, +1599371,16,3,1599421,14,1585233,2,19,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1599431,16, +3,1599481,14,1585233,2,21,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1599491,16,3,1599541, +14,1585233,2,27,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1599571,16,1594595,12,8,1585227, +1,10,3,6,10,4,8,1599333,14,1585233,2,95,28,1,6,1, +10,28,34,63,38,1,10,28,1599609,16,1599979,14,1594595,12,8,1585233, +2,95,28,1,6,1,10,28,34,63,38,3,26,1599755,16,1585233, +2,1,40,3,36,1599719,16,1585233,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,1599721,14,1,1599735,16,1594595,12,8,1599647,14,1585227,1,10,3,6, +10,4,8,1599327,14,1585233,2,85,28,1,6,1,10,28,34,63, +38,3,26,1599923,16,1594595,12,8,1585233,2,1,40,3,36,1599897,16, +1585233,2,85,28,1,6,1,10,28,34,63,38,3,26,1599887,16, +1594595,12,8,1585233,2,95,28,1,6,1,10,28,34,63,38,3, +26,1599883,16,1599897,14,1599893,14,1594595,12,8,1599793,14,1594595,12,8,1585227, +1,10,3,6,10,4,8,1599327,14,1585229,1585231,2,10,3,6,10, +4,8,1585245,1,26,95,10,3,6,10,4,8,3,1598979,12,8, +1,1601263,14,1599327,14,1585229,1585231,2,10,3,6,10,4,8,1585233,2, +1,40,1600047,16,1585223,1,10,3,6,10,4,8,1585225,1,10,3, +6,10,4,8,1,1601263,14,1585233,2,1597967,12,1600469,16,1310721,2,3, +26,1,10,3,6,10,4,8,1585233,2,97,28,1,6,1,10, +28,34,63,38,3,26,1600357,16,1594595,12,8,1585233,2,241,28,1, +6,1,10,28,34,63,38,3,26,1600157,16,3,1600207,14,1585233,2, +177,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1600357,16,1594595,12,8,1310721,2,5,26, +1585233,2,1598367,12,10,3,6,10,4,1,40,3,36,1600311,16,1310721, +2,3,26,1310721,2,3,26,2,33,30,1310721,2,5,26,2,26, +10,3,6,10,4,8,1594595,12,8,1600217,14,1585223,3,10,3,6, +10,4,8,1585225,1310721,2,3,26,2,10,3,6,10,4,8,1, +1601263,14,1585233,2,1597967,12,1600423,16,1310721,2,3,26,1310721,2,3,26, +2,21,30,1585233,2,26,97,28,10,3,6,10,4,8,1594595,12, +8,1600357,14,1585223,3,10,3,6,10,4,8,1585225,1310721,2,3,26, +2,10,3,6,10,4,8,1,1601263,14,1585233,2,1598089,12,1600679,16, +1585233,2,1598089,12,1600499,16,3,1600529,14,1585233,2,1597967,12,1,6,1, +10,28,34,63,38,1,10,28,1600613,16,1310721,2,2,2001,40,1600603, +16,1585245,1310721,2,2,26,1585233,2,10,3,6,10,4,8,1310721,2, +1,6,2,1,6,3,26,5,6,4,10,8,8,1594595,12,8, +1600481,14,1585245,1310721,2,2,26,1,10,3,6,10,4,8,1585223,5, +10,3,6,10,4,8,1585225,1585245,1589927,12,10,3,6,10,4,8, +1,1601263,14,1585233,2,79,28,1,6,1,10,28,34,63,38,3, +26,1600853,16,1594595,12,8,1585225,1598631,12,10,3,6,10,4,8,1585233, +2,79,28,1,6,1,10,28,34,63,38,1,10,28,1600825,16, +1600817,14,98,97,100,32,99,104,97,114,97,99,116,101,114,32, +108,105,116,101,114,97,108,0,1600773,1589197,12,8,1594595,12,8,1585223, +3,10,3,6,10,4,8,1,1601263,14,1585233,2,69,28,1,6, +1,10,28,34,63,38,3,26,1601145,16,1594595,12,8,1585233,2,1, +40,3,36,1600963,16,1585233,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,1600965, +14,1,1601073,16,1310721,2,3,26,1598631,12,10,3,6,10,4,8, +1310721,2,2,2001,40,1601069,16,1585245,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,1600891,14,1594595,12,8,1585245,1310721,2,2,26, +1,10,3,6,10,4,8,1585223,7,10,3,6,10,4,8,1585225, +1585245,1589927,12,10,3,6,10,4,8,1,1601263,14,1585245,1,26,1585233, +2,10,3,6,10,4,8,1594595,12,8,1585245,1,26,2,1597259,12, +1601199,16,3,1598979,12,1601263,14,1585245,3,26,1,10,3,6,10,4, +8,1585223,9,10,3,6,10,4,8,1585225,1585245,1589927,12,10,3,6, +10,4,8,1,1601263,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1601311,16,1966081,1310721,4,1579223,12,3, +1310721,2,4,1587449,2,1601651,16,1585223,1587451,1,26,2,10,3,6,10, +4,8,1585225,1587459,1,26,2,10,3,6,10,4,8,1585227,1587467,1, +26,2,10,3,6,10,4,8,1585229,1587475,1,26,2,10,3,6, +10,4,8,1310721,2,2,1587449,2,40,1601617,16,1587451,1310721,2,2,3, +28,26,1587451,1310721,2,2,26,2,10,3,6,10,4,8,1587459,1310721, +2,2,3,28,26,1587459,1310721,2,2,26,2,10,3,6,10,4, +8,1587467,1310721,2,2,3,28,26,1587467,1310721,2,2,26,2,10,3, +6,10,4,8,1587475,1310721,2,2,3,28,26,1587475,1310721,2,2,26, +2,10,3,6,10,4,8,1310721,2,1,6,2,1,6,3,26, +5,6,4,10,8,8,1601415,14,1587449,1,6,2,1,6,-1,26, +5,6,4,10,8,8,1,1601661,14,1602197,12,1601661,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1601709, +16,1966081,1310721,4,1579223,12,1310721,2,4,1587449,2,1310721,2,2,10,40, +3,36,1602063,16,1310721,2,3,26,1585223,2,10,3,6,10,4,8, +1310721,2,5,26,1585225,2,10,3,6,10,4,8,1310721,2,7,26, +1585227,2,10,3,6,10,4,8,1310721,2,9,26,1585229,2,10,3, +6,10,4,8,1602197,12,8,1587451,1587449,2,26,1585223,2,10,3,6, +10,4,8,1587459,1587449,2,26,1585225,2,10,3,6,10,4,8,1587467, +1587449,2,26,1585227,2,10,3,6,10,4,8,1587475,1587449,2,26,1585229, +2,10,3,6,10,4,8,1587449,1,6,2,1,6,3,26,5, +6,4,10,8,8,1585223,1310721,2,3,26,2,10,3,6,10,4, +8,1585225,1310721,2,5,26,2,10,3,6,10,4,8,1585227,1310721,2, +7,26,2,10,3,6,10,4,8,1585229,1310721,2,9,26,2,10, +3,6,10,4,8,1601715,14,1587445,1587451,1310721,2,2,26,2,10,3, +6,10,4,8,1587447,1587459,1310721,2,2,26,2,10,3,6,10,4, +8,1,1602123,14,1,1310721,2,11,26,1310721,4,18,1310721,2,1,28, +1310721,4,1310721,2,1835009,40,1602171,16,1966081,1310721,4,1579223,12,1,1601675,12, +1602183,14,1,1310721,2,1,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1602231,16,1966081,1310721,4,1579223,12,1310721,2,1540609,1585243,2, +65,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,1602313,16,1599269,12, +8,1,1602689,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, +1602601,16,1310721,2,3,26,1310721,2,2,3,26,2,10,3,6,10, +4,8,1585223,1310721,2,3,26,2,3,1310721,2,5,26,2,7,30, +26,26,2,10,3,6,10,4,8,1585225,1310721,2,3,26,2,5, +1310721,2,5,26,2,7,30,26,26,2,10,3,6,10,4,8, +1585229,1310721,2,3,26,2,7,1310721,2,5,26,2,7,30,26,26, +2,10,3,6,10,4,8,1585227,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,1602689,14,1310721,2,2,9,26,2,1,6,1,10,28,34, +63,38,3,26,1602675,16,1585223,1,10,3,6,10,4,8,1585225,1, +10,3,6,10,4,8,1,1602689,14,1596577,12,8,1,1602689,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1602737,16,1966081,1310721,4,1579223,12,1310721,2,4,1585223,2,9,28,1, +6,1,10,28,34,63,38,3,26,1602833,16,1585225,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,1602835,14,1,1602841,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1602889,16,1966081, +1310721,4,1579223,12,1310721,2,4,1585223,2,5,28,1,6,1,10,28, +34,63,38,3,26,1602985,16,1585225,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,1602987,14,1,1602993,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1603041,16,1966081,1310721,4,1579223,12, +1310721,2,4,1585223,2,9,28,1,6,1,10,28,34,63,38,3, +26,1603085,16,3,1603135,14,1585223,2,5,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1603197, +16,1585225,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,1603199,14,1,1603215, +16,1601277,12,8,3,1603223,14,1,1603223,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1603271,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,1603007,12,1,6,1,10,28, +34,63,38,3,26,1603505,16,1588225,2,1,6,1,10,28,34,63, +38,3,26,1603389,16,1587637,2,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1603391,14,1,1603451, +16,1588227,12,8,1603425,14,101,120,112,101,99,116,101,100,32,0, +1603405,1573495,12,8,1310721,2,2,1573495,12,8,1588371,12,8,1588225,3,10, +3,6,10,4,8,1585223,2,1,28,1,6,1,10,28,34,63, +38,3,26,1603505,16,1588531,12,8,1,1603513,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1603561,16,1966081, +1310721,4,1579223,12,1585225,2,1310721,2,4,1585223,2,5,28,1,6,1, +10,28,34,63,38,1,10,28,1603649,16,1603641,14,101,120,112,101, +99,116,101,100,32,97,32,110,97,109,101,0,1603609,1589197,12,8, +1601277,12,8,1310721,2,2,1603667,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,15,28,1310721,4,1310721,2,1835009,40,1603715,16,1966081,1310721,4,1579223, +12,1310721,2,4,1585171,2,1310721,2,3,26,4,3,1604789,16,1310721,2, +2,2,65,28,1,6,1,10,28,34,63,38,3,26,1603811,16, +1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8,1603741, +14,1310721,2,2,2,1,6,1,10,28,34,63,38,3,26,1603847, +16,1604789,14,1310721,2,5,26,1,10,3,6,10,4,8,1310721,2, +2,1310721,2,5,26,2,26,2,1603965,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,1603967,14,1,1604055, +16,1585245,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,1603869,14,1585245,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,1585245,1, +26,2,91,28,1,6,1,10,28,34,63,38,3,26,1604199,16, +1585245,3,26,2,1597967,12,1,6,1,10,28,34,63,38,1,10, +28,1604201,14,1,10,3,6,10,4,8,1585245,1310721,2,7,26,2, +26,2,1597967,12,1604529,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, +1585245,1310721,2,11,26,2,26,2,1604403,16,1310721,2,9,26,1310721,2, +9,26,2,21,30,1585245,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,1604289,14,1310721,2,7,26,2,1604451,16, +1310721,2,9,26,1,1310721,2,9,26,2,28,10,3,6,10,4, +8,1542657,1585171,2,26,1310721,2,9,26,2,1310721,2,9,26,2,26, +3,26,10,3,6,10,4,8,1585171,1,6,2,1,6,3,26, +5,6,4,10,8,8,1604785,14,1310721,2,5,26,2,3,28,1, +6,1,10,28,34,63,38,3,26,1604631,16,1310721,2,13,26,1585245, +1,26,2,1604819,12,10,3,6,10,4,1,40,3,36,1,6, +1,10,28,34,63,38,1,10,28,1604633,14,1,1604711,16,1542657,1585171, +2,26,1310721,2,13,26,2,1310721,2,13,26,2,26,10,3,6, +10,4,8,1585171,1,6,2,1,6,3,26,5,6,4,10,8, +8,1604785,14,1542657,1585171,2,26,-3,10,3,6,10,4,8,1542657,1585171, +2,3,26,26,1585245,1589927,12,10,3,6,10,4,8,1585171,1585171,2, +5,26,10,3,6,10,4,8,1603735,14,1310721,2,3,26,2,1604805, +14,1,1310721,2,15,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1604853,16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2, +3,26,4,1585173,2,1310721,2,3,26,2,26,2,1604995,16,1585173,2, +1310721,2,3,26,2,26,2,1310721,2,2,28,1,6,1,10,28, +34,63,38,3,26,1604957,16,1310721,2,3,26,2,1605009,14,1310721,2, +3,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1604871, +14,3,1,10,28,1605009,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,9,28,1310721,4,1310721,2,1835009,40,1605057,16,1966081,1310721,4,1579223,12, +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,1605503, +16,1542657,1310721,2,2,26,2,-3,28,1,6,1,10,28,34,63, +38,3,26,1605451,16,1310721,2,7,26,1542657,1310721,2,2,3,26,26, +2,1590943,12,10,3,6,10,4,8,1310721,2,7,26,2,1,40, +1605261,16,1310721,2,7,26,1542657,1310721,2,2,3,26,26,2,1592751,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,1605325,16,1310721,2,7,26, +2,1592875,12,8,1605421,14,1417729,1310721,2,7,26,2,26,2,13,28, +1,6,1,10,28,34,63,38,3,26,1605399,16,45,1425921,1310721,2, +7,26,2,26,2,26,1592369,12,8,1605421,14,1425921,1310721,2,7,26, +2,26,2,1592283,12,8,1310721,2,1310721,2,2,5,26,10,3,6, +10,4,8,1605499,14,1542657,1310721,2,2,26,2,1592089,12,8,1310721,2, +1,6,2,1,6,3,26,5,6,4,10,8,8,1605101,14,1, +1605511,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1605559,16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721, +2,3,26,4,1310721,2,3,26,2,1585169,2,40,1605689,16,1547777,1310721, +2,3,26,2,26,2,1310721,2,2,28,1,6,1,10,28,34, +63,38,3,26,1605651,16,1,1605751,14,1310721,2,3,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1605577,14,1547777,1585169,2,26, +1310721,2,2,10,3,6,10,4,8,1585169,1,6,2,1,6,3, +26,5,6,4,10,8,8,1,1605751,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1605799,16,1966081,1310721, +4,1579223,12,1310721,2,4,1585163,2,1310721,2,3,26,4,1310721,2,3, +26,2,1605933,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,1605929,16,1310721,2,3, +26,2,1605947,14,1605819,14,3,1,10,28,1605947,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1605995,16, +1966081,1310721,4,1579223,12,1310721,2,4,1585165,2,1310721,2,3,26,4,1310721, +2,3,26,2,1606129,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,1606125,16,1310721, +2,3,26,2,1606143,14,1606015,14,3,1,10,28,1606143,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40, +1606191,16,1966081,1310721,4,1579223,12,1310721,2,4,1585167,2,1310721,2,3,26, +4,1310721,2,3,26,2,1606325,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,1606321, +16,1310721,2,3,26,2,1606339,14,1606211,14,3,1,10,28,1606339,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2, +1835009,40,1606387,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2, +3,26,4,1310721,2,4,1310721,2,2,1589927,12,1310721,2,7,26,4, +1310721,2,7,26,2,1605765,12,1310721,2,9,26,4,1310721,2,9,26, +2,1,40,1606527,16,1310721,2,9,26,1585163,2,10,3,6,10,4, +8,1585163,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,1606751,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,1605525,12,8,1310721,2,9,26,2,1607379,14,1547009, +1310721,2,9,26,2,26,1310721,2,5,26,2,1603681,12,10,3,6, +10,4,8,1547137,1310721,2,9,26,2,26,1585171,2,1547009,1310721,2,9, +26,2,26,2,28,10,3,6,10,4,8,1310721,2,7,26,2, +1605525,12,8,1310721,2,13,26,1310721,2,2,1574039,12,10,3,6,10, +4,8,1585245,2001,26,1310721,2,2,1310721,2,13,26,2,1574491,12,8, +1585245,2001,1310721,2,13,26,2,26,26,123,10,3,6,10,4,8, +1585245,2003,1310721,2,13,26,2,26,26,1,10,3,6,10,4,8, +1310721,2,11,26,1585245,2001,26,1589927,12,10,3,6,10,4,8,1310721, +2,3,26,2,17,40,3,36,1607035,16,3,1607091,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,1607101,16,3,1607157,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,1607167,16,3,1607223,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,1607363,16,1310721,2,11, +26,2,1606157,12,1,40,1607307,16,1547457,1585167,2,26,1310721,2,11,26, +2,10,3,6,10,4,8,1585167,1,6,2,1,6,3,26,5, +6,4,10,8,8,1547585,1310721,2,11,26,2,1606157,12,26,1310721,2, +9,26,2,10,3,6,10,4,8,1310721,2,11,26,2,1605525,12, +8,1310721,2,9,26,2,1607379,14,1,1310721,2,15,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,1835009,40,1607427,16,1966081,1310721,4,1579223, +12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1589927,12,1310721,2, +5,26,4,1310721,2,5,26,2,1605961,12,1310721,2,7,26,4,1310721, +2,7,26,2,1,40,1607557,16,1310721,2,7,26,1585165,2,10,3, +6,10,4,8,1585165,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, +1603681,12,10,3,6,10,4,8,1547393,1310721,2,7,26,2,26,1585171, +2,1547329,1310721,2,7,26,2,26,2,28,10,3,6,10,4,8, +1310721,2,5,26,2,1605525,12,8,1310721,2,7,26,2,1607713,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009, +40,1607761,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3, +26,4,1310721,2,4,1310721,2,2,1589927,12,11,1310721,2,3,26,2, +1590445,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, +1607879,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1607927,16,1966081,1310721,4,1579223,12,1310721,2,4,1587491,2, +1310721,2,3,26,4,1310721,2,3,26,2,1587493,2,10,40,1608069,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,1608065,16,1310721,2,3,26,2,1608083,14, +1607947,14,3,1,10,28,1608083,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1608131,16,1966081,1310721,4,1579223, +12,1310721,2,4,1587491,2,1310721,2,3,26,4,1587491,2,1025,40,3, +36,1608211,16,1608203,14,116,111,111,32,109,97,110,121,32,108,111, +99,97,108,115,0,1608171,1588719,12,8,1587491,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,1587497,2, +10,3,6,10,4,8,1468929,1310721,2,3,26,2,26,1587495,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,1556993,1310721,2,3,26, +2,26,1587621,2,10,3,6,10,4,8,1558017,1310721,2,3,26,2, +26,1,10,3,6,10,4,8,1310721,2,3,26,2,1608545,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1608593,16,1966081,1310721,4,1579223,12,1310721,2,4,1469953,1310721,2,2,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1608671,16,1310721, +2,1470977,1310721,2,2,26,2,10,3,6,10,4,8,1608599,14,1310721, +2,2,1608683,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1608731,16,1966081,1310721,4,1579223,12,1310721,2,4, +1469953,1310721,2,2,26,2,1,28,1,6,1,10,28,34,63,38, +1,10,28,1608781,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1608829,16,1966081,1310721,4,1579223,12,1310721,2, +4,1472001,1310721,2,2,26,3,10,3,6,10,4,8,1587499,2,1, +6,1,10,28,34,63,38,3,26,1608893,16,1,1609269,14,1310721,2, +3,26,1310721,2,2,1608559,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,1609077, +16,1310721,2,2,1609063,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,1609005,1589603,12,8,1,1609269,14,1469953,1310721,2,3,26,2, +26,2,7,28,1,6,1,10,28,34,63,38,3,26,1609169,16, +1468929,1310721,2,3,26,2,26,2,1587495,2,40,1,6,1,10,28, +34,63,38,1,10,28,1609171,14,1,1609261,16,1468929,1310721,2,3,26, +2,26,1587495,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,1609269,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1609317,16,1966081,1310721,4, +1579223,12,1310721,2,4,1310721,2,2,3,28,1,6,1,10,28,34, +63,38,3,26,1609507,16,1609499,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,1609361,1589485,12, +8,1310721,2,2,5,40,3,36,1609541,16,1310721,2,2,5,28,1608795, +12,8,1,1609549,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1609597,16,1966081,1310721,4,1579223,12,1310721,2, +4,1467905,1310721,2,2,26,2,1593203,12,8,3,1592369,12,8,1587605,2, +1593049,12,8,9,1592369,12,8,1,1609655,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1609703,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587491,2,1310721,2,5, +26,4,1587499,2,1,6,1,10,28,34,63,38,3,26,1609767,16, +3,1609813,14,1587503,2,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1609823,16,1,1610383,14,1310721, +2,5,26,2,1587493,2,10,40,1610375,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,1609911,16,1609823,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,1610005,16, +1310721,2,5,26,2,1609563,12,8,1610371,14,1310721,2,7,26,2,5, +28,1,6,1,10,28,34,63,38,3,26,1610251,16,1310721,2,5, +26,2,1610239,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,1610057, +1589603,12,8,1610371,14,1310721,2,7,26,2,7,28,1,6,1,10, +28,34,63,38,3,26,1610371,16,1310721,2,5,26,2,1610363,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,1610303,1589603,12, +8,1609823,14,1,1610383,14,1,1310721,2,9,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1610431,16,1966081,1310721,4,1579223,12,1310721, +2,4,1310721,2,2,1587491,2,40,1610673,16,1587499,2,1610499,16,1474049,1310721, +2,2,26,2,1,6,1,10,28,34,63,38,1,10,28,1610501, +14,1,1610563,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,1610565, +14,1,1610639,16,1466881,1310721,2,2,26,2,1610631,14,109,32,111,98, +106,101,99,116,32,105,115,32,110,101,118,101,114,32,117,115, +101,100,0,1610585,1588983,12,8,1310721,2,1,6,2,1,6,3,26, +5,6,4,10,8,8,1610437,14,1,1610681,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1610729,16,1966081, +1310721,4,1579223,12,1310721,2,4,1587493,2,1310721,2,3,26,4,1310721,2, +2,1610397,12,8,1587495,2,3,1609669,12,8,1310721,2,3,26,2,1310721, +2,2,40,1610925,16,1468929,1310721,2,3,26,2,26,2,1587495,2,40, +3,36,1610887,16,1469953,1310721,2,3,26,2,26,9,10,3,6,10, +4,8,1468929,1310721,2,3,26,2,26,1587495,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,1610773,14,1587491,1310721,2,2,10,3,6,10,4,8, +1,1610953,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1611001,16,1966081,1310721,4,1579223,12,1587519,2,1310721,2, +4,1587493,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,1587493,2, +10,3,6,10,4,8,1310721,2,5,26,2,3,26,1587491,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,1587491,2,40,1611367,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,1611149,14,1587519,1310721,2,5,26,2,1507841,28,10,3,6,10,4, +8,1587519,2,16001,40,3,36,1611491,16,1611483,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,1611415,1588719,12, +8,1310721,2,2,1611503,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1611551,16,1966081,1310721,4,1579223,12,1310721, +2,4,1587519,1310721,2,2,10,3,6,10,4,8,1,1611585,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009, +40,1611633,16,1966081,1310721,4,1579223,12,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,1587491,2,10,40,1611757,16,1310721,2,7,26,1587491,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,1612015,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,1611791,14,1,1612023,14,1,1310721,2,9,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1612071,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,1,28,1,6,1,10,28, +34,63,38,3,26,1612117,16,3,1612169,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,1612175,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +11,28,1310721,4,1310721,2,1835009,40,1612223,16,1966081,1310721,4,1579223,12,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,1587491,2,10,40,1612347, +16,1310721,2,7,26,1587491,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,1612971,16,1310721,2,9,26,1469953, +1310721,2,5,26,2,26,2,10,3,6,10,4,8,1310721,2,9, +26,2,1612037,12,1612507,16,1310721,2,3,26,2,1,26,2,1612037,12, +1,6,1,10,28,34,63,38,1,10,28,1612509,14,1,1612589,16, +1310721,2,3,26,2,1,26,2,9,28,1,6,1,10,28,34, +63,38,3,26,1612585,16,1469953,1310721,2,5,26,2,26,9,10,3, +6,10,4,8,1612899,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,1612649, +16,3,1612727,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,1612737,16,3,1612881,14, +1310721,2,9,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1612857,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,1612859,14,1,1,6,1, +10,28,34,63,38,1,10,28,1612899,16,1310721,2,5,26,2,1612985, +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,1612381,14,3,1,10,28,1612985,14,1,1310721,2,11,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1613033,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,28,1,6,1,10, +28,34,63,38,3,26,1613095,16,1613089,14,101,109,112,116,121,0, +1613077,1613421,14,1310721,2,2,3,28,1,6,1,10,28,34,63,38, +3,26,1613143,16,1613137,14,109,0,1613133,1613421,14,1310721,2,2,5,28, +1,6,1,10,28,34,63,38,3,26,1613191,16,1613185,14,117,0, +1613181,1613421,14,1310721,2,2,7,28,1,6,1,10,28,34,63,38, +3,26,1613239,16,1613233,14,100,0,1613229,1613421,14,1310721,2,2,9,28, +1,6,1,10,28,34,63,38,3,26,1613305,16,1613299,14,103,105, +118,101,110,32,97,119,97,121,0,1613277,1613421,14,1310721,2,2,11, +28,1,6,1,10,28,34,63,38,3,26,1613391,16,1613385,14,111, +119,110,101,100,32,98,121,32,97,32,99,111,110,116,97,105, +110,101,114,0,1613343,1613421,14,1613413,14,98,111,114,114,111,119,101, +100,0,1613395,1613421,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7, +28,1310721,4,1310721,2,1835009,40,1613469,16,1966081,1310721,4,1579223,12,1310721,2, +5,26,4,1310721,2,3,26,4,1310721,2,4,1587499,2,1,6,1, +10,28,34,63,38,3,26,1613529,16,3,1613555,14,1588225,2,1,6, +1,10,28,34,63,38,1,10,28,1613565,16,3,1613591,14,1587637,2, +1,6,1,10,28,34,63,38,1,10,28,1613601,16,1,1613821,14, +1588227,12,8,1466881,1310721,2,2,26,2,1573495,12,8,1613635,14,58,32, +0,1613629,1573495,12,8,1310721,2,5,26,2,1573495,12,8,1613707,14,32, +40,111,110,101,32,112,97,116,104,32,108,101,97,118,101,115, +32,105,116,32,0,1613663,1573495,12,8,1310721,2,3,26,2,1612999,12, +1573495,12,8,1613761,14,44,32,97,110,111,116,104,101,114,32,0, +1613739,1573495,12,8,1469953,1310721,2,2,26,2,1612999,12,1573495,12,8,1613799, +14,41,0,1613795,1573495,12,8,1588371,12,8,1,1613821,14,1,1310721,2, +7,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,0,0,0,0,0,0,0,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,5,28,1310721,4,1310721,2,1835009, +40,1614001,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4, +1310721,2,3,26,2,1310721,2,2,3,26,2,40,3,36,1614055,16, +1,1614103,14,1310721,2,2,5,7,1310721,2,3,26,2,1310721,2,2, +1,26,2,28,30,26,26,2,1614103,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1614151,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,7,7, +1310721,2,3,26,2,1310721,2,2,1,26,2,28,30,26,26,2, +1614215,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1614263,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,9,7,1310721,2,3,26,2,1310721,2,2, +1,26,2,28,30,26,26,2,1614327,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1614375,16,1966081,1310721, +4,1579223,12,1310721,2,4,1567233,1613835,2,26,1310721,2,3,26,4,1587493, +2,1310721,2,5,26,4,1613835,2,7,26,7,1587491,2,1587493,2,28, +30,26,1572353,1567233,28,40,3,36,1614531,16,1614523,14,116,111,111,32, +109,97,110,121,32,98,114,101,97,107,115,32,102,111,114,32, +116,104,101,32,97,110,97,108,121,122,101,114,0,1614457,1588719,12, +8,1310721,2,3,26,2,1,26,1310721,2,2,10,3,6,10,4, +8,1310721,2,3,26,2,3,26,1587493,2,10,3,6,10,4,8, +1310721,2,3,26,2,5,26,1587491,2,10,3,6,10,4,8,1310721, +2,7,26,1310721,2,3,26,2,7,26,10,3,6,10,4,8, +1310721,2,5,26,2,1587491,2,40,1614875,16,1310721,2,7,26,2,1, +26,1469953,1310721,2,5,26,2,26,2,10,3,6,10,4,8,1310721, +2,7,26,2,3,26,1470977,1310721,2,5,26,2,26,2,10,3, +6,10,4,8,1310721,2,7,26,2,5,26,1468929,1310721,2,5,26, +2,26,2,10,3,6,10,4,8,1310721,2,7,26,1310721,2,7, +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,1614657,14,1613835,1310721,2, +7,26,2,1567233,28,10,3,6,10,4,8,1310721,2,3,26,2, +1614919,14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1614967,16,1966081,1310721,4,1579223,12,1310721,2,4,1613965,2, +129,40,3,36,1615065,16,1615057,14,116,111,111,32,109,97,110,121, +32,112,97,116,104,115,32,102,111,114,32,116,104,101,32,97, +110,97,108,121,122,101,114,0,1614993,1588719,12,8,1613837,1613965,2,26, +1310721,2,2,10,3,6,10,4,8,1613965,1,6,2,1,6,3, +26,5,6,4,10,8,8,1,1615127,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1615175,16,1966081,1310721, +4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4, +1310721,2,2,1310721,2,5,26,2,1613967,12,1310721,2,7,26,4,1310721, +2,3,26,2,1310721,2,5,26,2,1613967,12,1310721,2,9,26,4, +1310721,2,7,26,2,1612037,12,1615323,16,1310721,2,9,26,2,1612037,12, +1,6,1,10,28,34,63,38,1,10,28,1615325,14,1,1615335,16, +3,1615647,14,1310721,2,7,26,2,1310721,2,9,26,2,28,1,6, +1,10,28,34,63,38,3,26,1615473,16,1310721,2,2,1310721,2,5, +26,2,1614229,12,1310721,2,3,26,2,1310721,2,5,26,2,1614229,12, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1615475,14,1,1615639,16,1310721,2,7,26,2, +11,28,1,6,1,10,28,34,63,38,1,10,28,1615525,16,3, +1615613,14,1310721,2,2,1310721,2,5,26,2,1614117,12,1310721,2,3,26, +2,1310721,2,5,26,2,1614117,12,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,1615641,14,1,1615647,14,1,1310721, +2,11,26,1310721,4,18,1310721,2,21,28,1310721,4,1310721,2,1835009,40, +1615695,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587493, +2,1310721,2,5,26,4,1613965,2,1,6,1,10,28,34,63,38, +3,26,1615759,16,1,1617231,14,1310721,2,5,26,2,1310721,2,2,40, +1617223,16,1310721,2,9,26,1613837,1,26,2,10,3,6,10,4,8, +1310721,2,13,26,1310721,2,9,26,2,1310721,2,5,26,2,1613967,12, +10,3,6,10,4,8,1310721,2,15,26,1,10,3,6,10,4, +8,1310721,2,17,26,3,10,3,6,10,4,8,1310721,2,19,26, +3,1,10,28,10,3,6,10,4,8,1310721,2,7,26,1,10, +3,6,10,4,8,1310721,2,7,26,2,1613965,2,40,1616401,16,1310721, +2,11,26,1613837,1310721,2,7,26,2,26,2,1310721,2,5,26,2, +1613967,12,10,3,6,10,4,8,1310721,2,11,26,2,9,28,1, +6,1,10,28,34,63,38,3,26,1616061,16,3,1616117,14,1310721,2, +11,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,1616143,16,1310721,2,15,26, +3,10,3,6,10,4,8,1310721,2,11,26,2,5,28,1,6, +1,10,28,34,63,38,3,26,1616187,16,3,1616243,14,1310721,2,11, +26,2,13,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1616269,16,1310721,2,17,26,1, +10,3,6,10,4,8,1310721,2,9,26,2,1613837,1310721,2,7,26, +2,26,2,1310721,2,5,26,2,1615141,12,1,6,1,10,28,34, +63,38,3,26,1616363,16,1310721,2,19,26,1310721,2,7,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,1615947,14,1469953,1310721,2,5,26,2,26,1310721, +2,13,26,2,10,3,6,10,4,8,1470977,1310721,2,5,26,2, +26,1310721,2,9,26,2,1310721,2,5,26,2,1614117,12,10,3,6, +10,4,8,1468929,1310721,2,5,26,2,26,1310721,2,9,26,2,1310721, +2,5,26,2,1614229,12,10,3,6,10,4,8,1310721,2,19,26, +2,1,40,1616743,16,1310721,2,13,26,2,1612037,12,1616739,16,1310721,2, +7,26,1,10,3,6,10,4,8,1310721,2,7,26,2,1613965,2, +40,1616739,16,1613837,1310721,2,7,26,2,26,2,1310721,2,5,26,2, +1613967,12,9,28,1,6,1,10,28,34,63,38,3,26,1616701,16, +1469953,1310721,2,5,26,2,26,9,10,3,6,10,4,8,1310721,2, +7,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1616595, +14,1617185,14,1310721,2,15,26,2,1616793,16,1310721,2,17,26,2,1, +6,1,10,28,34,63,38,1,10,28,1616795,14,1,1616831,16,1469953, +1310721,2,5,26,2,26,9,10,3,6,10,4,8,1617185,14,1587499, +2,1616889,16,1588225,2,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1616891,14,1,1616945,16,1587637, +2,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1616947,14,1,1617185,16,1588227,12,8,1466881,1310721, +2,5,26,2,26,2,1573495,12,8,1616989,14,58,32,0,1616983,1573495, +12,8,1310721,2,3,26,2,1573495,12,8,1617061,14,32,40,111,110, +101,32,112,97,116,104,32,108,101,97,118,101,115,32,105,116, +32,0,1617017,1573495,12,8,1310721,2,13,26,2,1612999,12,1573495,12,8, +1617115,14,44,32,97,110,111,116,104,101,114,32,0,1617093,1573495,12, +8,1613837,1310721,2,19,26,2,26,2,1310721,2,5,26,2,1613967,12, +1612999,12,1573495,12,8,1617171,14,41,0,1617167,1573495,12,8,1588371,12,8, +1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1615759,14,1,1617231,14,1,1310721,2,21,26,1310721,4,18,1310721,2, +13,28,1310721,4,1310721,2,1835009,40,1617279,16,1966081,1310721,4,1579223,12,1310721, +2,5,26,4,1310721,2,3,26,4,1310721,2,4,1587493,2,1310721,2, +7,26,4,1,1310721,2,9,26,4,1587499,2,1,6,1,10,28, +34,63,38,3,26,1617365,16,1,1617725,14,1310721,2,7,26,2,1310721, +2,3,26,2,40,1617709,16,1310721,2,11,26,1310721,2,2,1310721,2, +7,26,2,1613967,12,10,3,6,10,4,8,1469953,1310721,2,7,26, +2,26,2,9,28,1,6,1,10,28,34,63,38,3,26,1617601, +16,1310721,2,11,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1617519,16,3,1617575,14,1310721,2,11,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,1,6,1,10,28,34,63,38,1,10,28,1617603,14, +1,1617671,16,1310721,2,9,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1310721,2,5,26,2,1617671,16,1310721,2,7,26,2, +1609563,12,8,1310721,2,7,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1617365,14,1310721,2,9,26,2,1617725,14,1,1310721,2, +13,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1617773, +16,1966081,1310721,4,1579223,12,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,1587499,2,1, +6,1,10,28,34,63,38,3,26,1617885,16,3,1617931,14,1587503,2, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1617941,16,1,1619307,14,1310721,2,7,26,2,1587491, +2,10,40,1617987,16,1310721,2,7,26,1587491,2,10,3,6,10,4, +8,1310721,2,5,26,2,1310721,2,7,26,2,40,1619299,16,1310721,2, +9,26,1469953,1310721,2,5,26,2,26,2,10,3,6,10,4,8, +1310721,2,9,26,2,1612037,12,1618121,16,1310721,2,3,26,2,1310721,2, +5,26,2,1613967,12,1612037,12,1,6,1,10,28,34,63,38,1, +10,28,1618123,14,1,1618211,16,1310721,2,3,26,2,1310721,2,5,26, +2,1613967,12,9,28,1,6,1,10,28,34,63,38,3,26,1618207, +16,1469953,1310721,2,5,26,2,26,9,10,3,6,10,4,8,1619261, +14,1310721,2,9,26,2,1310721,2,3,26,2,1310721,2,5,26,2, +1613967,12,28,1,6,1,10,28,34,63,38,1,10,28,1618279,16, +3,1618365,14,1468929,1310721,2,5,26,2,26,2,1310721,2,3,26,2, +1310721,2,5,26,2,1614229,12,28,1,6,1,10,28,34,63,38, +1,10,28,1,6,1,10,28,34,63,38,1,10,28,1618375,16, +3,1618527,14,1310721,2,9,26,2,11,28,1,6,1,10,28,34, +63,38,3,26,1618503,16,1470977,1310721,2,5,26,2,26,2,1310721,2, +3,26,2,1310721,2,5,26,2,1614117,12,28,1,6,1,10,28, +34,63,38,1,10,28,1,6,1,10,28,34,63,38,1,10, +28,1618505,14,1,1,6,1,10,28,34,63,38,1,10,28,1619261, +16,1310721,2,9,26,2,9,28,1,6,1,10,28,34,63,38, +3,26,1618575,16,3,1618631,14,1310721,2,9,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,1618865,16,1310721,2,5,26,2,1618853,14,105,115,32,103, +105,118,101,110,32,97,119,97,121,32,105,110,115,105,100,101, +32,97,32,108,111,111,112,32,116,104,97,116,32,99,111,109, +101,115,32,98,97,99,107,32,97,114,111,117,110,100,32,116, +111,32,105,116,59,32,103,105,118,101,32,105,116,32,97,119, +97,121,32,111,110,32,97,32,112,97,116,104,32,116,104,97, +116,32,108,101,97,118,101,115,32,116,104,101,32,108,111,111, +112,0,1618649,1589603,12,8,1619261,14,1588225,2,1,6,1,10,28,34, +63,38,3,26,1618943,16,1587637,2,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1618945,14,1, +1619261,16,1588227,12,8,1466881,1310721,2,5,26,2,26,2,1573495,12,8, +1619155,14,58,32,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,32,40,105,116,32,119,101, +110,116,32,102,114,111,109,32,0,1618981,1573495,12,8,1310721,2,3, +26,2,1310721,2,5,26,2,1613967,12,1612999,12,1573495,12,8,1619211,14, +32,116,111,32,0,1619201,1573495,12,8,1310721,2,9,26,2,1612999,12, +1573495,12,8,1619247,14,41,0,1619243,1573495,12,8,1588371,12,8,1310721,2, +5,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1617987, +14,1,1619307,14,1,1310721,2,11,26,1310721,4,18,1310721,2,19,28, +1310721,4,1310721,2,1835009,40,1619355,16,1966081,1310721,4,1579223,12,1310721,2,11, +26,4,1310721,2,9,26,4,1310721,2,7,26,4,1310721,2,5,26, +4,1310721,2,3,26,4,1310721,2,4,1310721,2,13,26,1610967,12,10, +3,6,10,4,8,1613965,1,10,3,6,10,4,8,1310721,2,3, +26,2,1619481,16,1507841,1310721,2,2,26,1614933,12,8,1310721,2,7,26, +2,1619515,16,1507841,1310721,2,13,26,2,26,1614933,12,8,1310721,2,9, +26,2,1310721,2,11,26,2,1615661,12,8,1310721,2,7,26,2,1619587, +16,1507841,1310721,2,13,26,2,26,1310721,2,9,26,2,3,1617245,12, +8,1310721,2,15,26,1,10,3,6,10,4,8,1310721,2,3,26, +2,1619669,16,1310721,2,15,26,1507841,1310721,2,2,26,1310721,2,9,26, +2,1,1617245,12,10,3,6,10,4,8,1310721,2,15,26,2,1619787, +16,1310721,2,17,26,1592669,12,10,3,6,10,4,8,15,1592369,12, +8,1310721,2,5,26,2,1587483,2,1592451,12,8,1507841,1310721,2,2,26, +1310721,2,9,26,2,3,1617245,12,8,1310721,2,17,26,2,1587483,2, +1592451,12,8,1619807,14,1310721,2,5,26,2,1587483,2,1592451,12,8,1587503, +1310721,2,3,26,2,1619829,16,3,1619861,14,1310721,2,7,26,2,1, +6,1,10,28,34,63,38,1,10,28,10,3,6,10,4,8, +1,1619881,14,1,1310721,2,19,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,1835009,40,1619929,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1587499,2,1,6,1,10,28,34,63,38,3,26, +1619983,16,1310721,2,2,1620953,14,1310721,2,2,5,40,1620099,16,1620081,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,1620001,1589485,12,8,1310721,2,2,1620953, +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,1620363,16,1310721,2,5,26,2,1620351,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,1620245, +1589603,12,8,1620941,14,1310721,2,7,26,2,13,28,1,6,1,10, +28,34,63,38,3,26,1620491,16,1310721,2,5,26,2,1620479,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,1620415, +1589603,12,8,1620941,14,1310721,2,7,26,2,1,28,1,6,1,10, +28,34,63,38,3,26,1620599,16,1310721,2,5,26,2,1620587,14,105, +115,110,39,116,32,97,110,32,111,119,110,101,100,32,111,98, +106,101,99,116,0,1620543,1589603,12,8,1620941,14,1310721,2,7,26,2, +9,28,1,6,1,10,28,34,63,38,3,26,1620721,16,1310721,2, +5,26,2,1620709,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,1620651,1589603,12,8,1620941,14,1310721,2,3,26,2,3,28,1, +6,1,10,28,34,63,38,3,26,1620821,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,1620823,14,1,1620905,16,1310721,2,5, +26,2,1620893,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,1620841,1589603, +12,8,1620941,14,1469953,1310721,2,5,26,2,26,1310721,2,3,26,2, +10,3,6,10,4,8,1310721,2,2,1620953,14,1,1310721,2,9,26, +1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1621001,16,1966081, +1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587499,2,1,6, +1,10,28,34,63,38,3,26,1621051,16,1,1622485,14,1310721,2,2, +3,28,1,6,1,10,28,34,63,38,3,26,1621295,16,1310721,2, +3,26,2,5,28,1,6,1,10,28,34,63,38,1,10,28, +1621289,16,1621281,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, +1621129,1589485,12,8,1,1622485,14,1310721,2,2,5,40,1621315,16,3,1621371, +14,1310721,2,2,5,28,1608697,12,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1621381,16,1, +1622485,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,1608559,12,26,2,9,28,1, +6,1,10,28,34,63,38,3,26,1621581,16,1310721,2,5,26,2, +1621567,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,1621509, +1589603,12,8,1,1622485,14,1310721,2,3,26,2,3,10,40,3,36, +1621809,16,1310721,2,7,26,2,7,28,1,6,1,10,28,34,63, +38,3,26,1621787,16,1310721,2,5,26,2,1621773,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,1621657,1589603,12,8,1,1622485,14,1310721,2,5, +26,2,1608795,12,8,1,1622485,14,1310721,2,7,26,2,7,28,1, +6,1,10,28,34,63,38,3,26,1621909,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,1622485,14,1310721,2,7,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1622037,16,1310721,2,5, +26,2,1622025,14,105,115,32,109,59,32,119,114,105,116,101,32, +100,42,120,32,116,111,32,103,105,118,101,32,105,116,32,97, +119,97,121,0,1621961,1589603,12,8,1622477,14,1310721,2,7,26,2,5, +28,1,6,1,10,28,34,63,38,3,26,1622213,16,1310721,2,5, +26,2,1622201,14,105,115,32,117,59,32,119,114,105,116,101,32, +100,42,120,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,1622089,1589603,12,8, +1622477,14,1310721,2,7,26,2,11,28,1,6,1,10,28,34,63, +38,3,26,1622383,16,1310721,2,5,26,2,1622371,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,1622265,1589603,12,8,1622477,14,1310721,2,5,26,2,1622469,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,1622397,1589603,12,8,1,1622485,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1622533,16,1966081,1310721,4, +1579223,12,1310721,2,4,1467905,1310721,2,2,26,2,1593203,12,8,3,1592369, +12,8,1556993,1310721,2,2,26,2,1,26,2,23,28,1,6,1, +10,28,34,63,38,3,26,1622635,16,5,1592283,12,8,27,1592369,12, +8,3,1592369,12,8,1587607,2,1593049,12,8,1,1622653,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1622701, +16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4, +1310721,2,4,1587499,2,1,6,1,10,28,34,63,38,3,26,1622761, +16,1,1626207,14,1310721,2,9,26,3,1,10,28,10,3,6,10, +4,8,1310721,2,5,26,2,5,40,3,36,1622855,16,1310721,2,5, +26,2,5,28,1608697,12,1,6,1,10,28,34,63,38,1,10, +28,1622857,14,1,1622895,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, +1622987,16,1469953,1310721,2,9,26,2,1608559,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,1622989,14,1,1623079,16,1310721,2,9,26,2,1623065,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,1623007,1589603,12,8, +1,1626207,14,1310721,2,2,3,28,1,6,1,10,28,34,63,38, +3,26,1624551,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,1623229,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,1623231,14,1,1623435, +16,1310721,2,7,26,2,1612037,12,1,6,1,10,28,34,63,38, +3,26,1623401,16,1310721,2,3,26,2,1623389,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,1623287,1589603, +12,8,1623429,14,1469953,1310721,2,3,26,2,26,1,10,3,6,10, +4,8,1,1626207,14,1310721,2,7,26,2,1612037,12,1,6,1,10, +28,34,63,38,3,26,1623603,16,1310721,2,3,26,2,1623589,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,1623487,1589603,12,8,1,1626207,14,1310721,2,5,26,2,3,28, +1,6,1,10,28,34,63,38,3,26,1623801,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,1558017,1310721,2,3,26,2,26,2,31,32, +1623795,16,1469953,1310721,2,3,26,2,26,1558017,1310721,2,3,26,2,26, +2,31,32,10,3,6,10,4,8,1,1626207,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,1623959, +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,1623961,14,1,1624181,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,1558017,1310721,2,3,26,2,26,2,31,32,1624175,16, +1469953,1310721,2,3,26,2,26,1558017,1310721,2,3,26,2,26,2,31, +32,10,3,6,10,4,8,1,1626207,14,1310721,2,13,26,2,5, +28,1,6,1,10,28,34,63,38,3,26,1624401,16,1310721,2,9, +26,2,1624389,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,1624233,1589603,12,8,1624545,14,1310721,2,9,26,2,1624537,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,1624415,1589603,12,8, +1,1626207,14,1310721,2,2,7,28,1,6,1,10,28,34,63,38, +3,26,1625875,16,1310721,2,11,26,1310721,2,3,26,2,1608559,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,1608795,12,8,1310721, +2,5,26,2,3,28,1,6,1,10,28,34,63,38,3,26, +1624731,16,1310721,2,3,26,2,1622499,12,8,1,1626207,14,1310721,2,9, +26,2,1,40,1624755,16,1,1626207,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,1624917,16,1310721,2, +9,26,2,1624905,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,1624843,1589603,12,8,1625869,14,1310721,2,13,26,2,13, +28,1,6,1,10,28,34,63,38,3,26,1625045,16,1310721,2,9, +26,2,1625033,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,1624969,1589603,12,8,1625869,14,1310721,2,7,26,2,13, +28,1,6,1,10,28,34,63,38,3,26,1625371,16,1310721,2,13, +26,2,5,28,1,6,1,10,28,34,63,38,3,26,1625295,16, +1310721,2,9,26,2,1625283,14,105,115,32,117,59,32,105,116,32, +104,97,115,32,116,111,32,108,101,97,118,101,32,116,104,114, +111,117,103,104,32,116,104,101,32,98,108,111,99,107,32,97, +98,111,118,101,44,32,110,111,116,32,105,110,116,111,32,97, +32,98,111,114,114,111,119,101,100,32,111,98,106,101,99,116, +0,1625135,1589603,12,8,1625367,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,1622499,12,8,1625869,14,1310721,2,13, +26,2,1310721,2,7,26,2,28,1,6,1,10,28,34,63,38, +1,10,28,1625577,16,1310721,2,9,26,2,1625565,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,1625433,1589603, +12,8,1625869,14,1468929,1310721,2,9,26,2,26,2,1468929,1310721,2,11, +26,2,26,2,40,1625761,16,1310721,2,9,26,2,1625749,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,1625629,1589603,12,8,1625869,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,1622499,12,8,1,1626207,14,1310721,2,9,26,2,1,40, +3,36,1626199,16,1469953,1310721,2,9,26,2,26,2,7,28,1,6, +1,10,28,34,63,38,3,26,1626001,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,1626199,14,1310721,2,9,26,2,1626191,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,1626015,1589603,12,8,1,1626207,14,1,1310721, +2,15,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40, +1626255,16,1966081,1310721,4,1579223,12,1310721,2,4,1587499,2,1,6,1,10, +28,34,63,38,3,26,1626295,16,1,1627221,14,1310721,2,3,26,3, +1,10,28,10,3,6,10,4,8,1310721,2,2,5,40,3,36, +1626381,16,1310721,2,2,5,28,1608697,12,1,6,1,10,28,34,63, +38,1,10,28,1626383,14,1,1626417,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,1626509,16,1469953,1310721,2,3,26,2,1608559,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,1626511,14,1,1626601,16,1310721,2,3,26,2,1626587,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,1626529,1589603,12, +8,1,1627221,14,1587501,2,1626857,16,1310721,2,3,26,2,1,40,3, +36,1626851,16,1469953,1310721,2,3,26,2,26,2,5,28,1,6,1, +10,28,34,63,38,3,26,1626735,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,1626851,14,1310721,2,3,26,2,1626843,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,117,42,120,39,0,1626749,1589603,12, +8,1,1627221,14,1310721,2,2,3,28,1,6,1,10,28,34,63, +38,3,26,1627021,16,1627009,14,114,101,116,117,114,110,115,32,97, +32,110,101,119,32,111,98,106,101,99,116,59,32,103,105,118, +101,32,116,104,101,32,102,117,110,99,116,105,111,110,32,97, +32,46,117,32,114,101,116,117,114,110,32,116,121,112,101,0, +1626895,1589485,12,8,1627213,14,1310721,2,3,26,2,1,40,3,36,1627213, +16,1310721,2,3,26,2,1627205,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,104,111,115,101,32,114,101,116, +117,114,110,32,116,121,112,101,32,105,115,110,39,116,32,46, +117,0,1627057,1589603,12,8,1,1627221,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1627269,16,1966081,1310721,4, +1579223,12,1310721,2,4,1587499,2,1,6,1,10,28,34,63,38,3, +26,1627309,16,1,1627937,14,1310721,2,2,3,28,1,6,1,10,28, +34,63,38,3,26,1627349,16,3,1627937,14,1310721,2,2,5,40,1627369, +16,3,1627425,14,1310721,2,2,5,28,1608697,12,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1627435,16,1,1627937,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,1627577,16,1468929,1310721,2,3,26,2, +26,2,1587495,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1627579,14,1,1627645,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,1627937,14,1469953,1310721, +2,3,26,2,26,2,5,28,1,6,1,10,28,34,63,38, +3,26,1627809,16,1310721,2,3,26,2,1627797,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,1627703,1589603,12,8,1627929,14, +1310721,2,3,26,2,1627921,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,1627823,1589603,12,8,1,1627937,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1627985,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,3,28, +1,6,1,10,28,34,63,38,3,26,1628141,16,1628129,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, +1628029,1589485,12,8,1628175,14,1310721,2,2,5,40,3,36,1628175,16,1310721, +2,2,5,28,1608795,12,8,1,1628183,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1628231,16,1966081,1310721, +4,1579223,12,1310721,2,4,1587617,2,1310721,2,3,26,4,1587617,2,1310721, +2,2,26,1310721,40,3,36,1628331,16,1628323,14,116,104,101,32,116, +121,112,101,32,97,114,101,97,32,105,115,32,102,117,108,108, +0,1628279,1588719,12,8,1587617,1587617,2,1310721,2,2,26,10,3,6,10, +4,8,1310721,2,3,26,2,1,1310721,2,2,1574703,12,8,1310721,2, +3,26,2,1628397,14,1,1310721,2,5,26,1310721,4,18,1310721,2,11, +28,1310721,4,1310721,2,1835009,40,1628445,16,1966081,1310721,4,1579223,12,1310721,2, +7,26,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4, +15,1310721,2,7,26,2,26,1628197,12,1310721,2,9,26,4,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,1310721,2,5,26,2,10,3,6,10, +4,8,1587619,2,2049,40,3,36,1628671,16,1628663,14,116,111,111,32, +109,97,110,121,32,116,121,112,101,115,0,1628633,1588719,12,8,1277953, +1587619,2,26,1310721,2,9,26,2,10,3,6,10,4,8,1587619,1, +6,2,1,6,3,26,5,6,4,10,8,8,1310721,2,9,26, +2,1628745,14,1,1310721,2,11,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1628793,16,1966081,1310721,4,1579223,12,1310721,2,4,1, +1310721,2,3,26,4,1310721,2,3,26,2,1587619,2,40,1629039,16,1310721, +2,5,26,1277953,1310721,2,3,26,2,26,2,10,3,6,10,4, +8,1310721,2,5,26,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1628981,16,1310721,2,5,26,2,9,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,1628983,14,1,1629001,16,1310721,2,5, +26,2,1629119,14,1310721,2,3,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1628811,14,1310721,2,5,26,11,3,1,1,1628411, +12,10,3,6,10,4,8,1310721,2,5,26,2,9,26,1310721,2, +2,10,3,6,10,4,8,1310721,2,5,26,2,1629119,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40, +1629167,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1, +1310721,2,5,26,4,1310721,2,5,26,2,1587619,2,40,1629503,16,1310721, +2,7,26,1277953,1310721,2,5,26,2,26,2,10,3,6,10,4, +8,1310721,2,7,26,2,1,26,2,13,28,1,6,1,10,28, +34,63,38,3,26,1629365,16,1310721,2,7,26,2,9,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,1629367,14,1,1629445,16,1310721,2,7, +26,2,7,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, +1629447,14,1,1629465,16,1310721,2,7,26,2,1629639,14,1310721,2,5,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1629195,14,1310721, +2,7,26,13,1310721,2,3,26,2,1310721,2,2,1633401,12,30,1, +1,1628411,12,10,3,6,10,4,8,1310721,2,7,26,2,9,26, +1310721,2,2,10,3,6,10,4,8,1310721,2,7,26,2,7,26, +1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,7,26,2, +1629639,14,1,1310721,2,9,26,1310721,4,18,1310721,2,15,28,1310721,4, +1310721,2,1835009,40,1629687,16,1966081,1310721,4,1579223,12,1310721,2,7,26,4, +1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2, +9,26,4,1310721,2,9,26,2,1587619,2,40,1630361,16,1310721,2,13, +26,1277953,1310721,2,9,26,2,26,2,10,3,6,10,4,8,1310721, +2,13,26,2,1,26,2,15,28,1,6,1,10,28,34,63, +38,3,26,1629905,16,1310721,2,13,26,2,9,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,1629907,14,1,1629985,16,1310721,2,13,26,2, +7,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,1629987,14, +1,1630065,16,1310721,2,13,26,2,11,26,2,1310721,2,7,26,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1630067,14,1,1630323,16,1310721,2,11,26,1, +10,3,6,10,4,8,1310721,2,11,26,2,1310721,2,3,26,2, +40,1630219,16,1310721,2,13,26,2,15,1310721,2,11,26,2,26,26, +2,1310721,2,5,26,2,1310721,2,11,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,1630221,14,1,1630263,16,1310721,2,11,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1630093,14,1310721,2,11,26,2, +1310721,2,3,26,2,28,1,6,1,10,28,34,63,38,3,26, +1630323,16,1310721,2,13,26,2,1630561,14,1310721,2,9,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1629735,14,1310721,2,13,26, +15,3,1,1310721,2,3,26,2,1628411,12,10,3,6,10,4,8, +1310721,2,13,26,2,9,26,1310721,2,2,10,3,6,10,4,8, +1310721,2,13,26,2,7,26,1310721,2,3,26,2,10,3,6,10, +4,8,1310721,2,13,26,2,11,26,1310721,2,7,26,2,10,3, +6,10,4,8,1310721,2,13,26,2,15,26,1310721,2,5,26,2, +1310721,2,3,26,2,1574491,12,8,1310721,2,13,26,2,1630561,14,1, +1310721,2,15,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009, +40,1630609,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4, +1,1310721,2,5,26,4,1310721,2,5,26,2,1587619,2,40,1630945,16, +1310721,2,7,26,1277953,1310721,2,5,26,2,26,2,10,3,6,10, +4,8,1310721,2,7,26,2,1,26,2,23,28,1,6,1,10, +28,34,63,38,3,26,1630807,16,1310721,2,7,26,2,9,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,1630809,14,1,1630887,16,1310721,2, +7,26,2,7,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,1630889,14,1,1630907,16,1310721,2,7,26,2,1631061,14,1310721,2,5, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1630637,14, +1310721,2,7,26,23,3,1,1,1628411,12,10,3,6,10,4,8, +1310721,2,7,26,2,9,26,1310721,2,2,10,3,6,10,4,8, +1310721,2,7,26,2,7,26,1310721,2,3,26,2,10,3,6,10, +4,8,1310721,2,7,26,2,1631061,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1631109,16,1966081,1310721,4, +1579223,12,1310721,2,3,26,4,1310721,2,4,1,1310721,2,5,26,4, +1310721,2,5,26,2,1587619,2,40,1631365,16,1310721,2,7,26,1277953,1310721, +2,5,26,2,26,2,10,3,6,10,4,8,1310721,2,7,26, +2,1,26,2,19,28,1,6,1,10,28,34,63,38,3,26, +1631307,16,1310721,2,7,26,2,7,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,1631309,14,1,1631327,16,1310721,2,7,26,2,1631453,14,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1631137,14,1310721,2,7,26,19,3,1310721,2,3,26,2,1,1628411,12, +10,3,6,10,4,8,1310721,2,7,26,2,7,26,1310721,2,2, +10,3,6,10,4,8,1310721,2,7,26,2,1631453,14,1,1310721,2, +9,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1631501, +16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4, +1310721,2,4,1,1310721,2,7,26,4,1310721,2,7,26,2,1587619,2, +40,1632041,16,1310721,2,11,26,1277953,1310721,2,7,26,2,26,2,10, +3,6,10,4,8,1310721,2,11,26,2,1,26,2,17,28,1, +6,1,10,28,34,63,38,3,26,1631709,16,1310721,2,11,26,2, +11,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,1631711,14,1,1632003, +16,1310721,2,13,26,1310721,2,11,26,2,13,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,5,26,2,40,1631899,16,1310721,2,13,26,2, +3,1310721,2,9,26,2,26,26,2,1310721,2,3,26,2,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,1631901,14,1,1631943,16, +1310721,2,9,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1631773,14,1310721,2,9,26,2,1310721,2,5,26,2,28,1,6, +1,10,28,34,63,38,3,26,1632003,16,1310721,2,11,26,2,1632315, +14,1310721,2,7,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1631539,14,1310721,2,13,26,1310721,2,5,26,2,3,26,1628197, +12,10,3,6,10,4,8,1310721,2,13,26,2,1,26,1310721,2, +5,26,2,10,3,6,10,4,8,1310721,2,13,26,2,3,26, +1310721,2,3,26,2,1310721,2,5,26,2,1574491,12,8,1310721,2,11, +26,17,1,1310721,2,2,5,26,2,1,1628411,12,10,3,6,10, +4,8,1310721,2,11,26,2,7,26,3,1,10,28,10,3,6, +10,4,8,1310721,2,11,26,2,11,26,1310721,2,2,10,3,6, +10,4,8,1310721,2,11,26,2,13,26,1310721,2,13,26,2,10, +3,6,10,4,8,1310721,2,11,26,2,1632315,14,1,1310721,2,15, +26,1310721,4,18,1310721,2,33,28,1310721,4,1310721,2,1835009,40,1632363,16, +1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2,13,26,4,1310721,2, +2,1,26,2,17,28,1,6,1,10,28,34,63,38,1,10, +28,1632429,16,3,1632471,14,1310721,2,2,7,26,2,1,40,3,36, +1,6,1,10,28,34,63,38,1,10,28,1632485,16,1310721,2,2, +1633387,14,1310721,2,2,7,26,2,5,1,10,28,28,1,6,1, +10,28,34,63,38,3,26,1632655,16,1632613,14,97,32,115,116,114, +117,99,116,32,99,97,110,39,116,32,99,111,110,116,97,105, +110,32,105,116,115,101,108,102,32,98,121,32,118,97,108,117, +101,0,1632535,1588813,12,8,1310721,2,2,7,26,1,10,3,6,10, +4,8,1310721,2,2,1633387,14,1310721,2,2,7,26,5,1,10,28, +10,3,6,10,4,8,1310721,2,3,26,1310721,2,2,11,26,2, +10,3,6,10,4,8,1310721,2,7,26,1310721,2,3,26,2,11, +26,2,10,3,6,10,4,8,1310721,2,5,26,1310721,2,3,26, +2,9,26,2,10,3,6,10,4,8,1310721,2,17,26,1,17, +1574703,12,8,1310721,2,17,26,1310721,2,2,13,26,2,3,26,1310721, +2,2,13,26,2,1,26,2,1574491,12,8,1310721,2,11,26,1310721, +2,7,26,2,7,30,3,26,1628197,12,10,3,6,10,4,8, +1310721,2,9,26,1,10,3,6,10,4,8,1310721,2,9,26,2, +1310721,2,7,26,2,40,1633279,16,1310721,2,15,26,1310721,2,5,26, +2,1310721,2,9,26,2,1310721,2,9,26,2,26,3,26,26,2, +1310721,2,17,26,1633573,12,10,3,6,10,4,8,1310721,2,11,26, +2,1310721,2,9,26,2,7,30,26,1310721,2,5,26,2,1310721,2, +9,26,2,1310721,2,9,26,2,26,26,2,10,3,6,10,4, +8,1310721,2,11,26,2,1310721,2,9,26,2,7,30,3,26,26, +1310721,2,15,26,2,10,3,6,10,4,8,1310721,2,11,26,2, +1310721,2,9,26,2,7,30,5,26,26,1310721,2,13,26,2,10, +3,6,10,4,8,1310721,2,13,26,1310721,2,13,26,2,1310721,2, +15,26,2,1633401,12,26,10,3,6,10,4,8,1310721,2,9,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1632919,14,1310721, +2,2,9,26,1310721,2,11,26,2,10,3,6,10,4,8,1310721, +2,2,3,26,1310721,2,13,26,2,10,3,6,10,4,8,1310721, +2,2,7,26,1310721,2,7,26,2,10,3,6,10,4,8,1310721, +2,2,1633387,14,1,1310721,2,33,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1633435,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,1,26,2,17,28,1,6,1,10,28,34,63,38, +3,26,1633523,16,1310721,2,2,7,26,2,1,40,1,6,1,10, +28,34,63,38,1,10,28,1633525,14,1,1633541,16,1310721,2,2,1632329, +12,8,1310721,2,2,3,26,2,1633559,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,61,28,1310721,4,1310721,2,1835009,40,1633607,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1,26, +2,1310721,2,5,26,4,1310721,2,5,26,2,19,28,1,6,1, +10,28,34,63,38,3,26,1633751,16,1310721,2,3,26,2,1310721,2, +2,7,26,2,26,2,1633743,16,1310721,2,3,26,2,1310721,2,2, +7,26,2,26,2,1634557,14,1587621,2,1634557,14,1310721,2,5,26,2, +11,28,1,6,1,10,28,34,63,38,3,26,1633823,16,1310721,2, +2,9,26,2,1310721,2,3,26,2,1633573,12,1628759,12,1634557,14,1310721, +2,5,26,2,13,28,1,6,1,10,28,34,63,38,3,26, +1633907,16,1310721,2,2,9,26,2,1310721,2,3,26,2,1633573,12,1310721, +2,2,7,26,2,1629133,12,1634557,14,1310721,2,5,26,2,15,28, +1,6,1,10,28,34,63,38,3,26,1634197,16,1310721,2,9,26, +1310721,2,2,7,26,2,10,3,6,10,4,8,1310721,2,7,26, +1,10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,9,26, +2,40,1634133,16,1310721,2,11,26,1310721,2,7,26,2,26,1310721,2, +2,15,1310721,2,7,26,2,26,26,2,1310721,2,3,26,2,1633573, +12,10,3,6,10,4,8,1310721,2,7,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1633999,14,1310721,2,2,9,26,2, +1310721,2,3,26,2,1633573,12,1310721,2,9,26,2,1310721,2,11,26, +1310721,2,2,11,26,2,1629653,12,1634557,14,1310721,2,5,26,2,17, +28,1,6,1,10,28,34,63,38,3,26,1634273,16,1310721,2,2, +11,26,2,1,6,1,10,28,34,63,38,1,10,28,1634275,14, +1,1634545,16,1310721,2,59,26,1310721,2,2,13,26,2,10,3,6, +10,4,8,1310721,2,9,26,1310721,2,59,26,2,1,26,2,10, +3,6,10,4,8,1310721,2,7,26,1,10,3,6,10,4,8, +1310721,2,7,26,2,1310721,2,9,26,2,40,1634507,16,1310721,2,11, +26,1310721,2,7,26,2,26,1310721,2,59,26,2,3,1310721,2,7, +26,2,26,26,2,1310721,2,3,26,2,1633573,12,10,3,6,10, +4,8,1310721,2,7,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1634369,14,1310721,2,2,11,26,2,1310721,2,11,26,1310721, +2,9,26,2,1631467,12,1634557,14,1310721,2,2,1634557,14,1,1310721,2, +61,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1634605, +16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1634657,16,3,1634715,14, +1310721,2,2,1,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,1634725,16,3, +1634783,14,1310721,2,2,1,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,1634789, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1634837,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2, +1,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1634889, +16,3,1634947,14,1310721,2,2,1,26,2,17,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1634953,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1635001,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,1,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1635053,16,3,1635111,14,1310721,2,2,1,26,2,13,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1635117,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1635165,16,1966081,1310721,4,1579223,12,1310721,2, +4,1310721,2,2,1,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1635231,16,1310721,2,2,9,26,2,1628759,12,1635243,14,1310721, +2,2,1635243,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1635291,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,1,26,2,11,28,1,6,1,10,28,34,63,38, +3,26,1635343,16,3,1635401,14,1310721,2,2,1,26,2,13,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1635421,16,1310721,2,2,9,26,2,1635431,14,1587621,2, +1635431,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1635479,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4, +1310721,2,4,1310721,2,2,1310721,2,3,26,2,28,1,6,1,10, +28,34,63,38,3,26,1635543,16,3,1635597,14,1310721,2,2,1587621,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1635607,16,3,1635665,14,1310721,2,3,26,2, +1587621,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1635675,16,3,1636747,14,1310721,2,2, +1634571,12,1635729,16,1310721,2,3,26,2,1634571,12,1,6,1,10,28, +34,63,38,1,10,28,1635731,14,1,1635741,16,3,1636747,14,1310721,2, +3,26,1310721,2,3,26,2,1635131,12,10,3,6,10,4,8,1310721, +2,2,1,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1635881,16,1310721,2,3,26,2,1,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,1635883,14,1,1636207,16,1310721,2,2,9,26,2,1587621,2,28, +1,6,1,10,28,34,63,38,3,26,1635935,16,3,1635999,14,1310721, +2,3,26,2,9,26,2,1587621,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1636009, +16,3,1636069,14,1310721,2,2,9,26,2,1587629,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1636079,16,3,1636143,14,1310721,2,3,26,2,9,26,2,1587629, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1636153,16,3,1636747,14,1310721,2,2,9, +26,2,1310721,2,3,26,2,9,26,2,28,1,6,1,10,28, +34,63,38,3,26,1636747,14,1310721,2,2,1,26,2,11,28,1, +6,1,10,28,34,63,38,3,26,1636253,16,3,1636311,14,1310721,2, +2,1,26,2,15,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1636321,16,3,1636379,14, +1310721,2,2,1,26,2,23,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1636413,16,1587635, +2,1,6,1,10,28,34,63,38,1,10,28,1636415,14,1,1636425, +16,3,1636747,14,1310721,2,2,1,26,2,23,28,1,6,1,10, +28,34,63,38,3,26,1636531,16,1310721,2,3,26,2,1,26,2, +23,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1636533,14,1,1636613,16,1310721,2,2,9, +26,2,1310721,2,3,26,2,9,26,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1636615,14,1,1636703,16,1310721,2,2,7,26,2,1636641,16,3,1636699,14, +1310721,2,3,26,2,7,26,2,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1636747,14,1310721, +2,2,1310721,2,3,26,2,28,1,6,1,10,28,34,63,38, +3,26,1636747,14,1,1310721,2,5,26,1310721,4,18,1310721,2,15,28, +1310721,4,1310721,2,1835009,40,1636795,16,1966081,1310721,4,1579223,12,1310721,2,5, +26,4,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1,26,2, +19,28,1,6,1,10,28,34,63,38,3,26,1637033,16,1310721,2, +7,26,1310721,2,2,7,26,2,10,3,6,10,4,8,1310721,2, +5,26,2,1310721,2,7,26,2,26,2,1,6,1,10,28,34, +63,38,3,26,1636991,16,1310721,2,5,26,2,1310721,2,7,26,2, +26,1310721,2,3,26,2,10,3,6,10,4,8,3,1637837,14,1310721, +2,5,26,2,1310721,2,7,26,2,26,2,1310721,2,3,26,2, +1635445,12,1637837,14,1310721,2,3,26,1310721,2,3,26,2,1635131,12,10, +3,6,10,4,8,1310721,2,2,1,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1637173,16,1310721,2,3,26,2,1,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,1637175,14,1,1637277,16,1310721,2,3, +26,2,9,26,2,1587621,2,28,1,6,1,10,28,34,63,38, +3,26,1637231,16,3,1637837,14,1310721,2,2,9,26,2,1310721,2,3, +26,2,9,26,2,1310721,2,5,26,2,1636761,12,1637837,14,1310721,2, +2,1,26,2,17,28,1,6,1,10,28,34,63,38,3,26, +1637355,16,1310721,2,2,11,26,2,1,6,1,10,28,34,63,38, +1,10,28,1637357,14,1,1637427,16,1310721,2,3,26,2,1,26,2, +17,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1637429,14,1,1637509,16,1310721,2,3,26, +2,11,26,2,1310721,2,2,11,26,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1637511,14,1,1637811,16,1310721,2,11,26,1310721,2,2,13,26,2,10, +3,6,10,4,8,1310721,2,13,26,1310721,2,3,26,2,13,26, +2,10,3,6,10,4,8,1310721,2,9,26,1310721,2,11,26,2, +1,26,2,10,3,6,10,4,8,1310721,2,7,26,1,10,3, +6,10,4,8,1310721,2,7,26,2,1310721,2,9,26,2,40,1637805, +16,1310721,2,11,26,2,3,1310721,2,7,26,2,26,26,2,1310721, +2,13,26,2,3,1310721,2,7,26,2,26,26,2,1310721,2,5, +26,2,1636761,12,1,6,1,10,28,34,63,38,3,26,1637767,16, +1,1637837,14,1310721,2,7,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1637641,14,3,1637837,14,1310721,2,2,1310721,2,3,26, +2,1635445,12,1637837,14,1,1310721,2,15,26,1310721,4,18,1310721,2,9, +28,1310721,4,1310721,2,1835009,40,1637885,16,1966081,1310721,4,1579223,12,1310721,2, +4,1310721,2,2,1,26,2,1310721,2,3,26,4,1310721,2,3,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1637979,16,85, +1573255,12,8,1310721,2,2,9,26,2,1637851,12,1639093,14,1310721,2,3, +26,2,23,28,1,6,1,10,28,34,63,38,3,26,1638097,16, +1310721,2,2,7,26,2,1638059,16,1638051,14,102,105,120,101,100,32, +0,1638037,1573495,12,8,1638069,14,91,93,0,1638063,1573495,12,8,1310721,2, +2,9,26,2,1637851,12,1639093,14,1310721,2,3,26,2,13,28,1, +6,1,10,28,34,63,38,3,26,1638189,16,183,1573255,12,8,1310721, +2,2,7,26,2,1573657,12,8,187,1573255,12,8,1310721,2,2,9, +26,2,1637851,12,1639093,14,1310721,2,3,26,2,15,28,1,6,1, +10,28,34,63,38,3,26,1638743,16,1310721,2,2,9,26,2,1587621, +2,28,1,6,1,10,28,34,63,38,3,26,1638291,16,1638279,14, +102,110,0,1638273,1573495,12,8,1638309,14,1310721,2,2,9,26,2,1637851, +12,8,1310721,2,2,11,26,2,3,32,1638347,16,1638339,14,46,117, +0,1638333,1573495,12,8,81,1573255,12,8,1310721,2,5,26,1,10,3, +6,10,4,8,1310721,2,5,26,2,1310721,2,2,7,26,2,40, +1638729,16,1310721,2,5,26,2,1638437,16,1638429,14,44,32,0,1638423,1573495, +12,8,1310721,2,2,15,1310721,2,5,26,2,26,26,2,1637851,12, +8,1310721,2,5,26,2,25,40,1638555,16,1310721,2,2,1310721,2,5, +26,2,1654383,12,3,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1638557,14,1,1638579,16, +1638571,14,46,109,0,1638565,1573495,12,8,1310721,2,5,26,2,25,40, +1638667,16,1310721,2,2,1310721,2,5,26,2,1654383,12,5,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1638669,14,1,1638691,16,1638683,14,46,100,0,1638677,1573495,12, +8,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1638377,14,83,1573255,12,8,1,1639093,14,1310721,2,2,5,26, +2,1638781,16,1310721,2,2,5,26,2,1573495,12,8,1638797,14,1638789,14, +63,0,1638785,1573495,12,8,1310721,2,3,26,2,17,28,1,6,1, +10,28,34,63,38,3,26,1638873,16,1310721,2,2,11,26,2,1, +6,1,10,28,34,63,38,1,10,28,1638875,14,1,1639085,16,1310721, +2,7,26,1310721,2,2,13,26,2,10,3,6,10,4,8,121, +1573255,12,8,1310721,2,5,26,1,10,3,6,10,4,8,1310721,2, +5,26,2,1310721,2,7,26,2,1,26,2,40,1639077,16,1310721,2, +5,26,2,1639005,16,1638997,14,44,32,0,1638991,1573495,12,8,1310721,2, +7,26,2,3,1310721,2,5,26,2,26,26,2,1637851,12,8,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1638941,14,125,1573255,12,8,1,1639093,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1639141,16,1966081,1310721,4, +1579223,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1587631, +2,1,6,1,10,28,34,63,38,3,26,1639201,16,3,1639247,14, +1587503,2,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1639257,16,3,1639283,14,1587637,2,1,6, +1,10,28,34,63,38,1,10,28,1639293,16,3,1639319,14,1588225,2, +1,6,1,10,28,34,63,38,1,10,28,1639329,16,1,1639493,14, +1588227,12,8,1639365,14,116,121,112,101,32,101,114,114,111,114,58, +32,0,1639339,1573495,12,8,1310721,2,2,1573495,12,8,1639413,14,58,32, +101,120,112,101,99,116,101,100,32,0,1639389,1573495,12,8,1310721,2, +3,26,2,1637851,12,8,1639455,14,44,32,103,111,116,32,0,1639441, +1573495,12,8,1310721,2,5,26,2,1637851,12,8,1588371,12,8,1,1639493, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721, +2,1835009,40,1639541,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,1639583,16,3,1639629,14,1587631, +2,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1639639,16,3,1639685,14,1587503,2,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1639695,16,3,1639721,14,1587637,2,1,6,1,10,28,34,63, +38,1,10,28,1639731,16,3,1639757,14,1588225,2,1,6,1,10,28, +34,63,38,1,10,28,1639767,16,1,1639883,14,1588227,12,8,1639803,14, +116,121,112,101,32,101,114,114,111,114,58,32,0,1639777,1573495,12, +8,1310721,2,3,26,2,1573495,12,8,1639845,14,44,32,103,111,116, +32,0,1639831,1573495,12,8,1310721,2,5,26,2,1637851,12,8,1588371,12, +8,1,1639883,14,1,1310721,2,7,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1639931,16,1966081,1310721,4,1579223,12,1310721,2,4, +1587655,2,1310721,2,3,26,4,1310721,2,3,26,2,1640065,16,1310721,2, +3,26,1,6,2,1,6,-1,26,5,6,4,10,8,8,1587639, +1310721,2,3,26,2,26,2,1310721,2,2,28,1,6,1,10,28, +34,63,38,3,26,1640061,16,1310721,2,3,26,2,1640079,14,1639951,14, +3,1,10,28,1640079,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1640127,16,1966081,1310721,4,1579223,12,1310721, +2,4,1310721,2,2,1588185,2,28,1,6,1,10,28,34,63,38, +3,26,1640175,16,3,1640357,14,1310721,2,2,1639897,12,1,40,3,36, +1640203,16,3,1640357,14,1310721,2,2,1607893,12,1,40,3,36,1640231,16, +1,1640357,14,1310721,2,3,26,1310721,2,2,1590943,12,10,3,6,10, +4,8,1310721,2,3,26,2,1,40,3,36,1640349,16,1417729,1310721,2, +3,26,2,26,2,15,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1640351,14,1,1640357, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1640405,16,1966081,1310721,4,1579223,12,1587665,2,1602703,12,1640441,16, +1585225,1587663,2,10,3,6,10,4,8,1,1640459,14,1587663,2,1603237,12, +8,1,1640459,14,1,1310721,2,1,26,1310721,4,18,1310721,2,53,28, +1310721,4,1310721,2,1835009,40,1640507,16,1966081,1310721,4,1579223,12,1640885,12,1310721, +2,4,1587533,2,1602703,12,1640859,16,1601277,12,8,1310721,2,3,26,1, +10,3,6,10,4,8,1587535,2,1602703,12,1,6,1,10,28,34, +63,38,3,26,1640779,16,3,1640779,16,1310721,2,3,26,2,49,40, +3,36,1640669,16,1640661,14,116,111,111,32,109,97,110,121,32,112, +97,114,97,109,101,116,101,114,115,0,1640621,1588719,12,8,1310721,2, +5,26,1310721,2,3,26,2,26,1640473,12,10,3,6,10,4,8, +1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1587545,2,1603007,12,1,6,1,10,28,34,63,38,3,26,1640775, +16,1640779,14,1640589,14,1587535,2,1603237,12,8,1310721,2,1310721,2,2,1310721, +2,3,26,2,1310721,2,5,26,1310721,2,3,26,2,1310721,2,3, +26,2,26,1629653,12,10,3,6,10,4,8,1640517,14,1310721,2,2, +1640871,14,1,1310721,2,53,26,1310721,4,18,1310721,2,27,28,1310721,4, +1310721,2,1835009,40,1640919,16,1966081,1310721,4,1579223,12,1,1310721,2,23,26, +4,1587557,2,1603007,12,1640955,16,1640885,12,1628759,12,1642599,14,1587541,2,1603007, +12,1641145,16,1587543,2,1603007,12,1640993,16,1640885,12,1,1630575,12,1642599,14, +1310721,2,1676587,12,10,3,6,10,4,8,1587543,2,1603237,12,8,1310721, +2,5,26,1640885,12,10,3,6,10,4,8,1310721,2,2,1,40, +1641121,16,1641113,14,97,32,110,101,103,97,116,105,118,101,32,97, +114,114,97,121,32,108,101,110,103,116,104,0,1641065,1588813,12,8, +1310721,2,5,26,2,1310721,2,2,1629133,12,1642599,14,1588185,2,1602855,12, +1641379,16,1601277,12,8,1310721,2,5,26,1640885,12,10,3,6,10,4, +8,1310721,2,5,26,2,1,26,2,23,28,1,6,1,10,28, +34,63,38,3,26,1641257,16,1310721,2,5,26,2,9,26,2,3, +1630575,12,1642599,14,1310721,2,5,26,2,1,26,2,13,28,1,6, +1,10,28,34,63,38,1,10,28,1641365,16,1641357,14,111,110,108, +121,32,97,114,114,97,121,115,32,99,97,110,32,98,101,32, +102,105,120,101,100,0,1641307,1588813,12,8,1310721,2,5,26,2,1642599, +14,1587573,2,1602855,12,1641535,16,1601277,12,8,1587533,2,1602703,12,1,6, +1,10,28,34,63,38,3,26,1641527,16,1641519,14,102,110,32,97, +115,32,97,32,116,121,112,101,32,110,101,101,100,115,32,105, +116,115,32,112,97,114,97,109,101,116,101,114,115,58,32,102, +110,40,105,110,116,41,0,1641433,1589197,12,8,1587621,2,1642599,14,1585223, +2,5,28,1,6,1,10,28,34,63,38,1,10,28,1641621,16, +1641605,14,101,120,112,101,99,116,101,100,32,97,32,116,121,112, +101,0,1641573,1589197,12,8,1587621,2,1642599,14,1310721,2,1585225,2,10,3, +6,10,4,8,1310721,2,25,26,1310721,2,2,1639897,12,10,3,6, +10,4,8,1310721,2,25,26,2,1,40,3,36,1641723,16,1601277,12, +8,1310721,2,25,26,2,1310721,2,2,1631075,12,1642599,14,1310721,2,3, +26,1310721,2,2,1590943,12,10,3,6,10,4,8,1310721,2,3,26, +2,1,40,1641777,16,3,1641841,14,1417729,1310721,2,3,26,2,26,2, +15,28,1,6,1,10,28,34,63,38,1,10,28,1,6,1, +10,28,34,63,38,1,10,28,1641897,16,1310721,2,2,1641881,14,105, +115,110,39,116,32,97,32,116,121,112,101,0,1641855,1589331,12,8, +1587621,2,1642599,14,1601277,12,8,1310721,2,5,26,1425921,1310721,2,3,26, +2,26,2,10,3,6,10,4,8,1310721,2,5,26,2,1,26, +2,21,28,1,6,1,10,28,34,63,38,1,10,28,1641999,16, +1310721,2,5,26,2,1642599,14,1587661,2,1603237,12,8,3,1642421,16,1310721, +2,23,26,2,17,40,3,36,1642097,16,1642089,14,116,111,111,32, +109,97,110,121,32,116,121,112,101,32,97,114,103,117,109,101, +110,116,115,0,1642041,1589197,12,8,1310721,2,7,26,1310721,2,23,26, +2,26,1640473,12,10,3,6,10,4,8,1310721,2,7,26,1310721,2, +23,26,2,26,2,1633401,12,3,28,1,6,1,10,28,34,63, +38,1,10,28,1642347,16,1642339,14,116,121,112,101,32,97,114,103, +117,109,101,110,116,115,32,104,97,118,101,32,116,111,32,98, +101,32,111,110,101,32,119,111,114,100,32,40,97,32,112,111, +105,110,116,101,114,44,32,97,32,110,117,109,98,101,114,44, +32,111,114,32,97,32,112,97,114,97,109,101,116,101,114,41, +0,1642193,1588813,12,8,1310721,2,23,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1587545,2,1603007,12,1,6,1,10,28,34, +63,38,3,26,1642417,16,1642421,14,1642009,14,1640371,12,8,1310721,2,23, +26,2,1310721,2,5,26,2,7,26,2,28,1,6,1,10,28, +34,63,38,1,10,28,1642561,16,1310721,2,2,1642553,14,119,114,111, +110,103,32,110,117,109,98,101,114,32,111,102,32,116,121,112, +101,32,97,114,103,117,109,101,110,116,115,0,1642491,1588983,12,8, +1310721,2,5,26,2,1310721,2,7,26,1310721,2,23,26,2,1631467,12, +1642599,14,1,1310721,2,27,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1642647,16,1966081,1310721,4,1579223,12,1585223,2,9,28,1, +6,1,10,28,34,63,38,3,26,1643285,16,1585225,2,1587541,2,28, +1,6,1,10,28,34,63,38,3,26,1642719,16,3,1642771,14,1585225, +2,1587571,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1642781,16,3,1643401,14,1585225,2, +1587557,2,28,1,6,1,10,28,34,63,38,3,26,1643279,16,1310721, +2,1,10,3,6,10,4,8,1310721,2,2,7,40,1643011,16,1310721, +2,2,1601675,12,8,1587445,2,9,28,1,6,1,10,28,34,63, +38,3,26,1642947,16,1587447,2,1587557,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1642949, +14,1,1,6,1,10,28,34,63,38,3,26,1642977,16,1643011,14, +1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8,1642833, +14,1310721,2,2,1601675,12,8,1587445,2,5,28,1,6,1,10,28, +34,63,38,3,26,1643151,16,1587447,2,1640093,12,1643073,16,3,1643125,14, +1587447,2,1587573,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,1643153,14,1,1643163,16,3,1643275,14,1587445,2,9, +28,1,6,1,10,28,34,63,38,3,26,1643251,16,1587447,2,1587541, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1643253,14,1,1,6,1,10,28,34, +63,38,1,10,28,1643401,14,1,1643401,14,1585223,2,5,28,1,6, +1,10,28,34,63,38,1,10,28,1643325,16,1,1643401,14,1585225,2, +1587573,2,28,1,6,1,10,28,34,63,38,3,26,1643365,16,3, +1643395,14,1585225,2,1640093,12,1,6,1,10,28,34,63,38,1,10, +28,1643401,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721, +4,1310721,2,1835009,40,1643449,16,1966081,1310721,4,1579223,12,1587657,1,10,3, +6,10,4,8,1587659,1,10,3,6,10,4,8,1587571,2,1602703,12, +1,6,1,10,28,34,63,38,3,26,1643531,16,1587657,1640473,12,10, +3,6,10,4,8,1587571,2,1603007,12,1643767,16,1585225,2,1587587,2,28, +1,6,1,10,28,34,63,38,3,26,1643597,16,1587659,3,10,3, +6,10,4,8,1643761,14,1585225,2,1587591,2,28,1,6,1,10,28, +34,63,38,3,26,1643651,16,1587659,5,10,3,6,10,4,8,1643761, +14,1585225,2,1587589,2,28,1,6,1,10,28,34,63,38,3,26, +1643705,16,1587659,7,10,3,6,10,4,8,1643761,14,1643753,14,97,32, +116,97,103,32,105,115,32,46,117,44,32,46,109,32,111,114, +32,46,100,0,1643709,1589197,12,8,1601277,12,8,1,1643775,14,1,1310721, +2,1,26,1310721,4,18,1310721,2,21,28,1310721,4,1310721,2,1835009,40, +1643823,16,1966081,1310721,4,1579223,12,1,1310721,2,7,26,4,1524225,1310721,2, +9,26,4,1,1310721,2,15,26,4,1,1310721,2,17,26,4,1601277, +12,8,1310721,2,1603527,12,10,3,6,10,4,8,1587661,2,1602703,12, +1644291,16,1601277,12,8,1587655,1,10,3,6,10,4,8,3,1644107,16, +1587655,2,17,40,3,36,1644015,16,1644007,14,116,111,111,32,109,97, +110,121,32,116,121,112,101,32,112,97,114,97,109,101,116,101, +114,115,0,1643957,1589197,12,8,1587639,1587655,2,26,1603527,12,10,3,6, +10,4,8,1587655,1,6,2,1,6,3,26,5,6,4,10,8, +8,1587545,2,1603007,12,1,6,1,10,28,34,63,38,3,26,1644103, +16,1644107,14,1643931,14,1640371,12,8,1310721,2,17,26,3,10,3,6, +10,4,8,1310721,2,3,26,21,1,1310721,2,2,1,1628411,12,10, +3,6,10,4,8,1310721,2,3,26,2,7,26,1587655,2,10,3, +6,10,4,8,1310721,2,13,26,1587655,2,1628197,12,10,3,6,10, +4,8,1310721,2,13,26,2,1587639,1587655,2,1574491,12,8,1310721,2,3, +26,2,13,26,1310721,2,13,26,2,10,3,6,10,4,8,1644361, +14,1310721,2,3,26,17,1,1310721,2,2,1,1628411,12,10,3,6, +10,4,8,1310721,2,3,26,2,7,26,5,1,10,28,10,3, +6,10,4,8,1310721,2,5,26,1310721,2,2,15,1310721,2,3,26, +2,1590445,12,10,3,6,10,4,8,1587537,2,1603237,12,8,1587539,2, +1602703,12,1,6,1,10,28,34,63,38,3,26,1644739,16,1310721,2, +19,26,1640473,12,10,3,6,10,4,8,3,1644725,16,1310721,2,7, +26,2,2001,40,3,36,1644541,16,1644533,14,116,111,111,32,109,97, +110,121,32,102,105,101,108,100,115,0,1644501,1588719,12,8,1310721,2, +9,26,2,1310721,2,7,26,2,1310721,2,7,26,2,26,26,1603527, +12,10,3,6,10,4,8,1310721,2,9,26,2,1310721,2,7,26, +2,1310721,2,7,26,2,26,3,26,26,1310721,2,19,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,1587545,2,1603007,12,1,6,1,10,28,34, +63,38,3,26,1644721,16,1644725,14,1644469,14,1587547,2,1603237,12,8,1644413, +14,1601277,12,8,1310721,2,17,26,2,1644945,16,1310721,2,13,26,1310721, +2,7,26,2,1310721,2,7,26,2,26,1628197,12,10,3,6,10, +4,8,1310721,2,13,26,2,1310721,2,9,26,2,1310721,2,7,26, +2,1310721,2,7,26,2,26,1574491,12,8,1310721,2,3,26,2,9, +26,1310721,2,13,26,2,10,3,6,10,4,8,1310721,2,3,26, +2,11,26,1310721,2,7,26,2,10,3,6,10,4,8,1587655,1, +10,3,6,10,4,8,1645655,14,1310721,2,13,26,1310721,2,7,26, +2,7,30,3,26,1628197,12,10,3,6,10,4,8,1310721,2,11, +26,1,10,3,6,10,4,8,1310721,2,11,26,2,1310721,2,7, +26,2,40,1645547,16,1310721,2,19,26,1310721,2,9,26,2,1310721,2, +11,26,2,1310721,2,11,26,2,26,3,26,26,2,10,3,6, +10,4,8,1310721,2,19,26,2,1310721,2,3,26,2,28,1,6, +1,10,28,34,63,38,3,26,1645285,16,1645253,14,97,32,115,116, +114,117,99,116,32,99,97,110,39,116,32,99,111,110,116,97, +105,110,32,105,116,115,101,108,102,32,98,121,32,118,97,108, +117,101,59,32,117,115,101,32,97,32,112,111,105,110,116,101, +114,0,1645145,1588813,12,8,1310721,2,19,26,1587621,2,10,3,6,10, +4,8,1310721,2,13,26,2,1310721,2,11,26,2,7,30,26,1310721, +2,9,26,2,1310721,2,11,26,2,1310721,2,11,26,2,26,26, +2,10,3,6,10,4,8,1310721,2,13,26,2,1310721,2,11,26, +2,7,30,3,26,26,1310721,2,19,26,2,10,3,6,10,4, +8,1310721,2,13,26,2,1310721,2,11,26,2,7,30,5,26,26, +1310721,2,15,26,2,10,3,6,10,4,8,1310721,2,15,26,1310721, +2,15,26,2,1310721,2,19,26,2,1633401,12,26,10,3,6,10, +4,8,1310721,2,11,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1645009,14,1310721,2,3,26,2,9,26,1310721,2,13,26, +2,10,3,6,10,4,8,1310721,2,3,26,2,3,26,1310721,2, +15,26,2,10,3,6,10,4,8,1310721,2,3,26,2,7,26, +1310721,2,7,26,2,10,3,6,10,4,8,1587547,2,1603007,12,8, +1310721,2,5,26,2,1645681,14,1,1310721,2,21,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1645729,16,1966081,1310721,4,1579223,12, +1601277,12,8,1310721,2,1603527,12,10,3,6,10,4,8,1587549,2,1603237, +12,8,1310721,2,2,15,1640473,12,1590445,12,8,1587547,2,1603237,12,8, +1,1645801,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721, +4,1310721,2,1835009,40,1645849,16,1966081,1310721,4,1579223,12,1601277,12,8,1587683, +2,1602855,12,1645887,16,1587631,3,10,3,6,10,4,8,1645991,14,1587685, +2,1602855,12,1645919,16,1587631,1,10,3,6,10,4,8,1645991,14,1645983, +14,116,121,112,101,99,104,101,99,107,32,111,110,32,111,114, +32,116,121,112,101,99,104,101,99,107,32,111,102,102,0,1645923, +1589197,12,8,1601277,12,8,1587547,2,1603237,12,8,1,1646015,14,1,1310721, +2,1,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40, +1646063,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1, +1310721,2,5,26,4,1310721,2,2,1632329,12,8,1310721,2,5,26,2, +1310721,2,2,7,26,2,40,1646249,16,1310721,2,2,9,26,2,1310721, +2,5,26,2,7,30,26,2,1310721,2,3,26,2,28,1,6, +1,10,28,34,63,38,3,26,1646211,16,1310721,2,5,26,2,1646263, +14,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1646103,14,3,1,10,28,1646263,14,1,1310721,2,7,26,1310721, +4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1646311,16,1966081,1310721, +4,1579223,12,1587533,2,1603237,12,8,1642613,12,1646383,16,1587571,2,1602703,12, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1646385,14,1,1646413,16,1310721,2,1640473,12,10,3, +6,10,4,8,1646575,14,1310721,2,3,26,1610967,12,10,3,6,10, +4,8,1587637,1,6,2,1,6,3,26,5,6,4,10,8,8, +1310721,2,5,26,1672327,12,10,3,6,10,4,8,1655683,12,8,1310721, +2,1587633,2,10,3,6,10,4,8,1587637,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1310721,2,3,26,2,1611599,12,8,1310721, +2,3,26,2,1611517,12,8,1587535,2,1603237,12,8,1310721,2,2,1646597, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1646645,16,1966081,1310721,4,1579223,12,1587533,2,1603237,12,8,1310721, +2,1672327,12,10,3,6,10,4,8,1655683,12,8,1310721,2,2,1609283, +12,8,1587633,2,1646703,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1646751,16,1966081,1310721,4,1579223,12,1310721, +2,4,1310721,2,2,1,26,2,23,28,1,6,1,10,28,34, +63,38,3,26,1646835,16,1310721,2,2,7,26,2,1,6,1,10, +28,34,63,38,1,10,28,1646837,14,1,1646923,16,1646915,14,97,32, +102,105,120,101,100,32,97,114,114,97,121,32,99,97,110,39, +116,32,103,114,111,119,32,111,114,32,115,104,114,105,110,107, +0,1646845,1588813,12,8,1,1646931,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1646979,16,1966081,1310721,4,1579223, +12,1601277,12,8,1310721,2,1646611,12,10,3,6,10,4,8,1587535,2, +1603237,12,8,1310721,2,2,1,26,2,13,28,1,6,1,10,28, +34,63,38,3,26,1647085,16,9,1592369,12,8,1310721,2,2,7,26, +2,1592283,12,8,1647339,14,1310721,2,2,1,26,2,23,28,1,6, +1,10,28,34,63,38,3,26,1647131,16,3,1647185,14,1310721,2,2, +1587621,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1647227,14,108,101,110,32,110,101, +101,100,115,32,97,110,32,97,114,114,97,121,0,1647189,1310721,2, +2,1639507,12,8,1587701,2,1647311,16,1310721,2,2,1,26,2,23,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1647313,14,1,1647329,16,3,1592369,12,8,1647339,14, +1588187,2,1593049,12,8,1587633,1587623,2,10,3,6,10,4,8,1,1647365, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1647413,16,1966081,1310721,4,1579223,12,1601277,12,8,1310721,2,1646611, +12,10,3,6,10,4,8,1587535,2,1603237,12,8,1310721,2,2,1, +26,2,23,28,1,6,1,10,28,34,63,38,3,26,1647495,16, +3,1647549,14,1310721,2,2,1587621,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1647585,14, +99,97,112,32,110,101,101,100,115,32,97,32,91,93,84,0, +1647553,1310721,2,2,1639507,12,8,1588189,2,1593049,12,8,1587633,1587623,2,10, +3,6,10,4,8,1,1647635,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1647683,16,1966081,1310721,4,1579223, +12,1601277,12,8,1310721,2,1646611,12,10,3,6,10,4,8,1310721,2, +2,1646717,12,8,1310721,2,2,1,26,2,23,28,1,6,1,10, +28,34,63,38,3,26,1647829,16,1310721,2,2,9,26,2,1633401,12, +3,28,1,6,1,10,28,34,63,38,1,10,28,1,6,1, +10,28,34,63,38,1,10,28,1647831,14,1,1647953,16,1647945,14,112, +117,115,104,32,116,97,107,101,115,32,111,110,101,45,119,111, +114,100,32,101,108,101,109,101,110,116,115,59,32,117,115,101, +32,114,101,115,105,122,101,32,102,111,114,32,115,116,114,117, +99,116,115,0,1647839,1588813,12,8,1587545,2,1603237,12,8,1310721,2,3, +26,1672327,12,10,3,6,10,4,8,1655683,12,8,1310721,2,3,26, +2,5,1620967,12,8,1310721,2,2,1,26,2,23,28,1,6,1, +10,28,34,63,38,3,26,1648117,16,1310721,2,2,9,26,2,1587633, +2,1635445,12,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1648119,14,1,1648161,16,1648137,14,112, +117,115,104,0,1648127,1310721,2,2,9,26,2,1587633,2,1639107,12,8, +1587535,2,1603237,12,8,1588195,2,1593049,12,8,1587633,1587623,2,10,3,6, +10,4,8,1,1648207,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1648255,16,1966081,1310721,4,1579223,12,1601277, +12,8,1310721,2,1646611,12,10,3,6,10,4,8,1310721,2,2,1646717, +12,8,1587535,2,1603237,12,8,1588197,2,1593049,12,8,1587633,1310721,2,2, +1635257,12,10,3,6,10,4,8,1310721,2,2,1,26,2,23,28, +1,6,1,10,28,34,63,38,3,26,1648403,16,1587633,1310721,2,2, +9,26,2,10,3,6,10,4,8,1,1648411,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1648459,16, +1966081,1310721,4,1579223,12,1601277,12,8,1310721,2,1646611,12,10,3,6,10, +4,8,1310721,2,2,1646717,12,8,1587545,2,1603237,12,8,1310721,2,3, +26,1672327,12,10,3,6,10,4,8,1655683,12,8,1310721,2,3,26, +2,1609283,12,8,1587535,2,1603237,12,8,1588199,2,1593049,12,8,1587633,1587623, +2,10,3,6,10,4,8,1,1648599,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1648647,16,1966081,1310721, +4,1579223,12,1601277,12,8,1310721,2,1646277,12,10,3,6,10,4,8, +1310721,2,2,1633401,12,1592283,12,8,1587633,1587623,2,10,3,6,10,4, +8,1,1648715,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1648763,16,1966081,1310721,4,1579223,12,1601277,12,8, +1310721,2,1646277,12,10,3,6,10,4,8,1310721,2,2,1592283,12,8, +1587633,1587621,2,10,3,6,10,4,8,1,1648827,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1648875,16, +1966081,1310721,4,1579223,12,1587617,1277953,2049,26,10,3,6,10,4,8,1587619, +1,10,3,6,10,4,8,1587621,1,3,1648931,14,119,111,114,100, +0,1648921,1589927,12,1,1628411,12,10,3,6,10,4,8,1587623,3,3, +1648973,14,105,110,116,0,1648965,1589927,12,1,1628411,12,10,3,6,10, +4,8,1587625,5,3,1649017,14,99,104,97,114,0,1649007,1589927,12,1, +1628411,12,10,3,6,10,4,8,1587627,7,3,1649061,14,98,111,111, +108,0,1649051,1589927,12,1,1628411,12,10,3,6,10,4,8,1587629,9, +1,1649105,14,118,111,105,100,0,1649095,1589927,12,1,1628411,12,10,3, +6,10,4,8,1587621,2,5,26,2,15,1587621,2,1590445,12,8,1587623, +2,5,26,2,15,1587623,2,1590445,12,8,1587625,2,5,26,2,15, +1587625,2,1590445,12,8,1587627,2,5,26,2,15,1587627,2,1590445,12,8, +1587629,2,5,26,2,15,1587629,2,1590445,12,8,1587661,1649249,14,60,0, +1649245,1589927,12,10,3,6,10,4,8,1587663,1649277,14,62,0,1649273,1589927, +12,10,3,6,10,4,8,1587665,1649307,14,62,62,0,1649301,1589927,12, +10,3,6,10,4,8,1587667,1649337,14,60,61,0,1649331,1589927,12,10, +3,6,10,4,8,1587669,1649367,14,62,61,0,1649361,1589927,12,10,3, +6,10,4,8,1587671,1649397,14,61,61,0,1649391,1589927,12,10,3,6, +10,4,8,1587673,1649427,14,33,61,0,1649421,1589927,12,10,3,6,10, +4,8,1587675,1649455,14,43,0,1649451,1589927,12,10,3,6,10,4,8, +1587677,1649493,14,115,116,114,117,99,116,0,1649479,1589927,12,10,3,6, +10,4,8,1587679,1649527,14,116,121,112,101,0,1649517,1589927,12,10,3, +6,10,4,8,1587681,1649571,14,116,121,112,101,99,104,101,99,107, +0,1649551,1589927,12,10,3,6,10,4,8,1587683,1649601,14,111,110,0, +1649595,1589927,12,10,3,6,10,4,8,1587685,1649633,14,111,102,102,0, +1649625,1589927,12,10,3,6,10,4,8,1587687,1649665,14,110,101,119,0, +1649657,1589927,12,10,3,6,10,4,8,1587689,1649701,14,110,101,119,95, +116,0,1649689,1589927,12,10,3,6,10,4,8,1587691,1649731,14,111,51, +0,1649725,1589927,12,10,3,6,10,4,8,1587693,1649763,14,108,102,97, +0,1649755,1589927,12,10,3,6,10,4,8,1587695,1649803,14,111,117,116, +115,105,100,101,0,1649787,1589927,12,10,3,6,10,4,8,1587697,1649843, +14,110,101,119,95,114,97,119,0,1649827,1589927,12,10,3,6,10, +4,8,1587699,1649875,14,111,111,98,0,1649867,1589927,12,10,3,6,10, +4,8,1588185,1649911,14,102,105,120,101,100,0,1649899,1589927,12,10,3, +6,10,4,8,1588187,1649945,14,100,108,101,110,0,1649935,1589927,12,10, +3,6,10,4,8,1588189,1649979,14,100,99,97,112,0,1649969,1589927,12, +10,3,6,10,4,8,1588191,1650013,14,100,110,101,119,0,1650003,1589927, +12,10,3,6,10,4,8,1588193,1650045,14,100,97,116,0,1650037,1589927, +12,10,3,6,10,4,8,1588195,1650081,14,100,112,117,115,104,0, +1650069,1589927,12,10,3,6,10,4,8,1588197,1650115,14,100,112,111,112, +0,1650105,1589927,12,10,3,6,10,4,8,1588199,1650155,14,100,114,101, +115,105,122,101,0,1650139,1589927,12,10,3,6,10,4,8,1588159,1, +26,1650187,14,42,0,1650183,1589927,12,10,3,6,10,4,8,1588159,3, +26,1650219,14,47,0,1650215,1589927,12,10,3,6,10,4,8,1588159,5, +26,1650251,14,37,0,1650247,1589927,12,10,3,6,10,4,8,1588159,7, +26,1650283,14,38,0,1650279,1589927,12,10,3,6,10,4,8,1588159,9, +26,1650315,14,124,0,1650311,1589927,12,10,3,6,10,4,8,1588159,11, +26,1650347,14,94,0,1650343,1589927,12,10,3,6,10,4,8,1588159,13, +26,1650381,14,60,60,0,1650375,1589927,12,10,3,6,10,4,8,1588159, +15,26,1587665,2,10,3,6,10,4,8,1588183,17,10,3,6,10, +4,8,1,1650445,14,1,1310721,2,1,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1650493,16,1966081,1310721,4,1579223,12,1310721,2, +4,1,1310721,2,3,26,4,1310721,2,3,26,2,1588183,2,40,1650623, +16,1588159,1310721,2,3,26,2,26,2,1310721,2,2,28,1,6,1, +10,28,34,63,38,3,26,1650585,16,3,1650631,14,1310721,2,3,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1650511,14,1, +1650631,14,1,1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721,4, +1310721,2,1835009,40,1650679,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4, +1310721,2,3,26,4,1310721,2,4,1546753,1310721,2,2,26,2,1310721,2, +7,26,4,1310721,2,3,26,1310721,2,3,26,2,1635131,12,10,3, +6,10,4,8,1310721,2,5,26,1310721,2,5,26,2,1635131,12,10, +3,6,10,4,8,1547137,1310721,2,2,26,2,1,40,1650991,16,1310721, +2,3,26,2,1634803,12,1,6,1,10,28,34,63,38,3,26, +1650913,16,1310721,2,5,26,2,1634803,12,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1650915,14, +1,1650965,14,38,38,32,97,110,100,32,124,124,32,110,101,101, +100,32,115,99,97,108,97,114,115,0,1650919,1310721,2,3,26,2, +1639507,12,8,1587627,2,1653417,14,1310721,2,7,26,2,1587671,2,28,1, +6,1,10,28,34,63,38,3,26,1651037,16,3,1651095,14,1310721,2, +7,26,2,1587673,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1651285,16,1310721,2,3, +26,2,1310721,2,5,26,2,1635445,12,1,6,1,10,28,34,63, +38,3,26,1651217,16,1310721,2,5,26,2,1310721,2,3,26,2,1635445, +12,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1651219,14,1,1651277,16,1651249,14,99,111,109, +112,97,114,105,115,111,110,0,1651227,1310721,2,3,26,2,1310721,2, +5,26,2,1639107,12,8,1587627,2,1653417,14,1310721,2,7,26,2,1587661, +2,28,1,6,1,10,28,34,63,38,3,26,1651331,16,3,1651389, +14,1310721,2,7,26,2,1587663,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1651399,16, +3,1651457,14,1310721,2,7,26,2,1587667,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1651467,16,3,1651525,14,1310721,2,7,26,2,1587669,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1651955,16,1310721,2,3,26,2,1587621,2,28,1,6,1,10, +28,34,63,38,3,26,1651575,16,3,1651633,14,1310721,2,5,26,2, +1587621,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1651643,16,3,1651725,14,1310721,2,3, +26,2,1634571,12,1651701,16,1310721,2,5,26,2,1634571,12,1,6,1, +10,28,34,63,38,1,10,28,1651703,14,1,1,6,1,10,28, +34,63,38,1,10,28,1651735,16,3,1651869,14,1310721,2,3,26,2, +1,26,2,11,28,1,6,1,10,28,34,63,38,3,26,1651845, +16,1310721,2,5,26,2,1,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, +1651847,14,1,1,6,1,10,28,34,63,38,1,10,28,1,6, +1,10,28,34,63,38,3,26,1651947,16,1651919,14,99,111,109,112, +97,114,105,115,111,110,0,1651897,1310721,2,3,26,2,1310721,2,5, +26,2,1639107,12,8,1587627,2,1653417,14,1310721,2,7,26,2,1587675,2, +28,1,6,1,10,28,34,63,38,3,26,1652503,16,1310721,2,3, +26,2,1,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1652147,16,1310721,2,5,26,2,1634571,12,1652063,16,3,1652121,14,1310721, +2,5,26,2,1587621,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,1652149,14,1,1652167,16,1310721,2,3,26, +2,1653417,14,1310721,2,5,26,2,1,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1652251,16,1310721,2,3,26,2,1634571,12, +1,6,1,10,28,34,63,38,1,10,28,1652253,14,1,1652271,16, +1310721,2,5,26,2,1653417,14,1310721,2,3,26,2,1587621,2,28,1, +6,1,10,28,34,63,38,3,26,1652317,16,3,1652375,14,1310721,2, +5,26,2,1587621,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1652387,16,1587621,2,1653417, +14,1310721,2,3,26,2,1634571,12,1652445,16,1310721,2,5,26,2,1634571, +12,1,6,1,10,28,34,63,38,1,10,28,1652447,14,1,1652459, +16,1587623,2,1653417,14,1652467,14,43,0,1652463,1310721,2,3,26,2,1310721, +2,5,26,2,1639107,12,8,1587621,2,1653417,14,1310721,2,7,26,2, +1587565,2,28,1,6,1,10,28,34,63,38,3,26,1653071,16,1310721, +2,3,26,2,1,26,2,11,28,1,6,1,10,28,34,63, +38,3,26,1652653,16,1310721,2,5,26,2,1,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,1652655,14,1,1652667,16,1587623,2,1653417,14,1310721,2,3, +26,2,1,26,2,11,28,1,6,1,10,28,34,63,38,3, +26,1652819,16,1310721,2,5,26,2,1634571,12,1652735,16,3,1652793,14,1310721, +2,5,26,2,1587621,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,1652821,14,1,1652839,16,1310721,2,3,26, +2,1653417,14,1310721,2,3,26,2,1587621,2,28,1,6,1,10,28, +34,63,38,3,26,1652885,16,3,1652943,14,1310721,2,5,26,2,1587621, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1652955,16,1587621,2,1653417,14,1310721,2,3, +26,2,1634571,12,1653013,16,1310721,2,5,26,2,1634571,12,1,6,1, +10,28,34,63,38,1,10,28,1653015,14,1,1653027,16,1587623,2,1653417, +14,1653035,14,45,0,1653031,1310721,2,3,26,2,1310721,2,5,26,2, +1639107,12,8,1587621,2,1653417,14,1310721,2,7,26,2,1650459,12,1653407,16, +1310721,2,3,26,2,1587621,2,28,1,6,1,10,28,34,63,38, +3,26,1653135,16,3,1653193,14,1310721,2,5,26,2,1587621,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1653205,16,1587621,2,1653417,14,1310721,2,3,26,2,1634571, +12,1653263,16,1310721,2,5,26,2,1634571,12,1,6,1,10,28,34, +63,38,1,10,28,1653265,14,1,1653277,16,1587623,2,1653417,14,1310721,2, +3,26,2,1634571,12,1653325,16,1310721,2,3,26,1310721,2,5,26,2, +10,3,6,10,4,8,1,1653381,14,97,114,105,116,104,109,101, +116,105,99,32,110,101,101,100,115,32,110,117,109,98,101,114, +115,0,1653331,1310721,2,3,26,2,1639507,12,8,1587621,2,1653417,14,1587621, +2,1653417,14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1653465,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,1,26,2,1653489,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1653537,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,1633401,12,1653559,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1653607,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,5,26,2,1653631,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1653679,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,7,26,2, +1653703,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1653751,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2, +2,1632329,12,8,1310721,2,2,7,26,2,1653787,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1653835,16, +1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2, +1632329,12,8,1310721,2,2,9,26,2,1310721,2,3,26,2,7,30, +26,2,1653899,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1653947,16,1966081,1310721,4,1579223,12,1310721,2,3, +26,4,1310721,2,4,1310721,2,2,1632329,12,8,1310721,2,2,9,26, +2,1310721,2,3,26,2,7,30,3,26,26,2,1654015,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40, +1654063,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721, +2,2,1632329,12,8,1310721,2,2,9,26,2,1310721,2,3,26,2, +7,30,5,26,26,2,1654131,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1654179,16,1966081,1310721,4,1579223, +12,1310721,2,4,1310721,2,2,9,26,2,1654203,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1654251,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,7,26,2,1654275,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +1835009,40,1654323,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2, +4,1310721,2,2,15,1310721,2,3,26,2,26,26,2,1654369,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1654417,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4, +1310721,2,2,11,26,2,13,38,1310721,2,3,26,2,1310721,2,3, +26,2,26,38,7,32,1654483,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1654531,16,1966081,1310721,4,1579223, +12,1310721,2,4,1310721,2,2,11,26,2,3,32,1654559,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1654607,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26,2, +17,28,1,6,1,10,28,34,63,38,1,10,28,1654661,16,3, +1654715,14,1310721,2,2,11,26,2,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1654725,16,1, +1654749,14,1310721,2,2,13,26,2,1,26,2,1654749,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1654797, +16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,13,26,2,3,1310721,2,3,26,2,26,26,2,1654849,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,59,28,1310721,4,1310721,2,1835009, +40,1654897,16,1966081,1310721,4,1579223,12,1310721,2,4,1585153,2,1310721,2,3, +26,4,3,1,10,28,1310721,2,5,26,4,1310721,2,3,26,2, +1655193,16,1310721,2,3,26,1,6,2,1,6,-1,26,5,6,4, +10,8,8,1417729,1310721,2,3,26,2,26,2,3,28,1,6,1, +10,28,34,63,38,3,26,1655097,16,1425921,1310721,2,3,26,2,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,1655099,14,1,1655149,16,1442305, +1310721,2,3,26,2,26,2,3,32,1,6,1,10,28,34,63, +38,1,10,28,1655151,14,1,1655189,16,1310721,2,5,26,1310721,2,3, +26,2,10,3,6,10,4,8,1655193,14,1654935,14,1310721,2,5,26, +2,1,40,1655217,16,1,1655471,14,1559041,1310721,2,5,26,2,26,2, +1655257,16,1559041,1310721,2,5,26,2,26,2,1655471,14,1310721,2,55,26, +1434113,1310721,2,5,26,2,26,2,3,38,63,32,10,3,6,10, +4,8,1310721,2,57,26,1,10,3,6,10,4,8,1310721,2,57, +26,2,1310721,2,55,26,2,40,1655423,16,1310721,2,7,26,1310721,2, +57,26,2,26,1587621,2,10,3,6,10,4,8,1310721,2,57,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1655323,14,1587621, +2,1310721,2,55,26,2,1310721,2,7,26,1434113,1310721,2,5,26,2, +26,2,1629653,12,1655471,14,1,1310721,2,59,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1655519,16,1966081,1310721,4,1579223,12,1310721, +2,4,1310721,2,2,1591445,12,1310721,2,3,26,4,1310721,2,3,26, +2,1,40,1655569,16,3,1655633,14,1417729,1310721,2,3,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,1655643,16,1,1655669,14,1425921,1310721,2, +3,26,2,26,2,1654863,12,1655669,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1655717,16,1966081,1310721,4, +1579223,12,1587521,2,1655781,16,1587633,2,1634803,12,1,6,1,10,28,34, +63,38,3,26,1655765,16,3,1592369,12,8,1587521,1,10,3,6,10, +4,8,1,1655789,14,1,1310721,2,1,26,1310721,4,18,1310721,2,11, +28,1310721,4,1310721,2,1835009,40,1655837,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1425921,1310721,2,2,26,2,1310721,2,5,26, +4,1587527,2,1310721,2,7,26,4,1587527,1310721,2,3,26,2,10,3, +6,10,4,8,1587529,1,10,3,6,10,4,8,1587633,1587621,2,10, +3,6,10,4,8,1587635,1,10,3,6,10,4,8,1310721,2,5, +26,2,1,6,12,10,8,8,1587527,1310721,2,7,26,2,10,3, +6,10,4,8,1310721,2,9,26,1587529,2,10,3,6,10,4,8, +1587521,1,10,3,6,10,4,8,1587523,1,10,3,6,10,4,8, +1310721,2,9,26,2,1656081,14,1,1310721,2,11,26,1310721,4,18,1310721, +2,1,28,1310721,4,1310721,2,1835009,40,1656129,16,1966081,1310721,4,1579223,12, +1587527,2,1656229,16,1656221,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,1656141,1588813, +12,8,1,1656237,14,1,1310721,2,1,26,1310721,4,18,1310721,2,13, +28,1310721,4,1310721,2,1835009,40,1656285,16,1966081,1310721,4,1579223,12,1310721,2, +5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2,7,26, +4,1587533,2,1603237,12,8,1587535,2,1602703,12,1,6,1,10,28,34, +63,38,3,26,1656757,16,3,1656757,16,1310721,2,9,26,1672327,12,10, +3,6,10,4,8,1655683,12,8,1310721,2,9,26,2,1310721,2,2, +1310721,2,7,26,2,1310721,2,7,26,2,26,38,7,32,1620967,12, +8,1310721,2,3,26,2,1656519,16,1310721,2,7,26,2,1310721,2,3, +26,2,7,26,2,40,1,6,1,10,28,34,63,38,1,10, +28,1656521,14,1,1656683,16,1310721,2,11,26,1310721,2,3,26,2,15, +1310721,2,7,26,2,26,26,2,10,3,6,10,4,8,1310721,2, +11,26,2,1587633,2,1310721,2,5,26,2,1636761,12,1,6,1,10, +28,34,63,38,3,26,1656683,16,1656647,14,97,114,103,117,109,101, +110,116,0,1656629,1310721,2,11,26,2,1310721,2,5,26,2,1633573,12, +1587633,2,1639107,12,8,1310721,2,7,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1587545,2,1603007,12,1,6,1,10,28,34, +63,38,3,26,1656753,16,1656757,14,1656365,14,1587535,2,1603237,12,8,1310721, +2,7,26,2,1656783,14,1,1310721,2,13,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1656831,16,1966081,1310721,4,1579223,12,1310721, +2,1640473,12,10,3,6,10,4,8,1310721,2,2,1,26,2,23, +28,1,6,1,10,28,34,63,38,3,26,1657217,16,1310721,2,2, +9,26,2,1633401,12,1592283,12,8,1587545,2,1603007,12,1656975,16,1310721,2, +3,26,1672327,12,10,3,6,10,4,8,1655683,12,8,1310721,2,3, +26,2,1609283,12,8,1657111,14,1,1592283,12,8,1310721,2,2,7,26, +2,1657111,16,1657103,14,97,32,102,105,120,101,100,32,97,114,114, +97,121,32,110,101,101,100,115,32,105,116,115,32,108,101,110, +103,116,104,58,32,110,101,119,40,102,105,120,101,100,32,91, +93,84,44,32,110,41,0,1657003,1588813,12,8,1310721,2,2,1592283,12, +8,1587535,2,1603237,12,8,1588191,2,1593049,12,8,1587521,1,10,3,6, +10,4,8,1587523,1,10,3,6,10,4,8,1587633,1310721,2,2,10, +3,6,10,4,8,1587635,1,10,3,6,10,4,8,3,1657737,14, +1587701,2,1657465,16,1587545,2,1603007,12,1657351,16,1310721,2,3,26,1672327,12, +10,3,6,10,4,8,1655683,12,8,1310721,2,3,26,2,1609283,12, +8,1310721,2,2,1633401,12,3,28,1,6,1,10,28,34,63,38, +1,10,28,1657347,16,1310721,2,2,1633401,12,1592283,12,8,31,1592369,12, +8,1657367,14,1310721,2,2,1633401,12,1592283,12,8,1587535,2,1603237,12,8, +1587697,2,1593049,12,8,1587521,1,10,3,6,10,4,8,1587523,1,10, +3,6,10,4,8,1587633,1310721,2,2,1628759,12,10,3,6,10,4, +8,1587635,1,10,3,6,10,4,8,3,1657737,14,1587545,2,1603007,12, +1657609,16,1310721,2,3,26,1672327,12,10,3,6,10,4,8,1655683,12, +8,1310721,2,3,26,2,1609283,12,8,1310721,2,2,1633401,12,3,28, +1,6,1,10,28,34,63,38,1,10,28,1657587,16,1310721,2,2, +1633401,12,1592283,12,8,31,1592369,12,8,1310721,2,2,1,1629133,12,1592283, +12,8,1657637,14,1310721,2,2,1633401,12,1592283,12,8,1310721,2,2,1592283, +12,8,1587535,2,1603237,12,8,1587689,2,1593049,12,8,1587521,1,10,3, +6,10,4,8,1587523,1,10,3,6,10,4,8,1587633,1310721,2,2, +1628759,12,10,3,6,10,4,8,1587635,1,10,3,6,10,4,8, +3,1657737,14,1,1310721,2,5,26,1310721,4,18,1310721,2,27,28,1310721, +4,1310721,2,1835009,40,1657785,16,1966081,1310721,4,1579223,12,1310721,2,4,1, +1310721,2,5,26,4,1,1310721,2,7,26,4,1559041,1310721,2,2,26, +2,1310721,2,9,26,4,1409537,1310721,2,2,26,2,1587687,2,28,1, +6,1,10,28,34,63,38,3,26,1657941,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,1657943,14,1,1658271,16,1602137,12,8, +1587445,2,9,28,1,6,1,10,28,34,63,38,3,26,1658103,16, +1587447,2,1587557,2,28,1,6,1,10,28,34,63,38,3,26,1658025, +16,3,1658077,14,1587447,2,1587541,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,1658105,14,1,1658123,16,1601277,12, +8,1656797,12,1659047,14,1587445,2,5,28,1,6,1,10,28,34,63, +38,3,26,1658251,16,1587447,2,1640093,12,1658173,16,3,1658225,14,1587447,2, +1587573,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,1658253,14,1,1658271,16,1601277,12,8,1656797,12,1659047,14,1587701, +2,1658343,16,1409537,1310721,2,2,26,2,1587687,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1658345,14,1,1658447,16,1310721,2,5,26,1587697,2,1590943,12,10,3, +6,10,4,8,1310721,2,5,26,2,1,40,3,36,1658425,16,1310721, +2,1310721,2,5,26,2,10,3,6,10,4,8,1310721,2,5,26, +1,10,3,6,10,4,8,1442305,1310721,2,2,26,2,5,32,1658543, +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,1658581,14,1442305,1310721,2,2,26,1442305,1310721,2,2, +26,2,9,34,10,3,6,10,4,8,1310721,2,11,26,1,17, +1574703,12,8,1588221,2,1658643,16,1310721,2,11,26,1588205,1588221,2,1574491,12, +8,1588221,1,10,3,6,10,4,8,1310721,2,3,26,1310721,2,5, +26,2,1310721,2,9,26,2,1310721,2,11,26,1656251,12,10,3,6, +10,4,8,1442305,1310721,2,2,26,2,5,32,1658795,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,1658797,14,1,1658877,16,1409537,1310721,2,2,26,2,1658869,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,1658817,1588983,12,8,1310721,2, +2,1592875,12,8,13,1592369,12,8,1587521,1,10,3,6,10,4,8, +1587523,1,10,3,6,10,4,8,1587635,1,10,3,6,10,4,8, +1587633,1587621,2,10,3,6,10,4,8,1310721,2,9,26,2,1659019,16, +1587633,1310721,2,9,26,2,9,26,2,1310721,2,11,26,1633573,12,10, +3,6,10,4,8,1310721,2,7,26,2,1659039,16,3,1659047,14,1, +1659047,14,1,1310721,2,27,26,1310721,4,18,1310721,2,11,28,1310721,4, +1310721,2,1835009,40,1659095,16,1966081,1310721,4,1579223,12,1310721,2,4,1434113,1310721, +2,2,26,2,31,32,1310721,2,3,26,4,1434113,1310721,2,2,26, +2,9,38,31,32,1310721,2,5,26,4,1,1310721,2,7,26,4, +1587533,2,1603237,12,8,1587535,2,1602703,12,1,6,1,10,28,34,63, +38,3,26,1659337,16,3,1659337,16,1310721,2,9,26,1672327,12,10,3, +6,10,4,8,1655683,12,8,1310721,2,9,26,2,1609283,12,8,1310721, +2,7,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1587545,2,1603007,12,1,6,1,10,28,34,63,38,3,26,1659333,16, +1659337,14,1659211,14,1587535,2,1603237,12,8,1310721,2,7,26,2,1310721,2, +3,26,2,28,1,6,1,10,28,34,63,38,1,10,28,1659465, +16,1409537,1310721,2,2,26,2,1659457,14,119,114,111,110,103,32,110, +117,109,98,101,114,32,111,102,32,105,110,112,117,116,115,0, +1659411,1588983,12,8,1587521,1,10,3,6,10,4,8,1587523,1,10,3, +6,10,4,8,1587633,1587621,2,10,3,6,10,4,8,1587635,1,10, +3,6,10,4,8,1442305,1310721,2,2,26,2,129,32,1659587,16,1450497, +1310721,2,2,26,2,3,28,1592875,12,8,13,1592369,12,8,1,1659785, +14,45,1425921,1310721,2,2,26,2,26,1592369,12,8,1310721,2,5,26, +2,1,28,1,6,1,10,28,34,63,38,3,26,1659655,16,1, +1592283,12,8,1310721,2,5,26,2,3,10,40,1659777,16,1409537,1310721,2, +2,26,2,1659769,14,108,101,97,118,101,115,32,115,101,118,101, +114,97,108,32,118,97,108,117,101,115,59,32,117,115,101,32, +105,116,32,102,114,111,109,32,97,115,109,0,1659691,1588983,12,8, +1,1659785,14,1,1310721,2,11,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,1835009,40,1659833,16,1966081,1310721,4,1579223,12,1587521,1,10,3, +6,10,4,8,1587523,1,10,3,6,10,4,8,1587635,1,10,3, +6,10,4,8,1588201,1,10,3,6,10,4,8,1585223,2,3,28, +1,6,1,10,28,34,63,38,3,26,1660045,16,1585225,2,1592283,12, +8,1587635,1585225,2,1,28,1,6,1,10,28,34,63,38,3,26, +10,3,6,10,4,8,1588201,3,10,3,6,10,4,8,1588203,1585225, +2,10,3,6,10,4,8,1587633,1587623,2,10,3,6,10,4,8, +1601277,12,8,1,1662715,14,1585223,2,7,28,1,6,1,10,28,34, +63,38,3,26,1660121,16,1585225,2,1594383,12,8,1601277,12,8,1587633,1587625, +2,1628759,12,10,3,6,10,4,8,1,1662715,14,1585223,2,9,28, +1,6,1,10,28,34,63,38,3,26,1660373,16,1585225,2,1587533,2, +28,1,6,1,10,28,34,63,38,3,26,1660241,16,1601277,12,8, +1310721,2,7,26,1672327,12,10,3,6,10,4,8,1587535,2,1603237,12, +8,1310721,2,7,26,2,1662715,14,1585225,2,1587537,2,28,1,6,1, +10,28,34,63,38,3,26,1660283,16,1675019,12,1662715,14,1660333,14,101, +120,112,101,99,116,101,100,32,97,110,32,101,120,112,114,101, +115,115,105,111,110,0,1660287,1589197,12,8,1,1592283,12,8,1587633,1587621, +2,10,3,6,10,4,8,1,1662715,14,1585223,2,5,28,1,6, +1,10,28,34,63,38,1,10,28,1660497,16,1660457,14,101,120,112, +101,99,116,101,100,32,97,110,32,101,120,112,114,101,115,115, +105,111,110,0,1660411,1589197,12,8,1,1592283,12,8,1587633,1587621,2,10, +3,6,10,4,8,1,1662715,14,1310721,2,1585225,2,10,3,6,10, +4,8,1310721,2,3,26,1310721,2,2,1607893,12,10,3,6,10,4, +8,1310721,2,3,26,2,1,40,3,36,1660963,16,1601277,12,8,1587499, +2,1,6,1,10,28,34,63,38,3,26,1660643,16,1310721,2,3, +26,2,1608697,12,1,6,1,10,28,34,63,38,1,10,28,1660645, +14,1,1660793,16,1310721,2,2,1660785,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,1660659,1588983,12,8,1310721,2,3,26, +2,1593311,12,8,1587633,1556993,1310721,2,3,26,2,26,2,10,3,6, +10,4,8,1473025,1310721,2,3,26,2,26,2,1660865,16,1,1662715,14, +1587521,3,10,3,6,10,4,8,1587523,3,10,3,6,10,4,8, +1587525,1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,3,26, +2,1608697,12,1660957,16,5,1310721,2,3,26,2,26,1662715,14,1,1662715, +14,1310721,2,5,26,1310721,2,2,1590943,12,10,3,6,10,4,8, +1310721,2,5,26,2,1,40,3,36,1661081,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,1661083,14,1,1661239,16,1442305, +1310721,2,5,26,2,26,2,33,32,1,6,1,10,28,34,63, +38,3,26,1661219,16,1310721,2,2,1661211,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,1661141,1589331,12, +8,1310721,2,5,26,2,3,1655803,12,1662715,14,1310721,2,5,26,2, +1,40,3,36,1661327,16,1417729,1310721,2,5,26,2,26,2,15,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1661329,14,1,1661429,16,1310721,2,2,1661389,14,105, +115,32,97,32,116,121,112,101,44,32,110,111,116,32,97,32, +118,97,108,117,101,0,1661343,1589331,12,8,1,1592283,12,8,1587633,1587621, +2,10,3,6,10,4,8,1,1662715,14,1601277,12,8,1587633,1587621,2, +10,3,6,10,4,8,1310721,2,5,26,2,1,40,3,36,1661541, +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, +1661543,14,1,1661693,16,1425921,1310721,2,5,26,2,26,2,1592283,12,8, +1587633,1587623,2,10,3,6,10,4,8,1587635,1425921,1310721,2,5,26,2, +26,2,1,28,1,6,1,10,28,34,63,38,3,26,10,3, +6,10,4,8,1588201,3,10,3,6,10,4,8,1588203,1425921,1310721,2, +5,26,2,26,2,10,3,6,10,4,8,1,1662715,14,1310721,2, +5,26,2,1,40,3,36,1661781,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,1661783,14,1,1661897,16,1425921,1310721,2, +5,26,2,26,2,1592283,12,8,1559041,1310721,2,5,26,2,26,2, +1661859,16,1587633,1559041,1310721,2,5,26,2,26,2,10,3,6,10,4, +8,1587521,3,10,3,6,10,4,8,1587523,5,10,3,6,10,4, +8,1,1662715,14,1310721,2,5,26,2,1,40,3,36,1661985,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,1661987,14, +1,1662069,16,1425921,1310721,2,5,26,2,26,2,1592283,12,8,1559041,1310721, +2,5,26,2,26,2,1662063,16,1587633,1559041,1310721,2,5,26,2,26, +2,10,3,6,10,4,8,1,1662715,14,1310721,2,5,26,2,1, +40,3,36,1662157,16,1417729,1310721,2,5,26,2,26,2,13,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1662159,14,1,1662181,16,1310721,2,5,26,2,1659061,12, +1662715,14,1310721,2,5,26,2,1,40,1662229,16,1310721,2,5,26,1310721, +2,2,1592751,12,10,3,6,10,4,8,1587661,2,1602703,12,1662287,16, +1442305,1310721,2,5,26,2,26,2,257,32,1,6,1,10,28,34, +63,38,1,10,28,1662289,14,1,1662611,16,1601277,12,8,1588221,1,10, +3,6,10,4,8,3,1662489,16,1588221,2,17,40,3,36,1662397,16, +1662389,14,116,111,111,32,109,97,110,121,32,116,121,112,101,32, +97,114,103,117,109,101,110,116,115,0,1662341,1589197,12,8,1588205,1588221, +2,26,1640473,12,10,3,6,10,4,8,1588221,1,6,2,1,6, +3,26,5,6,4,10,8,8,1587545,2,1603007,12,1,6,1,10, +28,34,63,38,3,26,1662485,16,1662489,14,1662315,14,1640371,12,8,1587533, +2,1602703,12,1,6,1,10,28,34,63,38,3,26,1662611,16,1662603, +14,101,120,112,101,99,116,101,100,32,40,32,97,102,116,101, +114,32,116,104,101,32,116,121,112,101,32,97,114,103,117,109, +101,110,116,115,0,1662531,1589197,12,8,1587533,2,1602703,12,1662641,16,1310721, +2,5,26,2,1657751,12,1662715,14,1310721,2,5,26,2,1592875,12,8, +1559041,1310721,2,5,26,2,26,2,1662707,16,1587633,1559041,1310721,2,5,26, +2,26,2,10,3,6,10,4,8,1,1662715,14,1,1310721,2,9, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1662763,16, +1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587521,2,1, +6,1,10,28,34,63,38,3,26,1662895,16,1662887,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,1662811,1589197,12,8,1587523,2,3,28,1,6,1,10,28, +34,63,38,3,26,1662957,16,1587499,2,1,6,1,10,28,34,63, +38,1,10,28,1662959,14,1,1662997,16,1587525,2,1608697,12,1,6,1, +10,28,34,63,38,1,10,28,1662999,14,1,1663099,16,1587525,2,1663091, +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,1663011,1589603,12,8,1587633,2,1634571, +12,1663117,16,3,1663173,14,1587633,2,1,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,1663183,16,3,1663235,14,1587633,2,1587621,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1663313,14,43,43,32,97,110,100,32,45,45,32,110,101,101, +100,32,97,32,110,117,109,98,101,114,32,111,114,32,97,32, +112,111,105,110,116,101,114,0,1663239,1587633,2,1639507,12,8,1587521,1, +10,3,6,10,4,8,1587523,1,10,3,6,10,4,8,1587635,1, +10,3,6,10,4,8,1,1592283,12,8,7,1592369,12,8,3,1592369, +12,8,1310721,2,2,1663475,16,1,1592283,12,8,7,1592369,12,8,1310721, +2,3,26,2,1592283,12,8,27,1592369,12,8,5,1592283,12,8,7, +1592369,12,8,5,1592369,12,8,1663539,14,1310721,2,3,26,2,1592283,12, +8,27,1592369,12,8,1,1592283,12,8,7,1592369,12,8,5,1592283,12, +8,7,1592369,12,8,5,1592369,12,8,11,1592369,12,8,9,1592369,12, +8,1,1663563,14,1,1310721,2,5,26,1310721,4,18,1310721,2,11,28, +1310721,4,1310721,2,1835009,40,1663611,16,1966081,1310721,4,1579223,12,1310721,2,4, +3,1,10,28,1310721,2,9,26,4,1601277,12,8,1310721,2,3,26, +1603527,12,10,3,6,10,4,8,1655683,12,8,1310721,2,2,3,28, +1,6,1,10,28,34,63,38,3,26,1663841,16,1663829,14,117,115, +101,32,97,32,102,105,101,108,100,32,111,102,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,1663709,1589485,12,8,1663905,14, +1310721,2,2,5,40,3,36,1663905,16,1310721,2,2,5,28,1608795,12, +8,1310721,2,9,26,1310721,2,2,5,28,10,3,6,10,4,8, +1310721,2,5,26,1587633,2,10,3,6,10,4,8,1310721,2,5,26, +2,1,26,2,11,28,1,6,1,10,28,34,63,38,3,26, +1664009,16,1310721,2,5,26,1310721,2,5,26,2,9,26,2,10,3, +6,10,4,8,1310721,2,5,26,2,1,26,2,17,28,1,6, +1,10,28,34,63,38,1,10,28,1664359,16,1588225,2,1,6,1, +10,28,34,63,38,3,26,1664133,16,1587637,2,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1664135,14,1,1664303,16,1588227,12,8,93,1573255,12,8,1310721,2,3,26, +2,1573495,12,8,1664197,14,58,32,116,104,97,116,39,115,32,97, +32,0,1664173,1573495,12,8,1587633,2,1637851,12,8,1664289,14,44,32,110, +111,116,32,97,32,115,116,114,117,99,116,32,111,114,32,97, +32,112,111,105,110,116,101,114,32,116,111,32,111,110,101,0, +1664219,1573495,12,8,1588371,12,8,1587633,1587621,2,10,3,6,10,4,8, +1587521,3,10,3,6,10,4,8,1587523,9,10,3,6,10,4,8, +1,1664915,14,1310721,2,7,26,1310721,2,5,26,2,1310721,2,3,26, +2,1646029,12,10,3,6,10,4,8,1310721,2,7,26,2,1,40, +1664647,16,1588225,2,1,6,1,10,28,34,63,38,3,26,1664499,16, +1587637,2,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1664501,14,1,1664591,16,1588227,12,8,1310721, +2,5,26,2,1637851,12,8,1664561,14,32,104,97,115,32,110,111, +32,102,105,101,108,100,32,0,1664531,1573495,12,8,1310721,2,3,26, +2,1573495,12,8,1588371,12,8,1587633,1587621,2,10,3,6,10,4,8, +1587521,3,10,3,6,10,4,8,1587523,9,10,3,6,10,4,8, +1,1664915,14,1310721,2,5,26,2,9,26,2,1310721,2,7,26,2, +7,30,5,26,26,2,1664741,16,1310721,2,5,26,2,9,26,2, +1310721,2,7,26,2,7,30,5,26,26,2,1592283,12,8,27,1592369, +12,8,1587633,1310721,2,5,26,2,9,26,2,1310721,2,7,26,2, +7,30,3,26,26,2,10,3,6,10,4,8,1587521,3,10,3, +6,10,4,8,1587635,1,10,3,6,10,4,8,1310721,2,9,26, +2,1,40,3,36,1664891,16,1587523,7,10,3,6,10,4,8,1587525, +1310721,2,9,26,2,10,3,6,10,4,8,1664907,14,1587523,9,10, +3,6,10,4,8,1,1664915,14,1,1310721,2,11,26,1310721,4,18, +1310721,2,31,28,1310721,4,1310721,2,1835009,40,1664963,16,1966081,1310721,4,1579223, +12,1659799,12,1310721,2,4,3,1667999,16,1585223,2,5,28,1,6,1, +10,28,34,63,38,3,26,1665067,16,1585225,2,1587581,2,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1665069,14,1,1665153,16,1601277,12,8,1310721,2,7,26,1640473, +12,10,3,6,10,4,8,1655683,12,8,1587633,1310721,2,7,26,2, +10,3,6,10,4,8,1587523,1,10,3,6,10,4,8,1664973,14, +1585223,2,9,28,1,6,1,10,28,34,63,38,1,10,28,1665197, +16,1310721,2,2,1668011,14,1585225,2,1587541,2,28,1,6,1,10,28, +34,63,38,3,26,1667219,16,1601277,12,8,1655683,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,1665423,16,1665411,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,1665309,1589485,12,8,1665487,14,1310721,2,2,5,40,3,36,1665487,16, +1310721,2,2,5,28,1608795,12,8,1310721,2,3,26,1310721,2,2,5, +28,10,3,6,10,4,8,1587633,2,1,26,2,23,28,1,6, +1,10,28,34,63,38,3,26,1666193,16,1310721,2,9,26,1587633,2, +9,26,2,10,3,6,10,4,8,1310721,2,1672327,12,10,3,6, +10,4,8,1655683,12,8,1310721,2,2,1609283,12,8,1587633,2,1634571,12, +1665611,16,3,1665663,14,1587633,2,1587621,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1665723, +14,97,110,32,105,110,100,101,120,32,104,97,115,32,116,111, +32,98,101,32,97,32,110,117,109,98,101,114,0,1665667,1587633,2, +1639507,12,8,1587543,2,1603237,12,8,1310721,2,29,26,1587695,2,1590943,12, +10,3,6,10,4,8,1587701,2,1665825,16,1310721,2,29,26,2,1, +40,3,36,1,6,1,10,28,34,63,38,1,10,28,1665827,14, +1,1665897,16,1417729,1310721,2,29,26,2,26,2,13,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1665899,14,1,1666179,16,1,1592283,12,8,7,1592369,12,8,5, +1592283,12,8,7,1592369,12,8,3,1592369,12,8,45,1425921,1310721,2,29, +26,2,26,2,26,1592369,12,8,1310721,2,29,26,1592669,12,10,3, +6,10,4,8,17,1592369,12,8,3,1592283,12,8,7,1592369,12,8, +3,1592369,12,8,1587699,2,1593049,12,8,1310721,2,29,26,2,1587483,2, +1592451,12,8,11,1592369,12,8,5,1592283,12,8,27,1592369,12,8,3, +1592369,12,8,11,1592369,12,8,1310721,2,9,26,2,1633401,12,3,28, +1,6,1,10,28,34,63,38,1,10,28,1666167,16,1310721,2,9, +26,2,1633401,12,1592283,12,8,31,1592369,12,8,27,1592369,12,8,1666189, +14,1588193,2,1593049,12,8,1667059,14,1587633,2,1634967,12,1666211,16,3,1666263, +14,1587633,2,1587621,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1666347,14,111,110,108, +121,32,112,111,105,110,116,101,114,115,32,97,110,100,32,97, +114,114,97,121,115,32,99,97,110,32,98,101,32,105,110,100, +101,120,101,100,0,1666267,1587633,2,1639507,12,8,1310721,2,9,26,1587633, +2,1635257,12,10,3,6,10,4,8,1310721,2,5,26,1,3,28, +10,3,6,10,4,8,1587633,2,1,26,2,13,28,1,6,1, +10,28,34,63,38,3,26,1666493,16,1587633,2,7,26,2,1,10, +40,1,6,1,10,28,34,63,38,1,10,28,1666495,14,1,1666529, +16,1310721,2,5,26,1587633,2,7,26,2,10,3,6,10,4,8, +1588201,1,10,3,6,10,4,8,1310721,2,1672327,12,10,3,6,10, +4,8,1655683,12,8,1310721,2,2,1609283,12,8,1310721,2,5,26,2, +1,40,3,36,1666635,16,1588201,2,1,6,1,10,28,34,63,38, +1,10,28,1666637,14,1,1666727,16,1588203,2,1,40,1666659,16,3,1666701, +14,1588203,2,1310721,2,5,26,2,40,3,36,1,6,1,10,28, +34,63,38,1,10,28,1,6,1,10,28,34,63,38,1,10, +28,1666729,14,1,1666827,16,1666819,14,116,104,101,32,105,110,100,101, +120,32,105,115,32,111,117,116,32,111,102,32,114,97,110,103, +101,32,102,111,114,32,116,104,105,115,32,97,114,114,97,121, +0,1666737,1588813,12,8,1587633,2,1634571,12,1666845,16,3,1666897,14,1587633,2, +1587621,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1666957,14,97,110,32,105,110,100, +101,120,32,104,97,115,32,116,111,32,98,101,32,97,32,110, +117,109,98,101,114,0,1666901,1587633,2,1639507,12,8,1587543,2,1603237,12, +8,1310721,2,9,26,2,1633401,12,3,28,1,6,1,10,28,34, +63,38,1,10,28,1667051,16,1310721,2,9,26,2,1633401,12,1592283,12, +8,31,1592369,12,8,27,1592369,12,8,1587521,3,10,3,6,10,4, +8,1587633,1310721,2,9,26,2,10,3,6,10,4,8,1587635,1,10, +3,6,10,4,8,1310721,2,3,26,2,1,40,3,36,1667181,16, +1587523,7,10,3,6,10,4,8,1587525,1310721,2,3,26,2,10,3, +6,10,4,8,1667197,14,1587523,9,10,3,6,10,4,8,1310721,2, +1,10,3,6,10,4,8,1664973,14,1585225,2,1587571,2,28,1,6, +1,10,28,34,63,38,3,26,1667259,16,3,1667311,14,1585225,2,1587551, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1667345,16,1310721,2,1310721,2,2,1663577,12, +10,3,6,10,4,8,1664973,14,1585225,2,1587533,2,28,1,6,1, +10,28,34,63,38,3,26,1667843,16,1655683,12,8,1310721,2,2,1609283, +12,8,1310721,2,11,26,1,10,3,6,10,4,8,1587633,2,1, +26,2,15,28,1,6,1,10,28,34,63,38,3,26,1667485,16, +1310721,2,11,26,1587633,2,10,3,6,10,4,8,1667589,14,1587633,2, +1587621,2,28,1,6,1,10,28,34,63,38,3,26,1667577,14,111, +110,108,121,32,102,117,110,99,116,105,111,110,115,32,99,97, +110,32,98,101,32,99,97,108,108,101,100,0,1667519,1587633,2,1639507, +12,8,1310721,2,13,26,1,17,1574703,12,8,1310721,2,5,26,1, +1310721,2,11,26,2,1310721,2,13,26,1656251,12,10,3,6,10,4, +8,1310721,2,5,26,2,1592283,12,8,7,1592369,12,8,13,1592369,12, +8,11,1592369,12,8,9,1592369,12,8,1587521,1,10,3,6,10,4, +8,1587523,1,10,3,6,10,4,8,1310721,2,1,10,3,6,10, +4,8,1587635,1,10,3,6,10,4,8,1587633,1587621,2,10,3,6, +10,4,8,1310721,2,11,26,2,1667839,16,1587633,1310721,2,11,26,2, +9,26,2,1310721,2,13,26,1633573,12,10,3,6,10,4,8,1664973, +14,1585225,2,1587553,2,28,1,6,1,10,28,34,63,38,3,26, +1667911,16,1601277,12,8,1310721,2,3,3,1662729,12,10,3,6,10,4, +8,1664973,14,1585225,2,1587555,2,28,1,6,1,10,28,34,63,38, +3,26,1667985,16,1601277,12,8,1310721,2,3,3,1,10,28,1662729,12, +10,3,6,10,4,8,1664973,14,1310721,2,2,1668011,14,1664973,14,1310721, +2,2,1668011,14,1,1310721,2,31,26,1310721,4,18,1310721,2,7,28, +1310721,4,1310721,2,1835009,40,1668059,16,1966081,1310721,4,1579223,12,1585223,2,5, +28,1,6,1,10,28,34,63,38,3,26,1668271,16,1585225,2,1587591, +2,28,1,6,1,10,28,34,63,38,3,26,1668131,16,3,1668183, +14,1585225,2,1587587,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1668193,16,3,1668245,14, +1585225,2,1587589,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,1668273,14,1,1668493,16,1310721,2,5,26,3,10, +3,6,10,4,8,1585225,2,1587591,2,28,1,6,1,10,28,34, +63,38,3,26,1668355,16,1310721,2,5,26,5,10,3,6,10,4, +8,1585225,2,1587589,2,28,1,6,1,10,28,34,63,38,3,26, +1668411,16,1310721,2,5,26,7,10,3,6,10,4,8,1601277,12,8, +1587557,2,1603237,12,8,1310721,2,1668025,12,10,3,6,10,4,8,1655683, +12,8,1587523,1,10,3,6,10,4,8,1310721,2,2,1310721,2,5, +26,2,1619895,12,1669891,14,1585223,2,9,28,1,6,1,10,28,34, +63,38,3,26,1669881,16,1585225,2,1587557,2,28,1,6,1,10,28, +34,63,38,3,26,1668859,16,1601277,12,8,1310721,2,1668025,12,10,3, +6,10,4,8,1655683,12,8,1310721,2,2,1609283,12,8,1587633,2,1, +26,2,11,28,1,6,1,10,28,34,63,38,3,26,1668647,16, +3,1668699,14,1587633,2,1587621,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1668771,14,111, +110,108,121,32,112,111,105,110,116,101,114,115,32,99,97,110, +32,98,101,32,100,101,114,101,102,101,114,101,110,99,101,100, +0,1668703,1587633,2,1639507,12,8,1587633,1587633,2,1635257,12,10,3,6,10, +4,8,1587521,3,10,3,6,10,4,8,1587523,9,10,3,6,10, +4,8,1587635,1,10,3,6,10,4,8,1,1669891,14,1585225,2,1587559, +2,28,1,6,1,10,28,34,63,38,3,26,1669375,16,1601277,12, +8,1310721,2,1668025,12,10,3,6,10,4,8,1587521,2,1,6,1, +10,28,34,63,38,3,26,1669001,16,1587633,2,1634803,12,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1669003,14,1,1669079,16,1669071,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,1669011,1589197,12,8,1587521,2,1669141,16,1587523, +2,3,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1669143,14,1,1669187,16,1558017,1587525,2, +26,2,33,32,1,6,1,10,28,34,63,38,1,10,28,1669189, +14,1,1669265,16,1669257,14,97,110,32,111,51,32,118,97,114,105, +97,98,108,101,32,104,97,115,32,110,111,32,97,100,100,114, +101,115,115,0,1669197,1588813,12,8,1310721,2,2,5,40,3,36,1669299, +16,1310721,2,2,5,28,1608795,12,8,1587521,1,10,3,6,10,4, +8,1587523,1,10,3,6,10,4,8,1587635,1,10,3,6,10,4, +8,1587633,1587633,2,1628759,12,10,3,6,10,4,8,1,1669891,14,1585225, +2,1587553,2,28,1,6,1,10,28,34,63,38,3,26,1669433,16, +1601277,12,8,1668025,12,8,1,3,1662729,12,1669891,14,1585225,2,1587555,2, +28,1,6,1,10,28,34,63,38,3,26,1669497,16,1601277,12,8, +1668025,12,8,1,3,1,10,28,1662729,12,1669891,14,1310721,2,3,26, +1585225,2,1605961,12,10,3,6,10,4,8,1310721,2,3,26,2,1, +40,3,36,1669881,16,1601277,12,8,1310721,2,1668025,12,10,3,6,10, +4,8,1655683,12,8,1310721,2,2,1609283,12,8,1547329,1310721,2,3,26, +2,26,2,1547393,1310721,2,3,26,2,26,2,1605023,12,8,1588201,1, +10,3,6,10,4,8,1310721,2,3,26,2,3,10,40,3,36, +1669691,16,1587633,1587627,2,10,3,6,10,4,8,1669827,14,1587633,2,1587621, +2,28,1,6,1,10,28,34,63,38,1,10,28,1669827,16,1587633, +2,1634571,12,1669797,14,116,104,105,115,32,111,112,101,114,97,116, +111,114,32,110,101,101,100,115,32,97,32,110,117,109,98,101, +114,0,1669739,1587633,2,1639507,12,8,1587633,1587623,2,10,3,6,10,4, +8,1587521,1,10,3,6,10,4,8,1587523,1,10,3,6,10,4, +8,1587635,1,10,3,6,10,4,8,1,1669891,14,1664929,12,1669891,14, +1,1310721,2,7,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2, +1835009,40,1669939,16,1966081,1310721,4,1579223,12,1310721,2,4,1668025,12,1310721,2, +3,26,4,1585223,2,9,28,1,6,1,10,28,34,63,38,3, +26,1670901,16,1310721,2,5,26,1585225,2,1605765,12,10,3,6,10,4, +8,1310721,2,5,26,2,1,40,1670051,16,1310721,2,3,26,2,1670917, +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,1670123,16,1310721,2, +3,26,2,1670917,14,1601277,12,8,1655683,12,8,1310721,2,3,26,2, +1609283,12,8,1310721,2,13,26,1587633,2,10,3,6,10,4,8,1547137, +1310721,2,5,26,2,26,2,3,1,10,28,28,1,6,1,10, +28,34,63,38,3,26,1670423,16,1310721,2,9,26,1592669,12,10,3, +6,10,4,8,17,1592369,12,8,1310721,2,3,26,1310721,2,7,26, +2,3,26,1669905,12,10,3,6,10,4,8,1655683,12,8,1310721,2, +3,26,2,1609283,12,8,1547329,3,26,2,1547393,3,26,2,1605023,12, +8,1310721,2,11,26,1592669,12,10,3,6,10,4,8,15,1592369,12, +8,1310721,2,9,26,2,1587483,2,1592451,12,8,1,1592283,12,8,1310721, +2,11,26,2,1587483,2,1592451,12,8,1670769,14,1547137,1310721,2,5,26, +2,26,2,5,1,10,28,28,1,6,1,10,28,34,63,38, +3,26,1670671,16,1310721,2,9,26,1592669,12,10,3,6,10,4,8, +17,1592369,12,8,3,1592283,12,8,1310721,2,11,26,1592669,12,10,3, +6,10,4,8,15,1592369,12,8,1310721,2,9,26,2,1587483,2,1592451, +12,8,1310721,2,3,26,1310721,2,7,26,2,3,26,1669905,12,10, +3,6,10,4,8,1655683,12,8,1310721,2,3,26,2,1609283,12,8, +1547329,3,26,2,1547393,3,26,2,1605023,12,8,1310721,2,11,26,2, +1587483,2,1592451,12,8,1670769,14,1310721,2,3,26,1310721,2,7,26,2, +3,26,1669905,12,10,3,6,10,4,8,1655683,12,8,1310721,2,3, +26,2,1609283,12,8,1547009,1310721,2,5,26,2,26,2,1547137,1310721,2, +5,26,2,26,2,1605023,12,8,1587633,1310721,2,5,26,2,1310721,2, +13,26,2,1587633,2,1650645,12,10,3,6,10,4,8,1587521,1,10, +3,6,10,4,8,1587523,1,10,3,6,10,4,8,1310721,2,3, +26,1,10,3,6,10,4,8,1587635,1,10,3,6,10,4,8, +1588201,1,10,3,6,10,4,8,1669959,14,1310721,2,3,26,2,1670917, +14,1,1310721,2,15,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1670965,16,1966081,1310721,4,1579223,12,11,1592369,12,8,3,1592283, +12,8,7,1592369,12,8,11,1592369,12,8,5,1592369,12,8,1,1671013, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,23,28,1310721,4,1310721, +2,1835009,40,1671061,16,1966081,1310721,4,1579223,12,1310721,2,4,1587503,2,1310721, +2,13,26,4,1587491,2,1310721,2,15,26,4,1655683,12,8,1310721,2, +2,1609283,12,8,1601277,12,8,1310721,2,3,26,1592669,12,10,3,6, +10,4,8,17,1592369,12,8,1310721,2,7,26,1610967,12,10,3,6, +10,4,8,1310721,2,17,26,1672327,12,10,3,6,10,4,8,1655683, +12,8,1310721,2,21,26,1587633,2,10,3,6,10,4,8,1310721,2, +17,26,2,3,28,1,6,1,10,28,34,63,38,1,10,28, +1671285,16,1310721,2,17,26,2,1609283,12,8,1310721,2,11,26,1587503,2, +10,3,6,10,4,8,1310721,2,9,26,1610967,12,10,3,6,10, +4,8,1310721,2,5,26,1592669,12,10,3,6,10,4,8,15,1592369, +12,8,1587561,2,1603237,12,8,1310721,2,3,26,2,1587483,2,1592451,12, +8,1310721,2,7,26,2,1611599,12,8,1587503,1310721,2,13,26,2,10, +3,6,10,4,8,1310721,2,19,26,1672327,12,10,3,6,10,4, +8,1655683,12,8,1310721,2,19,26,2,3,28,1,6,1,10,28, +34,63,38,1,10,28,1671521,16,1310721,2,19,26,2,1609283,12,8, +1310721,2,9,26,2,1310721,2,11,26,2,1310721,2,5,26,2,1587503, +2,1310721,2,15,26,2,1671659,14,101,110,100,115,32,116,104,101, +32,116,119,111,32,115,105,100,101,115,32,111,102,32,63,58, +32,105,110,32,100,105,102,102,101,114,101,110,116,32,115,116, +97,116,101,115,0,1671569,1619321,12,8,1310721,2,7,26,2,1611517,12, +8,1310721,2,21,26,2,1587633,2,1635445,12,1,6,1,10,28,34, +63,38,3,26,1671789,16,1587633,2,1310721,2,21,26,2,1635445,12,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1671791,14,1,1671861,16,1671839,14,116,104,101,32,116, +119,111,32,115,105,100,101,115,32,111,102,32,63,58,0,1671799, +1310721,2,21,26,2,1587633,2,1639107,12,8,1310721,2,21,26,2,1587621, +2,28,1,6,1,10,28,34,63,38,1,10,28,1671927,16,1587633, +1310721,2,21,26,2,10,3,6,10,4,8,1587521,1,10,3,6, +10,4,8,1587523,1,10,3,6,10,4,8,1587635,1,10,3,6, +10,4,8,1310721,2,17,26,2,3,28,1,6,1,10,28,34, +63,38,3,26,1672073,16,1310721,2,19,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,1672075,14,1,1672085,16,3,1672313,14,1310721,2,17,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1672129,16,3,1672185,14, +1310721,2,19,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,1672305,16,1672297,14, +98,111,116,104,32,115,105,100,101,115,32,111,102,32,63,58, +32,104,97,118,101,32,116,111,32,98,101,32,110,101,119,32, +111,98,106,101,99,116,115,44,32,111,114,32,110,101,105,116, +104,101,114,0,1672193,1589485,12,8,1,1672313,14,1,1310721,2,23,26, +1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1672361,16,1966081, +1310721,4,1579223,12,3,1669905,12,1310721,2,4,1585223,2,9,28,1,6, +1,10,28,34,63,38,1,10,28,1672417,16,1310721,2,2,1674511,14, +1585225,2,1587593,2,28,1,6,1,10,28,34,63,38,3,26,1672465, +16,1310721,2,2,1671027,12,1674511,14,1585225,2,1587549,2,28,1,6,1, +10,28,34,63,38,3,26,1673347,16,1587521,2,1,6,1,10,28, +34,63,38,3,26,1672591,16,1672583,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,1672531,1589197,12,8,1310721,2,3,26,1587523,2,10,3,6, +10,4,8,1310721,2,5,26,1587525,2,10,3,6,10,4,8,1310721, +2,11,26,1587633,2,10,3,6,10,4,8,1310721,2,11,26,2, +1634803,12,1672815,16,1672807,14,97,32,119,104,111,108,101,32,115,116, +114,117,99,116,32,111,114,32,97,114,114,97,121,32,99,97, +110,39,116,32,98,101,32,97,115,115,105,103,110,101,100,59, +32,97,115,115,105,103,110,32,105,116,115,32,102,105,101,108, +100,115,0,1672685,1588813,12,8,1601277,12,8,1310721,2,7,26,1587701,2, +1672897,16,1310721,2,3,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,1672899,14, +1,1672949,16,1558017,1310721,2,5,26,2,26,2,33,32,1,6,1, +10,28,34,63,38,1,10,28,1672951,14,1,1673017,16,1473025,1310721,2, +5,26,2,26,2,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1673019,14,1,10,3,6, +10,4,8,1310721,2,7,26,2,1673053,16,9,1592369,12,8,1310721,2, +9,26,1672327,12,10,3,6,10,4,8,1655683,12,8,1310721,2,11, +26,2,1587633,2,1635445,12,1,6,1,10,28,34,63,38,3,26, +1673173,16,1673151,14,97,115,115,105,103,110,109,101,110,116,0,1673129, +1310721,2,11,26,2,1587633,2,1639107,12,8,1310721,2,7,26,2,1673231, +16,1,1592283,12,8,7,1592369,12,8,1310721,2,5,26,2,1593311,12, +8,5,1592369,12,8,1673237,14,1670931,12,8,1587521,1,10,3,6,10, +4,8,1587523,1,10,3,6,10,4,8,1587633,1310721,2,11,26,2, +10,3,6,10,4,8,1587635,1,10,3,6,10,4,8,1310721,2, +3,26,2,1310721,2,5,26,2,1310721,2,9,26,2,1622667,12,1674511, +14,1310721,2,7,26,1585225,2,1606157,12,10,3,6,10,4,8,1310721, +2,7,26,2,1,40,3,36,1674499,16,1587521,2,1,6,1,10, +28,34,63,38,3,26,1673489,16,1673481,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,1673429,1589197,12,8,1587523,2,3,28,1,6,1,10, +28,34,63,38,3,26,1673551,16,1587499,2,1,6,1,10,28,34, +63,38,1,10,28,1673553,14,1,1673591,16,1587525,2,1608697,12,1,6, +1,10,28,34,63,38,1,10,28,1673593,14,1,1673713,16,1587525,2, +1673705,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,1673605,1589603,12,8,1310721,2,11,26,1587633,2,10,3, +6,10,4,8,1601277,12,8,1310721,2,5,26,1587701,2,1673813,16,1587523, +2,3,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1673815,14,1,1673859,16,1558017,1587525,2, +26,2,33,32,1,6,1,10,28,34,63,38,1,10,28,1673861, +14,1,1673921,16,1473025,1587525,2,26,2,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1673923,14, +1,10,3,6,10,4,8,1310721,2,5,26,2,1674043,16,1310721,2, +5,26,1587525,2,10,3,6,10,4,8,9,1592369,12,8,1310721,2, +5,26,2,1593311,12,8,3,1592369,12,8,1310721,2,5,26,1310721,2, +5,26,2,3,26,10,3,6,10,4,8,1674067,14,1,1592283,12, +8,7,1592369,12,8,3,1592369,12,8,1587521,1,10,3,6,10,4, +8,1310721,2,9,26,1672327,12,10,3,6,10,4,8,1655683,12,8, +1310721,2,9,26,2,1609283,12,8,1547009,1547585,1310721,2,7,26,2,26, +2,26,2,1547137,1547585,1310721,2,7,26,2,26,2,26,2,1605023,12, +8,1310721,2,3,26,1547585,1310721,2,7,26,2,26,2,1310721,2,11, +26,2,1587633,2,1650645,12,10,3,6,10,4,8,1310721,2,11,26, +2,1310721,2,3,26,2,1635445,12,1,6,1,10,28,34,63,38, +3,26,1674353,16,1674325,14,99,111,109,112,111,117,110,100,32,97, +115,115,105,103,110,109,101,110,116,0,1674285,1310721,2,11,26,2, +1310721,2,3,26,2,1639107,12,8,1310721,2,5,26,2,1674415,16,1, +1592283,12,8,7,1592369,12,8,1310721,2,5,26,2,3,28,1593311,12, +8,5,1592369,12,8,1674421,14,1670931,12,8,1587521,1,10,3,6,10, +4,8,1587523,1,10,3,6,10,4,8,1587633,1310721,2,11,26,2, +10,3,6,10,4,8,1587635,1,10,3,6,10,4,8,1,1674511, +14,1310721,2,2,1674511,14,1,1310721,2,13,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1674559,16,1966081,1310721,4,1579223,12,1585223, +2,9,28,1,6,1,10,28,34,63,38,3,26,1674723,16,1585225, +2,1587547,2,28,1,6,1,10,28,34,63,38,3,26,1674631,16, +3,1674683,14,1585225,2,1587537,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1674693,16,3, +1674719,14,1642613,12,1,6,1,10,28,34,63,38,1,10,28,1675005, +14,1585223,2,5,28,1,6,1,10,28,34,63,38,1,10,28, +1674763,16,3,1674801,14,1585225,2,1607893,12,1,40,3,36,1,6,1, +10,28,34,63,38,1,10,28,1674811,16,1,1675005,14,1642613,12,1674825, +16,3,1675005,14,1310721,2,1585225,2,1590943,12,10,3,6,10,4,8, +1310721,2,2,1,40,3,36,1674929,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,1674931,14,1,1674997,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,1674999,14,1,1675005,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1675053, +16,1966081,1310721,4,1579223,12,1587491,2,1310721,2,4,1,1310721,2,3,26, +4,1,1310721,2,5,26,4,1587623,2,1310721,2,7,26,4,1601277,12, +8,1587495,1,6,2,1,6,3,26,5,6,4,10,8,8,1587505, +1,6,2,1,6,3,26,5,6,4,10,8,8,1587539,2,1602703, +12,1,6,1,10,28,34,63,38,3,26,1675535,16,1585223,2,1, +28,1,6,1,10,28,34,63,38,3,26,1675259,16,1675251,14,109, +105,115,115,105,110,103,32,125,0,1675231,1589197,12,8,1674525,12,1675277, +16,1677555,12,8,1675163,14,1310721,2,3,26,1672327,12,10,3,6,10, +4,8,1655683,12,8,1587547,2,1603007,12,1675369,16,9,1592369,12,8,1310721, +2,3,26,2,1627951,12,8,1310721,2,3,26,1,10,3,6,10, +4,8,1675163,14,1587539,2,1602703,12,1,6,1,10,28,34,63,38, +3,26,1675485,16,1675477,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,1675405,1589197,12,8,1310721,2, +5,26,3,10,3,6,10,4,8,1310721,2,7,26,1587633,2,10, +3,6,10,4,8,1675163,14,1601277,12,8,1310721,2,5,26,2,1675593, +16,1310721,2,3,26,1310721,2,3,26,2,1627235,12,10,3,6,10, +4,8,1675601,14,1,1592283,12,8,1310721,2,2,1610695,12,8,1587495,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1587505,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1587521,1,10,3,6,10, +4,8,1587523,1,10,3,6,10,4,8,1587633,1310721,2,7,26,2, +10,3,6,10,4,8,1587635,1,10,3,6,10,4,8,1310721,2, +3,26,2,1675757,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1675805,16,1966081,1310721,4,1579223,12,1585223,2, +3,28,1,6,1,10,28,34,63,38,3,26,1675873,16,1310721,2, +1585225,2,10,3,6,10,4,8,1601277,12,8,1310721,2,2,1676573,14, +1587565,2,1603007,12,1675897,16,1,1675771,12,28,1676573,14,1585223,2,9,28, +1,6,1,10,28,34,63,38,3,26,1675989,16,1585225,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,1675991,14,1,1676013,16,1601277,12,8, +1675771,12,-1,36,1676573,14,1587533,2,1603007,12,1676065,16,1310721,2,1676587,12, +10,3,6,10,4,8,1587535,2,1603237,12,8,1310721,2,2,1676573,14, +1585223,2,5,28,1,6,1,10,28,34,63,38,3,26,1676513,16, +1310721,2,3,26,1585225,2,1590943,12,10,3,6,10,4,8,1310721,2, +3,26,2,1,40,3,36,1676481,16,1417729,1310721,2,3,26,2,26, +2,9,28,1,6,1,10,28,34,63,38,3,26,1676197,16,3, +1676259,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,1676269,16,3,1676383,14,1417729,1310721,2,3,26,2,26,2,3,28, +1,6,1,10,28,34,63,38,3,26,1676359,16,1442305,1310721,2,3, +26,2,26,2,3,32,1,6,1,10,28,34,63,38,1,10, +28,1676361,14,1,1,6,1,10,28,34,63,38,1,10,28,1676393, +16,3,1676455,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,1676483,14, +1,1676513,16,1601277,12,8,1425921,1310721,2,3,26,2,26,2,1676573,14, +1676557,14,101,120,112,101,99,116,101,100,32,97,32,99,111,110, +115,116,97,110,116,0,1676517,1589197,12,8,1,1676573,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1676621, +16,1966081,1310721,4,1579223,12,1675771,12,1310721,2,4,1585223,2,9,28,1, +6,1,10,28,34,63,38,3,26,1677275,16,1310721,2,3,26,1585225, +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,1676769,16,1601277,12,8, +1310721,2,1310721,2,2,1675771,12,26,10,3,6,10,4,8,1677271,14, +1310721,2,3,26,2,1546753,9,26,2,28,1,6,1,10,28,34, +63,38,3,26,1676851,16,1601277,12,8,1310721,2,1310721,2,2,1675771,12, +28,10,3,6,10,4,8,1677271,14,1310721,2,3,26,2,1546753,1, +26,2,28,1,6,1,10,28,34,63,38,3,26,1676933,16,1601277, +12,8,1310721,2,1310721,2,2,1675771,12,30,10,3,6,10,4,8, +1677271,14,1310721,2,3,26,2,1546753,31,26,2,28,1,6,1,10, +28,34,63,38,3,26,1677015,16,1601277,12,8,1310721,2,1310721,2,2, +1675771,12,34,10,3,6,10,4,8,1677271,14,1310721,2,3,26,2, +1546753,27,26,2,28,1,6,1,10,28,34,63,38,3,26,1677097, +16,1601277,12,8,1310721,2,1310721,2,2,1675771,12,32,10,3,6,10, +4,8,1677271,14,1310721,2,3,26,2,1546753,11,26,2,28,1,6, +1,10,28,34,63,38,3,26,1677179,16,1601277,12,8,1310721,2,1310721, +2,2,1675771,12,48,10,3,6,10,4,8,1677271,14,1310721,2,3, +26,2,1546753,13,26,2,28,1,6,1,10,28,34,63,38,3, +26,1677261,16,1601277,12,8,1310721,2,1310721,2,2,1675771,12,38,10,3, +6,10,4,8,1677271,14,1310721,2,2,1677287,14,1676631,14,1310721,2,2, +1677287,14,1,1310721,2,5,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1677335,16,1966081,1310721,4,1579223,12,1585223,2,1,28,1, +6,1,10,28,34,63,38,1,10,28,1677423,16,1587547,2,1602703,12, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1677425,14,1,1677483,16,1587539,2,1602703,12,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1677485,14,1,1677499,16,1601277,12,8,1677335,14,1587547,2,1602703, +12,1677517,16,1601277,12,8,1588225,1,10,3,6,10,4,8,1,1677541, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1677589,16,1966081,1310721,4,1579223,12,1588225,2,1677605,16,1677301,12, +1678077,14,1585223,2,5,28,1,6,1,10,28,34,63,38,3,26, +1677675,16,1585225,2,1607893,12,1,40,1,6,1,10,28,34,63,38, +1,10,28,1677677,14,1,1677859,16,1310721,2,1585225,2,1590943,12,10,3, +6,10,4,8,1310721,2,2,1,40,3,36,1677785,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,1677787,14,1,1677833,16,1442305, +1310721,2,2,26,2,17,32,1,6,1,10,28,34,63,38,1, +10,28,1677835,14,1,1677859,16,1310721,2,2,1,1655803,12,8,1,1678077, +14,1642613,12,1677881,16,3,1678507,12,8,1,1678077,14,1585223,2,9,28, +1,6,1,10,28,34,63,38,3,26,1678005,16,1585225,2,1587547,2, +28,1,6,1,10,28,34,63,38,3,26,1677959,16,1601277,12,8, +1,1678077,14,1585225,2,1587537,2,28,1,6,1,10,28,34,63,38, +3,26,1678005,16,1678091,12,8,1,1678077,14,1310721,2,3,26,1672327,12, +10,3,6,10,4,8,1655683,12,8,9,1592369,12,8,1587547,2,1603237, +12,8,1310721,2,3,26,2,1627951,12,8,1,1678077,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1678125, +16,1966081,1310721,4,1579223,12,1587491,2,1310721,2,4,1587537,2,1603237,12,8, +1587495,1,6,2,1,6,3,26,5,6,4,10,8,8,1587539,2, +1602703,12,1,6,1,10,28,34,63,38,3,26,1678279,16,1585223,2, +1,28,1,6,1,10,28,34,63,38,3,26,1678269,16,1678261,14, +109,105,115,115,105,110,103,32,125,0,1678241,1589197,12,8,1677555,12, +8,1678173,14,1310721,2,2,1610695,12,8,1601277,12,8,1587495,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1,1678333,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1678381, +16,1966081,1310721,4,1579223,12,1587491,2,1310721,2,4,1587537,2,1602703,12,1678411, +16,1678091,12,1678493,14,1587495,1,6,2,1,6,3,26,5,6,4, +10,8,8,1677555,12,8,1310721,2,2,1610695,12,8,1587495,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1,1678493,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1678541, +16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2,11,26,4,1, +1310721,2,13,26,4,1310721,2,2,1678737,16,1643415,12,8,1310721,2,11, +26,1587657,2,10,3,6,10,4,8,1310721,2,13,26,1587659,2,10, +3,6,10,4,8,1310721,2,11,26,2,1587629,2,28,1,6,1, +10,28,34,63,38,3,26,1678737,16,1678729,14,97,32,118,97,114, +105,97,98,108,101,32,99,97,110,39,116,32,98,101,32,118, +111,105,100,0,1678679,1588813,12,8,1587701,2,1678751,16,3,1678777,14,1587705, +2,1,6,1,10,28,34,63,38,1,10,28,1678833,16,1310721,2, +2,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1678835,14,1,1678901,16,1678893,14,111,51,32, +118,97,114,105,97,98,108,101,115,32,110,101,101,100,32,97, +32,116,121,112,101,0,1678843,1588813,12,8,3,1680017,16,1310721,2,3, +26,1603527,12,10,3,6,10,4,8,1310721,2,5,26,1310721,2,3, +26,2,1608097,12,10,3,6,10,4,8,1558017,1310721,2,5,26,2, +26,1310721,2,13,26,2,10,3,6,10,4,8,1587701,2,1679015,16, +3,1679041,14,1587705,2,1,6,1,10,28,34,63,38,1,10,28, +1679085,16,1558017,1310721,2,5,26,2,26,1310721,2,13,26,2,33,34, +10,3,6,10,4,8,1587541,2,1603007,12,1679311,16,1310721,2,9,26, +1676587,12,10,3,6,10,4,8,1587543,2,1603237,12,8,1310721,2,11, +26,2,1,6,1,10,28,34,63,38,3,26,1679189,16,1310721,2, +11,26,1587621,2,10,3,6,10,4,8,1473025,1310721,2,5,26,2, +26,3,10,3,6,10,4,8,1556993,1310721,2,5,26,2,26,1310721, +2,11,26,2,1310721,2,9,26,2,1629133,12,10,3,6,10,4, +8,1587497,1587497,2,1556993,1310721,2,5,26,2,26,2,1633401,12,26,10, +3,6,10,4,8,1679581,14,1310721,2,11,26,2,1679365,16,1310721,2, +11,26,2,1634803,12,1,6,1,10,28,34,63,38,1,10,28, +1679367,14,1,1679473,16,1473025,1310721,2,5,26,2,26,3,10,3,6, +10,4,8,1556993,1310721,2,5,26,2,26,1310721,2,11,26,2,10, +3,6,10,4,8,1587497,1587497,2,1310721,2,11,26,2,1633401,12,26, +10,3,6,10,4,8,1679581,14,1587497,1,6,2,1,6,3,26, +5,6,4,10,8,8,1310721,2,11,26,2,1679551,16,1556993,1310721,2, +5,26,2,26,1310721,2,11,26,2,10,3,6,10,4,8,1587701, +2,1679581,16,1467905,1310721,2,5,26,2,26,2,1593579,12,8,1587549,2, +1603007,12,1679977,16,1473025,1310721,2,5,26,2,26,2,1679723,16,1679715,14, +97,110,32,97,114,114,97,121,32,111,114,32,97,32,115,116, +114,117,99,116,32,99,97,110,39,116,32,98,101,32,105,110, +105,116,105,97,108,105,122,101,100,32,119,105,116,104,32,61, +0,1679617,1588813,12,8,1310721,2,7,26,1672327,12,10,3,6,10,4, +8,1655683,12,8,1310721,2,5,26,2,1593311,12,8,5,1592369,12,8, +1310721,2,11,26,2,1679887,16,1310721,2,11,26,2,1587633,2,1635445,12, +1,6,1,10,28,34,63,38,3,26,1679883,16,1679861,14,105,110, +105,116,105,97,108,105,122,101,114,0,1679837,1310721,2,11,26,2, +1587633,2,1639107,12,8,1679949,14,1587633,2,1634571,12,1,6,1,10,28, +34,63,38,3,26,1679949,16,1556993,1310721,2,5,26,2,26,1587633,2, +10,3,6,10,4,8,3,1310721,2,5,26,2,1310721,2,7,26, +2,1622667,12,8,1587545,2,1603007,12,1,6,1,10,28,34,63,38, +3,26,1680013,16,1680017,14,1678901,14,1587547,2,1603237,12,8,1,1680035,14, +1,1310721,2,15,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2, +1835009,40,1680083,16,1966081,1310721,4,1579223,12,1656095,12,8,1601277,12,8,1, +1678507,12,1680107,14,1,1310721,2,1,26,1310721,4,18,1310721,2,21,28, +1310721,4,1310721,2,1835009,40,1680155,16,1966081,1310721,4,1579223,12,1587491,2,1310721, +2,15,26,4,1656095,12,8,1601277,12,8,1587533,2,1603237,12,8,1310721, +2,5,26,1672327,12,10,3,6,10,4,8,1655683,12,8,1310721,2, +5,26,2,1609283,12,8,1587535,2,1603237,12,8,1310721,2,1592669,12,10, +3,6,10,4,8,17,1592369,12,8,1310721,2,11,26,1587503,2,10, +3,6,10,4,8,1310721,2,7,26,1610967,12,10,3,6,10,4, +8,1678347,12,8,1310721,2,13,26,1587503,2,10,3,6,10,4,8, +1310721,2,9,26,1610967,12,10,3,6,10,4,8,1587579,2,1602855,12, +1680643,16,1601277,12,8,1310721,2,3,26,1592669,12,10,3,6,10,4, +8,15,1592369,12,8,1310721,2,2,1587483,2,1592451,12,8,1310721,2,7, +26,2,1611599,12,8,1587503,1310721,2,11,26,2,10,3,6,10,4, +8,1678347,12,8,1310721,2,9,26,2,1310721,2,13,26,2,1310721,2, +3,26,2,1587503,2,1310721,2,15,26,2,1680631,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,1680537,1619321,12,8,1681175, +14,1613965,1,10,3,6,10,4,8,1310721,2,13,26,2,1680693,16, +1507841,1310721,2,9,26,2,26,1614933,12,8,1310721,2,11,26,2,1680727, +16,1507841,1310721,2,7,26,2,26,1614933,12,8,1310721,2,15,26,2, +1680835,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,1680741,1615661,12,8,1310721,2,13,26,2,1680889,16,1507841,1310721,2,9, +26,2,26,1310721,2,15,26,2,3,1617245,12,8,1310721,2,17,26, +1,10,3,6,10,4,8,1310721,2,11,26,2,1680975,16,1310721,2, +17,26,1507841,1310721,2,7,26,2,26,1310721,2,15,26,2,1,1617245, +12,10,3,6,10,4,8,1310721,2,17,26,2,1681093,16,1310721,2, +19,26,1592669,12,10,3,6,10,4,8,15,1592369,12,8,1310721,2, +2,1587483,2,1592451,12,8,1507841,1310721,2,7,26,2,26,1310721,2,15, +26,2,3,1617245,12,8,1310721,2,19,26,2,1587483,2,1592451,12,8, +1681109,14,1310721,2,2,1587483,2,1592451,12,8,1587503,1310721,2,13,26,2, +1681131,16,3,1681163,14,1310721,2,11,26,2,1,6,1,10,28,34, +63,38,1,10,28,10,3,6,10,4,8,1310721,2,7,26,2, +1611517,12,8,1,1681199,14,1,1310721,2,21,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1681247,16,1966081,1310721,4,1579223,12,1310721, +2,3,26,4,1310721,2,4,1552897,1587513,2,17,30,26,1310721,2,5, +26,4,1587513,2,121,40,3,36,1681361,16,1681353,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,1681305,1588719,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,1587495,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,1587505,2, +10,3,6,10,4,8,1310721,2,5,26,2,11,26,1587491,2,10, +3,6,10,4,8,1310721,2,5,26,2,13,26,1613835,2,10,3, +6,10,4,8,1587513,1,6,2,1,6,3,26,5,6,4,10, +8,8,1,1681613,14,1,1310721,2,7,26,1310721,4,18,1310721,2,15, +28,1310721,4,1310721,2,1835009,40,1681661,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1,1310721,2,13,26,4,1587513,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1310721,2,5,26,1552897,1587513, +2,17,30,26,10,3,6,10,4,8,1310721,2,11,26,1310721,2, +5,26,2,11,26,2,10,3,6,10,4,8,1613965,1,10,3, +6,10,4,8,1310721,2,3,26,2,1,40,3,36,1681843,16,1507841, +1310721,2,3,26,2,26,1614933,12,8,1310721,2,7,26,1567233,1310721,2, +5,26,2,13,26,2,26,10,3,6,10,4,8,1310721,2,9, +26,1567233,1613835,2,26,10,3,6,10,4,8,1310721,2,7,26,2, +1310721,2,9,26,2,40,1682035,16,1310721,2,7,26,2,3,26,1614933, +12,8,1310721,2,7,26,1310721,2,7,26,2,7,26,7,1310721,2, +7,26,2,5,26,2,1310721,2,7,26,2,3,26,2,28,30, +26,10,3,6,10,4,8,1681911,14,1310721,2,11,26,2,1682159,14, +108,101,97,118,101,115,32,116,104,101,32,108,111,111,112,32, +105,110,32,100,105,102,102,101,114,101,110,116,32,115,116,97, +116,101,115,32,111,110,32,100,105,102,102,101,114,101,110,116, +32,112,97,116,104,115,0,1682049,1615661,12,8,1587503,1613965,2,1,10, +40,10,3,6,10,4,8,1310721,2,7,26,1567233,1310721,2,5,26, +2,13,26,2,26,10,3,6,10,4,8,1310721,2,7,26,2, +1310721,2,9,26,2,40,1682527,16,1310721,2,7,26,2,3,26,1310721, +2,11,26,2,1,1617245,12,1682399,16,1310721,2,7,26,2,1,26, +2,1587483,2,1592451,12,8,1310721,2,7,26,2,3,26,1310721,2,11, +26,2,3,1617245,12,8,1310721,2,13,26,1592669,12,1310721,2,13,26, +2,1591519,12,10,3,6,10,4,8,15,1592369,12,8,1682449,14,1310721, +2,13,26,1310721,2,7,26,2,1,26,2,1310721,2,13,26,2, +1591519,12,10,3,6,10,4,8,1310721,2,7,26,1310721,2,7,26, +2,7,26,7,1310721,2,7,26,2,5,26,2,1310721,2,7,26, +2,3,26,2,28,30,26,10,3,6,10,4,8,1682231,14,1310721, +2,2,1,40,3,36,1682561,16,1310721,2,2,1587483,2,1592451,12,8, +1310721,2,3,26,2,1,40,3,36,1682615,16,1507841,1310721,2,3,26, +2,26,1310721,2,11,26,2,3,1617245,12,8,1310721,2,13,26,2, +1587483,2,1591871,12,8,1613835,1310721,2,5,26,2,13,26,2,10,3, +6,10,4,8,1,1682673,14,1,1310721,2,15,26,1310721,4,18,1310721, +2,13,28,1310721,4,1310721,2,1835009,40,1682721,16,1966081,1310721,4,1579223,12, +1587483,2,1310721,2,4,3,1,10,28,1310721,2,7,26,4,1,1310721, +2,11,26,4,1656095,12,8,1601277,12,8,1310721,2,5,26,1610967,12, +10,3,6,10,4,8,1587533,2,1603237,12,8,1585223,2,3,28,1, +6,1,10,28,34,63,38,3,26,1682869,16,1585225,2,1,6,1, +10,28,34,63,38,1,10,28,1682871,14,1,1682997,16,1602137,12,8, +1587445,2,9,28,1,6,1,10,28,34,63,38,3,26,1682969,16, +1587447,2,1587535,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1682971,14,1,1682997,16,1310721, +2,11,26,3,10,3,6,10,4,8,1310721,2,9,26,1672327,12, +10,3,6,10,4,8,1655683,12,8,1310721,2,9,26,2,1609283,12, +8,1587535,2,1603237,12,8,1310721,2,3,26,1592669,12,10,3,6,10, +4,8,17,1592369,12,8,1310721,2,11,26,2,1,6,1,10,28, +34,63,38,3,26,1683149,16,1587503,2,1,6,1,10,28,34,63, +38,1,10,28,1683151,14,1,1683179,16,1310721,2,7,26,1610967,12,10, +3,6,10,4,8,1310721,2,2,1310721,2,5,26,2,1681213,12,8, +1678347,12,8,1310721,2,5,26,2,1617739,12,8,1310721,2,2,1592587,12, +8,1310721,2,3,26,2,1310721,2,7,26,2,1681627,12,8,1310721,2, +5,26,2,1611517,12,8,1,1683285,14,1,1310721,2,13,26,1310721,4, +18,1310721,2,19,28,1310721,4,1310721,2,1835009,40,1683333,16,1966081,1310721,4, +1579223,12,1587491,2,1310721,2,4,3,1,10,28,1310721,2,5,26,4, +1,1310721,2,17,26,4,1656095,12,8,1601277,12,8,1587533,2,1603237,12, +8,1587495,1,6,2,1,6,3,26,5,6,4,10,8,8,1587575, +2,1602855,12,1683445,16,1680049,12,8,1683561,14,1642613,12,1683465,16,3,1678507, +12,8,1683561,14,1587547,2,1602703,12,1,6,1,10,28,34,63,38, +3,26,1683551,16,1310721,2,15,26,1672327,12,10,3,6,10,4,8, +1655683,12,8,9,1592369,12,8,1310721,2,15,26,2,1627951,12,8,1587547, +2,1603237,12,8,1310721,2,3,26,1610967,12,10,3,6,10,4,8, +1310721,2,7,26,1587483,2,10,3,6,10,4,8,1587547,2,1602703,12, +1,6,1,10,28,34,63,38,3,26,1683881,16,1585223,2,3,28, +1,6,1,10,28,34,63,38,3,26,1683703,16,1585225,2,1,6, +1,10,28,34,63,38,1,10,28,1683705,14,1,1683831,16,1602137,12, +8,1587445,2,9,28,1,6,1,10,28,34,63,38,3,26,1683803, +16,1587447,2,1587547,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1683805,14,1,1683831,16, +1310721,2,17,26,3,10,3,6,10,4,8,1310721,2,15,26,1672327, +12,10,3,6,10,4,8,1655683,12,8,1310721,2,15,26,2,1609283, +12,8,1683911,14,3,1592283,12,8,1310721,2,17,26,3,10,3,6, +10,4,8,1587547,2,1603237,12,8,1310721,2,9,26,1592669,12,10,3, +6,10,4,8,17,1592369,12,8,1310721,2,17,26,2,1,6,1, +10,28,34,63,38,3,26,1684017,16,1587503,2,1,6,1,10,28, +34,63,38,1,10,28,1684019,14,1,1684047,16,1310721,2,5,26,1610967, +12,10,3,6,10,4,8,1310721,2,11,26,1592669,12,10,3,6, +10,4,8,15,1592369,12,8,1310721,2,13,26,1587483,2,10,3,6, +10,4,8,1587535,2,1602703,12,1,6,1,10,28,34,63,38,3, +26,1684189,16,1310721,2,15,26,1672327,12,10,3,6,10,4,8,1655683, +12,8,9,1592369,12,8,1310721,2,15,26,2,1627951,12,8,1587535,2, +1603237,12,8,1310721,2,7,26,2,1592587,12,8,1310721,2,11,26,2, +1587483,2,1592451,12,8,1310721,2,13,26,2,1310721,2,3,26,2,1681213, +12,8,1678347,12,8,1310721,2,3,26,2,1617739,12,8,1310721,2,13, +26,2,1592587,12,8,1310721,2,9,26,2,1310721,2,5,26,2,1681627, +12,8,1310721,2,3,26,2,1611517,12,8,1310721,2,2,1610695,12,8, +1587495,1,6,2,1,6,-1,26,5,6,4,10,8,8,1,1684389, +14,1,1310721,2,19,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1684437,16,1966081,1310721,4,1579223,12,1656095,12,8,1601277,12,8, +1587547,2,1603237,12,8,1587513,2,1587515,2,10,40,3,36,1684563,16,1684549, +14,98,114,101,97,107,32,111,117,116,115,105,100,101,32,97, +32,108,111,111,112,32,111,114,32,97,32,115,119,105,116,99, +104,0,1684483,1588813,12,8,1,1684815,14,1310721,2,1552897,1587513,2,3,28, +17,30,26,10,3,6,10,4,8,1310721,2,2,9,26,2,1587505, +2,28,1,6,1,10,28,34,63,38,1,10,28,1684731,16,1684717, +14,98,114,101,97,107,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,1684643,1588813,12,8,1,1684815,14,1310721,2,2, +5,26,2,3,26,1,1609669,12,8,1587503,2,1684777,16,1592669,12,1614341, +12,8,1684783,14,1592669,12,8,15,1592369,12,8,1587503,1,10,3,6, +10,4,8,1,1684815,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1684863,16,1966081,1310721,4,1579223,12,1587513, +2,3,28,1310721,2,4,1656095,12,8,1601277,12,8,1587547,2,1603237,12, +8,1310721,2,2,1587515,2,40,3,36,1684991,16,1552897,1310721,2,2,17, +30,26,2,3,1,10,28,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1684993,14,1, +1685031,16,1310721,2,1,6,2,1,6,-1,26,5,6,4,10,8, +8,1684899,14,1310721,2,2,1587515,2,40,1685113,16,1685099,14,99,111,110, +116,105,110,117,101,32,111,117,116,115,105,100,101,32,97,32, +108,111,111,112,0,1685051,1588813,12,8,1,1685389,14,1310721,2,3,26, +1552897,1310721,2,2,17,30,26,10,3,6,10,4,8,1310721,2,3, +26,2,9,26,2,1587505,2,28,1,6,1,10,28,34,63,38, +1,10,28,1685293,16,1685279,14,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,1685199, +1588813,12,8,1,1685389,14,1310721,2,3,26,2,7,26,2,1617739,12, +8,1310721,2,3,26,2,5,26,2,3,26,1,1609669,12,8,1310721, +2,3,26,2,1,26,2,1592587,12,8,1587503,1,10,3,6,10, +4,8,1,1685389,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7, +28,1310721,4,1310721,2,1835009,40,1685437,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1587491,2,1310721,2,5,26,4,1310721,2,2, +1611599,12,8,1587503,1310721,2,3,26,2,10,3,6,10,4,8,1587495, +1,6,2,1,6,3,26,5,6,4,10,8,8,1587539,2,1602703, +12,1,6,1,10,28,34,63,38,3,26,1685617,16,1587595,2,1602855, +12,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1685619,14,1,1685677,16,1587597,2,1602855,12,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1685679,14,1,1685761,16,1585223,2,1,28,1,6,1, +10,28,34,63,38,3,26,1685751,16,1685739,14,109,105,115,115,105, +110,103,32,125,0,1685719,1589197,12,8,1685761,14,1677555,12,8,1685531,14, +1310721,2,5,26,2,1610695,12,8,1587495,1,6,2,1,6,-1,26, +5,6,4,10,8,8,1587503,2,1685831,16,1592669,12,1614341,12,8,15, +1592369,12,8,1587503,1,10,3,6,10,4,8,1,1685855,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,23,28,1310721,4,1310721,2,1835009,40, +1685903,16,1966081,1310721,4,1579223,12,1587491,2,1310721,2,4,3,1,10,28, +1310721,2,11,26,4,3,1,10,28,1310721,2,21,26,4,1656095,12, +8,1601277,12,8,1587533,2,1603237,12,8,1310721,2,5,26,1672327,12,10, +3,6,10,4,8,1655683,12,8,1310721,2,5,26,2,1609283,12,8, +1587535,2,1603237,12,8,1587495,1,6,2,1,6,3,26,5,6,4, +10,8,8,1310721,2,3,26,1,1608097,12,10,3,6,10,4,8, +1587497,1,6,2,1,6,3,26,5,6,4,10,8,8,1467905,1310721, +2,3,26,2,26,2,1593203,12,8,5,1592369,12,8,1310721,2,9, +26,1587503,2,10,3,6,10,4,8,1310721,2,7,26,1610967,12,10, +3,6,10,4,8,3,1,10,28,1310721,2,7,26,2,1681213,12, +8,1587537,2,1603237,12,8,1587539,2,1602703,12,1,6,1,10,28,34, +63,38,3,26,1686927,16,1585223,2,1,28,1,6,1,10,28,34, +63,38,3,26,1686321,16,1686309,14,109,105,115,115,105,110,103,32, +125,0,1686289,1589197,12,8,1686927,14,1587595,2,1602855,12,1686643,16,1601277,12, +8,1310721,2,17,26,1,10,3,6,10,4,8,3,1686531,16,1310721, +2,19,26,1676587,12,10,3,6,10,4,8,1467905,1310721,2,3,26, +2,26,2,1593203,12,8,3,1592369,12,8,1310721,2,19,26,2,1592283, +12,8,29,1592369,12,8,1310721,2,17,26,1592669,12,1310721,2,17,26, +2,1591519,12,10,3,6,10,4,8,17,1592369,12,8,1587545,2,1603007, +12,1,6,1,10,28,34,63,38,3,26,1686527,16,1686531,14,1686361, +14,1587561,2,1603237,12,8,1310721,2,15,26,1592669,12,10,3,6,10, +4,8,15,1592369,12,8,1310721,2,17,26,2,1587483,2,1591871,12,8, +1310721,2,7,26,2,1310721,2,9,26,2,1685403,12,8,1310721,2,15, +26,2,1587483,2,1592451,12,8,1686923,14,1587597,2,1602855,12,1686861,16,1601277, +12,8,1587561,2,1603237,12,8,1310721,2,11,26,2,1,40,3,36, +1686755,16,1686747,14,97,32,115,119,105,116,99,104,32,104,97,115, +32,111,110,101,32,100,101,102,97,117,108,116,0,1686697,1588813,12, +8,1310721,2,13,26,1592669,12,10,3,6,10,4,8,15,1592369,12, +8,1310721,2,11,26,1587483,2,10,3,6,10,4,8,1310721,2,7, +26,2,1310721,2,9,26,2,1685403,12,8,1310721,2,13,26,2,1587483, +2,1592451,12,8,1686923,14,1686915,14,101,120,112,101,99,116,101,100, +32,99,97,115,101,32,111,114,32,100,101,102,97,117,108,116, +0,1686865,1589197,12,8,1686221,14,1601277,12,8,1310721,2,7,26,2,1611599, +12,8,1587503,1310721,2,9,26,2,10,3,6,10,4,8,1310721,2, +11,26,2,1,40,3,36,1687037,16,1310721,2,11,26,2,1592587,12, +8,3,1,10,28,3,1,10,28,1681627,12,8,1687095,14,1310721,2, +21,26,1592669,12,10,3,6,10,4,8,15,1592369,12,8,1310721,2, +21,26,2,1310721,2,7,26,2,1681627,12,8,1310721,2,7,26,2, +1611517,12,8,1310721,2,2,1610695,12,8,1587495,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1,1687159,14,1,1310721,2,23,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1687207,16,1966081,1310721, +4,1579223,12,1656095,12,8,1601277,12,8,1587511,2,1,6,1,10,28, +34,63,38,3,26,1687311,16,1687303,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,1687251,1588813,12,8,1587505,2,1687407,16,1687399,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,1687323,1588813,12,8,1587547,2,1602703,12,1687449,16,1,1592283,12, +8,1310721,2,1,10,3,6,10,4,8,1687677,14,1310721,2,1672327,12, +10,3,6,10,4,8,1655683,12,8,1587531,2,1587629,2,28,1,6, +1,10,28,34,63,38,3,26,1687559,16,1687539,14,114,101,116,117, +114,110,32,118,97,108,117,101,0,1687513,1587629,2,1587633,2,1639107,12, +8,1687677,14,1587531,2,1687625,16,1587531,2,1587633,2,1635445,12,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1687627,14,1,1687677,16,1687661,14,114,101,116,117,114,110,32, +118,97,108,117,101,0,1687635,1587531,2,1587633,2,1639107,12,8,1587547,2, +1603237,12,8,1310721,2,2,1626221,12,8,3,1,1609669,12,8,1587507,1587483, +2,1587507,2,1591519,12,10,3,6,10,4,8,2097153,3,28,1592283,12, +8,15,1592369,12,8,1587503,1,10,3,6,10,4,8,1,1687779,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2, +1835009,40,1687827,16,1966081,1310721,4,1579223,12,1656095,12,8,1601277,12,8,1587537, +2,1602703,12,1,6,1,10,28,34,63,38,3,26,1687917,16,1587705, +3,10,3,6,10,4,8,3,1678507,12,8,1587705,1,10,3,6, +10,4,8,1,1688481,14,1587701,2,1687931,16,3,1687977,14,1587511,2,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1687989,16,1678091,12,1688481,14,1310721,2,1587483,2,5,26, +10,3,6,10,4,8,1310721,2,2,1592283,12,8,15,1592369,12,8, +1587701,3,10,3,6,10,4,8,1587723,1,10,3,6,10,4,8, +1310721,2,3,26,1587493,2,10,3,6,10,4,8,1310721,2,3,26, +2,1587491,2,40,1688261,16,1558017,1310721,2,3,26,2,26,2,33,32, +1688195,16,1473025,1310721,2,3,26,2,26,2,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1688197, +14,1,1688223,16,1467905,1310721,2,3,26,2,26,2,1593579,12,8,1310721, +2,3,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1688089,14,1678091,12,8,1587701,1,10,3,6,10,4,8,1588125,2,41, +40,1688473,16,1310721,2,5,26,1587725,1588125,2,21,30,26,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,1587483,2,10,3,6,10, +4,8,1310721,2,5,26,2,5,26,1587723,2,10,3,6,10,4, +8,1310721,2,5,26,2,7,26,1587707,1587723,2,1574491,12,8,1588125,1, +6,2,1,6,3,26,5,6,4,10,8,8,1,1688481,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1688529,16,1966081,1310721,4,1579223,12,1587499,2,1310721,2,4,1656095,12,8, +1601277,12,8,1587499,1,10,3,6,10,4,8,1678347,12,8,1587499,1310721, +2,2,10,3,6,10,4,8,1,1688601,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,21,28,1310721,4,1310721,2,1835009,40,1688649,16,1966081, +1310721,4,1579223,12,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,1587537,2,1603237,12, +8,1587539,2,1602703,12,1,6,1,10,28,34,63,38,3,26,1690925, +16,1585223,2,1,28,1,6,1,10,28,34,63,38,3,26,1688861, +16,1688853,14,117,110,116,101,114,109,105,110,97,116,101,100,32, +97,115,109,32,98,108,111,99,107,0,1688807,1589197,12,8,1585223,2, +3,28,1,6,1,10,28,34,63,38,3,26,1688913,16,1585225,2, +1592283,12,8,1601277,12,8,1688739,14,1585223,2,7,28,1,6,1,10, +28,34,63,38,3,26,1688965,16,1585225,2,1594383,12,8,1601277,12,8, +1688739,14,1587563,2,1602703,12,1689083,16,1601277,12,8,1585223,2,3,28,1, +6,1,10,28,34,63,38,1,10,28,1689063,16,1689055,14,35,32, +110,101,101,100,115,32,97,32,110,117,109,98,101,114,0,1689021, +1589197,12,8,1585225,2,1592089,12,8,1601277,12,8,1688739,14,1587565,2,1602703, +12,1689205,16,1601277,12,8,1585223,2,3,28,1,6,1,10,28,34, +63,38,3,26,1689163,16,1585227,2,1,6,1,10,28,34,63,38, +1,10,28,1689165,14,1,1689193,16,1,1585225,2,28,1592283,12,8,1601277, +12,8,1689201,14,29,1592369,12,8,1688739,14,1587561,2,1602703,12,1689395,16, +1601277,12,8,1310721,2,2,129,40,3,36,1689293,16,1689285,14,116,111, +111,32,109,97,110,121,32,97,115,109,32,108,97,98,101,108, +115,0,1689245,1588719,12,8,1310721,2,13,26,2,1310721,2,2,26,1603527, +12,10,3,6,10,4,8,1310721,2,15,26,2,1310721,2,2,26, +1587483,2,10,3,6,10,4,8,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1688739,14,1585225,2,1,26,2,1689465,16, +1585225,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,1689467,14,1,1689537,16,1310721, +2,9,26,1585225,2,1,26,2,1604819,12,10,3,6,10,4,1, +40,3,36,1,6,1,10,28,34,63,38,1,10,28,1689539,14, +1,1689569,16,1310721,2,9,26,2,1592369,12,8,1601277,12,8,1688739,14, +1585223,2,5,28,1,6,1,10,28,34,63,38,1,10,28,1689649, +16,1689641,14,98,97,100,32,116,111,107,101,110,32,105,110,32, +97,115,109,0,1689607,1589197,12,8,1310721,2,5,26,1585225,2,1607893,12, +10,3,6,10,4,8,1310721,2,5,26,2,1,40,3,36,1689745, +16,1558017,1310721,2,5,26,2,26,2,33,32,1,6,1,10,28, +34,63,38,1,10,28,1689747,14,1,1689813,16,1473025,1310721,2,5,26, +2,26,2,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1689815,14,1,1689893,16,1689885,14,97, +115,109,32,99,97,110,39,116,32,114,101,97,99,104,32,97, +110,32,111,51,32,118,97,114,105,97,98,108,101,0,1689823,1588813, +12,8,1310721,2,5,26,2,1,40,3,36,1689975,16,1472001,1310721,2, +5,26,2,26,3,10,3,6,10,4,8,1467905,1310721,2,5,26, +2,26,2,1593203,12,8,1601277,12,8,1688739,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,1690169,16,1310721, +2,13,26,2,1310721,2,5,26,2,26,2,1585225,2,28,1,6, +1,10,28,34,63,38,3,26,1690131,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,1690025,14,1310721,2,7,26, +2,1,40,3,36,1690231,16,1310721,2,15,26,2,1310721,2,7,26, +2,26,2,1592283,12,8,1601277,12,8,1688739,14,1310721,2,11,26,1585225, +2,1590943,12,10,3,6,10,4,8,1310721,2,11,26,2,1,40, +3,36,1690347,16,1417729,1310721,2,11,26,2,26,2,13,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1690349,14,1,1690389,16,45,1425921,1310721,2,11,26,2,26, +2,26,1592369,12,8,1601277,12,8,1688739,14,1310721,2,11,26,2,1, +40,3,36,1690479,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,1690481,14,1,1690553,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,1690555,14,1,1690591,16,1425921, +1310721,2,11,26,2,26,2,1592283,12,8,1601277,12,8,1688739,14,1310721, +2,11,26,2,1,40,3,36,1690679,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,1690681,14,1,1690711,16,1310721,2, +11,26,2,1592875,12,8,1601277,12,8,1688739,14,1310721,2,3,26,2, +501,40,3,36,1690805,16,1690797,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,1690737,1588719,12,8,1310721,2,17,26,2,1310721, +2,3,26,2,26,1585225,2,10,3,6,10,4,8,1310721,2,19, +26,2,1310721,2,3,26,2,26,1592669,12,10,3,6,10,4,8, +1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1601277,12,8,1688739,14,1601277,12,8,1310721,2,5,26,1,10,3, +6,10,4,8,1310721,2,5,26,2,1310721,2,3,26,2,40,1691379, +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,1691193,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,1691155,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,1691029,14,1310721,2,7,26, +2,1,40,1691287,16,1310721,2,17,26,2,1310721,2,5,26,2,26, +2,1691279,14,117,110,107,110,111,119,110,32,110,97,109,101,32, +105,110,32,97,115,109,0,1691239,1588983,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,1592451,12,8,1310721,2,5,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1690953,14,1,1691387,14,1,1310721,2,21, +26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1691435,16, +1966081,1310721,4,1579223,12,1601277,12,8,1688615,12,8,1587529,1,10,3,6, +10,4,8,1,1691471,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1691519,16,1966081,1310721,4,1579223,12,1, +1310721,2,4,1,1310721,2,3,26,4,1587537,2,1602703,12,1,6,1, +10,28,34,63,38,3,26,1691605,16,1691597,14,101,120,112,101,99, +116,101,100,32,123,0,1691575,1589197,12,8,1601277,12,8,3,1692027,16, +1585223,2,1,28,1,6,1,10,28,34,63,38,3,26,1691699,16, +1691691,14,117,110,116,101,114,109,105,110,97,116,101,100,32,113, +117,111,116,101,0,1691653,1589197,12,8,1587537,2,1602703,12,1691745,16,1310721, +2,3,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1587539,2,1602703,12,1691829,16,1310721,2,3,26,2,1,6,1,10,28, +34,63,38,3,26,1691795,16,1692027,14,1310721,2,3,26,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1310721,2,2,5401,40,3, +36,1691889,16,1691881,14,113,117,111,116,101,32,116,111,111,32,108, +111,110,103,0,1691851,1588719,12,8,1524225,1310721,2,2,7,30,26,1585223, +2,10,3,6,10,4,8,1524225,1310721,2,2,7,30,3,26,26, +1585225,2,10,3,6,10,4,8,1524225,1310721,2,2,7,30,5,26, +26,1585229,2,10,3,6,10,4,8,1310721,2,1,6,2,1,6, +3,26,5,6,4,10,8,8,1601277,12,8,1691611,14,1601277,12,8, +1310721,2,5,26,1310721,2,2,7,30,3,26,1580207,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,7,30, +1574491,12,8,1310721,2,5,26,2,1692151,14,1,1310721,2,7,26,1310721, +4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1692199,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,1,26,2,7,30,3,26, +1310721,2,3,26,4,1310721,2,3,26,2,1580207,12,1310721,2,5,26, +4,1310721,2,5,26,2,1310721,2,2,1310721,2,3,26,2,1574491,12, +8,1310721,2,5,26,2,1692307,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,7,28,1310721,4,1310721,2,1835009,40,1692355,16,1966081,1310721,4,1579223, +12,1310721,2,4,1310721,2,2,1,26,2,7,30,3,26,1310721,2, +3,26,4,1310721,2,3,26,2,1580207,12,1310721,2,5,26,4,1310721, +2,5,26,2,1310721,2,2,1310721,2,3,26,2,1574491,12,8,1310721, +2,5,26,2,1692463,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1692511,16,1966081,1310721,4,1579223,12,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,1692629,16,1310721,2,2,1310721,2,5, +26,2,26,2,1592089,12,8,1310721,2,5,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1692539,14,1,1692637,14,1,1310721,2, +7,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1692685, +16,1966081,1310721,4,1579223,12,1601277,12,8,1310721,2,1691485,12,10,3,6, +10,4,8,1310721,2,3,26,1592669,12,10,3,6,10,4,8,15, +1592369,12,8,1310721,2,5,26,1587483,2,10,3,6,10,4,8,1310721, +2,7,26,1310721,2,2,1,26,2,7,30,3,26,10,3,6, +10,4,8,1310721,2,2,1310721,2,7,26,2,1692477,12,8,1310721,2, +2,1580907,12,8,1310721,2,3,26,2,1587483,2,1592451,12,8,1310721,2, +5,26,2,1592283,12,8,1587609,2,1593049,12,8,1587529,3,10,3,6, +10,4,8,1,1692911,14,1,1310721,2,9,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1692959,16,1966081,1310721,4,1579223,12,1310721, +2,4,1,1310721,2,3,26,4,5,1310721,2,2,1,1,1595149,12, +8,1601277,12,8,1585223,2,1,28,1,6,1,10,28,34,63,38, +1,10,28,1693255,16,1310721,2,3,26,2,5401,40,3,36,1693101,16, +1693093,14,116,111,111,32,109,97,110,121,32,116,111,107,101,110, +115,0,1693061,1588719,12,8,1524225,1310721,2,3,26,2,7,30,26,1585223, +2,10,3,6,10,4,8,1524225,1310721,2,3,26,2,7,30,3, +26,26,1585225,2,10,3,6,10,4,8,1524225,1310721,2,3,26,2, +7,30,5,26,26,1585229,2,10,3,6,10,4,8,1310721,2,3, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1601277,12, +8,1693001,14,1596577,12,8,1310721,2,5,26,1310721,2,3,26,2,7, +30,3,26,1580207,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,7,30,1574491,12,8,1310721, +2,5,26,2,1693391,14,1,1310721,2,7,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1693439,16,1966081,1310721,4,1579223,12,1310721, +2,4,3,1310721,2,2,3,3,1595149,12,8,1601277,12,8,1,1693477, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721, +2,1835009,40,1693525,16,1966081,1310721,4,1579223,12,8181,1310721,2,4,8181,1580207, +12,1310721,2,3,26,4,1,1310721,2,5,26,4,1573381,12,1,6, +1,10,28,34,63,38,3,26,1694083,16,1310721,2,7,26,1573325,12, +511,32,10,3,6,10,4,8,1310721,2,7,26,2,193,28,1, +6,1,10,28,34,63,38,3,26,1693659,16,1694083,14,1310721,2,5, +26,2,5,38,5,26,1310721,2,2,40,3,36,1693847,16,1310721,2, +9,26,1310721,2,2,1310721,2,2,26,13,26,1580207,12,10,3,6, +10,4,8,1310721,2,9,26,2,1310721,2,3,26,2,1310721,2,2, +1574491,12,8,1310721,2,3,26,2,1580907,12,8,1310721,2,3,26,1310721, +2,9,26,2,10,3,6,10,4,8,1310721,2,1310721,2,2,1310721, +2,2,26,13,26,10,3,6,10,4,8,1310721,2,11,26,1310721, +2,5,26,2,5,38,10,3,6,10,4,8,1310721,2,5,26, +2,7,32,1,6,1,10,28,34,63,38,3,26,1693955,16,1310721, +2,3,26,2,1310721,2,11,26,2,26,1,10,3,6,10,4, +8,1310721,2,3,26,2,1310721,2,11,26,2,26,1310721,2,3,26, +2,1310721,2,11,26,2,26,2,1310721,2,7,26,2,1310721,2,5, +26,2,7,32,17,30,48,34,10,3,6,10,4,8,1310721,2, +5,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1693561, +14,1310721,2,3,26,2,1310721,2,5,26,2,5,38,26,1310721,2, +3,26,2,1310721,2,5,26,2,5,38,26,2,1574901,1310721,2,5, +26,2,7,32,17,30,26,2,3,28,32,10,3,6,10,4, +8,1310721,2,5,26,2,7,32,1,28,1,6,1,10,28,34, +63,38,3,26,1694261,16,1310721,2,3,26,2,1310721,2,5,26,2, +5,38,26,1,10,3,6,10,4,8,1310721,2,3,26,2,1310721, +2,5,26,2,5,38,3,26,26,1,10,3,6,10,4,8, +1310721,2,3,26,2,1694321,14,1,1310721,2,13,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1694369,16,1966081,1310721,4,1579223,12, +1,1310721,2,4,1585223,2,1,28,1,6,1,10,28,34,63,38, +1,10,28,1694577,16,1587661,2,1602703,12,1694457,16,1310721,2,1,6,2, +1,6,3,26,5,6,4,10,8,8,1694541,14,1587663,2,1602703,12, +1694503,16,1310721,2,1,6,2,1,6,-1,26,5,6,4,10,8, +8,1694541,14,1587665,2,1602703,12,1694541,16,1310721,2,1310721,2,2,5,28, +10,3,6,10,4,8,1601277,12,8,1310721,2,2,1,10,40,3, +36,1694573,16,1,1694585,14,1694377,14,1,1694585,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1694633,16,1966081, +1310721,4,1579223,12,1310721,2,4,1585225,2,1310721,2,3,26,4,1,1310721, +2,5,26,4,1,1310721,2,7,26,4,1,1310721,2,9,26,4, +1601277,12,8,1601277,12,8,1587535,2,1602703,12,1,6,1,10,28,34, +63,38,3,26,1695445,16,1310721,2,5,26,3,10,3,6,10,4, +8,1310721,2,11,26,3,10,3,6,10,4,8,1585223,2,1,28, +1,6,1,10,28,34,63,38,1,10,28,1695351,16,1587533,2,1602703, +12,1694861,16,1310721,2,11,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1695341,14,1587535,2,1602703,12,1694949,16,1310721,2,11,26, +1,6,2,1,6,-1,26,5,6,4,10,8,8,1310721,2,11, +26,2,1,6,1,10,28,34,63,38,3,26,1694945,16,1695351,14, +1695341,14,1310721,2,11,26,2,3,28,1,6,1,10,28,34,63, +38,3,26,1695021,16,1587545,2,1602703,12,1,6,1,10,28,34,63, +38,1,10,28,1695023,14,1,1695181,16,1310721,2,5,26,2,25,10, +40,3,36,1695121,16,1310721,2,7,26,1310721,2,7,26,2,1310721,2, +9,26,2,1310721,2,5,26,2,1310721,2,5,26,2,26,5,28, +48,26,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,10,3, +6,10,4,8,1695341,14,1310721,2,11,26,2,3,28,1,6,1, +10,28,34,63,38,3,26,1695253,16,1587571,2,1602703,12,1,6,1, +10,28,34,63,38,1,10,28,1695255,14,1,1695341,16,1601277,12,8, +1587587,2,1602855,12,1695303,16,1310721,2,9,26,3,10,3,6,10,4, +8,1695337,14,1587589,2,1602855,12,1695337,16,1310721,2,9,26,5,10,3, +6,10,4,8,1694777,14,1601277,12,8,1694777,14,1310721,2,5,26,2, +25,10,40,3,36,1695445,16,1310721,2,7,26,1310721,2,7,26,2, +1310721,2,9,26,2,1310721,2,5,26,2,1310721,2,5,26,2,26, +5,28,48,26,10,3,6,10,4,8,1601277,12,8,1587537,2,1602703, +12,1,6,1,10,28,34,63,38,3,26,1695537,16,1587547,2,1602703, +12,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1695539,14,1,1695549,16,1,1695983,14,1310721,2, +13,26,1310721,2,3,26,2,1590943,12,10,3,6,10,4,8,1310721, +2,13,26,2,1,40,1695607,16,3,1695645,14,1310721,2,13,26,2, +1585155,2,40,1,6,1,10,28,34,63,38,1,10,28,1695655,16, +3,1695719,14,1417729,1310721,2,13,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,1695729,16,3,1695771,14,1442305,1310721,2,13,26,2,26,2, +3,32,1,6,1,10,28,34,63,38,1,10,28,1695809,16,1310721, +2,13,26,1310721,2,3,26,2,1592751,12,10,3,6,10,4,8, +1442305,1310721,2,13,26,2,26,2,5,32,1,6,1,10,28,34, +63,38,3,26,1695975,16,1434113,1310721,2,13,26,2,26,1310721,2,2, +1310721,2,5,26,2,26,1310721,2,5,26,2,26,1310721,2,7,26, +2,129,30,26,10,3,6,10,4,8,1442305,1310721,2,13,26,2, +26,1442305,1310721,2,13,26,2,26,2,5,34,513,34,10,3,6, +10,4,8,1,1695983,14,1,1310721,2,15,26,1310721,4,18,1310721,2, +13,28,1310721,4,1310721,2,1835009,40,1696031,16,1966081,1310721,4,1579223,12,1310721, +2,3,26,4,1310721,2,4,1,1310721,2,5,26,4,1588225,2,1310721, +2,7,26,4,1588223,2,1310721,2,9,26,4,1,1310721,2,11,26, +4,1587637,1,6,2,1,6,3,26,5,6,4,10,8,8,1310721, +2,2,1310721,2,3,26,2,1,1,1595149,12,8,1601277,12,8,1585223, +2,1,28,1,6,1,10,28,34,63,38,1,10,28,1696699,16, +1587537,2,1602703,12,1696243,16,1310721,2,5,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1696689,14,1587539,2,1602703,12,1696315,16,1310721, +2,5,26,1,6,2,1,6,-1,26,5,6,4,10,8,8, +1310721,2,11,26,1,10,3,6,10,4,8,1696689,14,1310721,2,5, +26,2,1,10,40,3,36,1696689,16,1587547,2,1602703,12,1696377,16,1310721, +2,11,26,1,10,3,6,10,4,8,1696689,14,1587571,2,1602703,12, +1696515,16,1602137,12,8,1587445,2,5,28,1,6,1,10,28,34,63, +38,3,26,1696483,16,1587447,2,1587591,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1696485, +14,1,1696511,16,1310721,2,11,26,3,10,3,6,10,4,8,1696689, +14,1585223,2,5,28,1,6,1,10,28,34,63,38,3,26,1696689, +16,1602137,12,8,1587445,2,9,28,1,6,1,10,28,34,63,38, +3,26,1696641,16,1587447,2,1587533,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1696643,14, +1,1696689,16,1310721,2,11,26,2,1694599,12,8,1310721,2,11,26,1, +10,3,6,10,4,8,1696159,14,1601277,12,8,1696159,14,1596577,12,8, +1587637,1,6,2,1,6,-1,26,5,6,4,10,8,8,1588225,1310721, +2,7,26,2,10,3,6,10,4,8,1588223,1310721,2,9,26,2, +10,3,6,10,4,8,1,1696789,14,1,1310721,2,13,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1696837,16,1966081,1310721,4, +1579223,12,1693491,12,1310721,2,4,7,1310721,2,2,1695997,12,8,7,1310721, +2,2,1,1,1595149,12,8,1601277,12,8,1711115,12,8,1585155,2,1711215, +12,8,1596577,12,8,1310721,2,2,1580907,12,8,1,1696927,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1696975,16,1966081,1310721,4,1579223,12,1548801,1587517,2,49,30,26,1310721,2,4, +1587517,2,61,40,3,36,1697075,16,1697067,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,1697013,1588719,12,8,1587517,1,6,2,1,6,3, +26,5,6,4,10,8,8,1310721,2,2,1,26,1587491,2,10,3, +6,10,4,8,1310721,2,2,3,26,1587493,2,10,3,6,10,4, +8,1310721,2,2,5,26,1587495,2,10,3,6,10,4,8,1310721,2, +2,7,26,1587497,2,10,3,6,10,4,8,1310721,2,2,9,26, +1587499,2,10,3,6,10,4,8,1310721,2,2,11,26,1587501,2,10, +3,6,10,4,8,1310721,2,2,13,26,1587503,2,10,3,6,10, +4,8,1310721,2,2,15,26,1587505,2,10,3,6,10,4,8,1310721, +2,2,17,26,1587507,2,10,3,6,10,4,8,1310721,2,2,19, +26,1587509,2,10,3,6,10,4,8,1310721,2,2,21,26,1587511,2, +10,3,6,10,4,8,1310721,2,2,23,26,1587513,2,10,3,6, +10,4,8,1310721,2,2,25,26,1587515,2,10,3,6,10,4,8, +1310721,2,2,27,26,1587521,2,10,3,6,10,4,8,1310721,2,2, +29,26,1587523,2,10,3,6,10,4,8,1310721,2,2,31,26,1587525, +2,10,3,6,10,4,8,1310721,2,2,33,26,1587527,2,10,3, +6,10,4,8,1310721,2,2,35,26,1587529,2,10,3,6,10,4, +8,1310721,2,2,37,26,1587519,2,10,3,6,10,4,8,1310721,2, +2,39,26,1587531,2,10,3,6,10,4,8,1310721,2,2,41,26, +1587655,2,10,3,6,10,4,8,1310721,2,2,43,26,1587633,2,10, +3,6,10,4,8,1310721,2,2,45,26,1587639,5,1574491,12,8,1, +1697703,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1697751,16,1966081,1310721,4,1579223,12,1587517,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1310721,2,1548801,1587517,2,49,30, +26,10,3,6,10,4,8,1587491,1310721,2,2,1,26,2,10,3, +6,10,4,8,1587493,1310721,2,2,3,26,2,10,3,6,10,4, +8,1587495,1310721,2,2,5,26,2,10,3,6,10,4,8,1587497,1310721, +2,2,7,26,2,10,3,6,10,4,8,1587499,1310721,2,2,9, +26,2,10,3,6,10,4,8,1587501,1310721,2,2,11,26,2,10, +3,6,10,4,8,1587503,1310721,2,2,13,26,2,10,3,6,10, +4,8,1587505,1310721,2,2,15,26,2,10,3,6,10,4,8,1587507, +1310721,2,2,17,26,2,10,3,6,10,4,8,1587509,1310721,2,2, +19,26,2,10,3,6,10,4,8,1587511,1310721,2,2,21,26,2, +10,3,6,10,4,8,1587513,1310721,2,2,23,26,2,10,3,6, +10,4,8,1587515,1310721,2,2,25,26,2,10,3,6,10,4,8, +1587521,1310721,2,2,27,26,2,10,3,6,10,4,8,1587523,1310721,2, +2,29,26,2,10,3,6,10,4,8,1587525,1310721,2,2,31,26, +2,10,3,6,10,4,8,1587527,1310721,2,2,33,26,2,10,3, +6,10,4,8,1587529,1310721,2,2,35,26,2,10,3,6,10,4, +8,1587519,1310721,2,2,37,26,2,10,3,6,10,4,8,1587531,1310721, +2,2,39,26,2,10,3,6,10,4,8,1587655,1310721,2,2,41, +26,2,10,3,6,10,4,8,1587633,1310721,2,2,43,26,2,10, +3,6,10,4,8,1587639,1310721,2,2,45,26,5,1574491,12,8,1, +1698407,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1698455,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4, +1310721,2,4,1587493,1587491,2,10,3,6,10,4,8,1587495,3,10,3, +6,10,4,8,1587497,1,10,3,6,10,4,8,1587499,1310721,2,2, +1698563,16,1585221,2,1,6,1,10,28,34,63,38,1,10,28,1698565, +14,1,10,3,6,10,4,8,1587501,1310721,2,3,26,2,10,3, +6,10,4,8,1587531,1,10,3,6,10,4,8,1587503,3,10,3, +6,10,4,8,1587505,1,10,3,6,10,4,8,1587507,1,10,3, +6,10,4,8,1587511,3,10,3,6,10,4,8,1587515,1587513,2,10, +3,6,10,4,8,1587521,1,10,3,6,10,4,8,1587523,1,10, +3,6,10,4,8,1,1698739,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1698787,16,1966081,1310721,4,1579223, +12,1310721,1592283,12,8,3,1592369,12,8,1587509,1592669,12,10,3,6,10, +4,8,29,1592369,12,8,1310721,1592283,12,8,5,1592369,12,8,1587701,2, +1698859,16,1,1698977,14,1310721,1592283,12,8,3,1592369,12,8,1835009,1592283,12, +8,41,1592369,12,8,1310721,2,1592669,12,10,3,6,10,4,8,17, +1592369,12,8,1966081,1592283,12,8,1310721,1592283,12,8,5,1592369,12,8,1587599, +2,1593049,12,8,1310721,2,2,1587483,2,1592451,12,8,1,1698977,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009, +40,1699025,16,1966081,1310721,4,1579223,12,1,1592283,12,8,1587507,2,1587483,2, +1591871,12,8,1310721,1592283,12,8,3,1592369,12,8,1587497,2,1592283,12,8, +27,1592369,12,8,1310721,1592283,12,8,5,1592369,12,8,19,1592369,12,8, +1587509,2,1587497,2,1592451,12,8,1587511,1,10,3,6,10,4,8,1587491, +1587493,2,10,3,6,10,4,8,1,1699161,14,1,1310721,2,1,26, +1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1699209,16,1966081, +1310721,4,1579223,12,1587537,2,1603237,12,8,1587539,2,1602703,12,1,6,1, +10,28,34,63,38,3,26,1699375,16,1585223,2,1,28,1,6,1, +10,28,34,63,38,3,26,1699365,16,1699357,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,1699287,1589197, +12,8,1677555,12,8,1699219,14,1587493,2,1610397,12,8,1587499,2,1699423,16, +1587503,2,1,6,1,10,28,34,63,38,1,10,28,1699425,14,1, +1699557,16,3,3,1609669,12,8,1587501,2,1699557,16,1699549,14,97,32,102, +117,110,99,116,105,111,110,32,114,101,116,117,114,110,105,110, +103,32,46,117,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,1699451,1589485, +12,8,1601277,12,8,1,1699571,14,1,1310721,2,1,26,1310721,4,18, +1310721,2,175,28,1310721,4,1310721,2,1835009,40,1699619,16,1966081,1310721,4,1579223, +12,1310721,2,7,26,4,1310721,2,5,26,4,1310721,2,3,26,4, +1310721,2,4,1,1310721,2,11,26,4,1,1310721,2,13,26,4,1, +1310721,2,165,26,4,1587703,2,1310721,2,169,26,4,1587703,1,10,3, +6,10,4,8,1310721,2,3,26,2,1699741,16,3,1699767,14,1587655,2, +1,6,1,10,28,34,63,38,1,10,28,1699793,16,1310721,2,165, +26,3,10,3,6,10,4,8,1310721,2,9,26,1310721,2,7,26, +2,1590943,12,10,3,6,10,4,8,1310721,2,9,26,2,1,40, +1699851,16,3,1699889,14,1310721,2,9,26,2,1585155,2,40,1,6,1, +10,28,34,63,38,1,10,28,1699899,16,3,1699963,14,1417729,1310721,2, +9,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,1699973,16,3, +1700015,14,1442305,1310721,2,9,26,2,26,2,3,32,1,6,1,10, +28,34,63,38,1,10,28,1700085,16,1310721,2,9,26,1310721,2,7, +26,2,3,1,1590445,12,10,3,6,10,4,8,1442305,1310721,2,9, +26,2,26,1,10,3,6,10,4,8,1587533,2,1603237,12,8,1587535, +2,1602703,12,1,6,1,10,28,34,63,38,3,26,1701587,16,3, +1701587,16,1310721,2,15,26,1,10,3,6,10,4,8,1310721,2,117, +26,1310721,2,11,26,2,26,1587621,2,10,3,6,10,4,8,1587571, +2,1602703,12,1,6,1,10,28,34,63,38,3,26,1700563,16,1585223, +2,9,28,1,6,1,10,28,34,63,38,3,26,1700373,16,1585225, +2,1587557,2,28,1,6,1,10,28,34,63,38,3,26,1700295,16, +3,1700347,14,1585225,2,1587541,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,1700375,14,1,1700385,16,3,1700537,14, +1585223,2,5,28,1,6,1,10,28,34,63,38,3,26,1700513,16, +1585225,2,1587573,2,28,1,6,1,10,28,34,63,38,3,26,1700457, +16,3,1700487,14,1585225,2,1640093,12,1,6,1,10,28,34,63,38, +1,10,28,1,6,1,10,28,34,63,38,1,10,28,1700515,14, +1,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,1,10,28,1700565,14,1,1700751,16,1310721,2,117,26, +1310721,2,11,26,2,26,1640473,12,10,3,6,10,4,8,1310721,2, +165,26,3,10,3,6,10,4,8,1310721,2,117,26,1310721,2,11, +26,2,26,2,1634803,12,1700751,16,1700743,14,115,116,114,117,99,116, +115,32,97,110,100,32,97,114,114,97,121,115,32,97,114,101, +32,112,97,115,115,101,100,32,98,121,32,112,111,105,110,116, +101,114,0,1700661,1588813,12,8,1587571,2,1603007,12,1700957,16,1585225,2,1587587, +2,28,1,6,1,10,28,34,63,38,3,26,1700823,16,1310721,2, +15,26,3,10,3,6,10,4,8,1700951,14,1585225,2,1587589,2,28, +1,6,1,10,28,34,63,38,3,26,1700883,16,1310721,2,15,26, +5,10,3,6,10,4,8,1700951,14,1700943,14,97,32,112,97,114, +97,109,101,116,101,114,32,116,97,103,32,105,115,32,46,109, +32,111,114,32,46,100,0,1700887,1589197,12,8,1601277,12,8,1310721,2, +21,26,1310721,2,11,26,2,26,1603527,12,10,3,6,10,4,8, +1310721,2,169,26,2,1701081,16,1310721,2,117,26,1310721,2,11,26,2, +26,2,1587621,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1701083,14,1,1701151,16,1701143, +14,111,51,32,112,97,114,97,109,101,116,101,114,115,32,110, +101,101,100,32,97,32,116,121,112,101,0,1701091,1588813,12,8,1310721, +2,11,26,2,25,40,3,36,1701209,16,1310721,2,15,26,2,1, +6,1,10,28,34,63,38,1,10,28,1701211,14,1,1701313,16,1701305, +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,1701219,1589197,12,8, +1310721,2,69,26,1310721,2,11,26,2,26,1310721,2,15,26,2,10, +3,6,10,4,8,1310721,2,11,26,2,25,40,1701439,16,1310721,2, +13,26,1310721,2,13,26,2,1310721,2,15,26,2,1310721,2,11,26, +2,1310721,2,11,26,2,26,48,26,10,3,6,10,4,8,1310721, +2,11,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1310721,2,11,26,2,49,40,3,36,1701547,16,1701539,14,116,111,111, +32,109,97,110,121,32,112,97,114,97,109,101,116,101,114,115, +0,1701499,1589197,12,8,1587545,2,1603007,12,1,6,1,10,28,34,63, +38,3,26,1701583,16,1701587,14,1700127,14,1587535,2,1603237,12,8,1310721,2, +17,26,1310721,2,5,26,2,1310721,2,11,26,2,26,1310721,2,11, +26,2,26,1310721,2,13,26,2,129,30,26,10,3,6,10,4, +8,1442305,1310721,2,9,26,2,26,2,5,32,1701757,16,1442305,1310721,2, +9,26,2,26,2,513,32,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1701759,14,1,1701919, +16,1434113,1310721,2,9,26,2,26,2,1310721,2,17,26,2,28,1, +6,1,10,28,34,63,38,1,10,28,1701915,16,1310721,2,7,26, +2,1701907,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,1701831,1588983,12,8,1702207,14,1442305, +1310721,2,9,26,2,26,2,9,32,1702021,16,1310721,2,13,26,2, +1701963,16,3,1701995,14,1310721,2,5,26,2,1,6,1,10,28,34, +63,38,1,10,28,1,6,1,10,28,34,63,38,1,10,28, +1702023,14,1,1702207,16,1310721,2,7,26,2,1702199,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,1702041,1588983,12,8,1434113, +1310721,2,9,26,2,26,1310721,2,17,26,2,10,3,6,10,4, +8,1442305,1310721,2,9,26,2,26,1442305,1310721,2,9,26,2,26,2, +5,34,1442305,1310721,2,9,26,2,26,2,513,32,28,10,3,6, +10,4,8,1587655,2,1702365,16,1442305,1310721,2,9,26,2,26,1442305,1310721, +2,9,26,2,26,2,257,34,10,3,6,10,4,8,1310721,2, +165,26,2,1702735,16,1310721,2,3,26,2,1,6,1,10,28,34, +63,38,3,26,1702437,16,1310721,2,3,26,1587621,2,10,3,6,10, +4,8,1310721,2,167,26,1310721,2,3,26,2,1310721,2,11,26,2, +1310721,2,117,26,1310721,2,17,26,2,1629653,12,10,3,6,10,4, +8,1559041,1310721,2,9,26,2,26,2,1702595,16,1559041,1310721,2,9,26, +2,26,2,1310721,2,167,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,1702597, +14,1,1702699,16,1310721,2,7,26,2,1702691,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,1702615,1588983,12,8,1559041,1310721,2,9,26,2,26,1310721,2,167,26, +2,10,3,6,10,4,8,1587547,2,1603007,12,1702777,16,1587655,1,10, +3,6,10,4,8,1310721,2,9,26,2,1703951,14,1442305,1310721,2,9, +26,2,26,2,3,32,1702857,16,1310721,2,7,26,2,1702849,14,105, +115,32,100,101,102,105,110,101,100,32,116,119,105,99,101,0, +1702815,1588983,12,8,1425921,1310721,2,9,26,2,26,1587483,2,10,3,6, +10,4,8,1442305,1310721,2,9,26,2,26,1442305,1310721,2,9,26,2, +26,2,3,34,10,3,6,10,4,8,1450497,1310721,2,9,26,2, +26,2,1587483,2,1591871,12,8,1450497,1310721,2,9,26,2,26,1,10, +3,6,10,4,8,1310721,2,2,1310721,2,5,26,2,1698421,12,8, +1310721,2,165,26,2,1703047,16,1587531,1310721,2,3,26,2,10,3,6, +10,4,8,1588125,1,10,3,6,10,4,8,1310721,2,169,26,2, +1703109,16,1587701,3,10,3,6,10,4,8,1587723,1,10,3,6,10, +4,8,1698753,12,8,1310721,2,19,26,1,10,3,6,10,4,8, +1310721,2,19,26,2,1310721,2,11,26,2,40,1703643,16,1310721,2,15, +26,1310721,2,21,26,1310721,2,19,26,2,26,2,1608097,12,10,3, +6,10,4,8,1587497,1,6,2,1,6,3,26,5,6,4,10, +8,8,1556993,1310721,2,15,26,2,26,1310721,2,117,26,1310721,2,19, +26,2,26,2,10,3,6,10,4,8,1310721,2,169,26,2,1703349, +16,1558017,1310721,2,15,26,2,26,33,10,3,6,10,4,8,1467905, +1310721,2,15,26,2,26,2,1593579,12,8,1587499,2,1703429,16,1310721,2, +69,26,1310721,2,19,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, +1703431,14,1,1703463,16,1469953,1310721,2,15,26,2,26,13,10,3,6, +10,4,8,1587499,2,1703543,16,1310721,2,69,26,1310721,2,19,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,1703545,14,1,1703605,16,1469953,1310721, +2,15,26,2,26,3,10,3,6,10,4,8,1474049,1310721,2,15, +26,2,26,3,10,3,6,10,4,8,1310721,2,19,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1703137,14,1310721,2,19, +26,1310721,2,11,26,2,10,3,6,10,4,8,1310721,2,19,26, +2,1703749,16,1310721,2,19,26,1,6,2,1,6,-1,26,5,6, +4,10,8,8,1310721,2,19,26,2,1593203,12,8,5,1592369,12,8, +1703673,14,1310721,2,169,26,2,1703815,16,1310721,2,171,26,1587483,2,5, +26,10,3,6,10,4,8,1310721,2,171,26,2,1592283,12,8,15, +1592369,12,8,1699175,12,8,1310721,2,173,26,1587483,2,10,3,6,10, +4,8,1698991,12,8,1310721,2,169,26,2,1703913,16,1587701,1,10,3, +6,10,4,8,1310721,2,171,26,2,1310721,2,173,26,2,1587707,1587723, +2,1593831,12,8,1594151,12,8,1587655,1,10,3,6,10,4,8,1310721, +2,9,26,2,1703951,14,1,1310721,2,175,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1703999,16,1966081,1310721,4,1579223,12,1310721, +2,4,1601277,12,8,1,1,1603527,12,1704043,12,1704029,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1704077, +16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4, +1310721,2,4,1310721,2,3,26,2,1704221,16,1704213,14,116,97,103,115, +32,103,111,32,111,110,32,108,111,99,97,108,115,32,97,110, +100,32,112,97,114,97,109,101,116,101,114,115,44,32,110,111, +116,32,103,108,111,98,97,108,115,0,1704121,1588813,12,8,1310721,2, +2,1587629,2,28,1,6,1,10,28,34,63,38,3,26,1704319,16, +1704311,14,97,32,118,97,114,105,97,98,108,101,32,99,97,110, +39,116,32,98,101,32,118,111,105,100,0,1704261,1588813,12,8,3, +1705235,16,1587541,2,1603007,12,1704611,16,1310721,2,9,26,1676587,12,10,3, +6,10,4,8,1587543,2,1603237,12,8,1310721,2,11,26,1310721,2,5, +26,2,7,1587483,2,1590445,12,10,3,6,10,4,8,1310721,2,2, +1,6,1,10,28,34,63,38,3,26,1704461,16,1310721,2,1587621,2, +10,3,6,10,4,8,1559041,1310721,2,11,26,2,26,1310721,2,2, +1310721,2,9,26,2,1629133,12,10,3,6,10,4,8,1310721,2,9, +26,1559041,1310721,2,11,26,2,26,2,1633401,12,10,3,6,10,4, +8,1310721,2,9,26,2,1704607,16,1,1592089,12,8,1310721,2,9,26, +1,6,2,1,6,-1,26,5,6,4,10,8,8,1704547,14,1705171, +14,1310721,2,2,1704657,16,1310721,2,2,1634803,12,1,6,1,10,28, +34,63,38,1,10,28,1704659,14,1,1704829,16,1310721,2,11,26,1310721, +2,5,26,2,7,1587483,2,1590445,12,10,3,6,10,4,8,1559041, +1310721,2,11,26,2,26,1310721,2,2,10,3,6,10,4,8,1310721, +2,9,26,1310721,2,2,1633401,12,10,3,6,10,4,8,1310721,2, +9,26,2,1704825,16,1,1592089,12,8,1310721,2,9,26,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1704765,14,1705171,14,1310721,2, +7,26,1587483,2,10,3,6,10,4,8,1310721,2,11,26,1310721,2, +5,26,2,5,1310721,2,7,26,2,1590445,12,10,3,6,10,4, +8,1310721,2,2,1704941,16,1559041,1310721,2,11,26,2,26,1310721,2,2, +10,3,6,10,4,8,1,1592089,12,8,1587549,2,1603007,12,1705171,16, +1585223,2,7,28,1,6,1,10,28,34,63,38,3,26,1705139,16, +1310721,2,7,26,2,1587485,2,26,1587483,2,10,3,6,10,4,8, +1310721,2,9,26,1585225,2,10,3,6,10,4,8,1310721,2,9,26, +2,2,1705121,16,1310721,2,9,26,2,2,1592089,12,8,1310721,2,9, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1705049,14, +1,1592089,12,8,1601277,12,8,1705171,14,1310721,2,7,26,2,1587485,2, +26,1676587,12,10,3,6,10,4,8,1587545,2,1603007,12,1,6,1, +10,28,34,63,38,3,26,1705207,16,1705235,14,1310721,2,5,26,1603527, +12,10,3,6,10,4,8,1704319,14,1587547,2,1603237,12,8,1,1705253, +14,1,1310721,2,13,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1705301,16,1966081,1310721,4,1579223,12,1601277,12,8,3,1705401,16, +1310721,2,1603527,12,10,3,6,10,4,8,1587549,2,1603237,12,8,1310721, +2,2,9,1676587,12,1590445,12,8,1587545,2,1603007,12,1,6,1,10, +28,34,63,38,3,26,1705397,16,1705401,14,1705307,14,1587547,2,1603237,12, +8,1,1705419,14,1,1310721,2,3,26,1310721,4,18,1310721,2,43,28, +1310721,4,1310721,2,1835009,40,1705467,16,1966081,1310721,4,1579223,12,1,1310721,2, +3,26,4,3,1310721,2,5,26,4,1,1310721,2,13,26,4,1, +1310721,2,15,26,4,1601277,12,8,1585223,2,3,28,1,6,1,10, +28,34,63,38,3,26,1705723,16,1585225,2,1,40,1705571,16,3,1705603, +14,1585225,2,17,10,40,1,6,1,10,28,34,63,38,1,10, +28,1705693,16,1705685,14,97,110,32,101,110,104,97,110,99,101,109, +101,110,116,32,104,97,115,32,97,116,32,109,111,115,116,32, +56,32,111,117,116,112,117,116,115,0,1705611,1588813,12,8,1310721,2, +5,26,1585225,2,10,3,6,10,4,8,1601277,12,8,1310721,2,1603527, +12,10,3,6,10,4,8,1587533,2,1603237,12,8,1587535,2,1602703,12, +1,6,1,10,28,34,63,38,3,26,1706027,16,3,1706027,16,1310721, +2,3,26,2,17,28,1,6,1,10,28,34,63,38,3,26, +1705917,16,1705909,14,97,110,32,101,110,104,97,110,99,101,109,101, +110,116,32,116,97,107,101,115,32,97,116,32,109,111,115,116, +32,56,32,105,110,112,117,116,115,0,1705833,1589197,12,8,1310721,2, +27,26,1310721,2,3,26,2,26,1603527,12,10,3,6,10,4,8, +1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1587545,2,1603007,12,1,6,1,10,28,34,63,38,3,26,1706023, +16,1706027,14,1705785,14,1587535,2,1603237,12,8,1310721,2,7,26,1587483,2, +10,3,6,10,4,8,1310721,2,17,26,1,10,3,6,10,4, +8,1310721,2,17,26,2,15,40,1706147,16,1,1592089,12,8,1310721,2, +17,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1706083, +14,1310721,2,9,26,1587483,2,10,3,6,10,4,8,1310721,2,17, +26,1,10,3,6,10,4,8,1310721,2,17,26,2,1310721,2,3, +26,2,40,1706265,16,1,1592089,12,8,1310721,2,17,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1706193,14,1310721,2,17,26, +1,10,3,6,10,4,8,1310721,2,17,26,2,1310721,2,3,26, +2,40,1706517,16,1310721,2,9,26,2,1310721,2,17,26,2,26,1587485, +2,26,1587483,2,10,3,6,10,4,8,1310721,2,19,26,1310721,2, +27,26,1310721,2,17,26,2,26,2,10,3,6,10,4,8,1310721, +2,19,26,2,2,1706471,16,1310721,2,19,26,2,2,1592089,12,8, +1310721,2,19,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1706399,14,1,1592089,12,8,1310721,2,17,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1706287,14,1587613,2,1603007,12,1706813,16, +1310721,2,11,26,1587483,2,10,3,6,10,4,8,1585223,2,7,28, +1,6,1,10,28,34,63,38,1,10,28,1706663,16,1706655,14,101, +120,112,101,99,116,101,100,32,116,104,101,32,114,101,99,105, +112,101,32,97,115,32,97,32,115,116,114,105,110,103,0,1706591, +1589197,12,8,1585223,2,7,28,1,6,1,10,28,34,63,38,3, +26,1706801,16,1310721,2,19,26,1585225,2,10,3,6,10,4,8,1310721, +2,19,26,2,2,1706791,16,1310721,2,19,26,2,2,1592089,12,8, +1310721,2,19,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1706719,14,1601277,12,8,1706663,14,1,1592089,12,8,1706979,14,1587615,2, +1603007,12,1706925,16,1310721,2,11,26,1587483,2,10,3,6,10,4,8, +1688615,12,8,19,1592369,12,8,1310721,2,13,26,1587483,2,1310721,2,11, +26,2,28,10,3,6,10,4,8,1310721,2,15,26,3,10,3, +6,10,4,8,1706979,14,1706971,14,101,120,112,101,99,116,101,100, +32,109,105,99,114,111,32,111,114,32,118,109,0,1706929,1589197,12, +8,1310721,2,23,26,1585149,2,10,3,6,10,4,8,1310721,2,23, +26,2,1025,40,3,36,1707109,16,1707101,14,97,108,108,32,53,49, +50,32,101,110,104,97,110,99,101,109,101,110,116,32,115,108, +111,116,115,32,97,114,101,32,116,97,107,101,110,0,1707029,1588719, +12,8,1585149,1,6,2,1,6,3,26,5,6,4,10,8,8, +1310721,2,19,26,1310721,2,7,26,2,1587485,2,26,10,3,6,10, +4,8,1310721,2,19,26,2,1,26,1310721,2,23,26,2,10,3, +6,10,4,8,1310721,2,19,26,2,3,26,1310721,2,15,26,2, +10,3,6,10,4,8,1310721,2,19,26,2,5,26,1310721,2,3, +26,2,10,3,6,10,4,8,1310721,2,19,26,2,7,26,1310721, +2,5,26,2,10,3,6,10,4,8,1310721,2,19,26,2,9, +26,1310721,2,11,26,2,10,3,6,10,4,8,1310721,2,19,26, +2,11,26,1310721,2,13,26,2,10,3,6,10,4,8,1310721,2, +19,26,2,13,26,1310721,2,9,26,2,10,3,6,10,4,8, +1310721,2,21,26,1310721,2,2,13,1310721,2,23,26,2,1590445,12,10, +3,6,10,4,8,1434113,1310721,2,21,26,2,26,1310721,2,3,26, +2,1310721,2,5,26,2,33,30,26,1310721,2,7,26,2,513,30, +26,10,3,6,10,4,8,1587579,2,1603007,12,1707667,16,1310721,2,25, +26,1585225,2,1590943,12,10,3,6,10,4,8,1310721,2,25,26,2, +1,40,1707621,16,1310721,2,25,26,1585225,2,1592751,12,10,3,6,10, +4,8,1601277,12,8,1450497,1310721,2,21,26,2,26,1310721,2,25,26, +2,3,26,10,3,6,10,4,8,1587547,2,1603237,12,8,1587485,2, +1,6,1,10,28,34,63,38,3,26,1707987,16,1310721,2,25,26, +1310721,2,7,26,2,1572879,12,10,3,6,10,4,8,1310721,2,25, +26,2,1,40,1707987,16,1450497,1310721,2,21,26,2,26,2,1,6, +1,10,28,34,63,38,3,26,1707941,16,1310721,2,2,1707933,14,116, +104,101,32,101,110,104,97,110,99,101,109,101,110,116,32,100, +105,100,110,39,116,32,105,110,115,116,97,108,108,32,40,115, +101,101,32,105,110,115,116,97,108,108,39,115,32,99,111,100, +101,115,32,105,110,32,99,111,114,101,46,99,41,0,1707807,1588983, +12,8,1442305,1310721,2,21,26,2,26,1442305,1310721,2,21,26,2,26, +2,129,34,10,3,6,10,4,8,1,1707995,14,1,1310721,2,43, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1708043,16, +1966081,1310721,4,1579223,12,1,1310721,2,4,1585223,2,1,28,1,6,1, +10,28,34,63,38,1,10,28,1708933,16,1587537,2,1602703,12,1708131,16, +1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8,1708923, +14,1587539,2,1602703,12,1708209,16,1310721,2,1,6,2,1,6,-1,26, +5,6,4,10,8,8,1310721,2,2,1,40,1708205,16,1310721,2,1, +10,3,6,10,4,8,1708923,14,1310721,2,2,1,6,1,10,28, +34,63,38,3,26,1708293,16,1585223,2,5,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1708295,14,1,1708913,16,1585225,2,1587573,2,28,1,6,1,10,28,34, +63,38,3,26,1708339,16,3,1708391,14,1585225,2,1587575,2,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1708401,16,3,1708453,14,1585225,2,1587577,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1708463,16,3,1708515,14,1585225,2,1587677,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1708525,16,3,1708577,14,1585225,2,1587679,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1708587,16,3,1708639,14,1585225,2,1587611,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1708649, +16,3,1708701,14,1585225,2,1587681,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1708711,16, +3,1708763,14,1585225,2,1587583,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1708773,16,3, +1708825,14,1585225,2,1587585,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1708835,16,3,1708887, +14,1585225,2,1587691,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,1708915,14,1,1708923,16,1708933,14,1601277,12,8, +1708051,14,1588225,1,10,3,6,10,4,8,1,1708957,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1709005, +16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587655,1, +10,3,6,10,4,8,1310721,2,3,26,2,1709267,16,1587485,2,1709177, +16,1709169,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,1709063,1588813,12,8,1310721,2,5,26, +1409537,1310721,2,2,26,2,11,1425921,1310721,2,2,26,2,1590445,12,10, +3,6,10,4,8,1442305,1310721,2,5,26,2,26,3,17,34,33, +34,65,34,10,3,6,10,4,8,1,1709275,14,1,1310721,2,7, +26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1709323,16, +1966081,1310721,4,1579223,12,3,1310721,2,4,1,1310721,2,3,26,4,1588225, +2,1709359,16,1708009,12,1711101,14,1587583,2,1602855,12,1709429,16,1601277,12,8, +1587547,2,1603007,12,1709411,16,1585221,1,10,3,6,10,4,8,1,1711101, +14,1310721,2,1,10,3,6,10,4,8,1587585,2,1602855,12,1709469,16, +1601277,12,8,1310721,2,3,26,3,10,3,6,10,4,8,1587703,1, +10,3,6,10,4,8,1587691,2,1602855,12,1709519,16,1601277,12,8,1587703, +3,10,3,6,10,4,8,1587655,1,10,3,6,10,4,8,1587661, +2,1602703,12,1709735,16,1601277,12,8,3,1709729,16,1587655,2,17,40,3, +36,1709637,16,1709629,14,116,111,111,32,109,97,110,121,32,116,121, +112,101,32,112,97,114,97,109,101,116,101,114,115,0,1709579,1588719, +12,8,1587639,1587655,2,26,1603527,12,10,3,6,10,4,8,1587655,1, +6,2,1,6,3,26,5,6,4,10,8,8,1587545,2,1603007,12, +1,6,1,10,28,34,63,38,3,26,1709725,16,1709729,14,1709553,14, +1640371,12,8,1587573,2,1602855,12,1709939,16,1602137,12,8,1587445,2,9,28, +1,6,1,10,28,34,63,38,3,26,1709841,16,1587447,2,1587533,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1709843,14,1,1,6,1,10,28,34,63, +38,3,26,1709939,16,1601277,12,8,1310721,2,9,26,1603527,12,10,3, +6,10,4,8,1310721,2,2,1,1,1310721,2,9,26,2,1699585,12, +1310721,2,3,26,2,1708971,12,1711101,14,1587655,2,1709953,16,3,1710001,14, +1310721,2,2,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1710011,16,3,1710043,14,1310721,2,3, +26,2,1,6,1,10,28,34,63,38,1,10,28,1710053,16,3, +1710079,14,1587703,2,1,6,1,10,28,34,63,38,1,10,28,1710407, +16,1643415,12,8,1310721,2,9,26,1603527,12,10,3,6,10,4,8, +1587659,2,1710177,16,1587659,2,5,28,1,6,1,10,28,34,63,38, +1,10,28,1,6,1,10,28,34,63,38,1,10,28,1710179,14, +1,1710247,16,1710239,14,116,104,101,32,111,110,108,121,32,114,101, +116,117,114,110,32,116,97,103,32,105,115,32,46,117,0,1710187, +1588813,12,8,1587533,2,1602703,12,1,6,1,10,28,34,63,38,3, +26,1710337,16,1710323,14,101,120,112,101,99,116,101,100,32,97,32, +102,117,110,99,116,105,111,110,0,1710283,1589197,12,8,1,1711101,14, +1310721,2,2,1587657,2,1587659,2,5,28,1,6,1,10,28,34,63, +38,3,26,1310721,2,9,26,2,1699585,12,1310721,2,3,26,2,1708971, +12,1711101,14,1587575,2,1602855,12,1710429,16,1,1703965,12,1711101,14,1587677,2, +1602855,12,1710453,16,1643789,12,8,1,1711101,14,1587679,2,1602855,12,1710473,16, +1645695,12,1711101,14,1587681,2,1602855,12,1710493,16,1645815,12,1711101,14,1587611,2, +1602855,12,1710513,16,1705433,12,1711101,14,1587577,2,1602855,12,1710533,16,1705267,12, +1711101,14,1585223,2,5,28,1,6,1,10,28,34,63,38,3,26, +1710763,16,1310721,2,5,26,1585225,2,1590943,12,10,3,6,10,4,8, +1310721,2,5,26,2,1,40,3,36,1710681,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,1710683,14,1,1710733,16,1442305, +1310721,2,5,26,2,26,2,65,32,1,6,1,10,28,34,63, +38,1,10,28,1710735,14,1,1710763,16,1310721,2,5,26,2,1,1655803, +12,8,1,1711101,14,1642613,12,1711035,16,1643415,12,8,1310721,2,9,26, +1603527,12,10,3,6,10,4,8,1587533,2,1602703,12,1711009,16,1587659,2, +1710877,16,1587659,2,5,28,1,6,1,10,28,34,63,38,1,10, +28,1,6,1,10,28,34,63,38,1,10,28,1710879,14,1,1710947, +16,1710939,14,116,104,101,32,111,110,108,121,32,114,101,116,117, +114,110,32,116,97,103,32,105,115,32,46,117,0,1710887,1588813,12, +8,1310721,2,2,1587657,2,1587659,2,5,28,1,6,1,10,28,34, +63,38,3,26,1310721,2,9,26,2,1699585,12,1,1708971,12,1711101,14, +1587657,2,1587659,2,1310721,2,9,26,2,1704043,12,1711101,14,1711085,14,101, +120,112,101,99,116,101,100,32,97,32,100,101,99,108,97,114, +97,116,105,111,110,0,1711039,1589197,12,8,1,1711101,14,1,1310721,2, +11,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1711149, +16,1966081,1310721,4,1579223,12,1585223,2,1,28,1,6,1,10,28,34, +63,38,1,10,28,1711193,16,1709289,12,8,1711149,14,1,1711201,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1711249,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1310721,2, +3,26,4,1588225,1,10,3,6,10,4,8,1310721,2,3,26,2, +1585153,2,40,1711619,16,1417729,1310721,2,3,26,2,26,2,3,28,1, +6,1,10,28,34,63,38,3,26,1711417,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,1711419,14,1,1711465,16,1450497, +1310721,2,3,26,2,26,2,1,6,1,10,28,34,63,38,1, +10,28,1711467,14,1,1711581,16,1585229,1425921,1310721,2,3,26,2,26,2, +10,3,6,10,4,8,1409537,1310721,2,3,26,2,26,2,1711573,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,1711521,1588983,12,8,1310721,2, +3,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1711287, +14,1588223,2,1711633,16,1588531,12,8,1,1711641,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1711689,16,1966081, +1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,3,1,10,28, +1310721,2,5,26,4,1,1310721,2,7,26,4,1585153,2,1310721,2,9, +26,4,1696941,12,8,1587511,2,1711795,16,1310721,2,5,26,1592669,12,10, +3,6,10,4,8,15,1592369,12,8,1310721,2,3,26,2,1711823,16, +3,1310721,2,2,1695997,12,8,3,1310721,2,2,1,1,1595149,12,8, +1601277,12,8,1310721,2,3,26,2,1711871,16,1711115,12,8,1712025,14,1310721, +2,7,26,1587483,2,10,3,6,10,4,8,3,1,1698421,12,8, +1698753,12,8,1585223,2,1,28,1,6,1,10,28,34,63,38,1, +10,28,1711955,16,1677555,12,8,1711911,14,1587493,2,1610397,12,8,1587499,2, +1712003,16,1587503,2,1,6,1,10,28,34,63,38,1,10,28,1712005, +14,1,1712019,16,3,3,1609669,12,8,1698991,12,8,1596577,12,8,1310721, +2,9,26,2,1711215,12,8,1310721,2,5,26,2,1,40,3,36, +1712089,16,1310721,2,5,26,2,1587483,2,1592451,12,8,1587483,2,1587489,2, +10,40,1712123,16,1587489,1587483,2,10,3,6,10,4,8,1697717,12,8, +1310721,2,7,26,2,1712145,14,1,1310721,2,11,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1712193,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,1,1711655,12,1712217,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1712265,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,3,1711655,12,8,1,1712293, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1712341,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2, +1,1711655,12,1310721,2,3,26,4,1310721,2,3,26,2,1,6,12, +10,8,1712395,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28, +1310721,4,1310721,2,1835009,40,1712443,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,1692925,12,1310721,2,3,26,4,1310721,2,3,26,2,1712307, +12,1310721,2,5,26,4,1310721,2,3,26,2,1580907,12,8,1310721,2, +5,26,2,1712525,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7, +28,1310721,4,1310721,2,1835009,40,1712573,16,1966081,1310721,4,1579223,12,1310721,2, +4,1310721,2,2,1310721,2,3,26,4,1310721,2,3,26,2,1585153,2, +40,1712993,16,1417729,1310721,2,3,26,2,26,2,3,40,3,36,1712695, +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,1712697,14,1,1712707,16,3,1712769, +14,1417729,1310721,2,3,26,2,26,2,13,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1712955,16,1417729,1310721,2,3,26,2,26,2,1592089,12,8,1425921,1310721,2, +3,26,2,26,2,1592089,12,8,1434113,1310721,2,3,26,2,26,2, +1592089,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,1712947,16,1310721,2,5, +26,2,2,1592089,12,8,1310721,2,5,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1712875,14,1,1592089,12,8,1310721,2,3, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1712595,14, +1,1592089,12,8,1,1713009,14,1,1310721,2,7,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,1835009,40,1713057,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,2,1713405,16,1310721,2,5,26,1310721,2,2, +7,26,1589927,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,1590445, +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,2,1,26,2, +13,28,1,6,1,10,28,34,63,38,3,26,1713355,16,1310721,2, +2,3,26,2,1585149,2,40,3,36,1713333,16,1585149,1310721,2,2,3, +26,2,3,26,10,3,6,10,4,8,1310721,2,2,5,26,2, +17,38,1572879,12,8,1310721,2,1310721,2,2,7,26,1310721,2,2,7, +26,1574039,12,26,3,26,10,3,6,10,4,8,1713063,14,1,1713413, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,21,28,1310721,4,1310721, +2,1835009,40,1713461,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721, +2,4,1587483,2,1310721,2,5,26,4,1587485,2,1310721,2,7,26,4, +1587487,2,1310721,2,9,26,4,1585155,2,1310721,2,11,26,4,1585157,2, +1310721,2,13,26,4,1585153,2,1310721,2,15,26,4,1585149,2,1310721,2, +17,26,4,1585155,1585153,2,10,3,6,10,4,8,1585157,1585153,2,10, +3,6,10,4,8,1585149,1,10,3,6,10,4,8,1587483,1310721,2, +2,10,3,6,10,4,8,1587485,1310721,2,3,26,2,1310721,2,2, +28,10,3,6,10,4,8,1587487,1310721,2,2,393217,26,10,3,6, +10,4,8,1966081,1592283,12,8,1310721,1592283,12,8,5,1592369,12,8,1587601, +2,1592751,12,1592875,12,8,15,1592369,12,8,1,1592089,12,8,1,1592089, +12,8,1696803,12,8,1310721,2,3,26,2,11,26,1587483,2,10,3, +6,10,4,8,1585155,2,1712539,12,8,1310721,2,3,26,2,13,26, +1587483,2,10,3,6,10,4,8,1310721,2,19,26,1587483,2,1310721,2, +2,28,10,3,6,10,4,8,1310721,2,15,26,2,1591291,12,8, +1585155,1310721,2,11,26,2,10,3,6,10,4,8,1585157,1310721,2,13, +26,2,10,3,6,10,4,8,1587483,1310721,2,5,26,2,10,3, +6,10,4,8,1587485,1310721,2,7,26,2,10,3,6,10,4,8, +1587487,1310721,2,9,26,2,10,3,6,10,4,8,1585149,1310721,2,17, +26,2,10,3,6,10,4,8,1310721,2,19,26,2,1714049,14,1, +1310721,2,21,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009, +40,1714097,16,1966081,1310721,4,1579223,12,1,1587489,2,1583785,12,8,1587485,2, +1,6,1,10,28,34,63,38,3,26,1714175,16,1587483,2,1587489,2, +10,40,1,6,1,10,28,34,63,38,1,10,28,1714177,14,1, +1714195,16,1587489,2,1587483,2,1583785,12,8,1572865,1572865,13,26,2,1583785,12, +8,1540609,1540609,2049,26,1583785,12,8,1310721,2,1966081,1583785,12,8,2064385,2097121, +1583785,12,8,1,1714255,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +1,28,1310721,4,1310721,2,1835009,40,1714303,16,1966081,1310721,4,1579223,12,1585151, +1327617,10,3,6,10,4,8,1311233,1,16385,1574703,12,8,1585153,1,10, +3,6,10,4,8,1585159,1,10,3,6,10,4,8,1585161,1,10, +3,6,10,4,8,1585163,1,10,3,6,10,4,8,1585165,1,10, +3,6,10,4,8,1585167,1,10,3,6,10,4,8,1585169,1,10, +3,6,10,4,8,1585171,1,10,3,6,10,4,8,1587513,1,10, +3,6,10,4,8,1587517,1,10,3,6,10,4,8,1587519,1,10, +3,6,10,4,8,1587491,1,10,3,6,10,4,8,1587493,1,10, +3,6,10,4,8,1587533,1714549,14,40,0,1714545,1589927,12,10,3,6, +10,4,8,1587535,1714577,14,41,0,1714573,1589927,12,10,3,6,10,4, +8,1587537,1714605,14,123,0,1714601,1589927,12,10,3,6,10,4,8,1587539, +1714633,14,125,0,1714629,1589927,12,10,3,6,10,4,8,1587541,1714661,14, +91,0,1714657,1589927,12,10,3,6,10,4,8,1587543,1714689,14,93,0, +1714685,1589927,12,10,3,6,10,4,8,1587545,1714717,14,44,0,1714713,1589927, +12,10,3,6,10,4,8,1587547,1714745,14,59,0,1714741,1589927,12,10, +3,6,10,4,8,1587549,1714773,14,61,0,1714769,1589927,12,10,3,6, +10,4,8,1587551,1714803,14,45,62,0,1714797,1589927,12,10,3,6,10, +4,8,1587553,1714833,14,43,43,0,1714827,1589927,12,10,3,6,10,4, +8,1587555,1714863,14,45,45,0,1714857,1589927,12,10,3,6,10,4,8, +1587557,1714891,14,42,0,1714887,1589927,12,10,3,6,10,4,8,1587559,1714919, +14,38,0,1714915,1589927,12,10,3,6,10,4,8,1587561,1714947,14,58, +0,1714943,1589927,12,10,3,6,10,4,8,1587563,1714975,14,35,0,1714971, +1589927,12,10,3,6,10,4,8,1587565,1715003,14,45,0,1714999,1589927,12, +10,3,6,10,4,8,1587571,1715031,14,46,0,1715027,1589927,12,10,3, +6,10,4,8,1587593,1715059,14,63,0,1715055,1589927,12,10,3,6,10, +4,8,1587595,1715093,14,99,97,115,101,0,1715083,1589927,12,10,3,6, +10,4,8,1587597,1715133,14,100,101,102,97,117,108,116,0,1715117,1589927, +12,10,3,6,10,4,8,1587567,1715163,14,38,38,0,1715157,1589927,12, +10,3,6,10,4,8,1587569,1715193,14,124,124,0,1715187,1589927,12,10, +3,6,10,4,8,1587573,1715223,14,102,110,0,1715217,1589927,12,10,3, +6,10,4,8,1587575,1715255,14,108,101,116,0,1715247,1589927,12,10,3, +6,10,4,8,1587577,1715291,14,99,111,110,115,116,0,1715279,1589927,12, +10,3,6,10,4,8,1587579,1715325,14,101,108,115,101,0,1715315,1589927, +12,10,3,6,10,4,8,1587581,1715355,14,97,115,0,1715349,1589927,12, +10,3,6,10,4,8,1587583,1715399,14,117,110,99,104,101,99,107, +101,100,0,1715379,1589927,12,10,3,6,10,4,8,1587585,1715443,14,105, +109,109,101,100,105,97,116,101,0,1715423,1589927,12,10,3,6,10, +4,8,1587587,1715471,14,109,0,1715467,1589927,12,10,3,6,10,4,8, +1587589,1715499,14,100,0,1715495,1589927,12,10,3,6,10,4,8,1587591,1715527, +14,117,0,1715523,1589927,12,10,3,6,10,4,8,1587601,1715563,14,115, +116,97,114,116,0,1715551,1589927,12,10,3,6,10,4,8,1587603,1715597, +14,109,97,105,110,0,1715587,1589927,12,10,3,6,10,4,8,1587605, +1715631,14,102,114,101,101,0,1715621,1589927,12,10,3,6,10,4,8, +1587607,1715663,14,111,119,110,0,1715655,1589927,12,10,3,6,10,4,8, +1587609,1715697,14,113,110,101,119,0,1715687,1589927,12,10,3,6,10,4, +8,1587599,1715751,14,102,114,97,109,101,95,111,118,101,114,102,108, +111,119,0,1715721,1589927,12,10,3,6,10,4,8,1587611,1715791,14,101, +110,104,97,110,99,101,0,1715775,1589927,12,10,3,6,10,4,8, +1587613,1715827,14,109,105,99,114,111,0,1715815,1589927,12,10,3,6,10, +4,8,1587615,1715857,14,118,109,0,1715851,1589927,12,10,3,6,10,4, +8,1,1715883,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28, +1310721,4,1310721,2,1835009,40,1715931,16,1966081,1310721,4,1579223,12,1715939,14,33, +0,1715935,1715987,14,48,32,36,32,48,32,126,32,45,32,124,32, +51,49,32,62,32,49,32,43,0,1715945,1607393,12,8,1716005,14,33, +33,0,1715999,1716057,14,48,32,36,32,48,32,126,32,45,32,124, +32,51,49,32,62,32,48,32,126,32,45,0,1716011,1607393,12,8, +1716073,14,126,0,1716069,1716089,14,45,49,32,94,0,1716079,1607393,12,8, +1716105,14,45,0,1716101,1716123,14,48,32,126,32,45,0,1716111,1607393,12, +8,1716139,14,42,0,1716135,21,1716151,14,42,0,1716147,1606353,12,8,1716167, +14,47,0,1716163,21,1716185,14,105,100,105,118,0,1716175,1606353,12,8, +1716201,14,37,0,1716197,21,1716219,14,105,109,111,100,0,1716209,1606353,12, +8,1716235,14,43,0,1716231,19,1716247,14,43,0,1716243,1606353,12,8,1716263, +14,45,0,1716259,19,1716275,14,45,0,1716271,1606353,12,8,1716293,14,60, +60,0,1716287,17,1716311,14,105,115,104,108,0,1716301,1606353,12,8,1716329, +14,62,62,0,1716323,17,1716341,14,62,0,1716337,1606353,12,8,1716357,14, +60,0,1716353,15,1716369,14,60,0,1716365,1606353,12,8,1716385,14,62,0, +1716381,15,1716401,14,126,32,60,0,1716393,1606353,12,8,1716419,14,60,61, +0,1716413,15,1716443,14,126,32,60,32,49,32,94,0,1716427,1606353,12, +8,1716461,14,62,61,0,1716455,15,1716481,14,60,32,49,32,94,0, +1716469,1606353,12,8,1716499,14,61,61,0,1716493,13,1716553,14,45,32,48, +32,36,32,48,32,126,32,45,32,124,32,51,49,32,62,32, +49,32,43,0,1716507,1606353,12,8,1716571,14,33,61,0,1716565,13,1716629, +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,1716579,1606353,12,8,1716645,14, +38,0,1716641,11,1716657,14,38,0,1716653,1606353,12,8,1716673,14,94,0, +1716669,9,1716685,14,94,0,1716681,1606353,12,8,1716701,14,124,0,1716697,7, +1716713,14,124,0,1716709,1606353,12,8,1716731,14,38,38,0,1716725,3,1, +10,28,1,1606353,12,8,1716759,14,124,124,0,1716753,5,1,10,28, +1,1606353,12,8,1587549,2,1605525,12,8,1587551,2,1605525,12,8,1587553,2, +1605525,12,8,1587555,2,1605525,12,8,1716829,14,108,101,116,0,1716821,1680049, +17,1607727,12,8,1716851,14,105,102,0,1716845,1680121,17,1607727,12,8,1716879, +14,119,104,105,108,101,0,1716867,1682687,17,1607727,12,8,1716903,14,102, +111,114,0,1716895,1683299,17,1607727,12,8,1716933,14,115,119,105,116,99, +104,0,1716919,1685869,17,1607727,12,8,1716961,14,98,114,101,97,107,0, +1716949,1684403,17,1607727,12,8,1716995,14,99,111,110,116,105,110,117,101, +0,1716977,1684829,17,1607727,12,8,1717025,14,114,101,116,117,114,110,0, +1717011,1687173,17,1607727,12,8,1717061,14,117,110,99,104,101,99,107,101, +100,0,1717041,1688495,17,1607727,12,8,1717085,14,97,115,109,0,1717077,1691401, +17,33,34,1607727,12,8,1717117,14,113,117,111,116,101,0,1717105,1692651, +33,1607727,12,8,1717147,14,115,105,122,101,111,102,0,1717133,1648613,33, +1607727,12,8,1717177,14,116,121,112,101,111,102,0,1717163,1648729,33,1607727, +12,8,1717199,14,111,51,0,1717193,1687793,17,1607727,12,8,1717223,14,108, +101,110,0,1717215,1646945,33,1607727,12,8,1717247,14,99,97,112,0,1717239, +1647379,33,1607727,12,8,1717273,14,112,117,115,104,0,1717263,1647649,33,1607727, +12,8,1717297,14,112,111,112,0,1717289,1648221,33,1607727,12,8,1717327,14, +114,101,115,105,122,101,0,1717313,1648425,33,1607727,12,8,1,1717347,14, +1,1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +1835009,40,1717395,16,1966081,1310721,4,1579223,12,1577233,12,8,1714269,12,8,1572865, +11,26,2,1713023,12,8,1715897,12,8,1648841,12,8,1587483,1,10,3, +6,10,4,8,1587485,1,10,3,6,10,4,8,1587487,524289,10,3, +6,10,4,8,1587489,1,10,3,6,10,4,8,1585155,1585153,2,10, +3,6,10,4,8,1585157,1,10,3,6,10,4,8,1696803,12,8, +1587483,2,1587489,2,10,40,1717571,16,1587489,1587483,2,10,3,6,10,4, +8,1310721,2,1587603,2,1590943,12,10,3,6,10,4,8,1310721,2,2, +1,40,3,36,1717675,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,1717677,14,1,1717723,16,1442305,1310721,2,2,26,2,3,32, +1,6,1,10,28,34,63,38,1,10,28,1717725,14,1,1717783,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,1573437,12,8,1,1717797, +14,1,1310721,2,5,26,1310721,4,18,1,858680,0,115,116,97,114, +116,0,1,786439,2,105,110,115,116,97,108,108,0,1,786627,2, +112,117,116,99,0,1,786662,0,103,101,116,99,0,1,786690,0, +101,111,102,0,1,786718,0,104,97,108,116,0,1,786747,2,112, +117,116,115,0,1,786828,2,112,117,116,110,0,1,787019,2,115, +116,114,108,101,110,0,1,787091,4,115,116,114,101,113,0,1, +787245,6,119,99,111,112,121,0,1,787351,6,119,102,105,108,108, +0,1,787483,4,122,117,100,105,118,0,1,787714,4,122,100,105, +118,0,1,787902,4,122,109,111,100,0,1,787997,4,122,115,104, +108,0,1,788082,2,116,111,112,115,105,122,101,0,1,788258,4, +102,112,117,115,104,0,1,788382,4,102,117,110,108,105,110,107, +0,1,788495,4,109,107,98,108,111,99,107,0,1,788616,0,104, +101,97,112,95,105,110,105,116,0,1,788847,2,98,97,108,108, +111,99,0,1,789084,2,98,102,114,101,101,0,1,789482,2,105, +115,111,98,106,0,1,789611,0,102,114,97,109,101,95,111,118, +101,114,102,108,111,119,0,1,789674,0,111,111,109,0,1,789735, +3,110,101,119,95,114,97,119,0,1,790010,5,110,101,119,95, +116,0,1,790103,3,110,101,119,0,1,790139,2,111,115,105,122, +101,0,1,790200,2,116,121,112,101,111,102,95,111,98,106,0, +1,790259,2,114,101,108,101,97,115,101,0,1,790453,130,102,114, +101,101,0,1,790497,4,111,119,110,0,1,790561,7,100,110,101, +119,0,1,790747,4,100,103,114,111,119,0,1,791103,4,111,111, +98,0,1,791211,4,100,97,116,0,1,791318,516,100,112,117,115, +104,0,1,791425,2,100,112,111,112,0,1,791514,4,100,114,101, +115,105,122,101,0,1,791670,2,100,108,101,110,0,1,791706,2, +100,99,97,112,0,1,791746,2,109,97,114,107,0,1,791892,4, +109,97,114,107,114,97,110,103,101,0,1,791963,0,100,114,97, +105,110,0,1,857031,0,103,99,95,114,111,111,116,115,0,1, +792045,0,103,99,0,1,792363,0,108,105,118,101,95,111,98,106, +101,99,116,115,0,1,792459,0,108,97,114,103,101,115,116,95, +102,114,101,101,0,1,794113,0,101,114,114,97,116,0,1,794185, +0,101,114,114,101,110,100,0,1,794265,0,103,105,118,101,117, +112,0,1,794359,2,102,97,116,97,108,0,1,794406,2,115,101, +114,114,0,1,794491,4,115,101,114,114,110,0,1,794598,2,100, +105,101,0,1,794665,4,100,105,101,110,0,1,794742,2,99,101, +114,114,0,1,794801,4,99,101,114,114,110,0,1,794873,2,104, +97,115,104,115,0,1,794963,2,105,110,116,101,114,110,0,1, +795222,6,97,100,100,115,121,109,0,1,795471,2,108,111,111,107, +117,112,0,1,795645,2,112,111,112,115,121,109,115,0,1,795722, +2,108,111,111,107,117,112,115,0,1,795759,4,102,105,120,110, +101,119,0,1,795935,4,102,105,120,97,108,108,0,1,796044,2, +101,109,105,116,0,1,796141,2,108,105,116,0,1,796184,2,111, +112,0,1,796225,4,115,101,116,108,105,116,0,1,796293,2,106, +109,112,0,1,796334,0,104,111,108,101,0,1,796375,2,102,119, +100,102,110,0,1,796437,2,102,110,114,101,102,0,1,796524,2, +99,97,108,108,110,97,109,101,0,1,796601,2,108,97,100,100, +114,0,1,796655,2,118,97,100,100,114,0,1,796789,2,97,100, +100,115,108,0,1,796915,8,111,51,114,101,103,105,111,110,0, +1,797075,0,111,51,102,108,117,115,104,0,1,797191,2,115,116, +114,108,105,116,0,1,797297,0,110,101,120,116,99,104,0,1, +797574,8,115,114,99,95,112,117,115,104,0,1,798288,0,115,114, +99,95,112,111,112,0,1,798629,2,105,115,111,112,99,104,0, +1,798740,4,111,112,112,114,101,102,105,120,0,1,798983,2,105, +115,100,105,103,0,1,799044,2,105,115,97,108,0,1,799183,2, +104,101,120,118,0,1,799315,0,101,115,99,99,104,0,1,799489, +2,111,112,108,101,120,0,1,799634,0,108,101,120,0,1,800638, +0,110,101,120,116,0,1,800837,2,112,101,101,107,97,116,0, +1,801068,0,112,101,101,107,0,1,801098,0,110,101,120,116,48, +0,1,801351,2,105,115,95,111,112,0,1,801427,2,105,115,95, +105,100,0,1,801503,2,97,99,99,101,112,116,0,1,801618,2, +101,120,112,101,99,116,0,1,801763,0,110,97,109,101,0,1, +801840,2,115,101,113,97,115,109,0,1,802409,2,109,110,101,109, +105,100,120,0,1,802511,4,101,109,105,116,115,101,113,0,1, +802762,2,97,100,100,107,111,112,0,1,802882,2,98,105,110,102, +105,110,100,0,1,802980,2,117,110,102,105,110,100,0,1,803078, +2,97,115,103,102,105,110,100,0,1,803176,6,97,100,100,95, +98,105,110,111,112,0,1,803696,4,97,100,100,95,117,110,111, +112,0,1,803863,6,97,100,100,95,107,119,0,1,803946,2,102, +105,110,100,108,111,99,0,1,804048,2,110,101,119,108,111,99, +0,1,804279,2,108,114,111,111,116,0,1,804348,2,116,114,97, +99,107,101,100,0,1,804397,2,116,111,117,99,104,0,1,804641, +2,112,108,97,105,110,117,115,101,0,1,804781,2,102,114,101, +101,118,97,114,0,1,804834,4,101,120,105,116,95,118,97,114, +115,0,1,805198,2,117,110,117,115,101,100,95,99,104,101,99, +107,0,1,805347,2,98,108,111,99,107,95,99,108,111,115,101, +0,1,805483,0,115,110,97,112,95,112,117,115,104,0,1,805758, +2,115,110,97,112,95,112,111,112,0,1,805799,2,115,110,97, +112,95,114,101,115,116,111,114,101,0,1,806018,2,101,109,112, +116,121,0,1,806094,2,115,110,97,112,95,99,109,112,0,1, +806499,2,115,116,97,116,101,110,97,109,101,0,1,806717,6,109, +101,114,103,101,95,101,114,114,0,1,806983,4,106,115,116,0, +1,807058,4,106,111,119,0,1,807114,4,106,104,109,0,1,807170, +2,101,120,105,116,95,114,101,99,0,1,807466,2,106,97,100, +100,0,1,807570,6,106,115,97,109,101,0,1,807830,4,106,111, +105,110,0,1,808622,6,102,105,120,117,112,115,0,1,808869,2, +98,97,99,107,101,100,103,101,0,1,809660,12,106,111,105,110, +50,0,1,809947,4,114,101,99,97,115,116,0,1,810483,4,97, +114,103,99,104,101,99,107,0,1,811249,2,101,109,105,116,111, +119,110,0,1,811333,6,97,115,115,105,103,110,99,104,101,99, +107,0,1,813110,2,114,101,116,99,104,101,99,107,0,1,813617, +2,104,97,110,100,117,112,0,1,813975,2,100,105,115,99,97, +114,100,0,1,814098,2,116,97,108,108,111,99,0,1,814205,8, +116,110,101,119,0,1,814379,2,116,112,116,114,0,1,814566,4, +116,97,114,114,0,1,814826,8,116,102,110,0,1,815287,4,116, +100,121,110,0,1,815537,4,116,118,97,114,0,1,815733,6,116, +105,110,115,116,0,1,816164,2,116,114,101,115,111,108,118,101, +0,1,816700,2,116,115,122,0,1,816786,4,115,117,98,115,116, +0,1,817285,2,105,115,110,117,109,0,1,817401,2,105,115,97, +103,103,0,1,817483,2,105,115,112,116,114,0,1,817565,2,100, +101,99,97,121,0,1,817628,2,116,101,108,101,109,0,1,817722, +4,99,111,109,112,97,116,0,1,818380,6,117,110,105,102,121, +0,1,818925,2,116,112,114,105,110,116,0,1,819553,6,116,99, +101,114,114,0,1,819753,6,116,99,110,101,101,100,0,1,819948, +2,116,112,102,105,110,100,0,1,820046,2,105,115,116,121,112, +101,110,97,109,101,0,1,820185,0,99,108,111,115,101,97,110, +103,108,101,0,1,820236,0,112,116,121,112,101,0,1,820442,0, +112,116,121,112,101,48,0,1,821306,0,116,115,116,97,114,116, +0,1,821707,0,100,116,121,112,101,0,1,821894,0,107,119,95, +115,116,114,117,99,116,0,1,822847,0,107,119,95,116,121,112, +101,0,1,822907,0,107,119,95,116,121,112,101,99,104,101,99, +107,0,1,823014,4,116,102,105,110,100,102,105,101,108,100,0, +1,823138,0,116,121,112,101,97,114,103,0,1,823305,0,97,114, +114,97,114,103,0,1,823358,2,110,111,103,114,111,119,0,1, +823472,0,107,119,95,108,101,110,0,1,823689,0,107,119,95,99, +97,112,0,1,823824,0,107,119,95,112,117,115,104,0,1,824110, +0,107,119,95,112,111,112,0,1,824212,0,107,119,95,114,101, +115,105,122,101,0,1,824306,0,107,119,95,115,105,122,101,111, +102,0,1,824364,0,107,119,95,116,121,112,101,111,102,0,1, +824420,0,116,121,112,101,115,95,105,110,105,116,0,1,825229,2, +105,115,110,117,109,111,112,0,1,825322,6,98,105,110,116,121, +112,101,0,1,826715,2,116,107,105,110,100,0,1,826751,2,116, +115,105,122,101,0,1,826786,2,116,110,97,109,101,0,1,826822, +2,116,108,101,110,0,1,826858,2,116,110,102,105,101,108,100, +115,0,1,826900,4,116,102,110,97,109,101,0,1,826956,4,116, +102,116,121,112,101,0,1,827014,4,116,102,111,102,102,0,1, +827072,2,116,114,101,116,0,1,827108,2,116,110,112,97,114,97, +109,115,0,1,827144,4,116,112,97,114,97,109,0,1,827191,4, +116,112,97,114,97,109,116,97,103,0,1,827248,2,116,114,101, +116,117,0,1,827286,2,116,110,97,114,103,115,0,1,827381,4, +116,97,114,103,0,1,827431,2,115,105,103,111,102,0,1,827742, +2,115,105,103,111,102,115,0,1,827841,0,114,118,97,108,0, +1,827901,4,107,119,99,97,108,108,0,1,828047,0,115,116,109, +116,111,110,108,121,0,1,828125,6,97,114,103,115,0,1,828398, +0,110,101,119,116,121,112,101,100,0,1,828875,2,99,97,108, +108,0,1,829530,2,101,110,104,99,97,108,108,0,1,829899,0, +112,114,105,109,97,114,121,0,1,831364,4,105,110,99,100,101, +99,0,1,831788,2,102,105,101,108,100,0,1,832464,0,112,111, +115,116,102,105,120,0,1,834012,0,117,110,97,114,121,0,1, +834952,2,98,105,110,0,1,835465,0,115,116,111,114,101,107,101, +101,112,0,1,835513,2,116,101,114,110,97,114,121,0,1,836163, +0,101,120,112,114,0,1,837262,0,115,116,109,116,115,116,97, +114,116,0,1,837509,0,98,108,111,99,107,101,120,112,114,0, +1,837885,0,99,112,114,105,109,0,1,838293,0,99,101,120,112, +114,0,1,838650,0,114,101,115,121,110,99,0,1,838777,0,115, +116,109,116,0,1,839045,0,98,108,111,99,107,0,1,839173,0, +115,117,98,115,116,109,116,0,1,839253,2,108,111,99,97,108, +100,101,99,108,0,1,840024,0,107,119,95,118,97,114,0,1, +840060,0,107,119,95,105,102,0,1,840606,4,108,111,111,112,95, +112,117,115,104,0,1,840813,4,108,111,111,112,95,101,110,100, +0,1,841343,0,107,119,95,119,104,105,108,101,0,1,841649,0, +107,119,95,102,111,114,0,1,842201,0,107,119,95,98,114,101, +97,107,0,1,842414,0,107,119,95,99,111,110,116,105,110,117, +101,0,1,842701,4,99,97,115,101,98,111,100,121,0,1,842934, +0,107,119,95,115,119,105,116,99,104,0,1,843586,0,107,119, +95,114,101,116,117,114,110,0,1,843896,0,107,119,95,111,51, +0,1,844247,0,107,119,95,117,110,99,104,101,99,107,101,100, +0,1,844307,0,97,115,109,98,108,111,99,107,0,1,845700,0, +107,119,95,97,115,109,0,1,845742,1,103,114,97,98,0,1, +846082,3,113,110,101,119,0,1,846160,67,113,100,117,112,0,1, +846238,68,119,99,111,112,121,116,111,0,1,846325,0,107,119,95, +113,117,111,116,101,0,1,846462,3,116,111,107,101,110,115,0, +1,846702,130,102,101,101,100,0,1,846745,0,114,101,97,100,115, +114,99,0,1,847167,0,112,115,107,105,112,97,110,103,108,101, +0,1,847299,2,112,114,101,115,99,97,110,95,102,110,0,1, +847998,4,112,114,101,115,99,97,110,0,1,848401,0,117,110,105, +116,95,115,116,100,105,110,0,1,848470,0,99,116,120,95,112, +117,115,104,0,1,848858,0,99,116,120,95,112,111,112,0,1, +849210,4,102,110,95,98,101,103,105,110,0,1,849376,0,112,114, +111,108,111,103,117,101,0,1,849495,0,101,112,105,108,111,103, +117,101,0,1,849587,0,98,111,100,121,0,1,849792,8,102,110, +100,101,102,0,1,851982,2,103,100,101,99,108,0,1,852021,6, +103,100,101,99,108,50,0,1,852633,0,103,99,111,110,115,116, +0,1,852716,0,101,110,104,100,101,102,0,1,854004,0,116,111, +112,115,121,110,99,0,1,854485,4,102,110,100,111,110,101,0, +1,854644,0,116,111,112,105,116,101,109,0,1,855557,0,117,110, +105,116,95,116,111,112,0,1,855607,2,117,110,105,116,95,101, +110,100,0,1,855827,4,99,111,109,112,105,108,101,95,108,105, +115,116,0,1,856079,2,99,111,109,112,105,108,101,0,1,856115, +2,108,111,97,100,0,1,856153,2,101,118,97,108,0,1,856204, +2,101,118,97,108,115,0,1,856269,2,98,108,111,98,95,101, +109,105,116,0,1,856511,2,98,108,111,98,95,108,111,97,100, +0,1,856713,4,98,117,105,108,100,95,105,109,97,103,101,0, +1,857134,0,122,99,95,105,110,105,116,0,1,857948,0,122,99, +95,116,97,98,108,101,115,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,6,0,201337106,105,100,105,118,0,6,1,201343762, +105,109,111,100,0,6,2,201350418,105,115,104,108,0,6,3,201356817, +108,102,97,0,6,4,201366802,111,117,116,115,105,100,101,0,3, +787450,0,112,111,119,50,0,2,787482,0,122,114,101,109,0,4, +6,0,72,68,82,0,2,788046,0,104,98,117,109,112,0,3, +788047,0,102,114,101,101,108,0,2,788079,0,103,99,95,114,117, +110,115,0,2,788080,0,103,99,95,102,114,101,101,100,0,2, +788081,0,103,99,95,97,117,116,111,0,2,789083,0,102,101,110, +100,0,2,791742,0,109,115,95,116,111,112,0,2,791743,0,109, +115,95,111,118,101,114,0,2,791744,0,103,99,95,108,111,0, +2,791745,0,103,99,95,104,105,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,6,0,75,95,69,78,72,0,4,7,0,75,95,84,89, +80,69,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, +64,0,70,95,70,65,76,76,66,65,67,75,0,4,128,0, +70,95,71,69,78,0,4,256,0,70,95,80,82,69,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,20,0,79,95,76,84,0,4,22,0, +88,79,80,48,0,4,-2,0,83,69,81,82,69,70,0,2, +792574,0,110,101,110,104,0,2,792575,0,112,111,111,108,116,111, +112,0,2,792576,0,110,115,121,109,0,2,792577,0,117,98,97, +115,101,0,2,792578,0,118,105,115,108,111,0,2,792579,0,110, +102,105,120,117,0,2,792580,0,102,105,120,102,114,101,101,0, +2,792581,0,110,98,105,110,0,2,792582,0,110,117,110,0,2, +792583,0,110,97,115,103,0,2,792584,0,110,107,111,112,0,2, +792585,0,115,101,113,116,111,112,0,2,792586,0,109,110,101,109, +0,2,792610,0,99,104,101,99,107,95,111,110,0,2,792611,0, +116,107,0,2,792612,0,116,118,0,2,792613,0,116,103,108,117, +101,0,2,792614,0,116,108,105,110,101,0,2,792615,0,108,105, +110,101,0,2,792616,0,99,104,0,2,792617,0,99,104,107,105, +110,100,0,2,792618,0,99,104,112,116,114,0,2,792619,0,99, +104,98,97,115,101,0,2,792620,0,113,100,111,110,101,0,2, +792621,0,105,115,112,0,3,792622,0,116,98,117,102,0,2,793722, +0,112,107,95,116,107,0,2,793723,0,112,107,95,116,118,0, +2,793724,0,112,113,95,110,0,3,793725,0,112,113,95,116,107, +0,3,793729,0,112,113,95,116,118,0,3,793733,0,112,113,95, +103,108,0,3,793737,0,112,113,95,108,110,0,2,793741,0,104, +101,114,101,0,2,793742,0,104,100,101,108,116,97,0,2,793743, +0,104,108,105,109,105,116,0,2,793744,0,112,116,111,112,0, +2,793745,0,110,108,111,99,0,2,793746,0,108,98,97,115,101, +0,2,793747,0,102,100,101,112,116,104,0,2,793748,0,102,115, +108,111,116,115,0,2,793749,0,102,99,104,107,0,2,793750,0, +102,114,101,116,0,2,793751,0,108,105,118,101,0,2,793752,0, +98,120,100,101,112,116,104,0,2,793753,0,101,112,105,99,104, +97,105,110,0,2,793754,0,102,102,114,97,109,101,0,2,793755, +0,105,110,102,110,0,2,793756,0,108,115,112,0,2,793757,0, +108,111,111,112,98,97,115,101,0,2,793758,0,99,116,120,115, +112,0,2,793759,0,115,110,97,112,116,111,112,0,2,793760,0, +108,118,0,2,793761,0,108,118,107,0,2,793762,0,108,118,105, +0,2,793763,0,107,119,95,101,120,112,114,0,2,793764,0,120, +99,108,115,0,2,793765,0,102,116,121,0,2,793766,0,115,95, +108,112,0,2,793767,0,115,95,114,112,0,2,793768,0,115,95, +108,98,0,2,793769,0,115,95,114,98,0,2,793770,0,115,95, +108,107,0,2,793771,0,115,95,114,107,0,2,793772,0,115,95, +99,111,109,109,97,0,2,793773,0,115,95,115,101,109,105,0, +2,793774,0,115,95,101,113,0,2,793775,0,115,95,97,114,114, +111,119,0,2,793776,0,115,95,105,110,99,0,2,793777,0,115, +95,100,101,99,0,2,793778,0,115,95,115,116,97,114,0,2, +793779,0,115,95,97,109,112,0,2,793780,0,115,95,99,111,108, +111,110,0,2,793781,0,115,95,104,97,115,104,0,2,793782,0, +115,95,109,105,110,117,115,0,2,793783,0,115,95,97,110,100, +97,110,100,0,2,793784,0,115,95,111,114,111,114,0,2,793785, +0,115,95,100,111,116,0,2,793786,0,115,95,102,110,0,2, +793787,0,115,95,118,97,114,0,2,793788,0,115,95,99,111,110, +115,116,0,2,793789,0,115,95,101,108,115,101,0,2,793790,0, +115,95,97,115,0,2,793791,0,115,95,117,110,99,104,101,99, +107,101,100,0,2,793792,0,115,95,105,109,109,101,100,105,97, +116,101,0,2,793793,0,115,95,109,0,2,793794,0,115,95,100, +0,2,793795,0,115,95,117,0,2,793796,0,115,95,113,0,2, +793797,0,115,95,99,97,115,101,0,2,793798,0,115,95,100,101, +102,97,117,108,116,0,2,793799,0,115,95,102,111,118,102,0, +2,793800,0,115,95,115,116,97,114,116,0,2,793801,0,115,95, +109,97,105,110,0,2,793802,0,115,95,102,114,101,101,0,2, +793803,0,115,95,111,119,110,0,2,793804,0,115,95,113,110,101, +119,0,2,793805,0,115,95,101,110,104,97,110,99,101,0,2, +793806,0,115,95,109,105,99,114,111,0,2,793807,0,115,95,118, +109,0,4,0,0,84,89,95,87,79,82,68,0,4,1,0, +84,89,95,73,78,84,0,4,2,0,84,89,95,67,72,65, +82,0,4,3,0,84,89,95,66,79,79,76,0,4,4,0, +84,89,95,86,79,73,68,0,4,5,0,84,89,95,80,84, +82,0,4,6,0,84,89,95,65,82,82,0,4,7,0,84, +89,95,70,78,0,4,8,0,84,89,95,83,84,82,85,67, +84,0,4,9,0,84,89,95,86,65,82,0,4,10,0,84, +89,95,71,69,78,0,4,11,0,84,89,95,68,89,78,0, +4,638976,0,82,95,84,89,0,4,655360,0,82,95,84,89,69, +78,68,0,4,1024,0,78,84,76,0,4,778496,0,108,116,121, +112,101,0,4,779008,0,108,116,97,103,0,4,779520,0,115,116, +121,112,101,0,2,793808,0,116,121,116,111,112,0,2,793809,0, +110,116,108,0,2,793810,0,116,119,111,114,100,0,2,793811,0, +116,105,110,116,0,2,793812,0,116,99,104,97,114,0,2,793813, +0,116,98,111,111,108,0,2,793814,0,116,118,111,105,100,0, +2,793815,0,116,99,95,111,110,0,2,793816,0,120,116,121,0, +2,793817,0,120,122,101,114,111,0,2,793818,0,100,114,121,0, +3,793819,0,116,112,110,0,2,793827,0,110,116,112,0,2,793828, +0,100,116,121,0,2,793829,0,100,116,97,103,0,2,793830,0, +115,95,108,116,0,2,793831,0,115,95,103,116,0,2,793832,0, +115,95,115,104,114,0,2,793833,0,115,95,108,101,0,2,793834, +0,115,95,103,101,0,2,793835,0,115,95,101,113,101,113,0, +2,793836,0,115,95,110,101,0,2,793837,0,115,95,112,108,117, +115,0,2,793838,0,115,95,115,116,114,117,99,116,0,2,793839, +0,115,95,116,121,112,101,0,2,793840,0,115,95,116,121,112, +101,99,104,101,99,107,0,2,793841,0,115,95,111,110,0,2, +793842,0,115,95,111,102,102,0,2,793843,0,115,95,110,101,119, +0,2,793844,0,115,95,110,101,119,95,116,0,2,793845,0,115, +95,111,51,0,2,793846,0,115,95,108,102,97,0,2,793847,0, +115,95,111,117,116,115,105,100,101,0,2,793848,0,115,95,110, +101,119,95,114,97,119,0,2,793849,0,115,95,111,111,98,0, +2,793850,0,111,51,111,110,0,2,793851,0,111,51,110,120,116, +0,2,793852,0,111,51,111,110,101,0,3,793853,0,111,51,115, +108,0,2,793861,0,110,111,51,115,108,0,3,793862,0,111,51, +112,101,110,100,0,2,794062,0,110,111,51,112,101,110,100,0, +3,794063,0,111,51,100,115,99,0,3,794079,0,110,117,109,111, +112,115,0,2,794091,0,110,110,117,109,111,112,115,0,2,794092, +0,115,95,102,105,120,101,100,0,2,794093,0,115,95,100,108, +101,110,0,2,794094,0,115,95,100,99,97,112,0,2,794095,0, +115,95,100,110,101,119,0,2,794096,0,115,95,100,97,116,0, +2,794097,0,115,95,100,112,117,115,104,0,2,794098,0,115,95, +100,112,111,112,0,2,794099,0,115,95,100,114,101,115,105,122, +101,0,2,794100,0,120,99,111,110,115,116,0,2,794101,0,120, +99,118,97,108,0,3,794102,0,103,98,105,110,100,0,2,794110, +0,110,103,98,105,110,100,0,2,794111,0,110,101,114,114,0, +2,794112,0,112,97,110,105,99,0,4,783616,0,82,95,69,88, +73,84,0,4,786176,0,82,95,69,88,73,84,69,78,68,0, +2,806917,0,101,120,116,111,112,0,3,806918,0,106,112,115,0, +2,806982,0,110,106,112,115,0,0 +}; +#define GLEN 78217 diff --git a/docs/history/15-o3/code/io_linux.c b/docs/history/15-o3/code/io_linux.c new file mode 100644 index 0000000..7ea34e0 --- /dev/null +++ b/docs/history/15-o3/code/io_linux.c @@ -0,0 +1,6 @@ +#include +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/15-o3/code/mkgenome.c b/docs/history/15-o3/code/mkgenome.c new file mode 100644 index 0000000..8fb2cc5 --- /dev/null +++ b/docs/history/15-o3/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 +#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/15-o3/code/src/compiler.zc b/docs/history/15-o3/code/src/compiler.zc new file mode 100644 index 0000000..6e2388b --- /dev/null +++ b/docs/history/15-o3/code/src/compiler.zc @@ -0,0 +1,2832 @@ +// ============================================================================ +// 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, 32 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, 8 words per loop or switch +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, K_ENH = 6, K_TYPE = 7; +const F_DEF = 1, F_SIG = 2, F_UNTYPED = 4, F_STMT = 8, F_EXPR = 16, F_TOP = 32, F_FALLBACK = 64, F_GEN = 128, F_PRE = 256; +// 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, O_LT = 20; +const XOP0 = 22; // first enhancement opcode +const SEQREF = -2; // in an operator sequence: the next word names a symbol + +// ---- state ---- +let nenh, pooltop, nsym, ubase, vislo, nfixu, fixfree; +let nbin, nun, nasg, nkop, seqtop; +let mnem = "q@!$_~cjzr,?.+-*&|^><%"; +let check_on = 1; // set to 0 to switch the analyzer off for what follows +let tk, tv, tglue, tline, line = 1, ch, chkind, chptr, chbase, qdone, isp = -1; +let tbuf[1100]; +let pk_tk, pk_tv, pq_n, pq_tk[4], pq_tv[4], pq_gl[4], pq_ln[4]; // up to 4 tokens of lookahead +let here, hdelta, hlimit, ptop; +let nloc, lbase, fdepth, fslots, fchk, fret, live, bxdepth, epichain, fframe, infn; +let lsp, loopbase, ctxsp, snaptop; +let lv, lvk, lvi, kw_expr, xcls, fty; +// interned spellings the parser compares against +let s_lp, s_rp, s_lb, s_rb, s_lk, s_rk, s_comma, s_semi, s_eq, s_arrow, s_inc, s_dec; +let s_star, s_amp, s_colon, s_hash, s_minus, s_andand, s_oror; +let s_dot, s_fn, s_var, s_const, s_else, s_as, s_unchecked, s_immediate, s_m, s_d, s_u; +let s_q, s_case, s_default, s_fovf, s_start, s_main, s_free, s_own, s_qnew, s_enhance, s_micro, s_vm; + +// ---- types: kinds, tables and parser state (see the types section) ---- +const TY_WORD = 0, TY_INT = 1, TY_CHAR = 2, TY_BOOL = 3, TY_VOID = 4, TY_PTR = 5, TY_ARR = 6; +const TY_FN = 7, TY_STRUCT = 8, TY_VAR = 9, TY_GEN = 10, TY_DYN = 11; // dyn: []T, a = element, n = 1 if fixed +const R_TY = 0x9C000, R_TYEND = 0xA0000, NTL = 1024; // the first NTL words list every record +const ltype = 0xBE100, ltag = 0xBE300, stype = 0xBE500; // type per local, declared tag per local, type per symbol +let tytop, ntl, tword, tint, tchar, tbool, tvoid; +let tc_on; // the optional typechecker, off unless a program says typecheck on; +let xty, xzero, dry; // type of the last expression, was it a literal 0, and dry runs (typeof) +let tpn[8], ntp; // type parameters in scope +let dty, dtag; // result of dtype() +let s_lt, s_gt, s_shr, s_le, s_ge, s_eqeq, s_ne, s_plus, s_struct, s_type, s_typecheck, s_on, s_off, s_new, s_new_t; +let s_o3, s_lfa, s_outside, s_new_raw, s_oob; +let o3on, o3nxt, o3one, o3sl[8], no3sl, o3pend[200], no3pend, o3dsc[16]; // o3: in an o3 region; the promoted slots; o3 blocks waiting for the function's end +let numops[12], nnumops, s_fixed, s_dlen, s_dcap, s_dnew, s_dat, s_dpush, s_dpop, s_dresize, xconst, xcval; +let gbind[8], ngbind; // explicit type arguments for the next call: f(...) + +// ---- errors ---- +// the compiler reports up to 20 errors before it stops. a syntax error +// (die) skips the token it happened on and sets panic, which skips ahead to +// the next ; or } (or the next top-level item) and keeps quiet until then. +// other errors (serr) just report: the parse is still in step. +let nerr, panic; +fn errat() { puts("zc: line "); putn(tline); puts(": "); nerr++; return 0; } +fn errend() { putc(10); if (nerr >= 20) { puts("zc: too many errors, stopping\n"); halt(); } return 0; } +fn giveup() { puts("zc: "); putn(nerr); if (nerr == 1) puts(" error\n"); else puts(" errors\n"); halt(); return 0; } +fn fatal(msg) { errat(); puts(msg); putc(10); halt(); return 0; } +fn serr(msg) { if (!panic && !dry) { errat(); puts(msg); errend(); } return 0; } +fn serrn(name, msg) { if (!panic && !dry) { errat(); puts(name); puts(": "); puts(msg); errend(); } return 0; } +fn die(msg) { serr(msg); panic = 1; if (tk == T_EOF) giveup(); next(); return 0; } +fn dien(name, msg) { serrn(name, msg); panic = 1; if (tk == T_EOF) giveup(); next(); return 0; } +// analyzer errors only count in checked, reachable code +fn cerr(msg) { if (fchk && live) serr(msg); return 0; } +fn cerrn(i, msg) { if (fchk && live) serrn(lname[i], msg); return 0; } + +// ---- interning ---- +fn hashs(s) { let h = 0; while (*s) { h = h * 31 + *s; s++; } return h & (IHN - 1); } +fn intern(s) +{ + let 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) fatal("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) +{ + let i = nsym; + if (nsym >= NS) fatal("symbol table full"); + nsym++; + sname[i] = name; skind[i] = kind; sval[i] = val; ssig[i] = 0; sflag[i] = F_DEF; sfix[i] = 0; stype[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) +{ + let i = name[-1] - 1; + while (i >= 0) { + if (i >= vislo || skind[i] == K_KW || skind[i] == K_TYPE) 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) +{ + let i = fixfree; + if (i) fixfree = fnext[i]; + else { nfixu++; i = nfixu; if (i >= NF) fatal("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) +{ + let 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 (dry) return 0; if (here >= hlimit) fatal("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) { if (dry) return 0; *(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() { let a = here; lit(MW - 1); return a; } +fn fwdfn(name) { let s = addsym(name, K_FN, tline); sflag[s] = 0; return s; } // the line of the first use, until it's defined +fn fnref(s) +{ + if (sflag[s] & F_DEF) { lit(sval[s]); return 0; } + if (dry) 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) { let 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; } +// an o3 variable's address: lfa(k) is fp + k as one enhancement, which the +// jit specializes on the literal k +fn vaddr(i) +{ + let s; + if (ltag[i] & 16) { s = lookup(s_lfa); if (s >= 0 && skind[s] == K_ENH) { lit(lslot[i]); op(XOP0 + sval[s]); return 0; } } + return laddr(lslot[i]); +} +// the slots an o3 region keeps in registers (the cpu takes 7) +fn addsl(k) +{ + let i = 0; + while (i < no3sl) { if (o3sl[i] == k) return 0; i++; } + if (no3sl < 7) { o3sl[no3sl] = k; no3sl++; } + return 0; +} +// hands a region to the cpu: install kind 2 is [-, 2, lo, hi, n, slots...] +fn o3region(lo, hi, sl, n) +{ + if (hdelta || lo >= hi) return 0; + o3dsc[0] = 0; o3dsc[1] = 2; o3dsc[2] = lo; o3dsc[3] = hi; o3dsc[4] = n; + wcopy(o3dsc + 5, sl, n); + install(o3dsc); + return 0; +} +// o3 blocks go to the cpu once their function is done, so every jump in them is final +fn o3flush() +{ + let i = 0, p; + while (i < no3pend) { p = o3pend + i * 10; o3region(p[0], p[1], p + 3, p[2]); i++; } + no3pend = 0; + return 0; +} +fn strlit(s) +{ + let 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 12 saved line +// 13 saved token line 14 saved lookahead count 15..30 saved lookahead 31 saved char buffer +fn nextch() +{ + if (chkind == 0) { + if (qdone || eof()) { ch = -1; return 0; } + ch = getc() & 255; + if (ch == 96) { qdone = 1; ch = -1; return 0; } // a backtick ends the source + } else if (chkind == 3) { + ch = (chbase[chptr >> 2] >> ((chptr & 3) * 8)) & 255; + if (ch) chptr++; else ch = -1; + } else { + ch = *chptr & 255; + if (ch) chptr++; else ch = -1; + } + if (ch == 10) line++; + return 0; +} +fn src_push(kind, obj, trans, owned) +{ + let f, i; + isp++; + if (isp >= 32) fatal("sources nested too deeply"); + f = R_SRC + isp * 32; + 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; + f[12] = line; f[13] = tline; f[14] = pq_n; f[31] = chbase; + i = 0; while (i < pq_n) { f[15 + i * 4] = pq_tk[i]; f[16 + i * 4] = pq_tv[i]; f[17 + i * 4] = pq_gl[i]; f[18 + i * 4] = pq_ln[i]; i++; } + pq_n = 0; + if (kind == 1) f[3] = obj[0]; + if (kind == 0) { chkind = 0; qdone = 0; line = 1; nextch(); } + if (kind == 2) { chkind = 2; chptr = obj; line = 1; nextch(); } + if (kind == 3) { chkind = 3; chbase = obj; chptr = 0; line = 1; nextch(); } + return 0; +} +fn src_pop() +{ + let f = R_SRC + isp * 32, i = 0; + tk = f[5]; tv = f[6]; tglue = f[7]; ch = f[8]; chkind = f[9]; chptr = f[10]; + line = f[12]; tline = f[13]; pq_n = f[14]; chbase = f[31]; + while (i < pq_n) { pq_tk[i] = f[15 + i * 4]; pq_tv[i] = f[16 + i * 4]; pq_gl[i] = f[17 + i * 4]; pq_ln[i] = f[18 + i * 4]; i++; } + isp--; + if (f[11]) free(f[1]); + return 0; +} +fn isopch(c) +{ + let 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) +{ + let 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() +{ + let 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() +{ + let n = 0, v, dg; + 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 ((dg = hexv(ch)) >= 0) { v = v * 16 + dg; 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; +} +// one token of lookahead: peek() fills pk_*, next() takes it first +fn next() +{ + let i = 1; + if (pq_n) { + tk = pq_tk[0]; tv = pq_tv[0]; tglue = pq_gl[0]; tline = pq_ln[0]; + while (i < pq_n) { pq_tk[i - 1] = pq_tk[i]; pq_tv[i - 1] = pq_tv[i]; pq_gl[i - 1] = pq_gl[i]; pq_ln[i - 1] = pq_ln[i]; i++; } + pq_n--; + return 0; + } + return next0(); +} +// the k-th token after the current one (k from 0 to 3), into pk_tk and pk_tv +fn peekat(k) +{ + let a, b, c, e; + while (pq_n <= k) { + a = tk; b = tv; c = tglue; e = tline; + next0(); + pq_tk[pq_n] = tk; pq_tv[pq_n] = tv; pq_gl[pq_n] = tglue; pq_ln[pq_n] = tline; pq_n++; + tk = a; tv = b; tglue = c; tline = e; + } + pk_tk = pq_tk[k]; pk_tv = pq_tv[k]; + return 0; +} +fn peek() { return peekat(0); } +fn next0() +{ + let f, q, i; + f = R_SRC + isp * 32; + if (f[0] != 1) { lex(); return 0; } + i = f[2]; + if (i < f[3]) { q = f[1]; tk = q[1 + i * 3]; tv = q[2 + i * 3]; tline = q[3 + i * 3]; 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)) { if (!panic && !dry) { errat(); puts("expected "); puts(s); errend(); } panic = 1; if (tk == T_EOF) giveup(); } return 0; } +fn name() +{ + let 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) +{ + let 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) { let i = 0; while (mnem[i]) { if (mnem[i] == c) return i; i++; } return -1; } +fn emitseq(a, n) +{ + let 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 if (skind[s] == K_ENH) op(XOP0 + sval[s]); else lit(sval[s]); + a = a + 2; + } else { emit(R_SEQ[a]); a++; } + } + return 0; +} +fn addkop(p) { let i = 0; while (i < nkop) { if (kops[i] == p) return 0; i++; } kops[nkop] = p; nkop++; return 0; } +fn binfind(p) { let i = nbin; while (i) { i--; if (bname[i] == p) return i; } return -1; } +fn unfind(p) { let i = nun; while (i) { i--; if (uname[i] == p) return i; } return -1; } +fn asgfind(p) { let 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) +{ + let 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) +{ + let 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) { let 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) { let i = nloc; while (i > lbase) { i--; if (lname[i] == n) return i; } return -1; } +fn newloc(n) +{ + let i = nloc; + if (nloc >= NL) fatal("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; ltype[i] = tword; ltag[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) +{ + let 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) +{ + let 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]) serrn(lname[from], "m object is never used"); from++; } + return 0; +} +fn block_close(save) +{ + let 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() +{ + let 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) fatal("nesting too deep for the analyzer"); + return b; +} +fn snap_pop(b) { snaptop = b; return 0; } +fn snap_restore(b) +{ + let 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) +{ + let 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 || panic || dry) return 0; + errat(); puts(lname[i]); puts(": "); puts(what); + puts(" (one path leaves it "); puts(statename(sa)); puts(", another "); puts(statename(lstate[i])); puts(")"); + errend(); + return 0; +} +// after an if: the current state is the else path, sa is the then path + +// ---- joins ---- +// where control flow comes back together (after an if, a loop, a switch or +// ?:) every variable has to agree across the paths that reach the join. one +// exception: a variable that became d, or was given away, on some path is dead +// after the join, and the paths where it's still alive free it on the way in +// (fixups). u objects and borrows don't get this treatment: a u object still +// has to leave, and a borrow never changes. +const R_EXIT = 0xBF500, R_EXITEND = 0xBFF00; // exit records: the states at each break +let extop, jps[64], njps; // the paths being joined: [lbase, nloc, triples] +fn jst(p, i) { if (i >= p[1]) return S_PLAIN; return p[2 + 3 * (i - p[0])]; } +fn jow(p, i) { return p[3 + 3 * (i - p[0])]; } +fn jhm(p, i) { return p[4 + 3 * (i - p[0])]; } +// the states at a break, with the jump to patch: [site] then a snapshot +fn exit_rec(site) +{ + let p = R_EXIT + extop, i = lbase, q; + if (extop + 3 + 3 * (nloc - lbase) >= R_EXITEND - R_EXIT) fatal("too many breaks for the analyzer"); + p[0] = site; p[1] = lbase; p[2] = nloc; + q = p + 3; + while (i < nloc) { q[0] = lstate[i]; q[1] = lowner[i]; q[2] = lhome[i]; q = q + 3; i++; } + extop = q - R_EXIT; + return p; +} +fn jadd(p) { if (njps >= 64) fatal("too many paths for the analyzer"); jps[njps] = p; njps++; return 0; } +fn jsame(p, q, i) +{ + let s = jst(p, i), t = jst(q, i); + if (empty(s) && empty(t)) return 1; + return s == t && jhm(p, i) == jhm(q, i) && (s != S_CHILD || jow(p, i) == jow(q, i)); +} +// join the paths in jps over the locals [lbase, n0) into the current states +fn join(n0, what) +{ + let i = lbase, j, p, s, s0, dead, okdead, bad; + if (!njps) return 0; + while (i < n0) { + p = jps[0]; s0 = jst(p, i); + dead = 0; okdead = 1; bad = -1; + j = 0; + while (j < njps) { + s = jst(jps[j], i); + if (s == S_DEAD || s == S_D) dead = 1; + if (s == S_U || s == S_BORROW) okdead = 0; + if (!jsame(p, jps[j], i)) bad = j; + j++; + } + lstate[i] = s0; lowner[i] = jow(p, i); lhome[i] = jhm(p, i); + if (bad < 0) { + if (empty(s0)) { j = 0; while (j < njps) { if (jst(jps[j], i) == S_DEAD) lstate[i] = S_DEAD; j++; } } + } else if (dead && okdead) lstate[i] = S_DEAD; + else if (fchk && !panic && !dry) { + errat(); puts(lname[i]); puts(": "); puts(what); + puts(" (one path leaves it "); puts(statename(s0)); puts(", another "); puts(statename(jst(jps[bad], i))); puts(")"); + errend(); + } + i++; + } + return 0; +} +// on path p: count (and with doit, emit) the frees for what the join made dead but p still owns +fn fixups(p, n0, doit) +{ + let i = lbase, n = 0, s; + if (!fchk) return 0; + while (i < n0) { + s = jst(p, i); + if (lstate[i] == S_DEAD && (s == S_M || s == S_D)) { n++; if (doit) freevar(i); } + i++; + } + return n; +} +// a jump back to the top of a loop: whatever the loop owns has to be as it was +fn backedge(s0) +{ + let p = R_SNAP + s0, i = p[0], e = p[1], s; + if (!fchk || !live) return 0; + if (e > nloc) e = nloc; + while (i < e) { + s = lstate[i]; + if (empty(s) && empty(jst(p, i))) { if (jst(p, i) == S_DEAD) lstate[i] = S_DEAD; } + else if (s != jst(p, i) || lhome[i] != jhm(p, i) || (s == S_CHILD && lowner[i] != jow(p, i))) { + if (s == S_DEAD || s == S_D) cerrn(i, "is given away inside a loop that comes back around to it; give it away on a path that leaves the loop"); + else if (!panic && !dry) { + errat(); puts(lname[i]); puts(": changes state inside a loop; each pass has to leave it as it found it (it went from "); + puts(statename(jst(p, i))); puts(" to "); puts(statename(s)); puts(")"); errend(); + } + } + i++; + } + return 0; +} +// joins two paths that end at the same point, like the branches of if/else: +// path a jumped (through the hole at ja) and path b falls through to here +fn join2(sa, livea, ja, livebv, n0, what) +{ + let sb, nt, cj; + sb = snap_push(); + njps = 0; if (livea) jadd(R_SNAP + sa); if (livebv) jadd(R_SNAP + sb); + join(n0, what); + if (livebv) fixups(R_SNAP + sb, n0, 1); + nt = 0; if (livea) nt = fixups(R_SNAP + sa, n0, 0); + if (nt) { cj = hole(); op(O_JMP); setlit(ja, here); fixups(R_SNAP + sa, n0, 1); setlit(cj, here); } + else setlit(ja, here); + live = livea || livebv; + return 0; +} + +// ---- analyzer rules for the places values flow ---- +// recast: x as u / x as d / x as m +fn recast(c, t) +{ + let 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) +{ + let 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 <= 1) { // untagged parameters are m: a lend + 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 d*x to give it away"); + else if (st == S_U) cerrn(i, "is u; write d*x 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); + if (ltype[p][0] == TY_DYN) { lit(2); op(O_ADD); op(O_LD); } // a []T's elements live in its items object + 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) +{ + let 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; if (ltag[i] & 15) lstate[i] = ltag[i] & 15; 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; if (ltag[i] & 15) lstate[i] = ltag[i] & 15; + 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_U) cerrn(j, "is u; it has to leave through the block above, not into a borrowed object"); + else { lstate[j] = S_DEAD; lused[j] = 1; emitown(i); } // storing it gives it away + } 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) +{ + let 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 u*x'"); + } + return 0; + } + if (c == C_FRESH) cerr("returns a new object; give the function a .u return type"); + else if (i >= 0) cerrn(i, "is owned and can't be returned from a function whose return type isn't .u"); + return 0; +} +// the last expression of a block expression +fn handup(c) +{ + let 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; +} + +// ---- types ---- +// types are a compiler primitive: records in the type area, hash-consed so +// the same type is always the same pointer and comparing types is comparing +// words. untyped code is typed word, which goes with anything. the records +// stay in memory after compiling, so programs can inspect them. +// t[0] kind t[1] size in words t[2] name t[3] n t[4] a t[5] b t[6] c t[7..] extra +// ptr: a = element arr: a = element, n = length +// fn: a = return type, n = parameter count, b = signature (u m d tags), extra = parameter types +// struct: n = field count (-1 until laid out), a = fields (name, type, offset), +// b = generic template, c = type arguments [n, t1, t2 ...] +// var: a type parameter, n = its index +// gen: a generic struct: n = parameter count, a = fields (name, type), b = field count, c = parameter names + + +fn talloc(n) { let p = tytop; if (tytop + n >= R_TYEND) fatal("the type area is full"); tytop = tytop + n; wfill(p, 0, n); return p; } +fn tnew(kind, size, nm, extra) +{ + let t = talloc(7 + extra); + t[0] = kind; t[1] = size; t[2] = nm; + if (ntl >= NTL) fatal("too many types"); + R_TY[ntl] = t; ntl++; + return t; +} +fn tptr(e) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_PTR && t[4] == e) return t; i++; } + t = tnew(TY_PTR, 1, 0, 0); t[4] = e; + return t; +} +fn tarr(e, n) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_ARR && t[4] == e && t[3] == n) return t; i++; } + t = tnew(TY_ARR, n * tsz(e), 0, 0); t[4] = e; t[3] = n; + return t; +} +fn tfn(ret, np, ps, sig) +{ + let i = 0, j, t; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_FN && t[4] == ret && t[3] == np && t[5] == sig) { + j = 0; while (j < np && t[7 + j] == ps[j]) j++; + if (j == np) return t; + } + i++; + } + t = tnew(TY_FN, 1, 0, np); t[4] = ret; t[3] = np; t[5] = sig; + wcopy(t + 7, ps, np); + return t; +} +// []T, or fixed []T +fn tdyn(e, f) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_DYN && t[4] == e && t[3] == f) return t; i++; } + t = tnew(TY_DYN, 1, 0, 0); t[4] = e; t[3] = f; + return t; +} +fn tvar(i, nm) +{ + let k = 0, t; + while (k < ntl) { t = R_TY[k]; if (t[0] == TY_VAR && t[3] == i) return t; k++; } + t = tnew(TY_VAR, 1, nm, 0); t[3] = i; + return t; +} +fn tinst(g, args, n) +{ + let i = 0, j, t, v; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_STRUCT && t[5] == g) { + v = t[6]; j = 0; while (j < n && v[1 + j] == args[j]) j++; + if (j == n) return t; + } + i++; + } + v = talloc(n + 1); v[0] = n; wcopy(v + 1, args, n); + t = tnew(TY_STRUCT, 0, g[2], 0); t[3] = -1; t[5] = g; t[6] = v; + return t; +} +// lay out a generic instance on first use +fn tresolve(t) +{ + let g, f, n, i, fs, off = 0, ft, bs[8]; + if (t[0] != TY_STRUCT || t[3] >= 0) return t; + if (t[3] == -2) { serr("a struct can't contain itself by value"); t[3] = 0; return t; } + t[3] = -2; + g = t[5]; n = g[5]; f = g[4]; + wfill(bs, 0, 8); wcopy(bs, t[6] + 1, t[6][0]); + fs = talloc(n * 3 + 1); + i = 0; + while (i < n) { + ft = subst(f[i + i + 1], bs); + fs[i * 3] = f[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = n; + return t; +} +fn tsz(t) { if (t[0] == TY_STRUCT && t[3] < 0) tresolve(t); return t[1]; } +// replace type parameters with what they were bound to (unbound ones become word) +fn subst(t, bs) +{ + let k = t[0], i, n, v[24], vec; + if (k == TY_VAR) { if (bs[t[3]]) return bs[t[3]]; return tword; } + if (k == TY_PTR) return tptr(subst(t[4], bs)); + if (k == TY_ARR) return tarr(subst(t[4], bs), t[3]); + if (k == TY_FN) { n = t[3]; i = 0; while (i < n) { v[i] = subst(t[7 + i], bs); i++; } return tfn(subst(t[4], bs), n, v, t[5]); } + if (k == TY_STRUCT && t[5]) { vec = t[6]; n = vec[0]; i = 0; while (i < n) { v[i] = subst(vec[1 + i], bs); i++; } return tinst(t[5], v, n); } + return t; +} +fn isnum(t) { return t[0] == TY_INT || t[0] == TY_CHAR || t[0] == TY_BOOL; } +fn isagg(t) { return t[0] == TY_ARR || t[0] == TY_STRUCT; } +fn isptr(t) { return t[0] == TY_PTR || t[0] == TY_ARR; } +fn decay(t) { if (t[0] == TY_ARR) return tptr(t[4]); return t; } +fn telem(t) { if (t[0] == TY_PTR || t[0] == TY_ARR) return t[4]; return tword; } +// can a value of type src go where dst is expected? +fn compat(dst, src) +{ + if (dst == src || dst == tword || src == tword) return 1; + if (isnum(dst) && isnum(src)) return 1; + src = decay(src); + if (dst[0] == TY_PTR && src[0] == TY_PTR) { + if (dst[4] == tword || src[4] == tword || dst[4] == tvoid || src[4] == tvoid) return 1; + return dst[4] == src[4]; + } + if ((dst[0] == TY_PTR || dst[0] == TY_FN || dst[0] == TY_DYN) && xzero) return 1; // a literal 0 is a null pointer + if (dst[0] == TY_DYN && src[0] == TY_DYN && dst[4] == src[4]) return dst[3] || !src[3]; // a growable array can't hold a fixed one + return dst == src; +} +fn unify(p, a, bs) +{ + let i, n, pv, av; + if (p[0] == TY_VAR) { i = p[3]; if (!bs[i]) { bs[i] = a; return 1; } return compat(bs[i], a); } + a = decay(a); + if (p[0] == TY_PTR && a[0] == TY_PTR) { if (a[4] == tword) return 1; return unify(p[4], a[4], bs); } + if (p[0] == TY_STRUCT && p[5] && a[0] == TY_STRUCT && a[5] == p[5]) { + pv = p[6]; av = a[6]; n = pv[0]; i = 0; + while (i < n) { if (!unify(pv[1 + i], av[1 + i], bs)) return 0; i++; } + return 1; + } + return compat(p, a); +} +fn tprint(t) +{ + let k = t[0], i, v; + if (k == TY_PTR) { putc('*'); return tprint(t[4]); } + if (k == TY_DYN) { if (t[3]) puts("fixed "); puts("[]"); return tprint(t[4]); } + if (k == TY_ARR) { putc('['); putn(t[3]); putc(']'); return tprint(t[4]); } + if (k == TY_FN) { + if (t[4] == tword) puts("fn"); else tprint(t[4]); + if (t[5] & 1) puts(".u"); + putc('('); + i = 0; + while (i < t[3]) { + if (i) puts(", "); + tprint(t[7 + i]); + if (i < 12 && tparamtag(t, i) == 1) puts(".m"); + if (i < 12 && tparamtag(t, i) == 2) puts(".d"); + i++; + } + putc(')'); + return 0; + } + if (t[2]) puts(t[2]); else puts("?"); + if (k == TY_STRUCT && t[5]) { + v = t[6]; putc('<'); + i = 0; while (i < v[0]) { if (i) puts(", "); tprint(v[1 + i]); i++; } + putc('>'); + } + return 0; +} +fn tcerr(what, want, got) +{ + if (!tc_on || !live || dry || panic) return 0; + errat(); puts("type error: "); puts(what); + puts(": expected "); tprint(want); puts(", got "); tprint(got); + errend(); + return 0; +} +fn tcneed(ok, what, got) +{ + if (ok || !tc_on || !live || dry || panic) return 0; + errat(); puts("type error: "); puts(what); puts(", got "); tprint(got); + errend(); + return 0; +} +fn tpfind(n) { let i = ntp; while (i) { i--; if (tpn[i] == n) return i; } return -1; } +fn istypename(n) +{ + let s; + if (n == s_fixed) return 1; + if (tpfind(n) >= 0) return 1; + if (findloc(n) >= 0) return 0; + s = lookup(n); + return s >= 0 && skind[s] == K_TYPE; +} +// the closing > of a type argument list; splits >> in two +fn closeangle() +{ + if (is_op(s_shr)) { tv = s_gt; return 0; } + expect(s_gt); + return 0; +} +// a type, then any number of (params) after it: int(int, int) is a function +// returning int, fn(int) one returning a plain word +fn ptype() +{ + let t = ptype0(), np, ps[24]; + while (is_op(s_lp)) { + next(); np = 0; + if (!is_op(s_rp)) { while (1) { if (np >= 24) fatal("too many parameters"); ps[np] = ptype(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + t = tfn(t, np, ps, np + np); + } + return t; +} +fn ptype0() +{ + let n, s, t, args[8], na = 0, i; + if (accept(s_star)) return tptr(ptype0()); + if (accept(s_lk)) { + if (accept(s_rk)) return tdyn(ptype0(), 0); // []T: grows + n = cexpr(); expect(s_rk); t = ptype0(); if (n < 0) serr("a negative array length"); return tarr(t, n); + } + if (is_id(s_fixed)) { // fixed []T can't grow; fixed [n]T says what [n]T already means + next(); t = ptype0(); + if (t[0] == TY_DYN) return tdyn(t[4], 1); + if (t[0] != TY_ARR) serr("only arrays can be fixed"); + return t; + } + if (is_id(s_fn)) { next(); if (!is_op(s_lp)) die("fn as a type needs its parameters: fn(int)"); return tword; } + if (tk != T_ID) { die("expected a type"); return tword; } + n = tv; + i = tpfind(n); + if (i >= 0) { next(); return tvar(i, n); } + s = lookup(n); + if (s < 0 || skind[s] != K_TYPE) { dien(n, "isn't a type"); return tword; } + next(); + t = sval[s]; + if (t[0] != TY_GEN) return t; + expect(s_lt); + while (1) { + if (na >= 8) die("too many type arguments"); + args[na] = ptype(); + if (tsz(args[na]) != 1) serr("type arguments have to be one word (a pointer, a number, or a parameter)"); + na++; + if (!accept(s_comma)) break; + } + closeangle(); + if (na != t[3]) serrn(n, "wrong number of type arguments"); + return tinst(t, args, na); +} +// does a declaration start here? (a type, or a bare .tag) +fn tstart() +{ + let k; + if (tk == T_OP) { + if (tv == s_lk || tv == s_dot) return 1; + if (tv == s_star) { // *T name, **T name ...: look past the stars + k = 0; + while (k < 3) { peekat(k); if (!(pk_tk == T_OP && pk_tv == s_star)) break; k++; } + peekat(k); + return (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) || (pk_tk == T_OP && pk_tv == s_lk); + } + return 0; + } + if (tk != T_ID) return 0; + return tv == s_fn || istypename(tv); +} +// [type] [.tag] +fn dtype() +{ + dty = 0; dtag = 0; + if (!is_op(s_dot)) dty = ptype(); + if (accept(s_dot)) { + if (tv == s_m) dtag = S_M; else if (tv == s_u) dtag = S_U; else if (tv == s_d) dtag = S_D; else die("a tag is .u, .m or .d"); + next(); + } + return 0; +} +// struct name { type field, ... } or struct name { ... } +fn kw_struct() +{ + let n, t, s, nf = 0, buf = R_QBUF, i, fs, off = 0, gen = 0, ft; + next(); + n = name(); + if (is_op(s_lt)) { // generic + next(); ntp = 0; + while (1) { if (ntp >= 8) die("too many type parameters"); tpn[ntp] = name(); ntp++; if (!accept(s_comma)) break; } + closeangle(); + gen = 1; + t = tnew(TY_GEN, 0, n, 0); t[3] = ntp; + fs = talloc(ntp); wcopy(fs, tpn, ntp); t[6] = fs; + } else { t = tnew(TY_STRUCT, 0, n, 0); t[3] = -2; } // -2 while its fields are read + s = addsym(n, K_TYPE, t); + expect(s_lb); + while (!is_op(s_rb)) { + ft = ptype(); + while (1) { + if (nf >= 1000) fatal("too many fields"); + buf[nf + nf] = name(); buf[nf + nf + 1] = ft; nf++; + if (!accept(s_comma)) break; + } + expect(s_semi); + } + next(); + if (gen) { + fs = talloc(nf + nf); wcopy(fs, buf, nf + nf); + t[4] = fs; t[5] = nf; + ntp = 0; + } else { + fs = talloc(nf * 3 + 1); + i = 0; + while (i < nf) { + ft = buf[i + i + 1]; + if (ft == t) { serr("a struct can't contain itself by value; use a pointer"); ft = tword; } + fs[i * 3] = buf[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = nf; + } + accept(s_semi); + return s; +} +// type name = T; +fn kw_type() { let n; next(); n = name(); expect(s_eq); addsym(n, K_TYPE, ptype()); expect(s_semi); return 0; } +// typecheck on; / typecheck off; +fn kw_typecheck() +{ + next(); + if (is_id(s_on)) tc_on = 1; else if (is_id(s_off)) tc_on = 0; else die("typecheck on or typecheck off"); + next(); expect(s_semi); + return 0; +} +// the field of a struct type, or -1 +fn tfindfield(t, n) { let i = 0; tresolve(t); while (i < t[3]) { if (t[4][i * 3] == n) return i; i++; } return -1; } +// sizeof(T or expr), typeof(T or expr): the expression form is compiled dry, so it never runs +fn typearg() +{ + let t, sb, c; + expect(s_lp); + if (tstart() && !is_op(s_dot)) t = ptype(); + else { + sb = snap_push(); dry++; + c = expr(); rval(); + t = xty; + dry--; snap_restore(sb); snap_pop(sb); + } + expect(s_rp); + return t; +} +// len(a), cap(a), push(a, x), pop(a), resize(a, n): growable arrays. +// len of a [n]T is just n. +fn arrarg() +{ + let c; + expect(s_lp); c = expr(); rval(); plainuse(c); + return xty; +} +fn nogrow(t) { if (t[0] == TY_DYN && t[3]) serr("a fixed array can't grow or shrink"); return 0; } +fn kw_len() +{ + let t; + next(); t = arrarg(); expect(s_rp); + if (t[0] == TY_ARR) { op(O_DROP); lit(t[3]); } + else { tcneed(t[0] == TY_DYN || t == tword, "len needs an array", t); if (o3on && t[0] == TY_DYN) op(O_LD); else callname(s_dlen); } + xty = tint; + return 0; +} +fn kw_cap() { let t; next(); t = arrarg(); expect(s_rp); tcneed(t[0] == TY_DYN || t == tword, "cap needs a []T", t); callname(s_dcap); xty = tint; return 0; } +fn kw_push() +{ + let t, c; + next(); t = arrarg(); nogrow(t); + if (t[0] == TY_DYN && tsz(t[4]) != 1) serr("push takes one-word elements; use resize for structs"); + expect(s_comma); c = expr(); rval(); argcheck(c, 2); + if (t[0] == TY_DYN && !compat(t[4], xty)) tcerr("push", t[4], xty); + expect(s_rp); + callname(s_dpush); xty = tint; + return 0; +} +fn kw_pop() { let t; next(); t = arrarg(); nogrow(t); expect(s_rp); callname(s_dpop); xty = telem(t); if (t[0] == TY_DYN) xty = t[4]; return 0; } +fn kw_resize() { let t, c; next(); t = arrarg(); nogrow(t); expect(s_comma); c = expr(); rval(); plainuse(c); expect(s_rp); callname(s_dresize); xty = tint; return 0; } +fn kw_sizeof() { let t; next(); t = typearg(); lit(tsz(t)); xty = tint; return 0; } +fn kw_typeof() { let t; next(); t = typearg(); lit(t); xty = tword; return 0; } +fn types_init() +{ + tytop = R_TY + NTL; ntl = 0; + tword = tnew(TY_WORD, 1, intern("word"), 0); + tint = tnew(TY_INT, 1, intern("int"), 0); + tchar = tnew(TY_CHAR, 1, intern("char"), 0); + tbool = tnew(TY_BOOL, 1, intern("bool"), 0); + tvoid = tnew(TY_VOID, 0, intern("void"), 0); + addsym(tword[2], K_TYPE, tword); addsym(tint[2], K_TYPE, tint); addsym(tchar[2], K_TYPE, tchar); + addsym(tbool[2], K_TYPE, tbool); addsym(tvoid[2], K_TYPE, tvoid); + s_lt = intern("<"); s_gt = intern(">"); s_shr = intern(">>"); s_le = intern("<="); s_ge = intern(">="); + s_eqeq = intern("=="); s_ne = intern("!="); s_plus = intern("+"); + s_struct = intern("struct"); s_type = intern("type"); s_typecheck = intern("typecheck"); + s_on = intern("on"); s_off = intern("off"); s_new = intern("new"); s_new_t = intern("new_t"); + s_o3 = intern("o3"); s_lfa = intern("lfa"); s_outside = intern("outside"); s_new_raw = intern("new_raw"); s_oob = intern("oob"); + s_fixed = intern("fixed"); s_dlen = intern("dlen"); s_dcap = intern("dcap"); s_dnew = intern("dnew"); s_dat = intern("dat"); + s_dpush = intern("dpush"); s_dpop = intern("dpop"); s_dresize = intern("dresize"); + numops[0] = intern("*"); numops[1] = intern("/"); numops[2] = intern("%"); numops[3] = intern("&"); + numops[4] = intern("|"); numops[5] = intern("^"); numops[6] = intern("<<"); numops[7] = s_shr; nnumops = 8; + return 0; +} +fn isnumop(o) { let i = 0; while (i < nnumops) { if (numops[i] == o) return 1; i++; } return 0; } +// the type of a binary operation, checking it when the typechecker is on +fn bintype(b, lt, rt) +{ + let o = bname[b]; + lt = decay(lt); rt = decay(rt); + if (blen[b] < 0) { tcneed(!isagg(lt) && !isagg(rt), "&& and || need scalars", lt); return tbool; } + if (o == s_eqeq || o == s_ne) { if (!compat(lt, rt) && !compat(rt, lt)) tcerr("comparison", lt, rt); return tbool; } + if (o == s_lt || o == s_gt || o == s_le || o == s_ge) { + if (!(lt == tword || rt == tword || (isnum(lt) && isnum(rt)) || (lt[0] == TY_PTR && rt[0] == TY_PTR))) tcerr("comparison", lt, rt); + return tbool; + } + if (o == s_plus) { + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (rt[0] == TY_PTR && isnum(lt)) return rt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("+", lt, rt); return tword; + } + if (o == s_minus) { + if (lt[0] == TY_PTR && rt[0] == TY_PTR) return tint; + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("-", lt, rt); return tword; + } + if (isnumop(o)) { + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + if (isnum(lt)) lt = rt; + tcneed(0, "arithmetic needs numbers", lt); return tword; + } + return tword; // operators a program added +} + +// ---- reflection ---- +// for programs (and parse words) looking at types at runtime +fn tkind(t) { return t[0]; } +fn tsize(t) { return tsz(t); } +fn tname(t) { return t[2]; } +fn tlen(t) { return t[3]; } +fn tnfields(t) { tresolve(t); return t[3]; } +fn tfname(t, i) { tresolve(t); return t[4][i * 3]; } +fn tftype(t, i) { tresolve(t); return t[4][i * 3 + 1]; } +fn tfoff(t, i) { tresolve(t); return t[4][i * 3 + 2]; } +fn tret(t) { return t[4]; } +fn tnparams(t) { return t[3]; } +fn tparam(t, i) { return t[7 + i]; } +fn tparamtag(t, i) { return ((t[5] >> 6) >> (i + i)) & 3; } // 0 untagged (m), 1 .m, 2 .d +fn tretu(t) { return t[5] & 1; } +fn tnargs(t) { if (t[0] != TY_STRUCT || !t[5]) return 0; return t[6][0]; } +fn targ(t, i) { return t[6][1 + i]; } +// the type of a function, by address. untyped functions get one made from their signature +fn sigof(f) +{ + let i = nsym, s = -1, ws[24], n, k; + while (i) { i--; if (skind[i] == K_FN && sval[i] == f && (sflag[i] & F_DEF)) { s = i; break; } } + if (s < 0) return 0; + if (stype[s]) return stype[s]; + n = (ssig[s] >> 1) & 31; k = 0; + while (k < n) { ws[k] = tword; k++; } + return tfn(tword, n, ws, ssig[s]); +} +fn sigofs(nm) { let s = lookups(nm); if (s < 0 || skind[s] != K_FN) return 0; return sigof(sval[s]); } + +// ---- expressions ---- +// every expression leaves its value on the stack, returns its analyzer class, +// and sets xty to its type. lv means the stack holds an address that hasn't +// been loaded yet; structs and arrays are never loaded, their address is +// their value. +fn rval() { if (lv) { if (!isagg(xty)) op(O_LD); lv = 0; } return 0; } +fn kwcall(s, e) +{ + let f = sval[s], old = kw_expr, c; + kw_expr = e; xcls = C_PLAIN; xty = tword; xzero = 0; + f(); + kw_expr = old; + c = xcls; + lv = 0; lvk = LV_NONE; + return c; +} +fn stmtonly() { if (kw_expr) serr("this can't be used inside an expression"); return 0; } +// the arguments of a call. ft is the callee's type (or 0), bs the generic bindings +fn args(tags, ft, bs) +{ + let np = 0, c, pt; + expect(s_lp); + if (!is_op(s_rp)) { + while (1) { + c = expr(); rval(); + argcheck(c, (tags >> (np + np)) & 3); + if (ft && np < ft[3]) { pt = ft[7 + np]; if (!unify(pt, xty, bs)) tcerr("argument", subst(pt, bs), xty); } + np++; + if (!accept(s_comma)) break; + } + } + expect(s_rp); + return np; +} +// new(T) and new(T, count): a typed object, its type stamped into the header +fn newtyped() +{ + let t, c; + t = ptype(); + if (t[0] == TY_DYN) { // a growable array: element size, length, type + lit(tsz(t[4])); + if (accept(s_comma)) { c = expr(); rval(); plainuse(c); } + else { lit(0); if (t[3]) serr("a fixed array needs its length: new(fixed []T, n)"); } + lit(t); + expect(s_rp); + callname(s_dnew); + lv = 0; lvk = LV_NONE; xty = t; xzero = 0; + return C_FRESH; + } + if (o3on) { // o3: new_raw(words), no stamp, no zeroing + if (accept(s_comma)) { c = expr(); rval(); plainuse(c); if (tsz(t) != 1) { lit(tsz(t)); op(15); } } + else lit(tsz(t)); + expect(s_rp); + callname(s_new_raw); + lv = 0; lvk = LV_NONE; xty = tptr(t); xzero = 0; + return C_FRESH; + } + if (accept(s_comma)) { + c = expr(); rval(); plainuse(c); + if (tsz(t) != 1) { lit(tsz(t)); op(15); } + lit(tarr(t, 0)); + } else { lit(tsz(t)); lit(t); } + expect(s_rp); + callname(s_new_t); + lv = 0; lvk = LV_NONE; xty = tptr(t); xzero = 0; + return C_FRESH; +} +fn call(s) +{ + let np, tags = 0, ret = 0, ft = stype[s], bs[8]; + if (sname[s] == s_new && skind[s] == K_FN) { + peek(); + if (pk_tk == T_OP && (pk_tv == s_star || pk_tv == s_lk)) { next(); return newtyped(); } + if (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) { next(); return newtyped(); } + } + if (o3on && sname[s] == s_new) { tags = lookup(s_new_raw); if (tags >= 0) s = tags; tags = 0; } + if (sflag[s] & F_SIG) { tags = ssig[s] >> 6; ret = ssig[s] & 1; } + else sflag[s] = sflag[s] | F_UNTYPED; + wfill(bs, 0, 8); + if (ngbind) { wcopy(bs, gbind, ngbind); ngbind = 0; } + np = args(tags, ft, bs); + if ((sflag[s] & F_SIG) && np != ((ssig[s] >> 1) & 31)) serrn(sname[s], "wrong number of arguments"); + fnref(s); op(O_CALL); + lv = 0; lvk = LV_NONE; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + if (ret) return C_FRESH; + return C_PLAIN; +} +// an enhancement used like a function: the arguments, then its one opcode +fn enhcall(s) +{ + let nin = ssig[s] & 15, nout = (ssig[s] >> 4) & 15, n = 0, c; + expect(s_lp); + if (!is_op(s_rp)) { while (1) { c = expr(); rval(); plainuse(c); n++; if (!accept(s_comma)) break; } } + expect(s_rp); + if (n != nin) serrn(sname[s], "wrong number of inputs"); + lv = 0; lvk = LV_NONE; xty = tword; xzero = 0; + if (sflag[s] & F_FALLBACK) { fnref(sfix[s] - 1); op(O_CALL); return C_PLAIN; } + op(XOP0 + sval[s]); + if (nout == 0) lit(0); + if (nout > 1) serrn(sname[s], "leaves several values; use it from asm"); + return C_PLAIN; +} +fn primary() +{ + let n, i, s, c; + lv = 0; lvk = LV_NONE; xzero = 0; + xconst = 0; + if (tk == T_NUM) { lit(tv); xzero = tv == 0; xconst = 1; xcval = tv; xty = tint; next(); return C_PLAIN; } + if (tk == T_STR) { strlit(tv); next(); xty = tptr(tchar); 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"); lit(0); xty = tword; return C_PLAIN; + } + if (tk != T_ID) { die("expected an expression"); lit(0); xty = tword; return C_PLAIN; } + n = tv; + i = findloc(n); + if (i >= 0) { + next(); + if (!fchk && tracked(i)) serrn(n, "is tracked by the analyzer and can't be used in unchecked code"); + vaddr(i); + xty = ltype[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); + } + if (s >= 0 && skind[s] == K_TYPE) { dien(n, "is a type, not a value"); lit(0); xty = tword; return C_PLAIN; } + next(); + xty = tword; + if (s >= 0 && skind[s] == K_CONST) { lit(sval[s]); xty = tint; xzero = sval[s] == 0; xconst = 1; xcval = sval[s]; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GVAR) { lit(sval[s]); if (stype[s]) xty = stype[s]; lv = 1; lvk = LV_GLOBAL; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GARR) { lit(sval[s]); if (stype[s]) xty = stype[s]; return C_PLAIN; } + if (s >= 0 && skind[s] == K_ENH) return enhcall(s); + if (s < 0) s = fwdfn(n); + if (is_op(s_lt) && (sflag[s] & F_GEN)) { // f(...) + next(); ngbind = 0; + while (1) { if (ngbind >= 8) die("too many type arguments"); gbind[ngbind] = ptype(); ngbind++; if (!accept(s_comma)) break; } + closeangle(); + if (!is_op(s_lp)) die("expected ( after the type arguments"); + } + if (is_op(s_lp)) return call(s); + fnref(s); + if (stype[s]) xty = stype[s]; + return C_PLAIN; +} +// ++ and -- on the address at the top of the stack +fn incdec(post, dlt) +{ + 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"); + tcneed(isnum(xty) || xty[0] == TY_PTR || xty == tword, "++ and -- need a number or a pointer", xty); + lv = 0; lvk = LV_NONE; xzero = 0; + lit(0); op(O_PICK); op(O_LD); + if (post) { lit(0); op(O_PICK); lit(dlt); op(O_ADD); lit(2); op(O_PICK); op(O_ST); } + else { lit(dlt); 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; +} +// p.x and p->x: a field of a struct, or of the struct a pointer points at +fn field(c) +{ + let n, st, i, b = -1; + next(); + n = name(); + rval(); + if (c == C_FRESH) cerr("use a field of a new object only after binding it to a name"); + else if (c >= C_VAR) { touch(c - C_VAR); b = c - C_VAR; } + st = xty; + if (st[0] == TY_PTR) st = st[4]; + if (st[0] != TY_STRUCT) { + if (!panic && !dry) { errat(); putc('.'); puts(n); puts(": that's a "); tprint(xty); puts(", not a struct or a pointer to one"); errend(); } + xty = tword; lv = 1; lvk = LV_OTHER; return C_PLAIN; + } + i = tfindfield(st, n); + if (i < 0) { + if (!panic && !dry) { errat(); tprint(st); puts(" has no field "); puts(n); errend(); } + xty = tword; lv = 1; lvk = LV_OTHER; return C_PLAIN; + } + if (st[4][i * 3 + 2]) { lit(st[4][i * 3 + 2]); op(O_ADD); } + xty = st[4][i * 3 + 1]; + lv = 1; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + return C_PLAIN; +} +fn postfix() +{ + let c = primary(), b, n, t, et, ft, bs[8], k; + while (1) { + if (tk == T_ID && tv == s_as) { // e as T: same bits, another type + next(); t = ptype(); rval(); xty = 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; } + if (xty[0] == TY_DYN) { // a growable array: bounds-checked, through the runtime + et = xty[4]; + c = expr(); rval(); plainuse(c); + tcneed(isnum(xty) || xty == tword, "an index has to be a number", xty); + expect(s_rk); + k = lookup(s_outside); + if (o3on && k >= 0 && skind[k] == K_ENH) { // h i: check i against h[0], then h[2] + i * size + lit(0); op(O_PICK); lit(2); op(O_PICK); op(O_LD); op(XOP0 + sval[k]); + k = hole(); op(O_JZ); + lit(1); op(O_PICK); op(O_LD); callname(s_oob); + setlit(k, here); + op(O_SWAP); lit(2); op(O_ADD); op(O_LD); op(O_SWAP); + if (tsz(et) != 1) { lit(tsz(et)); op(15); } + op(O_ADD); + } else callname(s_dat); + } else { + tcneed(isptr(xty) || xty == tword, "only pointers and arrays can be indexed", xty); + et = telem(xty); + n = 0 - 1; if (xty[0] == TY_ARR && xty[3] > 0) n = xty[3]; + xconst = 0; + c = expr(); rval(); plainuse(c); + if (n >= 0 && xconst && (xcval < 0 || xcval >= n)) serr("the index is out of range for this array"); + tcneed(isnum(xty) || xty == tword, "an index has to be a number", xty); + expect(s_rk); + if (tsz(et) != 1) { lit(tsz(et)); op(15); } + op(O_ADD); + } + lv = 1; xty = et; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + c = C_PLAIN; + continue; + } + if (tv == s_dot || tv == s_arrow) { c = field(c); continue; } + if (tv == s_lp) { // call through a value + rval(); plainuse(c); + ft = 0; + if (xty[0] == TY_FN) ft = xty; + else tcneed(xty == tword, "only functions can be called", xty); + wfill(bs, 0, 8); + n = args(0, ft, bs); + lit(n); op(O_PICK); op(O_CALL); op(O_SWAP); op(O_DROP); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + 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() +{ + let c, un, t; + if (tk == T_ID && (tv == s_u || tv == s_m || tv == s_d)) { // u*x, d*x, m*x: recast + t = S_M; if (tv == s_u) t = S_U; if (tv == s_d) t = S_D; + next(); expect(s_star); + c = unary(); rval(); + lvk = LV_NONE; + return recast(c, t); + } + if (tk == T_OP) { + if (tv == s_star) { + next(); c = unary(); rval(); plainuse(c); + tcneed(xty[0] == TY_PTR || xty == tword, "only pointers can be dereferenced", xty); + xty = telem(xty); + lv = 1; lvk = LV_OTHER; xzero = 0; + return C_PLAIN; + } + if (tv == s_amp) { + next(); c = unary(); + if (!lv && !isagg(xty)) die("& needs something addressable"); + if (lv && lvk == LV_LOCAL && (ltag[lvi] & 16)) serr("an o3 variable has no address"); + if (c >= C_VAR) touch(c - C_VAR); + lv = 0; lvk = LV_NONE; xzero = 0; + xty = tptr(xty); + return C_PLAIN; + } + if (tv == s_inc) { next(); unary(); return incdec(0, 1); } + if (tv == s_dec) { next(); unary(); return incdec(0, -1); } + un = unfind(tv); + if (un >= 0) { + next(); c = unary(); rval(); plainuse(c); + emitseq(useq[un], ulen[un]); + xconst = 0; + if (un <= 1) xty = tbool; + else if (xty != tword) { tcneed(isnum(xty), "this operator needs a number", xty); xty = tint; } + lv = 0; lvk = LV_NONE; xzero = 0; + return C_PLAIN; + } + } + return postfix(); +} +fn bin(minp) +{ + let c = unary(), b, p, a, j, lt; + while (tk == T_OP) { + b = binfind(tv); + if (b < 0) return c; + p = bprec[b]; + if (p < minp) return c; + next(); rval(); plainuse(c); + lt = xty; + 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]); + } + xty = bintype(b, lt, xty); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; xconst = 0; + } + 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; } +// c ? a : b +fn ternary(c) +{ + let a, b, s0, sa, livea, live0 = live, n0 = nloc, ca, cb, ta; + rval(); plainuse(c); + next(); + a = hole(); op(O_JZ); + s0 = snap_push(); + ca = expr(); rval(); ta = xty; + if (ca != C_FRESH) plainuse(ca); + livea = live; sa = snap_push(); + b = hole(); op(O_JMP); + expect(s_colon); + setlit(a, here); + snap_restore(s0); live = live0; + cb = expr(); rval(); + if (cb != C_FRESH) plainuse(cb); + join2(sa, livea, b, live, n0, "ends the two sides of ?: in different states"); + snap_pop(s0); + if (!compat(ta, xty) && !compat(xty, ta)) tcerr("the two sides of ?:", ta, xty); + if (ta != tword) xty = ta; + lv = 0; lvk = LV_NONE; xzero = 0; + if (ca == C_FRESH && cb == C_FRESH) return C_FRESH; + if (ca == C_FRESH || cb == C_FRESH) cerr("both sides of ?: have to be new objects, or neither"); + return C_PLAIN; +} +fn expr() +{ + let c = bin(1), k, i, a, rc, lt; + if (tk != T_OP) return c; + if (tv == s_q) return ternary(c); + if (tv == s_eq) { + if (!lv) die("this can't be assigned to"); + k = lvk; i = lvi; lt = xty; + if (isagg(lt)) serr("a whole struct or array can't be assigned; assign its fields"); + next(); + a = o3on && k == LV_LOCAL && (ltag[i] & 16) && !larr[i]; + if (a) op(O_DROP); // an o3 variable: its address comes after the value, so it never waits on the stack across a branch + rc = expr(); rval(); + if (!compat(lt, xty)) tcerr("assignment", lt, xty); + if (a) { lit(0); op(O_PICK); vaddr(i); op(O_ST); } else storekeep(); + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + 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"); + lt = xty; + next(); + i = o3on && lvk == LV_LOCAL && (ltag[lvi] & 16) && !larr[lvi]; + if (i) { i = lvi; op(O_DROP); vaddr(i); op(O_LD); i = i + 1; } + else { lit(0); op(O_PICK); op(O_LD); } + lv = 0; + rc = expr(); rval(); plainuse(rc); + emitseq(bseq[abin[a]], blen[abin[a]]); + k = bintype(abin[a], lt, xty); + if (!compat(lt, k)) tcerr("compound assignment", lt, k); + if (i) { lit(0); op(O_PICK); vaddr(i - 1); op(O_ST); } else storekeep(); + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + return C_PLAIN; + } + return c; +} +// does the current token start a statement rather than an expression? +fn stmtstart() +{ + let s; + if (tk == T_OP) return tv == s_semi || tv == s_lb || tstart(); + if (tk != T_ID || findloc(tv) >= 0) return 0; + if (tstart()) return 1; + 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() +{ + let save = nloc, c = C_PLAIN, tail = 0, t = tint; + 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; t = xty; + } + next(); + if (tail) c = handup(c); else lit(0); + block_close(save); + fdepth--; bxdepth--; + lv = 0; lvk = LV_NONE; xty = t; xzero = 0; + return c; +} + +// ---- constant expressions ---- +fn cprim() +{ + let 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() +{ + let 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 ---- +// after a syntax error: skip to the end of the statement +fn resync() +{ + while (tk != T_EOF && !is_op(s_semi) && !is_op(s_rb)) next(); + if (is_op(s_semi)) next(); + panic = 0; + return 0; +} +fn stmt() +{ + let s, c; + if (panic) return resync(); + 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 (tstart()) { localdecl(1); 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() +{ + let save = nloc; + expect(s_lb); + fdepth++; + while (!is_op(s_rb)) { if (tk == T_EOF) die("missing }"); stmt(); } + block_close(save); // before the }, so its line is the one reported + next(); + fdepth--; + return 0; +} +// the body of if/while/for: its own block, even without braces +fn substmt() +{ + let save = nloc; + if (is_op(s_lb)) return block(); + fdepth++; + stmt(); + block_close(save); + fdepth--; + return 0; +} +// let a = e, b[10]; or, typed: int a = 1, b; *node.m p = new(node); .u r; +// let infers pointer, struct and function types from the initializer and +// keeps numbers as plain words. +fn localdecl(typed) +{ + let n, i, c, k, t = 0, tg = 0; + if (typed) { dtype(); t = dty; tg = dtag; if (t == tvoid) serr("a variable can't be void"); } + if ((o3on || o3one) && !typed) serr("o3 variables need a type"); + while (1) { + n = name(); + i = newloc(n); + ltag[i] = tg; + if (o3on || o3one) ltag[i] = tg | 16; + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + if (!t) t = tword; + larr[i] = 1; ltype[i] = tarr(t, k); fslots = fslots + tsz(ltype[i]); + } else if (t && isagg(t)) { larr[i] = 1; ltype[i] = t; fslots = fslots + tsz(t); } + else { fslots++; if (t) ltype[i] = t; if (o3on) addsl(lslot[i]); } + if (accept(s_eq)) { + if (larr[i]) serr("an array or a struct can't be initialized with ="); + c = expr(); rval(); vaddr(i); op(O_ST); + if (t) { if (!compat(t, xty)) tcerr("initializer", t, xty); } + else if (!isnum(xty)) ltype[i] = xty; + assigncheck(LV_LOCAL, i, c); + } + if (!accept(s_comma)) break; + } + expect(s_semi); + return 0; +} +fn kw_var() { stmtonly(); next(); return localdecl(0); } +fn kw_if() +{ + let a, b, c, s0, sa, live0, livea, n0 = nloc, nt, cj; + 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(); + join2(sa, livea, b, live, n0, "ends the branches of an if in different states"); + } else { + // the path that skips the then branch still has the states from before it + njps = 0; if (livea) jadd(R_SNAP + sa); if (live0) jadd(R_SNAP + s0); + join(n0, "ends the branches of an if in different states"); + if (livea) fixups(R_SNAP + sa, n0, 1); + nt = 0; if (live0) nt = fixups(R_SNAP + s0, n0, 0); + if (nt) { cj = hole(); op(O_JMP); setlit(a, here); fixups(R_SNAP + s0, n0, 1); setlit(cj, here); } + else setlit(a, here); + live = livea || live0; + } + snap_pop(s0); + return 0; +} +// loop frame: 0 continue target 1 break chain 2 depth 3 snapshot 4 block-expression depth +// loop frame: 0 continue target (-1 for a switch) 2 depth 3 snapshot at the top +// 4 block-expression depth 5 locals at the start 6 its first exit record +fn loop_push(cont, s0) +{ + let f = R_LOOP + lsp * 8; + if (lsp >= 60) fatal("loops nested too deeply"); + f[0] = cont; f[1] = 0; f[2] = fdepth; f[3] = s0; f[4] = bxdepth; f[5] = nloc; f[6] = extop; + lsp++; + return 0; +} +// the end of a loop or switch: join its exits (the fall-out path sc through +// the jump at a, if there is one, and every break) and lay out each path's +// fixups on its way to the end +fn loop_end(a, sc) +{ + let f, p, e, n0, outs = 0; + lsp--; + f = R_LOOP + lsp * 8; + n0 = f[5]; + njps = 0; + if (sc >= 0) jadd(R_SNAP + sc); + p = R_EXIT + f[6]; e = R_EXIT + extop; + while (p < e) { jadd(p + 1); p = p + 3 + 3 * (p[2] - p[1]); } + join(n0, "leaves the loop in different states on different paths"); + live = njps > 0; + p = R_EXIT + f[6]; + while (p < e) { + if (fixups(p + 1, n0, 0)) { setlit(p[0], here); fixups(p + 1, n0, 1); outs = fixnew(hole(), outs); op(O_JMP); } + else outs = fixnew(p[0], outs); + p = p + 3 + 3 * (p[2] - p[1]); + } + if (a >= 0) setlit(a, here); + if (sc >= 0) fixups(R_SNAP + sc, n0, 1); + fixall(outs, here); + extop = f[6]; + return 0; +} +fn kw_while() +{ + let c0 = here, a, s0, sc = -1, c, inf = 0; + stmtonly(); + next(); + s0 = snap_push(); + expect(s_lp); + if (tk == T_NUM && tv) { peek(); if (pk_tk == T_OP && pk_tv == s_rp) inf = 1; } // while (1): no way out but break + c = expr(); rval(); plainuse(c); expect(s_rp); + a = hole(); op(O_JZ); + if (!inf && live) sc = snap_push(); + loop_push(c0, s0); + substmt(); + backedge(s0); + jmp(c0); + loop_end(a, sc); + snap_pop(s0); + return 0; +} +fn kw_for() +{ + let save = nloc, s0, sc = -1, c0, a, b, st, c, inf = 0; + stmtonly(); + next(); + expect(s_lp); + fdepth++; + if (is_id(s_var)) kw_var(); + else if (tstart()) localdecl(1); + 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)) { + if (tk == T_NUM && tv) { peek(); if (pk_tk == T_OP && pk_tv == s_semi) inf = 1; } + c = expr(); rval(); plainuse(c); + } else { lit(1); inf = 1; } + expect(s_semi); + a = hole(); op(O_JZ); + if (!inf && live) sc = snap_push(); + b = hole(); op(O_JMP); + st = here; + if (!is_op(s_rp)) { c = expr(); rval(); op(O_DROP); discard(c); } + expect(s_rp); + jmp(c0); + setlit(b, here); + loop_push(st, s0); + substmt(); + backedge(s0); + jmp(st); + loop_end(a, sc); + snap_pop(s0); + block_close(save); + fdepth--; + return 0; +} +fn kw_break() +{ + let f; + stmtonly(); + next(); expect(s_semi); + if (lsp <= loopbase) { serr("break outside a loop or a switch"); return 0; } + f = R_LOOP + (lsp - 1) * 8; + if (f[4] != bxdepth) { serr("break can't leave a block expression"); return 0; } + exit_vars(f[2] + 1, 0); + if (live) exit_rec(hole()); else hole(); + op(O_JMP); + live = 0; + return 0; +} +fn kw_continue() +{ + let j = lsp - 1, f; + stmtonly(); + next(); expect(s_semi); + while (j >= loopbase && R_LOOP[j * 8] == -1) j--; // past any switch + if (j < loopbase) { serr("continue outside a loop"); return 0; } + f = R_LOOP + j * 8; + if (f[4] != bxdepth) { serr("continue can't leave a block expression"); return 0; } + backedge(f[3]); + exit_vars(f[2] + 1, 0); + jmp(f[0]); + live = 0; + return 0; +} +// switch (e) { case 1, 2: ... case 'x': ... default: ... } +// cases don't fall through: each one ends where the next begins, and break +// leaves the switch early. case labels are constants. +fn casebody(s0, live0) +{ + let save = nloc; + snap_restore(s0); live = live0; + fdepth++; + while (!is_op(s_rb) && !is_id(s_case) && !is_id(s_default)) { if (tk == T_EOF) { die("missing }"); break; } stmt(); } + block_close(save); + fdepth--; + if (live) { exit_rec(hole()); op(O_JMP); } // the end of a case leaves the switch + live = 0; + return 0; +} +fn kw_switch() +{ + let save = nloc, tmp, c, s0, live0, defent = -1, skip, nxt, bj, v, a = -1; + stmtonly(); + next(); + expect(s_lp); c = expr(); rval(); plainuse(c); expect(s_rp); + fdepth++; + tmp = newloc(0); fslots++; // a hidden local holds the value + laddr(lslot[tmp]); op(O_ST); + live0 = live; + s0 = snap_push(); + loop_push(-1, s0); + expect(s_lb); + while (!is_op(s_rb)) { + if (tk == T_EOF) { die("missing }"); break; } + if (is_id(s_case)) { + next(); + bj = 0; + while (1) { + v = cexpr(); + laddr(lslot[tmp]); op(O_LD); lit(v); op(O_SUB); + bj = fixnew(hole(), bj); op(O_JZ); + if (!accept(s_comma)) break; + } + expect(s_colon); + nxt = hole(); op(O_JMP); + fixall(bj, here); + casebody(s0, live0); + setlit(nxt, here); + } else if (is_id(s_default)) { + next(); expect(s_colon); + if (defent >= 0) serr("a switch has one default"); + skip = hole(); op(O_JMP); // only reached when nothing matched + defent = here; + casebody(s0, live0); + setlit(skip, here); + } else die("expected case or default"); + } + next(); + snap_restore(s0); live = live0; + if (defent >= 0) { jmp(defent); loop_end(-1, -1); } + else { a = hole(); op(O_JMP); loop_end(a, s0); } // nothing matched: out with the states from the top + snap_pop(s0); + block_close(save); + fdepth--; + return 0; +} +fn kw_return() +{ + let c; + stmtonly(); + next(); + if (!infn) serr("return outside a function"); + if (bxdepth) serr("return can't leave a block expression"); + if (is_op(s_semi)) { lit(0); c = C_PLAIN; } + else { + c = expr(); rval(); + if (fty == tvoid) tcerr("return value", tvoid, xty); + else if (fty && !compat(fty, xty)) tcerr("return value", fty, xty); + } + expect(s_semi); + retcheck(c); + exit_vars(1, 0); + epichain = fixnew(here, epichain); + lit(MW - 1); op(O_JMP); + live = 0; + return 0; +} +// o3 { ... }: an optimized region. o3 T x = e;: one o3 variable +fn kw_o3() +{ + let lo, i, p; + stmtonly(); + next(); + if (!is_op(s_lb)) { o3one = 1; localdecl(1); o3one = 0; return 0; } + if (o3on || !infn) return block(); + lo = here + 2; lit(lo); op(O_JMP); + o3on = 1; no3sl = 0; + i = lbase; + while (i < nloc) { if ((ltag[i] & 16) && !larr[i]) addsl(lslot[i]); i++; } // o3 variables declared outside + block(); + o3on = 0; + if (no3pend < 20) { p = o3pend + no3pend * 10; p[0] = lo; p[1] = here; p[2] = no3sl; wcopy(p + 3, o3sl, no3sl); no3pend++; } + return 0; +} +fn kw_unchecked() +{ + let 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() +{ + let 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) fatal("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 && (ltag[i] & 16) && !larr[i]) serr("asm can't reach an o3 variable"); + 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_ENH) { op(XOP0 + sval[s]); next(); continue; } + 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) fatal("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) serrn(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, line for each token. names, +// strings and operators are interned pointers. +.u grab() +{ + let 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 >= 2700) fatal("quote too long"); + R_QBUF[n * 3] = tk; R_QBUF[n * 3 + 1] = tv; R_QBUF[n * 3 + 2] = tline; n++; + next(); + } + next(); + q = new(n * 3 + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n * 3); + return u*q; +} +unchecked .u qnew(src) { let n = src[0] * 3 + 1, q = new(n); wcopy(q, src, n); return q; } +.u qdup(.m q) { let n = q[0] * 3 + 1, r = new(n); wcopy(r, q, n); return u*r; } +fn wcopyto(.m q, n) { let i = 0; while (i < n) { emit(q[i]); i++; } return 0; } +fn kw_quote() +{ + let q, j, a, n; + next(); + q = grab(); + j = hole(); op(O_JMP); + a = here; + n = q[0] * 3 + 1; + wcopyto(q, n); + free(d*q); + setlit(j, here); + lit(a); + callname(s_qnew); + xcls = C_FRESH; + return 0; +} +// tokens of a string, as a token list +.u tokens(s) +{ + let n = 0, q; + src_push(2, s, 0, 0); + next(); + while (tk != T_EOF) { + if (n >= 2700) fatal("too many tokens"); + R_QBUF[n * 3] = tk; R_QBUF[n * 3 + 1] = tv; R_QBUF[n * 3 + 2] = tline; n++; + next(); + } + src_pop(); + q = new(n * 3 + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n * 3); + return u*q; +} +// 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; } + +// ---- reading a unit and scanning it for signatures ---- +// a unit from stdin is read whole first (4 chars to a word), then scanned +// once for function signatures, so a function's tags are known before its first +// call even when it's defined further down. +unchecked fn readsrc() +{ + let cap = 4090, b = new(4090), n = 0, c, nb, w; + while (!eof()) { + c = getc() & 255; + if (c == 96) break; + if ((n >> 2) + 2 >= cap) { nb = new(cap + cap + 6); wcopy(nb, b, cap); free(b); b = nb; cap = cap + cap + 6; } + w = n >> 2; + if (!(n & 3)) b[w] = 0; + b[w] = b[w] | (c << ((n & 3) * 8)); + n++; + } + b[n >> 2] = b[n >> 2] & (pow2[(n & 3) * 8] - 1); // the 0 at the end + if ((n & 3) == 0) b[n >> 2] = 0; + b[(n >> 2) + 1] = 0; + return b; +} +// skip a <...> group (type parameters) +fn pskipangle() +{ + let dp = 0; + while (tk != T_EOF) { + if (is_op(s_lt)) dp++; + else if (is_op(s_gt)) dp--; + else if (is_op(s_shr)) dp = dp - 2; + next(); + if (dp <= 0) return 0; + } + return 0; +} +// at the name after fn: read the signature's tags and record them +fn prescan_fn(ret) +{ + let n = tv, np = 0, tags = 0, t = 0, dp, s; + next(); + next(); // the ( + if (!is_op(s_rp)) { + np = 1; dp = 1; + while (tk != T_EOF) { + if (is_op(s_lp)) dp++; + else if (is_op(s_rp)) { dp--; if (!dp) break; } + else if (dp == 1 && is_op(s_comma)) { if (np <= 12) tags = tags + (t << (np + np - 2)); np++; t = 0; } + else if (dp == 1 && is_op(s_dot)) { next(); if (is_id(s_m)) t = 1; else if (is_id(s_d)) t = 2; continue; } + next(); + } + if (np <= 12) tags = tags + (t << (np + np - 2)); + } + next(); + if (!is_op(s_lb) && !is_op(s_semi)) return 0; // not a function: an enhancement, a call in a parse word... + s = lookup(n); + if (s < 0 || s < ubase || skind[s] != K_FN || (sflag[s] & F_DEF)) s = fwdfn(n); + if (!(sflag[s] & F_SIG)) { ssig[s] = ret + np + np + tags * 64; sflag[s] = sflag[s] | F_SIG | F_PRE; } + return 0; +} +fn prescan(kind, obj) +{ + let depth = 0, sp = panic, sn = nerr, pend = 0; + dry++; + src_push(kind, obj, 0, 0); + next(); + while (tk != T_EOF) { + if (is_op(s_lb)) depth++; + else if (is_op(s_rb)) { depth--; pend = 0; } + else if (depth <= 0) { + if (is_op(s_semi)) pend = 0; + else if (is_op(s_dot)) { peek(); if (pk_tk == T_ID && pk_tv == s_u) pend = 1; } + else if (tk == T_ID) { peek(); if (pk_tk == T_OP && pk_tv == s_lp) { prescan_fn(pend); pend = 0; continue; } } + } + next(); + } + src_pop(); + dry--; panic = sp; nerr = sn; + return 0; +} +// compile a whole unit from stdin +fn unit_stdin() +{ + let src = readsrc(); + prescan(3, src); + src_push(3, src, 0, 0); + next(); + unit_top(); + unit_end(ubase); + src_pop(); + free(src); + 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() +{ + let f = R_CTX + ctxsp * 24; + if (ctxsp >= 30) fatal("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; + f[19] = fty; f[20] = ntp; f[21] = xty; wcopy(f + 22, tpn, 2); + return 0; +} +fn ctx_pop() +{ + let 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]; + fty = f[19]; ntp = f[20]; xty = f[21]; wcopy(tpn, f + 22, 2); + return 0; +} + +// ---- functions and the top level ---- +fn fn_begin(chk, ret) +{ + lbase = nloc; fdepth = 1; fslots = 0; fchk = chk && check_on; fret = ret; fty = 0; + live = 1; bxdepth = 0; epichain = 0; infn = 1; loopbase = lsp; lv = 0; lvk = LV_NONE; + return 0; +} +// fp -= frame size, then check the frame stack: past FBOT, reset fp and stop +fn prologue() +{ + let k; + lit(ZFP); op(O_LD); fframe = hole(); op(O_SUB); lit(ZFP); op(O_ST); + if (o3on) return 0; // o3 gave up the frame check + lit(ZFP); op(O_LD); lit(FBOT); op(O_LT); k = hole(); op(O_JZ); + lit(FTOP); lit(ZFP); op(O_ST); callname(s_fovf); + setlit(k, here); + 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(); } + unused_check(lbase); + if (fchk && live) { exit_vars(1, 1); if (fret) cerr("a function returning .u has to end with a return"); } + next(); + return 0; +} +// the rest of a function, after its return type and name: +// int f(int a, *node.m n, .d x, b) { ... } *list.u mk(int n) { ... } +// rty is 0 for fn (a plain word), ret is 1 for a .u return +fn fndef(chk, rty, ret, n) +{ + let s, np = 0, tags = 0, t, sig, i, pn[24], pt[24], pty[24], typed = 0, ft, o3f = o3nxt, lo, hi; + o3nxt = 0; + if (rty || ntp) typed = 1; + 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; + pty[np] = tword; + if (!is_op(s_dot) && ((tk == T_OP && (tv == s_star || tv == s_lk)) || (tk == T_ID && (tv == s_fn || istypename(tv))))) { + pty[np] = ptype(); typed = 1; + if (isagg(pty[np])) serr("structs and arrays are passed by pointer"); + } + if (accept(s_dot)) { // .m lends, .d takes over + if (tv == s_m) t = 1; else if (tv == s_d) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + pn[np] = name(); + if (o3f && pty[np] == tword) serr("o3 parameters need a type"); + 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); + sig = ret + np + np + tags * 64; + if ((sflag[s] & F_SIG) && !(sflag[s] & F_PRE)) { if (ssig[s] != sig) serrn(n, "doesn't match its earlier declaration"); } + else if ((sflag[s] & F_UNTYPED) && (tags || ret)) serrn(n, "was called before its tags were declared; put a prototype above the first call"); + ssig[s] = sig; + sflag[s] = (sflag[s] | F_SIG) - (sflag[s] & F_PRE); + if (ntp) sflag[s] = sflag[s] | F_GEN; + if (typed) { + if (!rty) rty = tword; + ft = tfn(rty, np, pty, sig); + if (stype[s] && stype[s] != ft) serrn(n, "doesn't match its earlier declaration"); + stype[s] = ft; + } + if (accept(s_semi)) { ntp = 0; return s; } + if (sflag[s] & F_DEF) serrn(n, "is defined twice"); + sval[s] = here; + sflag[s] = sflag[s] | F_DEF; + fixall(sfix[s], here); sfix[s] = 0; + fn_begin(chk, ret); + if (typed) fty = rty; + no3pend = 0; + if (o3f) { o3on = 1; no3sl = 0; } + prologue(); + i = 0; + while (i < np) { + t = newloc(pn[i]); fslots++; + ltype[t] = pty[i]; + if (o3f) { ltag[t] = 16; addsl(lslot[t]); } + 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); } + if (o3f) { lo = here + 2; lit(lo); op(O_JMP); } // the region starts here: a jump, so the cpu enters it + body(); + hi = here; + epilogue(); + if (o3f) { o3on = 0; o3region(lo, hi, o3sl, no3sl); } + o3flush(); + ntp = 0; + return s; +} +// let g = 1, buf[10]; int g = 3; [10]int buf; point origin; +fn gdecl(typed) { next(); return gdecl2(0, 0, name()); } +fn gdecl2(t, tg, n) +{ + let a, k, s; + if (tg) serr("tags go on locals and parameters, not globals"); + if (t == tvoid) serr("a variable can't be void"); + while (1) { + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + s = addsym(n, K_GARR, here); + if (!t) t = tword; + stype[s] = tarr(t, k); + k = tsz(stype[s]); + while (k) { emit(0); k--; } + } else if (t && isagg(t)) { + s = addsym(n, K_GARR, here); stype[s] = t; + k = tsz(t); + while (k) { emit(0); k--; } + } else { + a = here; + s = addsym(n, K_GVAR, a); + if (t) stype[s] = t; + 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; + n = name(); + } + expect(s_semi); + return 0; +} +fn gconst() +{ + let n; + next(); + while (1) { n = name(); expect(s_eq); addsym(n, K_CONST, cexpr()); if (!accept(s_comma)) break; } + expect(s_semi); + return 0; +} +// enhance [n] name(a, b) micro "recipe" [else fn]; n outputs, 1 if left out +// enhance [n] name(a, b) vm { asm } [else fn]; +// lays out the descriptor the install opcode reads, and wires it in right +// away (an image wires its own in when it boots). +fn enhdef() +{ + let n, np = 0, nout = 1, dsc, na, pay, len = 0, kind = 0, i, p, s, slot, r, pn[8]; + next(); + if (tk == T_NUM) { if (tv < 0 || tv > 8) serr("an enhancement has at most 8 outputs"); nout = tv; next(); } // enhance 2 divmod(a, b) + n = name(); + expect(s_lp); + if (!is_op(s_rp)) { while (1) { if (np == 8) die("an enhancement takes at most 8 inputs"); pn[np] = name(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + dsc = here; i = 0; while (i < 7) { emit(0); i++; } + na = here; i = 0; while (i < np) { emit(0); i++; } + i = 0; + while (i < np) { *(na + i + hdelta) = here; p = pn[i]; while (*p) { emit(*p); p++; } emit(0); i++; } + if (accept(s_micro)) { + pay = here; + if (tk != T_STR) die("expected the recipe as a string"); + while (tk == T_STR) { p = tv; while (*p) { emit(*p); p++; } next(); } + emit(0); + } else if (accept(s_vm)) { pay = here; asmblock(); op(O_RET); len = here - pay; kind = 1; } + else die("expected micro or vm"); + slot = nenh; + if (slot >= 512) fatal("all 512 enhancement slots are taken"); + nenh++; + p = dsc + hdelta; + p[0] = slot; p[1] = kind; p[2] = np; p[3] = nout; p[4] = pay; p[5] = len; p[6] = na; + s = addsym(n, K_ENH, slot); + ssig[s] = np + nout * 16 + dsc * 256; + if (accept(s_else)) { r = lookup(tv); if (r < 0) r = fwdfn(tv); next(); sfix[s] = r + 1; } + expect(s_semi); + if (!hdelta) { + r = install(dsc); + if (r < 0) { + if (!sfix[s]) serrn(n, "the enhancement didn't install (see install's codes in core.c)"); + sflag[s] = sflag[s] | F_FALLBACK; + } + } + return 0; +} +// after a syntax error at the top level: skip to something that starts a declaration +fn topsync() +{ + let depth = 0; + while (tk != T_EOF) { + if (is_op(s_lb)) depth++; + else if (is_op(s_rb)) { depth--; if (depth < 0) depth = 0; } + else if (!depth && tk == T_ID && (tv == s_fn || tv == s_var || tv == s_const || tv == s_struct || tv == s_type + || tv == s_enhance || tv == s_typecheck || tv == s_unchecked || tv == s_immediate || tv == s_o3)) break; + next(); + } + panic = 0; + return 0; +} +fn fndone(s, imm) +{ + let k; + ntp = 0; + if (imm) { + if (hdelta) serr("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; +} +fn topitem() +{ + let chk = 1, imm = 0, s, k, n; + if (panic) return topsync(); + 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; } + o3nxt = 0; + if (is_id(s_o3)) { next(); o3nxt = 1; } + ntp = 0; + if (is_op(s_lt)) { // before a generic function + next(); + while (1) { if (ntp >= 8) fatal("too many type parameters"); tpn[ntp] = name(); ntp++; if (!accept(s_comma)) break; } + closeangle(); + } + if (is_id(s_fn)) { peek(); if (!(pk_tk == T_OP && pk_tv == s_lp)) { next(); n = name(); return fndone(fndef(chk, 0, 0, n), imm); } } + if (ntp || !chk || imm || o3nxt) { // has to be a function, with a return type + dtype(); n = name(); + if (dtag && dtag != S_U) serr("the only return tag is .u"); + if (!is_op(s_lp)) { die("expected a function"); return 0; } + return fndone(fndef(chk, dty, dtag == S_U, n), imm); + } + if (is_id(s_var)) return gdecl(0); + if (is_id(s_struct)) { kw_struct(); return 0; } + if (is_id(s_type)) return kw_type(); + if (is_id(s_typecheck)) return kw_typecheck(); + if (is_id(s_enhance)) return enhdef(); + 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; } + } + if (tstart()) { // int f(...) { } or int g = 1; + dtype(); n = name(); + if (is_op(s_lp)) { + if (dtag && dtag != S_U) serr("the only return tag is .u"); + return fndone(fndef(chk, dty, dtag == S_U, n), 0); + } + return gdecl2(dty, dtag, n); + } + die("expected a declaration"); + return 0; +} +fn unit_top() { while (tk != T_EOF) topitem(); return 0; } +fn unit_end(from) +{ + let i = from; + panic = 0; + while (i < nsym) { + if (skind[i] == K_FN && !(sflag[i] & F_DEF) && sfix[i]) { tline = sval[i]; serrn(sname[i], "is used but never defined"); } + i++; + } + if (nerr) giveup(); + 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(q, top) +{ + let hop = -1, entry = 0, from = nsym; + ctx_push(); + if (infn) { hop = hole(); op(O_JMP); } + if (top) prescan(1, q); + 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(q) { return compile_list(q, 0); } +fn load(q) { compile_list(q, 1); return 0; } +fn eval(q) { let f = compile_list(q, 0); return f(); } +fn evals(s) { let q = tokens(s), r = eval(q); free(d*q); 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) +{ + let i = from, p; + while (i < nsym) { + if ((skind[i] >= K_FN && skind[i] <= K_CONST) || skind[i] == K_ENH) { + 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) +{ + let 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; + if (p[0] == K_ENH) { if (p[1] >= nenh) nenh = p[1] + 1; install(p[2] >> 8); } + 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) +{ + let sh = here, sd = hdelta, sl = hlimit, sub = ubase, svl = vislo, sns = nsym, sen = nenh, n; + ubase = nsym; vislo = nsym; nenh = 0; + 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); + unit_stdin(); + *(dst + 5) = here; + blob_emit(ubase); + *(dst + 6) = here; + n = here - org; + popsyms(sns); + ubase = sub; vislo = svl; here = sh; hdelta = sd; hlimit = sl; nenh = sen; + 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 + 1024); + 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_dot = intern("."); s_q = intern("?"); s_case = intern("case"); s_default = intern("default"); s_andand = intern("&&"); s_oror = intern("||"); + s_fn = intern("fn"); s_var = intern("let"); 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"); s_fovf = intern("frame_overflow"); + s_enhance = intern("enhance"); s_micro = intern("micro"); s_vm = intern("vm"); + 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, "idiv"); // native divide, wired in by rt.zc + add_binop("%", 10, "imod"); + add_binop("+", 9, "+"); // 3 + add_binop("-", 9, "-"); // 4 + add_binop("<<", 8, "ishl"); // 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("let", 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("switch", kw_switch, 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); + add_kw("sizeof", kw_sizeof, F_EXPR); + add_kw("typeof", kw_typeof, F_EXPR); + add_kw("o3", kw_o3, F_STMT); + add_kw("len", kw_len, F_EXPR); + add_kw("cap", kw_cap, F_EXPR); + add_kw("push", kw_push, F_EXPR); + add_kw("pop", kw_pop, F_EXPR); + add_kw("resize", kw_resize, F_EXPR); + return 0; +} +fn start() +{ + let s, f; + heap_init(); + zc_init(); + blob_load(GORG[5]); + zc_tables(); + types_init(); + here = 0; hdelta = 0; hlimit = HEAP_LO; ptop = 0; + ubase = nsym; vislo = 0; + unit_stdin(); + 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/15-o3/code/src/rt.zc b/docs/history/15-o3/code/src/rt.zc new file mode 100644 index 0000000..d85ba8e --- /dev/null +++ b/docs/history/15-o3/code/src/rt.zc @@ -0,0 +1,290 @@ +// ============================================================================ +// 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; + +// ---- virtual enhancements ---- +// install(desc) wires a custom opcode into the cpu (the % opcode). these three +// give the language native division and left shift (zdiv, zmod and zshl +// below are the same thing done in software). they come first, since the +// compiler resolves / % and << to them by name. +fn install(desc) { return asm { desc @ % }; } +enhance idiv(a, b) micro "a = sdiv a b"; +enhance imod(a, b) micro "a = srem a b"; +enhance ishl(a, b) micro "a = shl a b"; +// for o3: an o3 variable's address (fp + k), and a bounds check (1 if i isn't in 0..n-1) +enhance lfa(k) micro "r1 = ld 655360; k = add r1 k"; +enhance outside(i, n) micro "i = ltu i n; i = xor i 1"; + +// ---- 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(s) { let i = 0; while (s[i]) { putc(s[i]); i++; } return 0; } +fn putn(n) +{ + let 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(s) { let n = 0; while (s[n]) n++; return n; } +fn streq(a, b) { let i = 0; while (a[i] && a[i] == b[i]) i++; return a[i] == b[i]; } +fn wcopy(dst, src, n) { let i = 0; while (i < n) { dst[i] = src[i]; i++; } return 0; } +fn wfill(dst, v, n) { let i = 0; while (i < n) { dst[i] = v; i++; } return 0; } + +// ---- arithmetic the hardware doesn't have ---- +let pow2[32]; +let zrem; +fn zudiv(n, dv) +{ + let q = 0, r = 0, i = 30; + if (n < dv) { zrem = n; return 0; } + while (i >= 0) { + r = r + r + ((n >> i) & 1); + q = q + q; + if (r >= dv) { r = r - dv; q++; } + i--; + } + zrem = r; + return q; +} +fn zdiv(a, b) +{ + let 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) { let neg = a < 0; if (b == 0) return a; zdiv(a, b); if (neg) return 0 - zrem; return zrem; } +fn zshl(a, b) { return a * pow2[b & 31]; } + +// ---- heap ---- +// a buddy allocator. the heap is cut into aligned power-of-two chunks, every +// block is a power of two words, and a freed block merges with its buddy +// (the other half of the block they were split from) whenever that one is +// free too, so freed space can be reused at any size. every block has a 6 +// word header before the pointer the program sees: +// p[-6] block size p[-5] size class p[-4] flags (0 free, 1 live, 3 marked) +// p[-3] p ^ MAGIC p[-2] owner (the container that owns it, or 0) +// p[-1] its type (a type record from new(T), or 0 from new(n)) +// free blocks sit on a doubly linked list per class, linked through p[0], p[1]. +const HDR = 6; +let hbump, freel[32], gc_runs, gc_freed, gc_auto = 1; + +// the size of the top-level chunk holding heap offset off +fn topsize(off) +{ + let h = HEAP_HI - HEAP_LO, base = 0, sz; + while (h) { + sz = 1; + while (sz + sz <= h) sz = sz + sz; + if (off < base + sz) return sz; + base = base + sz; h = h - sz; + } + return 0; +} +fn fpush(b, k) { b[2] = 0; b[6] = freel[k]; b[7] = 0; if (freel[k]) freel[k][7] = b; freel[k] = b; return 0; } +fn funlink(b, k) +{ + if (b[7]) b[7][6] = b[6]; else freel[k] = b[6]; + if (b[6]) b[6][7] = b[7]; + return 0; +} +fn mkblock(b, k) { b[0] = pow2[k]; b[1] = k; b[2] = 0; b[3] = 0; b[4] = 0; b[5] = 0; return b; } +fn heap_init() +{ + let i = 1, b = HEAP_LO, sz, k; + pow2[0] = 1; + while (i < 32) { pow2[i] = pow2[i - 1] + pow2[i - 1]; i++; } + hbump = HEAP_HI; + wfill(freel, 0, 32); + while (b < HEAP_HI) { + sz = topsize(b - HEAP_LO); k = 0; + while (pow2[k] < sz) k++; + fpush(mkblock(b, k), k); + b = b + sz; + } + return 0; +} +// a free block of class k, split down from a bigger one if needed; 0 if none +fn balloc(k) +{ + let j = k, b, h; + while (j < 32 && !freel[j]) j++; + if (j >= 32) return 0; + b = freel[j]; + funlink(b, j); + while (j > k) { j--; h = b + pow2[j]; fpush(mkblock(h, j), j); } + mkblock(b, k); + return b; +} +let fend; // end of the block bfree last made, for the sweep +// put block b back, merging it with its buddy as long as it can +fn bfree(b) +{ + let k = b[1], sz = pow2[k], off, bud; + while (1) { + off = b - HEAP_LO; + if (sz >= topsize(off)) break; + bud = HEAP_LO + (off ^ sz); + if (bud[2] != 0 || bud[1] != k || bud[0] != sz) break; + funlink(bud, k); + if (bud < b) { b[0] = 0; b[3] = 0; b = bud; } // the upper header is inside the merged block now + else { bud[0] = 0; bud[3] = 0; } + k++; sz = sz + sz; + mkblock(b, k); + } + fpush(mkblock(b, k), k); + fend = b + sz; + return 0; +} +fn isobj(x) { return x >= HEAP_LO + HDR && x < hbump && x[-3] == (x ^ MAGIC) && (x[-4] & 1); } + +// every prologue checks the frame stack; on overflow it resets the frame +// pointer (so this can run at all) and stops +fn frame_overflow() { puts("zy: frame stack overflow\n"); halt(); return 0; } +fn oom() { puts("zc: out of heap memory\n"); halt(); return 0; } +// n words, untyped and not zeroed: what new gives o3 code +unchecked .u new_raw(n) +{ + let need = n + HDR, k = 3, b, p; + if (n < 0) need = HDR; + while (pow2[k] < need) k++; + b = balloc(k); + if (!b && gc_auto) { gc(); b = balloc(k); } + if (!b) oom(); + p = b + HDR; + b[2] = 1; b[3] = p ^ MAGIC; b[4] = 0; b[5] = 0; + return p; +} +// n words typed t, zeroed +unchecked .u new_t(n, t) +{ + let p = new_raw(n); + p[-1] = t; + wfill(p, 0, p[-6] - HDR); + return p; +} +unchecked .u new(n) { return new_t(n, 0); } +fn osize(p) { if (!isobj(p)) return 0; return p[-6] - HDR; } +fn typeof_obj(p) { if (!isobj(p)) return 0; return p[-1]; } + +// frees p and, recursively, every object p owns +fn release(p) +{ + let b = p - HDR, n = b[0] - HDR, i = 0, w; + b[2] = 2; // going: not live, and not free yet either, so a child's buddy check can't merge into it + while (i < n) { w = p[i]; if (isobj(w) && w[-2] == p) release(w); i++; } + bfree(b); + return 0; +} +unchecked fn free(.d p) { if (isobj(p)) release(p); return 0; } +fn own(c, p) { if (isobj(c)) c[-2] = p; return c; } + +// ---- growable arrays ---- +// a []T is a handle: [len, cap, items, element size]. items is an object the +// handle owns; growing swaps it for a bigger one and moves its children over. +unchecked .u dnew(es, n, t) +{ + let h = new_t(4, t), c = n, it; + if (c < 4) c = 4; + it = new(c * es); + h[0] = n; h[1] = c; h[2] = own(it, h); h[3] = es; + return h; +} +unchecked fn dgrow(h, need) +{ + let c = h[1], it, old = h[2], i = 0, w, n; + if (need <= c) return 0; + while (c < need) c = c + c; + it = new(c * h[3]); + n = h[0] * h[3]; + wcopy(it, old, n); + while (i < n) { w = it[i]; if (isobj(w) && w[-2] == old) w[-2] = it; i++; } // the children move with the elements + h[2] = own(it, h); h[1] = c; + free(old); + return 0; +} +fn oob(i, n) { puts("zy: index "); putn(i); puts(" out of range (length "); putn(n); puts(")\n"); halt(); return 0; } +unchecked fn dat(h, i) { if (i < 0 || i >= h[0]) oob(i, h[0]); return h[2] + i * h[3]; } +unchecked fn dpush(h, .d x) { dgrow(h, h[0] + 1); h[2][h[0]] = x; own(x, h[2]); h[0] = h[0] + 1; return 0; } +unchecked fn dpop(h) { if (!h[0]) oob(-1, 0); h[0] = h[0] - 1; return h[2][h[0]]; } +unchecked fn dresize(h, n) +{ + let old = h[0] * h[3]; + if (n < 0) n = 0; + dgrow(h, n); + if (n * h[3] > old) wfill(h[2] + old, 0, n * h[3] - old); + h[0] = n; + return 0; +} +fn dlen(h) { return h[0]; } +fn dcap(h) { return h[1]; } + +// ---- 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. +let ms_top, ms_over, gc_lo, gc_hi; +fn mark(w) +{ + if (!isobj(w) || (w[-4] & 2)) return 0; + w[-4] = w[-4] | 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() +{ + let p; + while (ms_top) { ms_top--; p = MARK0[ms_top]; markrange(p, p + p[-6] - HDR); } + return 0; +} +fn gc_roots(); +unchecked fn gc() +{ + let 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 < HEAP_HI) { if (b[2] == 3) markrange(b + HDR, b + b[0]); b = b + b[0]; drain(); } + } + b = HEAP_LO; + while (b < HEAP_HI) { + sz = b[0]; + if (b[2] == 1) { bfree(b); n++; b = fend; } // merging may swallow what follows + 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() { let b = HEAP_LO, n = 0; while (b < HEAP_HI) { if (b[2] & 1) n++; b = b + b[0]; } return n; } +// the biggest block that's free right now, in words +fn largest_free() { let k = 31; while (k > 0 && !freel[k]) k--; if (!freel[k]) return 0; return pow2[k]; } diff --git a/docs/history/15-o3/code/test.sh b/docs/history/15-o3/code/test.sh new file mode 100755 index 0000000..a4cf785 --- /dev/null +++ b/docs/history/15-o3/code/test.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# full check: bootstraps the compiler from zc0, verifies the fixpoint, then runs +# the examples and tests on the portable interpreter (host), the arm64 jit under +# qemu, and the llvm backend. needs gcc; the jit half needs aarch64-linux-gnu-gcc +# and qemu-aarch64, the llvm half needs llvm-config and libLLVM (each is skipped +# if 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 < examples/typed.zc | tr '\n' '/')" "last: 4/point is 2 words: x int, y int/vec<*point> is 3 words: len int, cap int, items **point/push is bool(*vec, T.d)/the heap says v is a vec, and v.items[0] is a point/" "$l typed example" + chk "$($vm < examples/wiring.zc)" "16 1234 25 4/9" "$l enhancement example" + 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" + chk "$($vm < tests/types.zc | tr '\n' '/')" "12 5 2 15 56 42 7 14 3/rect *rect *list *list.u(int) T(*list) fn(word.d)/a:point@0 b:point@2 tag:int@4 /point 1 1/" "$l types, generics, reflection" + chk "$($vm < tests/typeok.zc)" "14" "$l a program the typechecker accepts" + chk "$($vm < tests/typeoff.zc)" "6" "$l the typechecker is off by default" + chk "$($vm < tests/enhance.zc)" "100 0 343 3,2 5 -2 0" "$l virtual enhancements" + chk "$($vm < tests/joins.zc)" "0 0 5 80 8 3 9 0" "$l joins free what one path gave away; switch, ?:, no prototypes" + chk "$($vm < tests/buddy.zc)" "131072 262144 1 0" "$l buddy allocator merges freed blocks" + chk "$($vm < tests/borrowmove.zc)" "6" "$l storing into a borrowed object moves it" + chk "$($vm < tests/manyerrors.zc | tr '\n' '/')" "zc: line 3: expected an expression/zc: line 4: x: m object is never used/zc: line 5: type error: initializer: expected *char, got int/zc: line 6: expected ;/zc: 4 errors/" "$l several errors in one run" + chk "$($vm < tests/overflow_return.zc 2>&1)" "zy: return stack overflow" "$l return stack overflow is caught" + chk "$($vm < tests/overflow_data.zc 2>&1)" "zy: data stack overflow" "$l data stack overflow is caught" + chk "$($vm < tests/overflow_frame.zc 2>&1)" "zy: frame stack overflow" "$l frame stack overflow is caught" + chk "$($vm < examples/mandel.zc 2>&1 | md5sum | cut -c1-32)" "f41aecbf2c844168050413cfa832db0e" "$l example: mandelbrot with a fixed-point enhancement" + chk "$($vm < examples/bf.zc 2>&1 | md5sum | cut -c1-32)" "223570983752b17f7ece32e93d5e19e4" "$l example: brainfuck compiled at runtime" + chk "$($vm < examples/dump.zc 2>&1 | md5sum | cut -c1-32)" "757774b00f6b3cd0bfbcba66448a8619" "$l example: struct printer through reflection" + chk "$($vm < examples/tree.zc 2>&1 | md5sum | cut -c1-32)" "b86a2e4e9e31acc294a4ddf86be863f2" "$l example: owning tree frees itself" + chk "$($vm < examples/lang.zc 2>&1 | md5sum | cut -c1-32)" "aa1a18c78b5200129c7c2b315f163d28" "$l example: pipe operator, unless, assert, times" + chk "$($vm < examples/staged.zc 2>&1 | md5sum | cut -c1-32)" "6f790a125c48b0cc7a897cee73ee5627" "$l example: staged code compiled while running" + chk "$($vm < examples/quine.zc 2>&1 | md5sum | cut -c1-32)" "c868ecb9dd7b05224a1bd8a4c32ae788" "$l example: quine" + chk "$($vm < examples/primes.zc 2>&1 | md5sum | cut -c1-32)" "814faffc70dad0ae520c0671c33e73d4" "$l example: o3 prime sieve" + chk "$($vm < examples/life.zc 2>&1 | md5sum | cut -c1-32)" "aefb036b6f9ad1dadfc3e6bb47a6885d" "$l example: game of life" + chk "$($vm < tests/arrays.zc | tr '\n' '/')" "100 128 9801 9801 99 3 4 12 19 8 19 28/0/" "$l growable and fixed arrays" + chk "$($vm < tests/o3.zc)" "3142 42 43 9 57 98781 520625 10192 -18782 1152" "$l o3 regions: loops, calls, recursion, switch, arrays, more vars than registers" + chk "$($vm < tests/o3_bounds.zc 2>&1)" "zy: index 7 out of range (length 5)" "$l o3 bounds check" + local r; r=$(tests/runerr.sh "$vm" tests/errors | tail -1) + chk "$r" "rejected: $(ls tests/errors/*.zc | wc -l) passed, 0 failed" "$l analyzer rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/typeerrors | tail -1) + chk "$r" "rejected: $(ls tests/typeerrors/*.zc | wc -l) passed, 0 failed" "$l typechecker rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/langerrors | tail -1) + chk "$r" "rejected: $(ls tests/langerrors/*.zc | wc -l) passed, 0 failed" "$l o3 and array misuse is rejected" +} +gcc -O2 -w -DJTYPE=int core.c io_linux.c -o $T/zy +run $T/zy "interp" +chk "$(ZYTRACE=1 $T/zy < tests/o3.zc 2>&1 | grep -c 'micro-ops$')" "8" "every o3 region lifts" +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" + chk "$(ZYTRACE=1 $T/jit < tests/o3.zc 2>&1 | grep -c 'bytes of arm64')" "8" "jit compiles every o3 region to arm64" + 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 +if command -v llvm-config >/dev/null; then + gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c -o $T/zyl $(llvm-config --ldflags --libs) || exit 1 + run $T/zyl "llvm" + chk "$(ZYTRACE=1 $T/zyl < tests/o3.zc 2>&1 | grep -c 'compiled by llvm')" "8" "llvm compiles every o3 region" + printf '#!/bin/sh\nZYHOT=1 exec %s "$@"\n' $T/zyl > $T/llall; chmod +x $T/llall + chk "$($T/llall < tests/types.zc | md5sum)" "$($T/zy < tests/types.zc | md5sum)" "llvm compiling every block agrees" + selfc $T/zyl $T/gl.bin; cmp -s $T/g1.bin $T/gl.bin && chk 1 1 "llvm self-compile matches" || chk 0 1 "llvm self-compile matches" +else echo "skip llvm (no llvm-config)"; fi +echo "$ok passed, $bad failed"; [ $bad = 0 ] diff --git a/docs/history/15-o3/code/tests/arrays.zc b/docs/history/15-o3/code/tests/arrays.zc new file mode 100644 index 0000000..f8d46d8 --- /dev/null +++ b/docs/history/15-o3/code/tests/arrays.zc @@ -0,0 +1,24 @@ +// growable arrays and fixed ones +struct point { int x, y; }; +fn main() +{ + let before = live_objects(); + { + []int a = new([]int); + for (int i = 0; i < 100; i++) push(a, i * i); + putn(len(a)); putc(' '); putn(cap(a)); putc(' '); putn(a[99]); putc(' '); + putn(pop(a)); putc(' '); putn(len(a)); putc(' '); + resize(a, 3); putn(len(a)); putc(' '); putn(a[2]); putc(' '); + fixed []int f = new(fixed []int, 5); + f[4] = 7; putn(f[4] + len(f)); putc(' '); + []point ps = new([]point, 2); + ps[1].y = 9; resize(ps, 10); putn(ps[1].y + len(ps)); putc(' '); + [8]int st; putn(len(st)); putc(' '); + []*point owned = new([]*point); + for (int i = 0; i < 20; i++) { *point p = new(point); p.x = i; push(owned, d*p); } + putn(owned[19].x); putc(' '); + putn(live_objects() - before); putc(10); + } + putn(live_objects() - before); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/tests/basics.zc b/docs/history/15-o3/code/tests/basics.zc new file mode 100644 index 0000000..c1f1faf --- /dev/null +++ b/docs/history/15-o3/code/tests/basics.zc @@ -0,0 +1,22 @@ +let table[10]; +let 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() +{ + let i, s = 0, a[5]; + for (i = 0; i < N; i++) table[i] = i * i; + for (let 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); + let b = { let 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); + let x = asm { 2 3 + }; + putn(x); putc(10); + asm { 'o' . 'k' . 10 . } + return 0; +} diff --git a/docs/history/15-o3/code/tests/bench.zc b/docs/history/15-o3/code/tests/bench.zc new file mode 100644 index 0000000..a7e53f5 --- /dev/null +++ b/docs/history/15-o3/code/tests/bench.zc @@ -0,0 +1,30 @@ +// four kernels with and without o3; bench.sh runs each one on each backend +int csum(int lim) { int s = 0; for (int n = 1; n < lim; n++) { int x = n; while (x != 1) { if (x & 1) x = 3 * x + 1; else x = x / 2; s++; } } return s; } +o3 int csum3(int lim) { int s = 0; for (int n = 1; n < lim; n++) { int x = n; while (x != 1) { if (x & 1) x = 3 * x + 1; else x = x / 2; s++; } } return s; } +int sieve(fixed []int f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; } +o3 int sieve3(fixed []int f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; } +int digits(int n) { int s = 0; for (int i = 0; i < n; i++) { int x = i; while (x) { s = s + x % 10; x = x / 10; } } return s; } +o3 int digits3(int n) { int s = 0; for (int i = 0; i < n; i++) { int x = i; while (x) { s = s + x % 10; x = x / 10; } } return s; } +int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +o3 int fib3(int n) { if (n < 2) return n; return fib3(n - 1) + fib3(n - 2); } +// input: a letter (the kernel; z runs none) and how many times to run it +fn main() +{ + fixed []int f = new(fixed []int, 50000); + let which = getc(), reps = 0, ch = getc(), r = 0; + while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = getc(); } + while (reps > 0) { + if (which == 'a') r = csum(30000); + if (which == 'b') r = csum3(30000); + if (which == 'c') r = sieve(f); + if (which == 'd') r = sieve3(f); + if (which == 'e') r = digits(300000); + if (which == 'f') r = digits3(300000); + if (which == 'g') r = fib(22); + if (which == 'h') r = fib3(22); + reps--; + } + putn(r); putc(10); + free(d*f); + return 0; +} diff --git a/docs/history/15-o3/code/tests/borrowmove.zc b/docs/history/15-o3/code/tests/borrowmove.zc new file mode 100644 index 0000000..43f27b2 --- /dev/null +++ b/docs/history/15-o3/code/tests/borrowmove.zc @@ -0,0 +1,2 @@ +fn put(.m box, int v) { *int c = new(int); *c = v; box[0] = c; return 0; } +fn main() { let b = new(1); put(b, 6); putn(*(b[0] as *int)); putc(10); return 0; } diff --git a/docs/history/15-o3/code/tests/buddy.zc b/docs/history/15-o3/code/tests/buddy.zc new file mode 100644 index 0000000..2000598 --- /dev/null +++ b/docs/history/15-o3/code/tests/buddy.zc @@ -0,0 +1,15 @@ +// the buddy allocator: 20000 small blocks, freed, merge back into one big one +let keep[20000]; +fn main() +{ + let i = 0, p; + while (i < 20000) { keep[i] = new(2); i++; } // 20000 8-word blocks + putn(largest_free()); putc(' '); + i = 0; while (i < 20000) { free(keep[i]); i++; } + putn(largest_free()); putc(' '); + p = new(200000); // only possible if the small blocks merged back + putn(osize(p) >= 200000); putc(' '); + free(d*p); + putn(live_objects()); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/tests/enhance.zc b/docs/history/15-o3/code/tests/enhance.zc new file mode 100644 index 0000000..33eb85b --- /dev/null +++ b/docs/history/15-o3/code/tests/enhance.zc @@ -0,0 +1,29 @@ +// custom opcodes: recipes, lifted vm code, several outputs, and a fallback +enhance clampadd(a, b) micro "a = add a b; a = min a 100; a = max a 0"; +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance 2 divmod(a, b) micro "r2 = sdiv a b" "\n r1 = srem a b\n r0 = r2"; +enhance div7(a) micro "a = sdiv a 7"; +enhance urem10(a) micro "a = urem a 10"; +enhance hi(a, b) micro "a = mulhu a b"; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // i/o can't be lifted, so calls use the fallback +fn soft_noisy(x) { return x + 1; } +let qq, rr, seed = 7; +fn rnd() { seed = seed * 1103515245 + 12345; return seed ^ (seed >> 11); } +fn main() +{ + let i = 0, a, bad = 0; + putn(clampadd(70, 50)); putc(' '); putn(clampadd(-50, 2)); putc(' '); putn(cube(7)); putc(' '); + asm { 17 5 divmod rr ! qq ! } + putn(qq); putc(','); putn(rr); putc(' '); + putn(noisy(4)); putc(' '); + putn(hi(-1, -1)); putc(' '); + while (i < 5000) { + a = rnd(); + if (div7(a) != zdiv(a, 7)) bad++; + if (urem10(a) < 0 || urem10(a) > 9) bad++; + if (a / (i + 1) != zdiv(a, i + 1)) bad++; + i++; + } + putn(bad); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/tests/errors/back_to_m.zc b/docs/history/15-o3/code/tests/errors/back_to_m.zc new file mode 100644 index 0000000..b8c160f --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/back_to_m.zc @@ -0,0 +1,2 @@ +// expect: x: can't be recast back to m +fn main() { let x = new(3); d*x; m*x; return 0; } diff --git a/docs/history/15-o3/code/tests/errors/borrow_escape.zc b/docs/history/15-o3/code/tests/errors/borrow_escape.zc new file mode 100644 index 0000000..ce24480 --- /dev/null +++ b/docs/history/15-o3/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() { let x = new(1); f(x); return 0; } diff --git a/docs/history/15-o3/code/tests/errors/branch_mismatch.zc b/docs/history/15-o3/code/tests/errors/branch_mismatch.zc new file mode 100644 index 0000000..bd19968 --- /dev/null +++ b/docs/history/15-o3/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() { let x = new(1); if (x[0]) take(d*x); else u*x; return 0; } diff --git a/docs/history/15-o3/code/tests/errors/child_dies.zc b/docs/history/15-o3/code/tests/errors/child_dies.zc new file mode 100644 index 0000000..67caca9 --- /dev/null +++ b/docs/history/15-o3/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() { let p = new(2), c = new(1); p[0] = c; take(d*p); return c[0]; } diff --git a/docs/history/15-o3/code/tests/errors/child_recast.zc b/docs/history/15-o3/code/tests/errors/child_recast.zc new file mode 100644 index 0000000..c9ccd62 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/child_recast.zc @@ -0,0 +1,2 @@ +// expect: c: belongs to a container; recast the container instead +fn main() { let p = new(2), c = new(1); p[0] = c; d*c; return 0; } diff --git a/docs/history/15-o3/code/tests/errors/copy_owned.zc b/docs/history/15-o3/code/tests/errors/copy_owned.zc new file mode 100644 index 0000000..862c7ef --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/copy_owned.zc @@ -0,0 +1,2 @@ +// expect: x: is an owned object and can't be copied +fn main() { let x = new(1); let y = x; return y[0]; } diff --git a/docs/history/15-o3/code/tests/errors/d_into_block.zc b/docs/history/15-o3/code/tests/errors/d_into_block.zc new file mode 100644 index 0000000..2d7f526 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/d_into_block.zc @@ -0,0 +1,2 @@ +// expect: x: used after it was given away +fn main() { let x = new(1); d*x; { x[0] = 5; } return x[0]; } diff --git a/docs/history/15-o3/code/tests/errors/d_kept.zc b/docs/history/15-o3/code/tests/errors/d_kept.zc new file mode 100644 index 0000000..dcbfb86 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/d_kept.zc @@ -0,0 +1,2 @@ +// expect: x: d object was never given away +fn main() { let x = new(3); d*x; x[0] = 1; return 0; } diff --git a/docs/history/15-o3/code/tests/errors/discard_u.zc b/docs/history/15-o3/code/tests/errors/discard_u.zc new file mode 100644 index 0000000..9293378 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/discard_u.zc @@ -0,0 +1,3 @@ +// expect: can't be thrown away +.u mk() { let p = new(1); return u*p; } +fn main() { mk(); return 0; } diff --git a/docs/history/15-o3/code/tests/errors/give_m.zc b/docs/history/15-o3/code/tests/errors/give_m.zc new file mode 100644 index 0000000..cd67896 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/give_m.zc @@ -0,0 +1,3 @@ +// expect: x: is m; write d*x +fn take(.d p) { return p[0]; } +fn main() { let x = new(3); take(x); return 0; } diff --git a/docs/history/15-o3/code/tests/errors/global_store.zc b/docs/history/15-o3/code/tests/errors/global_store.zc new file mode 100644 index 0000000..dc0e546 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/global_store.zc @@ -0,0 +1,3 @@ +// expect: x: must be d to be stored in a global +let g; +fn main() { let x = new(1); g = x; return 0; } diff --git a/docs/history/15-o3/code/tests/errors/leak_overwrite.zc b/docs/history/15-o3/code/tests/errors/leak_overwrite.zc new file mode 100644 index 0000000..d19b5fd --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/leak_overwrite.zc @@ -0,0 +1,2 @@ +// expect: x: still owns an object +fn main() { let x = new(1); x = new(2); return x[0]; } diff --git a/docs/history/15-o3/code/tests/errors/lend_d.zc b/docs/history/15-o3/code/tests/errors/lend_d.zc new file mode 100644 index 0000000..55ac7e0 --- /dev/null +++ b/docs/history/15-o3/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() { let x = new(3); d*x; look(x); take(x); return 0; } diff --git a/docs/history/15-o3/code/tests/errors/loop_move.zc b/docs/history/15-o3/code/tests/errors/loop_move.zc new file mode 100644 index 0000000..df3c94a --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/loop_move.zc @@ -0,0 +1,3 @@ +// expect: x: is given away inside a loop that comes back around to it +fn take(.d p) { return p[0]; } +fn main() { let x = new(1); let i = 0; d*x; while (i < 3) { take(x); i++; } return 0; } diff --git a/docs/history/15-o3/code/tests/errors/plain_return.zc b/docs/history/15-o3/code/tests/errors/plain_return.zc new file mode 100644 index 0000000..45fb545 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/plain_return.zc @@ -0,0 +1,3 @@ +// expect: returns a new object; give the function a .u return type +fn mk() { return new(1); } +fn main() { return mk(); } diff --git a/docs/history/15-o3/code/tests/errors/return_m.zc b/docs/history/15-o3/code/tests/errors/return_m.zc new file mode 100644 index 0000000..b5ef519 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/return_m.zc @@ -0,0 +1,3 @@ +// expect: x: has to be u to be returned +.u mk() { let x = new(1); return x; } +fn main() { let y = mk(); return y[0]; } diff --git a/docs/history/15-o3/code/tests/errors/tag_mismatch.zc b/docs/history/15-o3/code/tests/errors/tag_mismatch.zc new file mode 100644 index 0000000..079f249 --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/tag_mismatch.zc @@ -0,0 +1,2 @@ +// expect: c: its tag doesn't match its container's +fn main() { let p = new(2), c = new(1); u*p; p[0] = c; return 0; } diff --git a/docs/history/15-o3/code/tests/errors/u_dropped.zc b/docs/history/15-o3/code/tests/errors/u_dropped.zc new file mode 100644 index 0000000..e1ca68a --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/u_dropped.zc @@ -0,0 +1,2 @@ +// expect: x: u object must leave this block +fn main() { let x = new(3); u*x; return 0; } diff --git a/docs/history/15-o3/code/tests/errors/u_skip_level.zc b/docs/history/15-o3/code/tests/errors/u_skip_level.zc new file mode 100644 index 0000000..6caeeb3 --- /dev/null +++ b/docs/history/15-o3/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() { let r; { { let t = new(1); u*t; r = t; } } return r[0]; } diff --git a/docs/history/15-o3/code/tests/errors/unchecked_touch.zc b/docs/history/15-o3/code/tests/errors/unchecked_touch.zc new file mode 100644 index 0000000..141639d --- /dev/null +++ b/docs/history/15-o3/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() { let x = new(1); unchecked { x[0] = 1; } return 0; } diff --git a/docs/history/15-o3/code/tests/errors/unused.zc b/docs/history/15-o3/code/tests/errors/unused.zc new file mode 100644 index 0000000..64aff1f --- /dev/null +++ b/docs/history/15-o3/code/tests/errors/unused.zc @@ -0,0 +1,2 @@ +// expect: x: m object is never used +fn main() { let x = new(3); return 0; } diff --git a/docs/history/15-o3/code/tests/errors/use_after_give.zc b/docs/history/15-o3/code/tests/errors/use_after_give.zc new file mode 100644 index 0000000..8a10922 --- /dev/null +++ b/docs/history/15-o3/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() { let x = new(3); take(d*x); return x[0]; } diff --git a/docs/history/15-o3/code/tests/gc.zc b/docs/history/15-o3/code/tests/gc.zc new file mode 100644 index 0000000..41f14a0 --- /dev/null +++ b/docs/history/15-o3/code/tests/gc.zc @@ -0,0 +1,20 @@ +let keep; +unchecked fn churn(n) +{ + let i = 0, p; + while (i < n) { p = new(10); p[0] = i; if (i % 100 == 0) keep = p; i++; } + return 0; +} +fn main() +{ + let 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/15-o3/code/tests/joins.zc b/docs/history/15-o3/code/tests/joins.zc new file mode 100644 index 0000000..913929b --- /dev/null +++ b/docs/history/15-o3/code/tests/joins.zc @@ -0,0 +1,32 @@ +// joins: something given away on one path is dead afterwards, and the paths +// that still own it free it on the way in. nothing here leaks. +fn take(.d p) { return p[0]; } +fn later(.d p); // not needed any more, but still allowed +*int.u mk(int v) { *int p = new(int); *p = v; return u*p; } +fn count(int n) { let s = 0; switch (n % 4) { case 0: s = 10; case 1, 2: s = 20; break; default: s = 30; } return s; } +fn main() +{ + let base = live_objects(), i = 0, hits = 0, k; + while (i < 50) { + let x = mk(i); + if (i % 3 == 0) take(d*x); // else: freed here by the fixup + i++; + } + putn(live_objects() - base); putc(' '); + // give away and break: fine now; the normal exit frees it + i = 0; + let y = mk(7); + while (i < 10) { if (i == 4) { take(d*y); break; } i++; } + putn(live_objects() - base); putc(' '); + let z = mk(5); + while (1) { if (z[0] == 5) { hits = take(d*z); break; } } + putn(hits); putc(' '); + putn(count(0) + count(1) + count(2) + count(3)); putc(' '); + k = i > 3 ? i * 2 : 0 - 1; + putn(k); putc(' '); + putn(forward(new(int))); putc(' '); // tagged and defined below: the prescan knows .d + **int pp; *int q = new(int); *q = 9; pp = &q; putn(**pp); free(d*q); putc(' '); + putn(live_objects() - base); putc(10); + return 0; +} +fn forward(*int.d p) { return 3 + *p; } diff --git a/docs/history/15-o3/code/tests/langerrors/const_index.zc b/docs/history/15-o3/code/tests/langerrors/const_index.zc new file mode 100644 index 0000000..03e927b --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/const_index.zc @@ -0,0 +1,2 @@ +// expect: the index is out of range for this array +fn main() { [4]int a; a[4] = 1; return 0; } diff --git a/docs/history/15-o3/code/tests/langerrors/fixed_nolen.zc b/docs/history/15-o3/code/tests/langerrors/fixed_nolen.zc new file mode 100644 index 0000000..b79c31e --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/fixed_nolen.zc @@ -0,0 +1,2 @@ +// expect: a fixed array needs its length +fn main() { fixed []int f = new(fixed []int); free(d*f); return 0; } diff --git a/docs/history/15-o3/code/tests/langerrors/fixed_push.zc b/docs/history/15-o3/code/tests/langerrors/fixed_push.zc new file mode 100644 index 0000000..a19bcb4 --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/fixed_push.zc @@ -0,0 +1,2 @@ +// expect: a fixed array can't grow or shrink +fn main() { fixed []int f = new(fixed []int, 3); push(f, 1); free(d*f); return 0; } diff --git a/docs/history/15-o3/code/tests/langerrors/fixed_to_dyn.zc b/docs/history/15-o3/code/tests/langerrors/fixed_to_dyn.zc new file mode 100644 index 0000000..483f62f --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/fixed_to_dyn.zc @@ -0,0 +1,4 @@ +// expect: type error: argument: expected []int, got fixed []int +typecheck on; +int take([]int.m g) { return len(g); } +fn main() { fixed []int f = new(fixed []int, 3); take(f); free(d*f); return 0; } diff --git a/docs/history/15-o3/code/tests/langerrors/o3_addr.zc b/docs/history/15-o3/code/tests/langerrors/o3_addr.zc new file mode 100644 index 0000000..815253d --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/o3_addr.zc @@ -0,0 +1,2 @@ +// expect: an o3 variable has no address +fn main() { o3 int z = 2; *int q = &z; return *q; } diff --git a/docs/history/15-o3/code/tests/langerrors/o3_asm.zc b/docs/history/15-o3/code/tests/langerrors/o3_asm.zc new file mode 100644 index 0000000..c8afb44 --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/o3_asm.zc @@ -0,0 +1,2 @@ +// expect: asm can't reach an o3 variable +fn main() { o3 int zz = 2; asm { zz @ _ } return 0; } diff --git a/docs/history/15-o3/code/tests/langerrors/o3_let.zc b/docs/history/15-o3/code/tests/langerrors/o3_let.zc new file mode 100644 index 0000000..d2aff9a --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/o3_let.zc @@ -0,0 +1,2 @@ +// expect: o3 variables need a type +fn main() { o3 { let x = 1; x++; } return 0; } diff --git a/docs/history/15-o3/code/tests/langerrors/o3_param.zc b/docs/history/15-o3/code/tests/langerrors/o3_param.zc new file mode 100644 index 0000000..5694720 --- /dev/null +++ b/docs/history/15-o3/code/tests/langerrors/o3_param.zc @@ -0,0 +1,3 @@ +// expect: o3 parameters need a type +o3 int f(x) { return x; } +fn main() { return f(1); } diff --git a/docs/history/15-o3/code/tests/manyerrors.zc b/docs/history/15-o3/code/tests/manyerrors.zc new file mode 100644 index 0000000..f4c0c68 --- /dev/null +++ b/docs/history/15-o3/code/tests/manyerrors.zc @@ -0,0 +1,6 @@ +// several errors in one run: a syntax error, an analyzer error, a type error +typecheck on; +fn f() { let a = ; return 0; } +fn g() { let x = new(3); return 0; } +int h() { *char s = 5; return 1; } +fn main() { return 0 } diff --git a/docs/history/15-o3/code/tests/meta.zc b/docs/history/15-o3/code/tests/meta.zc new file mode 100644 index 0000000..bc89454 --- /dev/null +++ b/docs/history/15-o3/code/tests/meta.zc @@ -0,0 +1,46 @@ +fn ipow(a, b) { let 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() +{ + let 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() +{ + let n, body, i = 0; + next(); n = tv; next(); + body = grab(); + while (i < n) { feed(qdup(body)); i++; } + free(d*body); + 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); + let q = quote { putn(40 + 2); putc(10); return 7; }; + putn(q[0]); putc(' '); + putn(eval(q)); putc(10); + let f = compile(q); + putn(f()); putc(10); + free(d*q); + let defs = quote { fn sq(x) { return x * x; } }; + load(defs); + free(d*defs); + putn(evals("return sq(12);")); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/tests/misc.zc b/docs/history/15-o3/code/tests/misc.zc new file mode 100644 index 0000000..25fc53b --- /dev/null +++ b/docs/history/15-o3/code/tests/misc.zc @@ -0,0 +1,30 @@ +// ct { ... } runs a block while compiling and leaves its result as a constant +immediate fn ct() +{ + let q, v; + next(); + q = grab(); + v = eval(q); + free(d*q); + 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 { let 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() { let p = new(3); p[0] = 'o'; p[1] = 'k'; return p; } diff --git a/docs/history/15-o3/code/tests/o3.zc b/docs/history/15-o3/code/tests/o3.zc new file mode 100644 index 0000000..296d1d5 --- /dev/null +++ b/docs/history/15-o3/code/tests/o3.zc @@ -0,0 +1,83 @@ +// o3 regions: every kind of control flow, against the same code without o3 +struct pt { int x; int y; }; +int g = 3; +int sq(int x) { return x * x; } +o3 int collatz(int n) +{ + int steps = 0; + while (n != 1) { if (n % 2 == 0) n = n / 2; else n = 3 * n + 1; steps++; } + return steps; +} +o3 int ack(int am, int n) +{ + if (am == 0) return n + 1; + if (n == 0) return ack(am - 1, 1); + return ack(am - 1, ack(am, n - 1)); +} +o3 int many(int a, int b, int c) +{ + int dd = a + b, e = b + c, f = c + a, h = dd * e, i2 = e * f, j = f * dd, k = h + i2 + j, l = k / 7; + for (int t = 0; t < 5; t++) { dd += t; e -= t; f = f ^ t; l = l + dd * e - f; } + return dd + e + f + h + i2 + j + k + l; +} +o3 int mix(int n) +{ + int acc = 0; + for (int i = 0; i < n; i++) { + if (i % 3 == 0 && i % 5 == 0) acc += 15; + else if (i % 3 == 0 || i > 90) acc += 3; + else acc = acc + (i & 1 ? sq(i) : g); + switch (i % 4) { case 0: acc += 1; case 1: acc -= 2; default: acc = acc ^ 1; } + if (acc > 100000) break; + if (i == 7) continue; + acc = acc + i / 10 - i % 7 + (i << 2) - (i >> 1); + } + return acc; +} +o3 int dyn(int n) +{ + []int a = new([]int, n); + fixed []int f = new(fixed []int, n); + int s = 0; + for (int i = 0; i < len(a); i++) { a[i] = i * i; f[i] = n - i; } + for (int i = 0; i < n; i++) s = s + a[i] * f[i]; + free(d*a); free(d*f); + return s; +} +o3 int pts(int n) +{ + *pt p = new(pt); + int s = 0; + p->x = 1; p->y = 2; + for (int i = 0; i < n; i++) { p->x = p->x + p->y; p->y = p->x - p->y; s = s + p->x % 1000; } + free(d*p); + return s; +} +o3 int divs(int x) +{ + int s = 0; + for (int i = -50; i < 50; i++) s = s + (x + i) / 7 + (x + i) % 7 + (x - i) / -3 + i / 16 + i % 16; + return s; +} +fn main() +{ + o3 int lone = 2; + let r = 0; + lone = lone * 21; + o3 { + int i = 0, s = 0; + while (i < 100) { s = s + collatz(i + 1); i++; } + putn(s); putc(' '); + putn(lone); putc(' '); + lone++; + } + putn(lone); putc(' '); + putn(ack(2, 3)); putc(' '); + putn(many(1, 2, 3)); putc(' '); + putn(mix(100)); putc(' '); + putn(dyn(50)); putc(' '); + putn(pts(30)); putc(' '); + putn(divs(1000)); putc(' '); + putn(divs(-77)); putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/tests/o3_bounds.zc b/docs/history/15-o3/code/tests/o3_bounds.zc new file mode 100644 index 0000000..fb347c0 --- /dev/null +++ b/docs/history/15-o3/code/tests/o3_bounds.zc @@ -0,0 +1,2 @@ +// an index outside a []T inside o3 code: caught by the inline check +fn main() { []int a = new([]int, 5); o3 { int i = 7; a[i] = 1; } free(d*a); return 0; } diff --git a/docs/history/15-o3/code/tests/overflow_data.zc b/docs/history/15-o3/code/tests/overflow_data.zc new file mode 100644 index 0000000..3042f0a --- /dev/null +++ b/docs/history/15-o3/code/tests/overflow_data.zc @@ -0,0 +1 @@ +fn main() { while (1) asm { 1 } return 0; } diff --git a/docs/history/15-o3/code/tests/overflow_frame.zc b/docs/history/15-o3/code/tests/overflow_frame.zc new file mode 100644 index 0000000..3897bf4 --- /dev/null +++ b/docs/history/15-o3/code/tests/overflow_frame.zc @@ -0,0 +1,2 @@ +fn big(n) { let a[500]; a[0] = n; return big(n + 1) + a[0]; } +fn main() { return big(0); } diff --git a/docs/history/15-o3/code/tests/overflow_return.zc b/docs/history/15-o3/code/tests/overflow_return.zc new file mode 100644 index 0000000..9d5c622 --- /dev/null +++ b/docs/history/15-o3/code/tests/overflow_return.zc @@ -0,0 +1,2 @@ +fn deep(n) { return deep(n + 1) + 1; } +fn main() { return deep(0); } diff --git a/docs/history/15-o3/code/tests/runerr.sh b/docs/history/15-o3/code/tests/runerr.sh new file mode 100755 index 0000000..23ea054 --- /dev/null +++ b/docs/history/15-o3/code/tests/runerr.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# runs every .zc in a folder (tests/errors by default) and checks the compiler +# rejects it with the message on its first line: // expect: ... +vm=${1:-zy}; dir=${2:-$(dirname "$0")/errors}; pass=0; fail=0 +for f in "$dir"/*.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 "rejected: $pass passed, $fail failed" diff --git a/docs/history/15-o3/code/tests/typeerrors/arg.zc b/docs/history/15-o3/code/tests/typeerrors/arg.zc new file mode 100644 index 0000000..909672a --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/arg.zc @@ -0,0 +1,5 @@ +// expect: type error: argument: expected *point, got *int +typecheck on; +struct point { int x, y; }; +int f(*point p) { return p.x; } +fn main() { *int q = new(int); f(q); free(d*q); return 0; } diff --git a/docs/history/15-o3/code/tests/typeerrors/arith.zc b/docs/history/15-o3/code/tests/typeerrors/arith.zc new file mode 100644 index 0000000..76e3111 --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/arith.zc @@ -0,0 +1,3 @@ +// expect: type error: arithmetic needs numbers, got *int +typecheck on; +fn main() { *int p = 0; int x = p * 2; return x; } diff --git a/docs/history/15-o3/code/tests/typeerrors/assign.zc b/docs/history/15-o3/code/tests/typeerrors/assign.zc new file mode 100644 index 0000000..8b8a888 --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/assign.zc @@ -0,0 +1,3 @@ +// expect: type error: initializer: expected *char, got int +typecheck on; +fn main() { *char s = 5; return 0; } diff --git a/docs/history/15-o3/code/tests/typeerrors/call.zc b/docs/history/15-o3/code/tests/typeerrors/call.zc new file mode 100644 index 0000000..7b03dbf --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/call.zc @@ -0,0 +1,3 @@ +// expect: type error: only functions can be called, got int +typecheck on; +fn main() { int k = 3; return k(1); } diff --git a/docs/history/15-o3/code/tests/typeerrors/deref.zc b/docs/history/15-o3/code/tests/typeerrors/deref.zc new file mode 100644 index 0000000..ed030f5 --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/deref.zc @@ -0,0 +1,3 @@ +// expect: type error: only pointers can be dereferenced, got int +typecheck on; +fn main() { int x = 3; return *x; } diff --git a/docs/history/15-o3/code/tests/typeerrors/field.zc b/docs/history/15-o3/code/tests/typeerrors/field.zc new file mode 100644 index 0000000..ba03697 --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/field.zc @@ -0,0 +1,3 @@ +// expect: point has no field z +struct point { int x, y; }; +fn main() { point p; return p.z; } diff --git a/docs/history/15-o3/code/tests/typeerrors/generic.zc b/docs/history/15-o3/code/tests/typeerrors/generic.zc new file mode 100644 index 0000000..6d4c4da --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/generic.zc @@ -0,0 +1,4 @@ +// expect: type error: argument: expected int, got *char +typecheck on; + T same(T a, T b) { return a; } +fn main() { return same(1, "x"); } diff --git a/docs/history/15-o3/code/tests/typeerrors/notstruct.zc b/docs/history/15-o3/code/tests/typeerrors/notstruct.zc new file mode 100644 index 0000000..0dff6bd --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/notstruct.zc @@ -0,0 +1,2 @@ +// expect: .x: that's a int, not a struct or a pointer to one +fn main() { int n = 1; return n.x; } diff --git a/docs/history/15-o3/code/tests/typeerrors/ret.zc b/docs/history/15-o3/code/tests/typeerrors/ret.zc new file mode 100644 index 0000000..be951d5 --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/ret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected bool, got *char +typecheck on; +bool f() { return "no"; } +fn main() { return f(); } diff --git a/docs/history/15-o3/code/tests/typeerrors/voidret.zc b/docs/history/15-o3/code/tests/typeerrors/voidret.zc new file mode 100644 index 0000000..86c9c17 --- /dev/null +++ b/docs/history/15-o3/code/tests/typeerrors/voidret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected void, got int +typecheck on; +void f() { return 3; } +fn main() { f(); return 0; } diff --git a/docs/history/15-o3/code/tests/typeoff.zc b/docs/history/15-o3/code/tests/typeoff.zc new file mode 100644 index 0000000..e44e450 --- /dev/null +++ b/docs/history/15-o3/code/tests/typeoff.zc @@ -0,0 +1,2 @@ +// the typechecker is off unless asked for: this mismatch compiles and runs +fn main() { *char s = 5; putn(s as int + 1); putc(10); return 0; } diff --git a/docs/history/15-o3/code/tests/typeok.zc b/docs/history/15-o3/code/tests/typeok.zc new file mode 100644 index 0000000..2d1997b --- /dev/null +++ b/docs/history/15-o3/code/tests/typeok.zc @@ -0,0 +1,21 @@ +// passes the typechecker: words mix with everything, literal 0 is null, +// arrays decay to pointers, generic calls bind their parameters +typecheck on; +struct pair { A a; B b; }; + *pair.u mk(A x, B y) { *pair p = new(pair); p.a = x; p.b = y; return u*p; } + A left(*pair p) { return p.a; } +int strlen2(*char s) { int n = 0; while (s[n]) n++; return n; } +int main() { + *pair p = mk(3, "four"); + int a = left(p); + *char s = p.b; + [8]char buf; + *char q = buf; + *int nothing = 0; + let w = 5; + int mixed = w + 1; + q[0] = 'h'; q[1] = 0; + putn(a + strlen2(s) + strlen2(buf) + mixed); putc(10); + free(d*p); + return 0; +} diff --git a/docs/history/15-o3/code/tests/types.zc b/docs/history/15-o3/code/tests/types.zc new file mode 100644 index 0000000..3408d10 --- /dev/null +++ b/docs/history/15-o3/code/tests/types.zc @@ -0,0 +1,56 @@ +struct point { int x, y; }; +struct rect { point a, b; int tag; }; +struct list { int len; *T items; }; +struct node { int v; *node next; }; +type num = int; + +int counter = 5; +[4]int squares; +point origin; + +int area(*rect r) { return (r.b.x - r.a.x) * (r.b.y - r.a.y); } + *list.u mklist(int cap) { + *list l = new(list); + l.len = 0; + l.items = new(T, cap) as *T; + return u*l; +} + T first(*list l) { return l.items[0]; } +int sum(*node n) { int s = 0; while (n) { s += n.v; n = n.next; } return s; } + +fn main() +{ + rect r; + r.a.x = 1; r.a.y = 2; r.b.x = 4; r.b.y = 6; + putn(area(&r)); putc(' '); + putn(sizeof(rect)); putc(' '); putn(sizeof(point)); putc(' '); putn(sizeof([3]rect)); putc(' '); + let p = new(point); // let infers *point + p.x = 7; p->y = 8; + putn(p.x * p.y); putc(' '); + free(d*p); + *list l = mklist(4); + l.items[0] = 42; l.len = 1; + putn(first(l)); putc(' '); + free(d*l); + *node a = new(node), b = new(node); + a.v = 3; b.v = 4; a.next = b; + putn(sum(a)); putc(' '); + free(d*a); // b went with it: a.next = b made a its owner + [3]point pts; + pts[2].y = 9; + putn(pts[2].y + counter); putc(' '); + num k = 3; + putn(k); putc(10); + + // reflection + tprint(typeof(r)); putc(' '); tprint(typeof(&r)); putc(' '); tprint(typeof(l)); putc(' '); + tprint(sigof(mklist)); putc(' '); tprint(sigof(first)); putc(' '); tprint(sigofs("free")); putc(10); + let t = typeof(r), i = 0; + while (i < tnfields(t)) { puts(tfname(t, i)); putc(':'); tprint(tftype(t, i)); putc('@'); putn(tfoff(t, i)); putc(' '); i++; } + putc(10); + *point q = new(point); + tprint(typeof_obj(q)); putc(' '); putn(typeof_obj(q) == typeof(point)); putc(' '); putn(tkind(typeof_obj(q)) == TY_STRUCT); + free(d*q); + putc(10); + return 0; +} diff --git a/docs/history/15-o3/code/tests/umd.zc b/docs/history/15-o3/code/tests/umd.zc new file mode 100644 index 0000000..497c9fc --- /dev/null +++ b/docs/history/15-o3/code/tests/umd.zc @@ -0,0 +1,51 @@ +// lists as [len, items...], items owned by the list +.u mklist(n) { + let l = new(n + 1); + l[0] = 0; + return u*l; +} +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn sum(.m l) { let s = 0, i = 1; while (i <= l[0]) { s += l[i][0]; i++; } return s; } +.u box(v) { let b = new(1); b[0] = v; return u*b; } +fn consume(.d b) { return b[0]; } + +fn main() +{ + let base = live_objects(); + { + let l = mklist(8); // u from mklist arrives m*here + let i = 0; + while (i < 5) { + let b = box(i * 10); // m in the loop body + d*b; // 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 + let outer; + { + let t = box(7); + u*t; + outer = t; + } + let v = { let w = box(8); u*w }; + putn(outer[0] + v[0]); putc(' '); + + // d given away to a callee + let g = box(99); + putn(consume(d*g)); putc(' '); + + // containers: child takes its parent's tag + let 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/15-o3/code/tools/build.zc b/docs/history/15-o3/code/tools/build.zc new file mode 100644 index 0000000..a38e97f --- /dev/null +++ b/docs/history/15-o3/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() +{ + let 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/15-o3/code/zc0.c b/docs/history/15-o3/code/zc0.c new file mode 100644 index 0000000..7615cd7 --- /dev/null +++ b/docs/history/15-o3/code/zc0.c @@ -0,0 +1,461 @@ +/* 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 +#include +#include +#include + +#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, K_KW, K_ENH }; +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, ""); 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 if (tk == T_ID && (!strcmp(ts, "u") || !strcmp(ts, "m") || !strcmp(ts, "d"))) { next(); expect("*"); unary(); } /* u*x: a recast, no code */ + 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("let") || 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("let") || 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(int ret) +{ + char *n = ident(); Sym *s; int np = 0, tags = 0, t, 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 (accept(".")) { /* .m name, .d name */ + if (is("m")) t = 1; else if (is("d")) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + if (np < 12) tags += t << (2 * np); + strcpy(pn[np++], ident()); + } while (accept(",")); + expect(")"); + } + 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; +} +/* enhance name(params) [-> n] micro "recipe"; or ... vm { asm }; + emits the install descriptor; the booted genome installs it */ +static int nenh; +static void enhdef(void) +{ + char *n, pn[8][64]; int np = 0, nout = 1, d, na, pay, len = 0, i, j; Sym *s; + if (tk == T_NUM) { nout = tv; next(); } /* enhance 2 name(...) */ + n = ident(); + expect("("); + if (!accept(")")) { do { if (np == 8) die("at most 8 inputs"); strcpy(pn[np++], ident()); } while (accept(",")); expect(")"); } + d = here; for (i = 0; i < 7; i++) emit(0); + na = here; for (i = 0; i < np; i++) emit(0); + for (i = 0; i < np; i++) { img[na + i - GORG] = here; for (j = 0; pn[i][j]; j++) emit((unsigned char)pn[i][j]); emit(0); } + if (accept("micro")) { pay = here; while (tk == T_STR) { for (j = 0; ts[j]; j++) emit((unsigned char)ts[j]); next(); } emit(0); } + else if (accept("vm")) { pay = here; asmblock(); op(O_RET); len = here - pay; img[d + 1 - GORG] = 1; } + else die("expected micro or vm"); + img[d - GORG] = nenh; img[d + 2 - GORG] = np; img[d + 3 - GORG] = nout; + img[d + 4 - GORG] = pay; img[d + 5 - GORG] = len; img[d + 6 - GORG] = na; + s = add(n, K_ENH, nenh++); s->sig = np + nout * 16 + d * 256; + expect(";"); +} +static void top(void) +{ + while (tk != T_EOF) { + if (accept("unchecked")) continue; + if (accept("fn")) { fndef(0); continue; } + if (accept(".")) { if (strcmp(ident(), "u")) die("the only return tag is .u"); fndef(1); continue; } /* .u name(...) */ + if (accept("const")) { do { char *n = ident(); expect("="); add(n, K_CONST, cexpr()); } while (accept(",")); expect(";"); continue; } + if (accept("enhance")) { enhdef(); continue; } + if (accept("let") || 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; +} diff --git a/docs/history/15-o3/notes.md b/docs/history/15-o3/notes.md new file mode 100644 index 0000000..c18d50b --- /dev/null +++ b/docs/history/15-o3/notes.md @@ -0,0 +1,49 @@ +# o3, growable arrays, c-style return types + +code/ next to this file is the tree at the end of this stage. + +## message 15 + +> write some really cool examples for this language + +> no, wdym building a fresh vm?? just pocs 😭 we already have a compiler and everything + +the examples (mandel, bf, dump, tree, lang, staged, quine, life). "building a fresh vm" in my progress note only meant compiling core.c into a binary to run them. no snapshot of its own: they're all in this stage's code. + +## message 16 + +> add opt keywords, for example `optim` (or o3, i prefer o3 as the keyword) will cause any vars in a scope to not assign heap type metadata, compiles with opt level o3 and is immediately compiled down to native, and when used with variables they must be always typed and it reduces the perf cost for accessing or modifying them, etc etc. add a `fixed` keyword which says that an array has a fixed size and cannot be resized, etc + +answers: functions, blocks and single vars; a real optimizing tier; give up type stamps, zero-filling, the address of o3 vars, stack and frame checks; c-like return types instead of `->`; growable arrays too. + +## working notes + +order of work: return syntax first (it touches every test), then arrays, then o3 in the compiler, then the core. + +**return types.** `topitem` reads a type and a name, then decides between function and global by whether `(` follows. `fn name(` stays the untyped form. generics moved to a `` prefix, because `T first(...)` would need the type parameter before it's declared. fn types became `int(int, int)`: `ptype()` takes a postfix parameter list after any type. the prescan looks for `NAME (` ... `)` followed by `{` or `;`, carrying a pending `.u`. + +**arrays.** a `[]T` is a 4-word handle `[len, cap, items, element size]` that owns `items`. growing copies into a new items object and moves the children's owner fields over. `fixed` is a flag on the same type record (TY_DYN, `t[3]`), so `fixed []T` and `[]T` are different hash-consed types and compat allows fixed <- growable but not the reverse. + +**o3, compiler side.** the region is the code range plus the frame slots of its typed scalar locals. a function region starts after the prologue's parameter stores, at a `jmp` to the next word, so the cpu enters it through dispatch. it ends where the epilogue starts, so `return` is a jump out. block regions are queued and installed when the function ends, since a `return` inside the block is still a hole until the epilogue exists. ltag bit 16 marks o3 variables (the tag itself is the low 4 bits). + +first bug: `t = t + a[j]` with the bounds check in the middle. the address of `t` was pushed before the right-hand side, crossed the check's branch on the memory stack, and the store in the next block went to the frame instead of the register. fixed in the compiler: assignment to an o3 variable in o3 code drops the address, evaluates the value, and only then pushes the address. compound assignment the same way. the lifter also refuses any block that would leave a register variable's address on the stack, so the same mistake can't come back silently. + +**o3, core side.** blocks start at the region's start, at literal jump targets, after a `jz` and after a call. the leader pass walks from the start, so inline strings (jumped over) never get lifted. per block, the lifter runs the vm code symbolically: a value table keyed by stack offset from the entry top, lazily loading entry words (SLD), and `fp + k` is tracked so loads and stores to promoted slots become variable reads and writes. what's left on the stack at the end, minus words still holding what they held at entry, gets stored. var 0 is the frame pointer, read once at entry. it never changes inside a region, since a store to the frame pointer word ends the block. + +arm64: vars in w0..w7, temps from w8..w14 and w26..w28 (x26..x28 now saved by the enter stub), x15..x17 scratch, constants have no register. the end of a block does the stack stores, moves the condition to w17, adjusts x20, and resolves the var moves as a parallel move (a cycle parks one value in w16). exits spill the vars to the frame and go through x_disp, so the stack checks still run between regions and normal code. stores check the coverage byte and call the hook with x0..x15 saved on the native stack. + +llvm: vars as allocas, one basic block per region block, a switch on the entry index, O3 pipeline. most of the speed comes from mem2reg and llvm's loop passes once there's no stack traffic. + +second bug, not o3's: the region's coverage byte made a stray store visible. a store of 10 into address 16 of the first function, every time a growable array was freed. `release` set the container's flags to 0 (free) before releasing its children, and a child whose buddy was the container then merged into it and unlinked it from a free list it wasn't on, writing through its data words. the fix is a third state (2, going) during release. the bug had been there since the buddy allocator; lists just rarely had a child adjacent to its parent. + +**literal specialization.** with `lfa(k)` as an enhancement for single o3 variables in normal code, the plain jit emitted `li k; push; pop; li ZFP; ld with range check; add`, no better than the 4 vm ops. so the jit now looks for literals feeding an enhancement's last inputs, re-runs the optimizer with them as constants, and folds constant addresses and small addends into instructions. `x / 7` in ordinary code got the multiply-high sequence from this too. + +**numbers** (bench.sh, ms per run, start-up removed by taking the slope between 1 and n runs): + +``` +interp collatz 309.63 -> 209.87 sieve 45.58 -> 15.95 digits 191.32 -> 92.29 fib 6.70 -> 5.50 +llvm collatz 27.69 -> 3.48 sieve 17.32 -> 0.17 digits 24.72 -> 1.60 fib 1.82 -> 0.84 +arm64 (qemu) collatz 327.33 -> 16.78 sieve 90.23 -> 3.85 digits 147.67 -> 3.46 fib 22.62 -> 5.73 +``` + +left for later: direct calls between regions, picking promoted vars by use count, caching a fixed array's length and items, cross-block optimization in the core's own optimizer, o3 inside images. diff --git a/docs/history/17-o3-boundaries/code/README.md b/docs/history/17-o3-boundaries/code/README.md new file mode 100644 index 0000000..7b91935 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/README.md @@ -0,0 +1,528 @@ +# 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, compiled through llvm on other hosts if you build with it, or interpreted. 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, and 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. types are a compiler primitive, with structs, generics, reflection and an optional typechecker. a program can also wire up to 512 custom opcodes into the cpu (virtual enhancements), which the jits inline as native code. and code marked `o3` skips the stack machine: the core compiles it as a whole region, with its variables in registers. + +this folder has the latest code. `history/` is the scrapbook: notes for every stage, plus frozen code from the stages that still have it. + +## files + +`core.c` is the native core and the only native code at runtime: the arm64 jit, the llvm backend (behind `-DZYLLVM`), the portable interpreter, the enhancement unit (recipe parser, vm-code lifter, optimizer and lowering) and the o3 region compiler. `src/rt.zc` is the runtime (i/o, the native division enhancements, 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` 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 the small ones (hello, factorial, echo, self-patching code, an owning list, a repl, a typed program, an enhancement demo) and some bigger proofs of concept: + +- `mandel.zc`: the mandelbrot set in 16.16 fixed point, with the fixed-point multiply wired in as a custom opcode. +- `bf.zc`: a brainfuck compiler. it turns brainfuck into zc source, has the resident compiler compile it, and runs it (native code on the jit). it takes a program after a backtick, or runs hello world. +- `dump.zc`: prints any heap struct, nested ones included, with no printing code, by walking its type through reflection. +- `tree.zc`: a binary search tree whose nodes own their children. there's no `free` anywhere, and the live object count drops back to 0 when the root's block ends. +- `lang.zc`: grows the language while it compiles: a `|>` pipe operator (one table entry, since on a stack machine it's just `call`), `unless`, an `assert` that knows its source line, and `times n { }`. +- `staged.zc`: writes a polynomial as source with its coefficients baked in, compiles it while running, and finds it by name. +- `quine.zc`: prints its own source. +- `life.zc`: conway's life on a typed 2d board, with a glider wrapping around a torus. +- `primes.zc`: an o3 sieve over a fixed array, the primes gathered into a growable one, then twin primes and the widest gap. + +`tests/` has feature tests, `tests/errors/` (programs the lifetime analyzer has to reject), `tests/typeerrors/` (programs the typechecker has to reject) and `tests/langerrors/` (o3 and array misuse). each of those starts with the message it expects, and `tests/runerr.sh` runs a folder of them. `test.sh` does the whole bootstrap and runs everything on all three backends. `bench.sh` times o3 against plain code on each backend. `history/` is the scrapbook. + +## build + +``` +cc -O2 core.c io_linux.c -o zy # io_linux.c provides Q, G and J +./zy `). `ZYNOLLVM=1` turns the llvm tier off. with `ZYTRACE=1`, `ZYO3DUMP=1` also prints every o3 block's micro-ops. + +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, on every backend. + +## zc, the language + +it reads like c. underneath every value is a 32 bit word and memory is word addressed, so `p + 1` is the next word whatever `p` points at, and strings are one char per word with a 0 at the end. types are optional: untyped code is typed `word`, which goes with anything. + +``` +const N = 10; +[N]int table; // a global array +int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +fn main() { + for (int i = 0; i < N; i++) table[i] = fib(i); + let sq = { let t = table[5]; t * t }; // a block is an expression too, its last line is its value + let x = asm { 2 3 + }; // raw vm code, leaves one value + putn(sq + x); putc(10); + return 0; +} +``` + +declarations are c-style, type first: `int a = 1, b;`, `*node p = new(node);`, `[4]char buf;`, `point origin;`. `let` declares without a type: it infers pointer, struct and function types from the initializer and keeps numbers as plain words, and `let a[10];` is an untyped array. statements are declarations, `if`/`else`, `while`, `for`, `switch`, `break`, `continue`, `return`, `{ }` blocks, `asm { }` and expressions. `switch (e) { case 1, 2: ... default: ... }` takes constant labels, and its cases don't fall through: each ends where the next begins, and `break` leaves early. operators are c's with c's precedence, including `c ? a : b`, plus `p.x` and `p->x` (the same thing: `.` goes through a pointer on its own), `e as T` to change a type without changing the bits, and the casts below. comparisons and `&& ||` give 0 or 1. `/`, `%` and `<<` compile to native enhancement opcodes. character literals, `0x` hex and the usual escapes are there. + +functions are declared like c, return type first: `int f(int x)`, `*node.u make()`, `.u grab()` (a tag on its own), `void log(*char s)`. `fn f(a, b)` is the untyped form, returning a word. a generic function lists its type parameters after its name, `T first(*list l)`, the same place a call gives explicit ones, `first(l)`. the return type can use them before they're declared: while it's read, an unknown name is taken as a type parameter, and the list after the name has to confirm it. function types are written the same way, `int(int, *char)`, and `fn(int)` for one that returns a word. the earlier `fn f(...) -> T` spelling is gone. + +arrays come in three kinds. `[n]T` has its size in the type and lives in place. `[]T` is a growable array: a small handle object that owns its items, made with `new([]T)` or `new([]T, n)`, indexed with a bounds check, and changed with `push(a, x)`, `pop(a)` and `resize(a, n)`. `len(a)` works on both (for `[n]T` it's the constant) and `cap(a)` gives the room before the next grow. `fixed []T` is a `[]T` that can't change size: `new(fixed []T, n)` needs the length, and `push`, `pop` and `resize` on it are compile errors. a `fixed []T` can't be passed where a `[]T` is expected, the other way round is fine, and a constant index outside a `[n]T` is caught at compile time. the items belong to the array, so freeing it frees them, and objects stored into a `[]*T` are its children like any container's. + +a unit is read whole and scanned for function signatures before it compiles, so calls can come before definitions, tags included, and prototypes are optional. `main` runs after the whole program has compiled. every function returns one word, 0 if it falls off the end. + +builtins from the runtime: `putc`, `getc`, `eof`, `puts`, `putn`, `halt`, `strlen`, `streq`, `wcopy`, `wfill`, `new`, `new_t`, `new_raw`, `free`, `gc`, `isobj`, `osize`, `typeof_obj`, `live_objects`, `install`, `zdiv`, `zmod`, `zshl`. + +## memory model: u, m and d + +`new(n)` or `new(T)` gives back a fresh object. 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. a tag is written after the type, `*node.u p`, or alone, `.d x`. `u`, `m` and `d` are reserved words. + +**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, 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. the first time it's handed to a lower scope its life here is over: passing it to a `.d` parameter, 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. it has to leave this block for the one above, where it arrives as m. it leaves through `return` (the function's return type has to carry `.u`, like `*node.u make()` or just `.u make()`), as the value of a block expression, or by assignment to a variable of the directly enclosing block. letting it fall out of scope, or throwing away a u result, is an error. + +recasting is multiplication by the tag: `u*x`, `d*x`, `m*x`. it 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 declaration can carry a tag too, `.u r;`, and then whatever lands in it gets that tag. + +parameters: an untagged parameter is m from the caller's side, a lend, and the callee sees a plain word. `.m` makes it a checked borrow: the callee can read and write it but can't free it, return it, recast it or store it anywhere. `.d` hands the object over, and it arrives as m. + +``` +*int.u box(int v) { *int b = new(int); *b = v; return u*b; } +fn add(*list l, *int.d item) { l.items[l.len] = d*item; l.len++; return 0; } +``` + +containers own what you store in them. `p[i] = c` or `p.f = 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 gives the child away: it's dead here afterwards, and the caller's object owns it. 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 `d*`, and the mark-sweep collector takes it over. a fresh object can go straight in. + +where paths join (after an `if`, a loop, a `switch` or `?:`) every variable has to be in the same state on every path that reaches the join, with one exception. a variable that became d, or was given away, on some path is dead afterwards, and the compiler frees it on the paths where it's still alive, on their way in. a loop's exit state is the join of its `break`s and its normal exit, so giving something away and breaking is fine. what a loop can't do is give something away on a path that comes back around to the top, since the next pass would use it dead. a u object doesn't get the dead treatment: it still has to leave. + +### the analyzer + +it runs inside the compiler on every function, including code compiled at runtime by `eval` and friends, and reports each violation with a line number and the variable's name. the compiler keeps going after errors, up to 20: a syntax error skips to the next `;` or `}` (or the next top-level declaration), and analyzer and type errors just get reported, since the parse is still in step. a unit with errors doesn't run. `tests/errors/` has one small program per rule. 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 what it allocates belongs to the collector, and checked variables can't be touched from inside an unchecked block. + +## types + +types are a compiler primitive. the compiler keeps them as records in a type area at 0x9C000, hash-consed so the same type is always the same pointer. they stay in memory after compiling, so programs and parse words can look at them. + +``` +struct point { int x, y; }; +struct list { int len; *T items; }; +type num = int; +T first(*list l) { return l.items[0]; } +*list.u mk(int cap) { *list l = new(list); l.items = new(T, cap); return u*l; } +... +*list<*point> ps = mk<*point>(8); // explicit type arguments, or inferred from the arguments +``` + +the kinds are `word`, `int`, `char`, `bool`, `void`, pointers `*T`, arrays `[n]T`, `[]T` and `fixed []T`, function types `int(int, *char)`, structs, generic structs and generic functions. structs and arrays live in place (in a frame, a global or inside another struct), and their value is their address, so they're passed around by pointer. `sizeof` counts words. type arguments have to be one word (a number, a pointer or another parameter), so a generic function is compiled once and works for every instance. indexing scales by the element's size, while plain pointer arithmetic stays in words, like b. `new(T)` and `new(T, n)` stamp the type into the object's header. + +### reflection + +`typeof(e)` and `typeof(T)` give a type record and `sizeof(...)` its size. both work on any expression, which is compiled dry and never runs. at runtime: `tkind(t)` (one of the `TY_` constants), `tsize`, `tname`, `tlen`, `tnfields`, `tfname(t, i)`, `tftype`, `tfoff`, `tret`, `tnparams`, `tparam`, `tparamtag` (the u/m/d tag of a parameter), `tretu`, `tnargs` and `targ` for generic instances, and `tprint(t)`. `sigof(f)` gives the type of a function by address (untyped ones get a signature built from their arity and tags), `sigofs("name")` by name, and `typeof_obj(p)` reads the type stamped on a heap object (0 for an o3 object that hasn't been fattened yet). + +### the typechecker + +off by default. `typecheck on;` turns it on for what follows and `typecheck off;` turns it back off (a parse word can flip `tc_on`). it checks initializers, assignments, arguments (unifying generic parameters), return values, arithmetic, comparisons, dereferencing, indexing and calls. `word` matches anything, numbers mix with each other, a literal 0 is a null pointer, and arrays decay to pointers. it stops at the first error, printing what it expected and what it got. `tests/typeerrors/` has one per rule. some things are checked whatever the setting, because the compiler needs them to generate code: field names, and field access on something that isn't a struct. + +## virtual enhancements + +the cpu has room for 512 custom opcodes (22 to 533), and opcode 21 (`%` in asm) installs one at runtime. it's the closest a soft cpu gets to rewiring itself. an enhancement takes up to 8 inputs off the data stack and leaves up to 8 outputs, and it's written one of two ways: + +``` +enhance clamp(x, lo, hi) micro "x = max x lo; x = min x hi"; +enhance 2 divmod(a, b) micro "r2 = sdiv a b; r1 = srem a b; r0 = r2"; // the number is how many outputs +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // can't be lifted (it does i/o), so calls use the fallback +``` + +a micro recipe works on registers `r0`..`r15`, which the inputs arrive in (also under the parameter names), and the outputs leave from `r0` up. the micro-ops are `li mov add sub mul sdiv udiv srem urem and or xor shl shr sar neg not lt ltu eq ne min max minu maxu mulhs mulhu clz abs sel ld st`. a `vm` body is straight-line vm code that gets lifted by running it symbolically. both turn into ssa, and the core's optimizer folds constants, simplifies algebra, removes common subexpressions and dead code, and turns division by a constant into a multiply-high sequence (`ZYTRACE=1` prints the result). the arm64 jit then inlines the code at every use with registers allocated, the llvm backend inlines it as ir, and the interpreter runs the optimized list. if something doesn't fit in registers, the jit calls the interpreter for that op. when literals feed an enhancement's last inputs (`x / 7` is `x 7 idiv`), the arm64 jit specializes that use on them: the literals become constants, the optimizer runs again, and `x / 7` turns into a multiply-high and two shifts instead of a divide. + +an enhancement is called like a function when it has one output, or by name from asm. `enhance` installs at compile time, so the wiring is there before `main` runs, and a parse word can use it right away. an image installs its own enhancements when it boots, from its symbol table. that's how `/`, `%` and `<<` work: `rt.zc` declares `idiv`, `imod` and `ishl` as one-instruction recipes. `install(desc)` is the raw interface, and its descriptor format is documented in `core.c`. stores done by an enhancement don't invalidate compiled code, so use them for data. + +this replaces my first plan for enhancements, which compiled c or llvm ir sources at runtime. part of that reply got stopped by a safety check, and once it turned out llvm was meant for portability, it moved into the backend below instead. + +## o3 + +`o3` marks code for the optimizing tier. it goes on a function, a block or a single variable: + +``` +o3 int sum(fixed []int a) { int s = 0; for (int i = 0; i < len(a); i++) s += a[i]; return s; } +fn main() { + o3 int hits = 0; // one o3 variable + o3 { for (int i = 0; i < 1000; i++) if (i % 7 == 3) hits++; } + ... +} +``` + +what it gives up, as asked: variables declared in o3 code must be typed (`let` and untyped parameters are errors), they have no address (`&x` and naming one from `asm` are errors), `new` in o3 code returns raw memory with no type stamp and no zero fill (`new_raw`), and an o3 function skips the frame stack check in its prologue. what it gets: the compiler hands each o3 function body and each o3 block to the core as a region (install kind 2: the range of vm words plus its typed scalar variables' frame slots, each with a register), and the core compiles the region right away. the cpu has 7 registers for variables. a variable takes the one most recently freed by a scope that closed, or the next unused one, so loop counters in sibling loops share a register, and a variable declared when all 7 are busy stays in memory. a register shared by several slots gets written back to all of them when the region exits, and they never hold different live values, since their scopes don't overlap. + +inside the core, a region is cut into basic blocks at jump targets, branch fallthroughs and call return points. each block is lifted to ssa the way enhancements are: the vm stack becomes values, and only what's still on it at the end of the block is written to memory. the frame pointer and the promoted slots become variables that live in registers across the whole region, so `i++` on an o3 int is one add. enhancements are spliced into the block, so `/`, `%` and `<<` become one instruction or a magic-number sequence. every block then goes through the same optimizer (folding, algebra, cse, dce, division by constants). in o3 code `a[i]` on a `[]T` is compiled inline with its bounds check (`outside(i, len)`, one enhancement), and `len(a)` is a load. a `fixed []T` in an o3 variable does better: its items pointer and length can't change, so the compiler gives it two hidden o3 variables holding them. they're loaded when the region starts and whenever the array variable is assigned, so indexing is a compare against a register and an indexed load, with no loads through the handle. + +the backends: on arm64 the region becomes one piece of native code. variables sit in w0..w7, block values in w8..w14 and w26..w28, constants are folded into instructions where they fit, loads from a fixed address are one `ldr`, and blocks branch to each other directly with no dispatch and no stack checks. on the llvm build the region becomes one function, with the variables in allocas that mem2reg turns into ssa across blocks, and it goes through llvm's O3 pipeline. on the plain interpreter, a small region interpreter runs the optimized blocks with the variables in locals. + +calls, returns, jumps out of the region, i/o, `install`, a store to the frame pointer and anything else a block can't lift all leave the region: the variables are written back to the frame first, so outside code sees ordinary memory. a call's return point is an entry, which loads them again. stores inside a region still check the coverage map, so writing to compiled code works, and a store into the region's own code drops it (it lifts again at its next entry). to keep variable addresses from waiting on the stack across a branch, assignment to an o3 variable in o3 code evaluates the value first and the address after. the lifter refuses a block that would leave such an address on the stack, rather than miscompile it. single o3 variables outside o3 code are reached through `lfa(k)`, an enhancement for `fp + k`, which the arm64 jit specializes into a load and an add. + +`bench.sh` runs four kernels from `tests/bench.zc` with and without `o3`. milliseconds per run, with start-up and compile time removed by timing 1 run against enough runs to take more than a second (arm64 is under qemu on an x86 host, so only its ratios mean much, and the machine was noisy enough that the small numbers move by 20% between runs): + +``` +backend kernel plain ms o3 ms speedup +interp collatz 324.90 240.61 1.4x +interp sieve 47.08 21.71 2.2x +interp digits 160.89 100.82 1.6x +interp fib 3.48 4.09 0.8x +llvm collatz 47.03 3.34 14.1x +llvm sieve 10.77 0.28 38.9x +llvm digits 18.93 1.45 13.1x +llvm fib 0.87 1.01 0.9x +arm64 (qemu) collatz 323.89 13.04 24.8x +arm64 (qemu) sieve 56.84 1.74 32.6x +arm64 (qemu) digits 147.06 4.17 35.3x +arm64 (qemu) fib 5.19 5.71 0.9x +``` + +fib gains nothing and can lose a little, since every call leaves the region through the dispatcher and comes back in through an entry stub, which costs about what the body saves. + +### leaving o3: fattening + +going into o3 is free: o3 code reads normal objects the same way and ignores their metadata. coming out is where the work is, since an object made by `new` in o3 code has no type stamp and garbage after what was asked for. `new_raw` keeps one hint for later: the header's type word holds -(n + 1), the number of words asked for, so the object stays recognizably raw and its real size is known. + +the compiler fattens at the points where o3 data reaches code that expects the metadata, using the static type it knows there: storing a pointer anywhere other than an o3 variable (a normal local, a global, a field, an element), passing one to a function that isn't o3 (`free` excepted), returning one from o3 code, `push` into a growable array, and, at the end of an o3 block, whatever the o3 variables declared outside it hold. `fatten(p, t)` (in the compiler, so it can read type records) stamps the type, as `[0]T` when more than one element was asked for, zeroes the slack, and then follows every typed pointer, field, array element and growable array element inside, fattening what it finds. objects that are already fat stop the walk, so building a list in o3 costs one stamp per node, and a depth limit of 32 stops cycles through growable arrays. untyped words carry no hint, so pointers kept in `word` variables stay raw until typed code sees them. + +## the llvm backend + +a tiered jit for hosts the arm64 backend doesn't cover. the interpreter counts how often each block start gets reached, and a hot block is translated to llvm ir using the same block rules as the arm64 jit: it ends at call, jump, ret or halt, keeps going past a jz, and literal targets are fused. the ir goes through the O2 pipeline and gets compiled by orc's lljit. stores into compiled words drop the blocks covering them, like on arm64. it pays off for long-running code: a loop-and-recursion benchmark runs about 3.3x faster than the interpreter. short bursty work like the self-compile is slower, since compile time dominates there. `ZYHOT=1` compiles every block, which is a good stress test, and the test suite runs that way too. + +## the heap + +0x40000 to 0x9BFFF, managed by a buddy allocator. the heap is split into aligned power-of-two chunks, every block is a power of two words, and a freed block merges with its buddy whenever that one is free too, so freed space can be reused at any size. (stage 15 fixed a bug here: `release` marked a container free before freeing its children, so a child whose buddy was the container merged into it while the container was still being freed, and corrupted a free list. growable arrays hit it every time, since a handle and its items are often buddies.) allocation finds the smallest free block that fits and splits it down. free blocks sit on a doubly linked list per class, so taking a buddy off its list during a merge is constant time. checked code frees deterministically. under that runs a mark-sweep collector, conservative and non-moving, which handles globals, unchecked code and anything given to it. it runs on `gc()`, which returns how many objects it freed, or when an allocation doesn't fit. the sweep frees through the same merging path. + +## code as data + +the compiler is in memory with your program and every name in it is callable. + +`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, enhancement names emit their opcode, and other names push the address of a variable or function. + +`quote { ... }` is a token list as a fresh object: `[n, kind, value, line, kind, value, line, ...]`, so errors inside a macro expansion point at the line the tokens came from, where names, strings and operators are interned pointers (`intern("while")` gets one). `tokens(s)` makes one from a string, and `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)` runs `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()`, `peek()` and `peekat(k)` (up to 4 tokens ahead), `tk`/`tv` (current token kind and value), `expect`, `accept`, `expr()`, `stmt()`, `substmt()`, `ptype()`, `emit`, `lit`, `op`, `hole`/`setlit` for jumps, and `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` partway through a 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 both. `mnem` is the asm mnemonic table, `q@!$_~cjzr,?.+-*&|^><%`, and can be rewritten. + +## the bootstrap + +`zc0.c` compiles the subset `compiler.zc` uses (no analyzer, types, quote, parse words or block expressions, but it does lay out `enhance` declarations) into a first genome. that genome compiles `compiler.zc` again on the vm. that's where the real compiler, the analyzer and native division first meet their own source, and `compiler.zc` passes its own lifetime checks. the result compiles itself into identical words, on all three backends, and that's the `genome.h` that ships (84118 words). an image build (`build_image(org, dst)`) compiles with only the image's own names visible (plus keywords and builtin types), writes code meant for one address into another, and appends a symbol table so the booted genome knows its own names and enhancements. + +## the instruction set + +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 21 % install +2 ! store 7 j jump 12 . out (G) 17 | or 22..533 enhancements +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, `c` and `j` take their target from the stack, and `%` is `(descriptor -- status)`. there's still no div or mod in the base set, because a divider can't finish in one cycle in hardware. an enhancement can add one. + +## memory map and abi + +memory is 1m (1048576) words. it could grow until the host runs out (literals already reach 1g words), but that would mean reserving the jit tables with mmap instead of static arrays, and 1m is plenty for now. + +``` +0x00000.. the program: code, with globals between functions +0x40000..0x9BFFF heap +0x9C000..0x9FFFF type records +0xA0000 frame pointer word +0xA0100..0xBFFFF 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. heap objects have a 6 word header: size, size class, flags, a check word, owner, type. + +## 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, install hook, enhancement fallback). o3 regions also use x26..x28, which the entry stub saves. + +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 dispatch stub that checks both stack pointers against their limits (kept in x24 and x25), bounds-checks the target, loads `tab[t]`, and branches straight to it when it's already compiled. otherwise it returns to c, which compiles the block and re-enters. enhancements are inlined: inputs load from the data stack into w0..w15, the optimized micro-ops run in registers with x16 and x17 as scratch, and the outputs go back. an install calls into c and then returns to the loop, which flushes every translation, since code built before the install may have inlined the old version. a flush drops o3 regions too, and they lift again on their next entry. when the loop reaches an o3 entry point, it compiles the region (or reuses it) instead of translating a block. + +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. + +the stacks are checked. the data and return stacks are checked at every block exit on all three backends, so the cost is a couple of compares per block rather than per push. a block pushes at most about 1024 words, which the data stack limit leaves room for. overflowing either one stops the cpu with `zy: data stack overflow` or `zy: return stack overflow`. the frame stack is checked in every function prologue, which resets the frame pointer and stops with `zy: frame stack overflow`. + +platform: the darwin path uses `MAP_JIT`, `pthread_jit_write_protect_np` and `sys_icache_invalidate`. linux uses rwx mmap and `__builtin___clear_cache`. only linux arm64 has actually been run, under qemu. the darwin path follows apple's documented recipe but hasn't been tested, and under the hardened runtime it also needs the allow-jit entitlement. every host shares the same semantics: shift counts wrap at 32, stores outside memory are ignored, loads outside memory read 0, and jumping outside memory or to an unwired opcode halts. + +## test results + +`test.sh` passes all 131 checks on x86-64 linux: the fixpoint, an up-to-date `genome.h`, and then every example and feature test on the interpreter, on the arm64 jit under qemu, and on the llvm backend, all with identical output. it also covers joins and fixup frees (with a leak count), `switch` and `?:`, the buddy allocator, several errors in one run, all three stack overflows, growable and fixed arrays, and `tests/o3.zc` (loops, recursion, calls inside loops, `switch`, `&& ||`, structs through pointers, arrays, division by constants, and a function with more variables than registers), whose output matches the same file with `o3` taken out, register sharing between scopes with a cached fixed array, and fattening (a list returned from o3 typed all the way down, a struct assigned out of an o3 block and its pointer field). it checks that every o3 region in that test lifts, and gets compiled on the jit and on llvm, that the o3 bounds check fires, and that all 22 programs in `tests/errors/`, all 10 in `tests/typeerrors/` and all 9 in `tests/langerrors/` get rejected with the expected message on each backend, that llvm agrees when it compiles every block, and that the self-compile matches byte for byte on all three. separately, 80000 random divisions through enhancements matched the software routine, covering divide by zero, INT_MIN/-1, negatives and the magic-number path for constants. + +## open ends + +fixed in stage 13 (details in `history/13-gap-fixes`): branch and loop joins, free lists that never merged (now a buddy allocator), missing stack checks, stopping at the first error, macro line numbers, required prototypes, `d*` for storing into borrowed objects, `**` declarations, and `?:` and `switch`. still open: + +**untracked aliases.** the analyzer only follows bare variable names, so `let q = p + 0;` or `let c = list[1];` is a plain word nobody tracks, and it dangles once the owner is freed. two cheap fixes, and they combine well. at runtime: don't reuse a freed block right away. `free` would put it on a quarantine list, and the collector's next sweep only releases quarantined blocks that no word points at. the conservative mark already finds such words, so that's maybe 30 lines in rt.zc. a stale alias then reads a dead but intact block, and a second free through it is a no-op, because the header's flags say free. at compile time: now that there are types, a pointer-typed value computed from a tracked variable (`p + k`, `p.field`, `p[i]` when the element is a pointer) can carry a "borrowed from p" mark into the local it's stored in. using that local after `p` dies becomes an error. that's the same machinery children already use. + +**the conservative collector.** it scans the whole data stack region, because the vm can't read its own stack pointer, and stale words keep garbage alive a little longer. the fix is one base opcode that pushes the data stack depth, which is trivial in hardware since the register already exists. then the collector scans only the live part. zeroing a frame in the prologue would do the same for the frame stack, at a few words per call. + +**coarse invalidation.** a store to a covered word rescans every block, and an install flushes everything. three fixes, in order of payoff. first, index blocks by page (say 64 words): a covered store only looks at the blocks touching its page, and dropping a block only rebuilds the coverage bytes for that block. second, record which enhancement slots each translation inlines, so an install only drops those. third, on llvm, give each block its own resource tracker, so dropped code actually gets freed. + +**automatic tiering.** o3 is the explicit version of what you asked about in message 14. doing it without the keyword means a run counter per block (about 4 instructions per block entry) and, for a hot loop, finding its region and its variables without the compiler's help. the hard part is the variables: o3 can keep them in registers because the compiler promises nothing takes their address, and code without that promise would need the lifter to prove it. + +**o3's own gaps.** calls always leave the region through the dispatcher, so call-heavy code gains nothing (fib above). a direct call from one compiled region into another, with the variables spilled only for the slots the callee can't see, would fix most of that. a value that stays on the vm stack across a branch (like an index across its bounds check) goes through memory, since blocks only share variables. the core's own optimizer works one block at a time (no loop-invariant motion or cross-block cse); llvm does that on its build. regions aren't built into images, so `rt.zc` and the compiler can't use o3. and o3 code that rewrites its own region sees the change at the next entry, not right away. + +**generics are erased.** a generic function is compiled once, so the type stamped by `new(T)` inside it says `T`, and type arguments have to be one word. + +**the rest.** the prescan only knows tags, not types, so a call to a typed function that's defined further down gets `word` as its result type until the definition shows up. the llvm backend compiles one module per block, so it warms up slowly. stores done by enhancements don't invalidate compiled code. a parse word that changes the syntax can confuse the prescan. it only records signatures, though, and a real definition always overrides what the prescan guessed. + +--- + +## 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 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/`. + +### 11 + +> progress report? +> add types please :) +> mostly as a compiler primitive though, plus type-inspection via reflection +> and a small optional typechecker (default off) +> oh and keep the stuff you write as a history scrapbook +> if it helps, add a path to the hardware which is called "virtual enhancements", and allows up to 512 custom operations to be compiled down via jit into hardware-level speeds and interoped directly into a fast path in the vm to become essentially custom wiring. useful for division and other stuff as a dynamic runtime path + +my answers to the clarifying questions, exactly: + +> types: words + structs + generics +> +> reflection: runtime type of heap objects, function signatures, typeof at compile time +> +> how an enhancement is defined: either actual C or llvm ir code or vm code or micro-ops passed through an optimizer. since for example, micro-ops and vm code are not sufficient for optimizing things like division +> +> scrapbook: notes + code snapshots + +**summary:** the progress report said the previous round was finished and shipped. i then laid out a plan where the core would compile c or llvm ir enhancement sources at runtime with the host toolchain and load the result. part of that reply was stopped by a safety check before it finished, so i stopped and checked in instead of building it. + +### 12 + +> also make the umd syntax like `type.u name`, and casting is multiplication `u*name` +> ideally i'd prefer memory to be unlimited words growing until system oom, but 1m is fine +> core.c plain interp is also nice +> zc0.c own file is fine +> i mentioned llvm for portability to non-arm targets +> yes, d object semantic that was intended +> u object hands up one block and becomes an m, that's fine. the code can make it a u or a d or whatever +> explain your gaps more +> +> wait why safety check? what's wrong with that + +my answers to the clarifying questions, exactly: + +> declarations: c-style, var -> let +> +> tags on untyped values and the names u, m, d: names reserved, bare .u allowed, untype is m by default +> +> llvm: llvm jit backend (Recommended) + +**summary:** on the safety check: nothing was wrong with the request. my best guess was that it tripped on the plan for a program inside the vm handing source text to the system compiler and loading the result into the running process, since that pattern also shows up in malware. with llvm meant for portability, that path wasn't needed. the gaps got the longer explanations that are now under open ends above. then the round itself: + +**syntax.** declarations are c-style (`int x`, `*node.m p`), `let` replaces `var` for untyped and inferred declarations, tags are `.u .m .d` after the type or on their own, recasts are `u*x` / `d*x` / `m*x`, `u m d` are reserved, and an untagged parameter counts as an m lend. + +**types.** a compiler primitive: hash-consed records with structs, generic structs and functions, fixed arrays, function types, `typeof`/`sizeof`, `as` casts and a reflection api, with object headers carrying their type. the typechecker is off by default and turned on with `typecheck on;`. + +**virtual enhancements.** opcode 21 installs, 22 to 533 are the slots. micro-op recipes and lifted vm code go through an optimizer in the core (folding, cse, dce, multiply-high division by constants) and get inlined by both jits. the language's own `/ % <<` now run on them. + +**backends.** a tiered llvm backend (`-DZYLLVM`) for non-arm hosts. + +**bootstrap and history.** it still reaches its fixpoint on all three backends. `history/` holds notes for every stage and code from stages 7, 10 and this one (in 11-types-enhancements). + +### 13 + +> gaps +> 1. when there's a var state change to d, mark that var as dead by default for any other scope that can access it afterwards. u is fine since it just returns +> 2. any suggestions for a cheap fix? +> 3. it's fine, rare occurrence (probably?), suggest a fix +> 4. fix that +> 5. suggest a fix +> 6. fix +> 7. fix + +**summary:** the numbers followed the gap list from my previous chat message. here's what each one got. + +**1. joins.** a variable that became d, or was given away, on any path is dead after the join, and fixup code frees it on the paths that still own it. a loop's exit state is the join of its breaks and its normal exit. giving something away on a path that loops back is still an error. u and borrows don't get the dead treatment. + +**2, 3 and 5.** suggestions only, now under open ends: a quarantine on reuse plus "borrowed from" marks on pointer-typed values for aliases, a stack-depth opcode for the collector, and page-indexed invalidation plus per-slot install tracking for the jit. + +**4. heap.** a buddy allocator. + +**6. stack checks.** all three stacks are checked: data and return at every block exit on all backends, and frames in every prologue. + +**7. the small stuff.** error recovery with up to 20 reported errors, line numbers carried in token lists, a signature prescan over the whole unit so prototypes are optional, storing into a borrowed object moving the object automatically, `?:`, and go-style `switch`. on the side, a 4-token lookahead fixed `**` declarations. + +### 14 + +> how costly is it if we add a counter to each block to see how many times it runs, then run the optimizer on it if it's a hot path? + +> continue + +**summary:** answered without building anything. about 4 instructions per block entry while a block is being counted, and nothing once its optimized translation replaces it. the optimizing pass would reuse the enhancement lifter, optimizer and register allocator. lifting whole blocks would need jz side exits and barriers at calls and i/o. compiling a block that way takes microseconds, against milliseconds for llvm, and keeping values in registers instead of the memory stack likely gives 2 to 4x on tight loops. it's listed under open ends. then the gap fixes continued. + +### 15 + +> write some really cool examples for this language + +> no, wdym building a fresh vm?? just pocs 😭 we already have a compiler and everything + +**summary:** my progress note had said "building a fresh vm", which only meant compiling core.c into a binary to run the examples. eight proofs of concept went into `examples/`: mandel, bf, dump, tree, lang, staged, quine and life, each described under files above and checked by `test.sh` on all three backends. + +### 16 + +> add opt keywords, for example `optim` (or o3, i prefer o3 as the keyword) will cause any vars in a scope to not assign heap type metadata, compiles with opt level o3 and is immediately compiled down to native, and when used with variables they must be always typed and it reduces the perf cost for accessing or modifying them, etc etc. add a `fixed` keyword which says that an array has a fixed size and cannot be resized, etc + +my answers to the clarifying questions, exactly: + +> where o3 goes: functions, blocks and single vars +> +> how far o3 goes: real optimizing tier (Recommended) +> +> what o3 code may give up: type stamps on objects, zero-filling new objects, the address of o3 vars, stack and frame checks, also i don't like the -> return type syntax. please replace it with the c-like syntax +> +> arrays: add growable arrays too (Recommended) + +**summary:** three things changed. + +**return types.** functions are declared c-style now, `int f(int x)`, `*node.u make()`, with fn types written `int(int, *char)`. `->` is gone from the compiler, zc0, the tests and the examples. + +**arrays.** `[]T` grows (`push`, `pop`, `resize`, `len`, `cap`), and `fixed []T` can't change size after `new(fixed []T, n)`. both are bounds-checked. `[n]T` stays as it was, plus a compile-time check for constant indexes. + +**o3.** on functions, blocks and single variables, with the trade-offs you picked, and a real optimizing tier in the core, described in the o3 section above. it compiles at install time on arm64 and llvm and has a region interpreter for the plain build. measured gains are 1.5 to 2.8x on the interpreter, 8 to 100x on llvm and 20 to 43x on arm64 (under qemu) for loop-heavy kernels, and much less for call-heavy ones. on the way, the arm64 jit learned to specialize an enhancement on literal inputs, so `x / 7` is a multiply-high everywhere, not only in o3 code. tests for arrays and o3 turned up an old heap bug: freeing a container could merge one of its children into it while it was still being freed, which corrupted a free list. growable arrays hit it every time. it's fixed. + +### 17 + +> generics should go after fn name and before parens +> we also need some machinery for converting values to/from o3. to is pretty easy, we just hand over the data, and o3 ignores the fat metadata. from is a bit harder, there needs to be a system to get type hints and fatten the metadata for the packed data +> variables just get the latest free register, it's fine for now +> add the fixed array once per region thing +> +> also if you have any tips on how to make the memory system better (aka avoiding gc and leaks/uaf as much as possible) do tell + +**summary:** generics went back after the name, `T first(...)`, with the return type allowed to use them before the list declares them. o3 got fattening on the way out (the section above): `new_raw` keeps the requested size in the type word, and the compiler calls `fatten` with the static type wherever o3 data reaches normal code. registers now follow scopes, so a closed scope's register goes to the next variable. fixed arrays in o3 variables keep their items and length in two hidden register variables. the memory tips were answered in chat, not built. diff --git a/docs/history/17-o3-boundaries/code/bench.sh b/docs/history/17-o3-boundaries/code/bench.sh new file mode 100755 index 0000000..b1f268c --- /dev/null +++ b/docs/history/17-o3-boundaries/code/bench.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# o3 against plain code: each kernel in tests/bench.zc on each backend, with +# the time to start up and compile (the 'z' run) taken off. needs bc. +cd "$(dirname "$0")"; T=$(mktemp -d); trap 'rm -rf $T' EXIT +gcc -O2 -w -DJTYPE=int core.c io_linux.c -o $T/zy +vms=("$T/zy"); names=("interp") +if command -v llvm-config >/dev/null; then + gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c -o $T/zyl $(llvm-config --ldflags --libs) && { vms+=("$T/zyl"); names+=("llvm"); } +fi +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 && { vms+=("qemu-aarch64 $T/zyj"); names+=("arm64 (qemu)"); } +fi +# seconds per run of kernel $2 on vm $1: the slope between $3 runs and 1 run, +# best of three each, so starting up and compiling cancel out +t(){ local s e; s=$(date +%s.%N); (cat tests/bench.zc; printf '`%s%s' $2 $3) | $1 >/dev/null; e=$(date +%s.%N); echo "$e - $s" | bc; } +best(){ local b=999 x i; for i in 1 2 3; do x=$(t "$1" $2 $3); b=$(echo "if ($x < $b) $x else $b" | bc); done; echo $b; } +# grows the run count until the difference is at least a second, so the noise +# of starting up is small next to it +per(){ + local one n=4 many + one=$(best "$1" $2 1) + while :; do + many=$(best "$1" $2 $n) + if [ "$(echo "$many - $one > 1" | bc)" = 1 ] || [ $n -ge 4096 ]; then break; fi + n=$((n * 4)) + done + echo "scale=6; ($many - $one) / ($n - 1)" | bc +} +printf "%-14s %-8s %10s %10s %8s\n" backend kernel "plain ms" "o3 ms" speedup +for i in "${!vms[@]}"; do + for k in "collatz a b" "sieve c d" "digits e f" "fib g h"; do + set -- $k + p=$(per "${vms[$i]}" $2); o=$(per "${vms[$i]}" $3) + printf "%-14s %-8s %10.2f %10.2f %7.1fx\n" "${names[$i]}" $1 $(echo "$p * 1000" | bc) $(echo "$o * 1000" | bc) $(echo "scale=2; $p / $o" | bc) + done +done diff --git a/docs/history/17-o3-boundaries/code/core.c b/docs/history/17-o3-boundaries/code/core.c new file mode 100644 index 0000000..7f4aa33 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/core.c @@ -0,0 +1,2030 @@ +/* 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 +#include +#include +#if defined(__aarch64__) && !defined(ZYINTERP) +#define ZYJIT 1 +#include +#ifdef __APPLE__ +#include +#include +#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 DSLIM (0xFC000 + 1100) /* data stack overflows below this (a block pushes at most ~1024) */ +#define RSLIM (0xF8000 - 8) /* return stack overflows above this */ +/* why the cpu stopped, when it wasn't a halt */ +static int stopped(int p) +{ + if (p == MW + 1) { fprintf(stderr, "zy: data stack overflow\n"); return 2; } + if (p == MW + 2) { fprintf(stderr, "zy: return stack overflow\n"); return 2; } + return 0; +} +#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; + +/* ---- virtual enhancements ---- + up to 512 custom opcodes (22 .. 533), wired in at runtime by the install + opcode (21). an enhancement is a short program over native micro-ops, + written either as a recipe (text) or as straight-line vm code that gets + lifted. both become ssa, go through the optimizer below, and then run in + the interpreter or get inlined by the jit as native code. */ +#define NENH 512 +#define XOP0 22 +enum { U_LI, U_MOV, U_ADD, U_SUB, U_MUL, U_SDIV, U_UDIV, U_SREM, U_UREM, U_AND, U_OR, U_XOR, + U_SHL, U_SHR, U_SAR, U_NEG, U_NOT, U_LT, U_LTU, U_EQ, U_NE, U_MIN, U_MAX, U_MINU, U_MAXU, + U_MULHS, U_MULHU, U_CLZ, U_ABS, U_SEL, U_LD, U_ST, U_N }; +static const char *unames[U_N] = { "li", "mov", "add", "sub", "mul", "sdiv", "udiv", "srem", "urem", + "and", "or", "xor", "shl", "shr", "sar", "neg", "not", "lt", "ltu", "eq", "ne", "min", "max", + "minu", "maxu", "mulhs", "mulhu", "clz", "abs", "sel", "ld", "st" }; +static const signed char uarity[U_N] = { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2 }; +typedef struct { int op, d, a, b, c, imm; } Uop; /* ssa: d is a fresh value, a b c are values */ +typedef struct { + int live, kind, nin, nout, n, nv, out[8]; + Uop *u; + signed char *reg; /* physical register per value, for the jit; 0 if it didn't fit */ +} Enh; +static Enh enh[NENH]; +static int need_flush; + +#define MAXUOP 4096 +static Uop ub[MAXUOP]; static int un, unv, uerr; /* the program being built */ +static int unew(int op, int a, int b, int c, int imm) +{ + Uop *u; + if (un >= MAXUOP) { uerr = -5; return 0; } + u = &ub[un++]; u->op = op; u->d = unv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + return u->d; +} +static int mread(int a) { return (unsigned)a < MW ? m[a] : 0; } + +/* recipe text: one statement per line or per ';' + r0 = sdiv r0 r1 dst = op operands, operands are rN, parameter names or numbers + r2 = r0 a copy, or a number + st r1 r0 memory[r1] = r0 + inputs arrive in r0.. (and under the parameter names), outputs leave from r0.. */ +static int parse_recipe(int src, int names, int nin, int nout, int *out) +{ + int cur[16], i, p = src, n, k, op, args[3], na, dst, isst; + char tok[8][32]; int nt; + for (i = 0; i < 16; i++) cur[i] = i < nin ? i : -1; + for (;;) { + /* read one statement into tokens */ + nt = 0; + for (;;) { + int c = mread(p); + while (c == ' ' || c == '\t' || c == '\r') c = mread(++p); + if (!c || c == '\n' || c == ';') break; + if (c == '=') { if (nt < 8) strcpy(tok[nt++], "="); p++; continue; } + n = 0; + while (c && c != ' ' && c != '\t' && c != '\n' && c != ';' && c != '=' && c != '\r') { if (n < 31) tok[nt < 8 ? nt : 7][n++] = (char)c; c = mread(++p); } + if (nt < 8) tok[nt++][n] = 0; + } + if (nt) { + isst = !strcmp(tok[0], "st"); + if (!isst && (nt < 3 || strcmp(tok[1], "="))) return -2; + /* destination register */ + dst = -1; + if (!isst) { + if (tok[0][0] == 'r' && tok[0][1] >= '0' && tok[0][1] <= '9') dst = atoi(tok[0] + 1); + else for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)tok[0][j]) j++; + if (!mread(s + j) && !tok[0][j]) dst = i; + } + if (dst < 0 || dst > 15) return -2; + } + k = isst ? 1 : 2; /* first token after "=" (or after st) */ + op = -1; + if (!isst && nt > 3) { for (i = 0; i < U_N; i++) if (!strcmp(tok[k], unames[i])) op = i; if (op < 0) return -2; k++; } + if (isst) op = U_ST; + na = 0; + for (; k < nt; k++) { + char *t = tok[k], *e; int v = -1; + if (na >= 3) return -2; + if (t[0] == 'r' && t[1] >= '0' && t[1] <= '9') { int r = atoi(t + 1); if (r > 15) return -2; if (cur[r] < 0) cur[r] = unew(U_LI, 0, 0, 0, 0); v = cur[r]; } + else if ((t[0] >= '0' && t[0] <= '9') || t[0] == '-') { long x = strtol(t, &e, 0); if (*e) return -2; v = unew(U_LI, 0, 0, 0, (int)x); } + else { + for (i = 0; i < nin && names; i++) { + int s = mread(names + i), j = 0; + while (mread(s + j) && mread(s + j) == (unsigned char)t[j]) j++; + if (!mread(s + j) && !t[j]) v = cur[i] < 0 ? (cur[i] = unew(U_LI, 0, 0, 0, 0)) : cur[i]; + } + if (v < 0) return -2; + } + args[na++] = v; + } + if (op < 0) { /* x = y */ + if (na != 1) return -2; + cur[dst] = args[0]; + } else { + if (na != (op == U_LI ? 0 : uarity[op])) { + if (!(op == U_LI && na == 1)) return -2; + } + if (op == U_LI) cur[dst] = args[0]; + else if (op == U_ST) unew(U_ST, args[0], args[1], 0, 0); + else cur[dst] = unew(op, args[0], na > 1 ? args[1] : 0, na > 2 ? args[2] : 0, 0); + } + if (uerr) return uerr; + } + if (!mread(p)) break; + p++; + } + for (i = 0; i < nout; i++) { if (cur[i] < 0) cur[i] = unew(U_LI, 0, 0, 0, 0); out[i] = cur[i]; } + return uerr; +} + +/* straight-line vm code from addr up to its ret, run symbolically */ +static int lift_vm(int a, int len, int nin, int nout, int *out) +{ + int st[256], sp = 0, i, w, k, x, y; + for (i = 0; i < nin; i++) st[sp++] = i; + for (i = 0; i < len; i++) { + w = mread(a + i); + if (w & 1) { if (sp >= 256) return -4; st[sp++] = unew(U_LI, 0, 0, 0, w >> 1); continue; } + k = w / 2; + if (k == 9) break; + switch (k) { + case 1: if (sp < 1) return -4; st[sp - 1] = unew(U_LD, st[sp - 1], 0, 0, 0); break; + case 2: if (sp < 2) return -4; unew(U_ST, st[sp - 1], st[sp - 2], 0, 0); sp -= 2; break; + case 3: /* pick needs a constant index */ + if (sp < 1) return -4; + x = st[sp - 1]; + if (x < nin) return -4; + { int j; for (j = 0; j < un && ub[j].d != x; j++); if (j == un || ub[j].op != U_LI) return -4; y = ub[j].imm; } + if (y < 0 || y >= sp - 1) return -4; + st[sp - 1] = st[sp - 2 - y]; + break; + case 4: if (sp < 1) return -4; sp--; break; + case 5: if (sp < 2) return -4; x = st[sp - 1]; st[sp - 1] = st[sp - 2]; st[sp - 2] = x; break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: { + static const int map[] = { U_ADD, U_SUB, U_MUL, U_AND, U_OR, U_XOR, U_SAR, U_LT }; + if (sp < 2) return -4; + x = st[sp - 1]; y = st[sp - 2]; sp -= 2; + st[sp++] = unew(map[k - 13], y, x, 0, 0); + break; } + default: return -4; /* control flow, i/o and other enhancements don't lift */ + } + if (uerr) return uerr; + } + if (sp != nout) return -4; + for (i = 0; i < nout; i++) out[i] = st[i]; + return uerr; +} + +/* ---- the optimizer ---- + one forward pass of copy propagation, constant folding, algebraic + simplification, division by constants (the multiply-high trick) and + common subexpression elimination, then dead code removal. */ +static int ev(int op, int a, int b, int c) +{ + unsigned ua = (unsigned)a, ub_ = (unsigned)b; + switch (op) { + case U_ADD: return (int)(ua + ub_); + case U_SUB: return (int)(ua - ub_); + case U_MUL: return (int)(ua * ub_); + case U_SDIV: return b == 0 ? 0 : (a == (int)0x80000000 && b == -1) ? a : a / b; + case U_UDIV: return b == 0 ? 0 : (int)(ua / ub_); + case U_SREM: return b == 0 ? a : (a == (int)0x80000000 && b == -1) ? 0 : a % b; + case U_UREM: return b == 0 ? a : (int)(ua % ub_); + case U_AND: return a & b; + case U_OR: return a | b; + case U_XOR: return a ^ b; + case U_SHL: return (int)(ua << (b & 31)); + case U_SHR: return (int)(ua >> (b & 31)); + case U_SAR: return a >> (b & 31); + case U_NEG: return (int)(0u - ua); + case U_NOT: return ~a; + case U_LT: return a < b; + case U_LTU: return ua < ub_; + case U_EQ: return a == b; + case U_NE: return a != b; + case U_MIN: return a < b ? a : b; + case U_MAX: return a > b ? a : b; + case U_MINU: return ua < ub_ ? a : b; + case U_MAXU: return ua > ub_ ? a : b; + case U_MULHS: return (int)(((long long)a * (long long)b) >> 32); + case U_MULHU: return (int)(((unsigned long long)ua * ub_) >> 32); + case U_CLZ: { int n = 0; if (!ua) return 32; while (!(ua & 0x80000000u)) { ua <<= 1; n++; } return n; } + case U_ABS: return a < 0 ? (int)(0u - ua) : a; + case U_SEL: return a ? b : c; + } + return 0; +} +static void smagic(int d, int *mul, int *sh) /* hacker's delight, signed */ +{ + const unsigned two31 = 0x80000000u; + unsigned ad = d < 0 ? 0u - (unsigned)d : (unsigned)d, t = two31 + ((unsigned)d >> 31); + unsigned anc = t - 1 - t % ad, q1 = two31 / anc, r1 = two31 - q1 * anc, q2 = two31 / ad, r2 = two31 - q2 * ad, delta; + int p = 31; + do { + p++; + q1 *= 2; r1 *= 2; if (r1 >= anc) { q1++; r1 -= anc; } + q2 *= 2; r2 *= 2; if (r2 >= ad) { q2++; r2 -= ad; } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + *mul = (int)(q2 + 1); if (d < 0) *mul = -*mul; + *sh = p - 32; +} +static void umagic(unsigned d, unsigned *mul, int *add, int *sh) /* hacker's delight, unsigned */ +{ + unsigned nc = 0xFFFFFFFFu - (0u - d) % d, q1, r1, q2, r2, delta; + int p = 31; + *add = 0; + q1 = 0x80000000u / nc; r1 = 0x80000000u - q1 * nc; + q2 = 0x7FFFFFFFu / d; r2 = 0x7FFFFFFFu - q2 * d; + do { + p++; + if (r1 >= nc - r1) { q1 = 2 * q1 + 1; r1 = 2 * r1 - nc; } else { q1 = 2 * q1; r1 = 2 * r1; } + if (r2 + 1 >= d - r2) { if (q2 >= 0x7FFFFFFFu) *add = 1; q2 = 2 * q2 + 1; r2 = 2 * r2 + 1 - d; } + else { if (q2 >= 0x80000000u) *add = 1; q2 = 2 * q2; r2 = 2 * r2 + 1; } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + *mul = q2 + 1; *sh = p - 32; +} + +static Uop ob[MAXUOP]; static int on, onv; +static int *omap, *isk, *kv; /* old value -> new value; constness of new values */ +static int pure(int op) { return op != U_LD && op != U_ST; } +static int ispow2(unsigned x) { return x && !(x & (x - 1)); } +static int lg2(unsigned x) { int n = 0; while (x > 1) { x >>= 1; n++; } return n; } +static int oe(int op, int a, int b, int c, int imm); +static int K(int v) { return oe(U_LI, 0, 0, 0, v); } +static int raw(int op, int a, int b, int c, int imm) +{ + Uop *u; int i; + if (pure(op)) /* cse */ + for (i = 0; i < on; i++) { + u = &ob[i]; + if (u->op == op && u->a == a && u->b == b && u->c == c && u->imm == imm) return u->d; + } + if (on >= MAXUOP) { uerr = -5; return 0; } + u = &ob[on++]; u->op = op; u->d = onv++; u->a = a; u->b = b; u->c = c; u->imm = imm; + isk[u->d] = op == U_LI; kv[u->d] = imm; + return u->d; +} +static int sdivk(int a, int d) /* a / d for a constant d, no divide instruction */ +{ + int mul, sh, q, t; + if (d == 1) return a; + if (d == -1) return oe(U_NEG, a, 0, 0, 0); + if (d == (int)0x80000000) return oe(U_EQ, a, K(d), 0, 0); + if (ispow2((unsigned)(d < 0 ? -d : d))) { + int k = lg2((unsigned)(d < 0 ? -d : d)); + t = oe(U_SAR, a, K(31), 0, 0); + t = oe(U_SHR, t, K(32 - k), 0, 0); + q = oe(U_SAR, oe(U_ADD, a, t, 0, 0), K(k), 0, 0); + return d < 0 ? oe(U_NEG, q, 0, 0, 0) : q; + } + smagic(d, &mul, &sh); + q = oe(U_MULHS, a, K(mul), 0, 0); + if (d > 0 && mul < 0) q = oe(U_ADD, q, a, 0, 0); + if (d < 0 && mul > 0) q = oe(U_SUB, q, a, 0, 0); + if (sh) q = oe(U_SAR, q, K(sh), 0, 0); + return oe(U_ADD, q, oe(U_SHR, q, K(31), 0, 0), 0, 0); +} +static int udivk(int a, unsigned d) +{ + unsigned mul; int add, sh, t; + if (d == 1) return a; + if (ispow2(d)) return oe(U_SHR, a, K(lg2(d)), 0, 0); + if (d > 0x80000000u) return oe(U_XOR, oe(U_LTU, a, K((int)d), 0, 0), K(1), 0, 0); /* a >= d */ + umagic(d, &mul, &add, &sh); + t = oe(U_MULHU, a, K((int)mul), 0, 0); + if (!add) return sh ? oe(U_SHR, t, K(sh), 0, 0) : t; + t = oe(U_ADD, oe(U_SHR, oe(U_SUB, a, t, 0, 0), K(1), 0, 0), t, 0, 0); + return sh > 1 ? oe(U_SHR, t, K(sh - 1), 0, 0) : t; +} +static int oe(int op, int a, int b, int c, int imm) +{ + int ka, kb, A, B; + if (op == U_LI) return raw(U_LI, 0, 0, 0, imm); + if (op == U_MOV) return a; + if (op == U_LD || op == U_ST) return raw(op, a, b, 0, 0); + ka = isk[a]; kb = uarity[op] > 1 && isk[b]; + A = kv[a]; B = kv[b]; + /* everything constant: fold */ + if (ka && (uarity[op] < 2 || kb) && (uarity[op] < 3 || isk[c])) return K(ev(op, A, B, kv[c])); + /* constants go right for commutative ops */ + if (ka && !kb && (op == U_ADD || op == U_MUL || op == U_AND || op == U_OR || op == U_XOR || op == U_EQ || op == U_NE || + op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU || op == U_MULHS || op == U_MULHU)) { + int t = a; a = b; b = t; kb = 1; B = A; ka = 0; + } + if (op == U_SEL && ka) return A ? b : c; + if (op == U_SEL && b == c) return b; + if (kb) switch (op) { + case U_ADD: case U_SUB: case U_OR: case U_XOR: case U_SHL: case U_SHR: case U_SAR: + if (!B || (op >= U_SHL && op <= U_SAR && !(B & 31))) return a; + break; + case U_MUL: + if (B == 0) return K(0); + if (B == 1) return a; + if (B == -1) return oe(U_NEG, a, 0, 0, 0); + if (ispow2((unsigned)B)) return oe(U_SHL, a, K(lg2((unsigned)B)), 0, 0); + break; + case U_AND: if (B == 0) return K(0); if (B == -1) return a; break; + case U_SDIV: if (B == 0) return K(0); return sdivk(a, B); + case U_SREM: if (B == 0) return a; if (B == 1 || B == -1) return K(0); + return oe(U_SUB, a, oe(U_MUL, sdivk(a, B), b, 0, 0), 0, 0); + case U_UDIV: if (B == 0) return K(0); return udivk(a, (unsigned)B); + case U_UREM: if (B == 0) return a; + if (ispow2((unsigned)B)) return oe(U_AND, a, K(B - 1), 0, 0); + return oe(U_SUB, a, oe(U_MUL, udivk(a, (unsigned)B), b, 0, 0), 0, 0); + } + if (a == b && uarity[op] == 2) { + if (op == U_SUB || op == U_XOR || op == U_LT || op == U_LTU || op == U_NE) return K(0); + if (op == U_AND || op == U_OR || op == U_MIN || op == U_MAX || op == U_MINU || op == U_MAXU) return a; + if (op == U_EQ) return K(1); + } + return raw(op, a, b, c, 0); +} +/* runs the optimizer over ub[0..un) with nin inputs; leaves the result in e */ +static int optimize(Enh *e, int nin, int *out, int nout) +{ + int i, *live, n = 0; + static int omap_[MAXUOP + 16], isk_[MAXUOP * 4], kv_[MAXUOP * 4]; + omap = omap_; isk = isk_; kv = kv_; + on = 0; onv = nin; + for (i = 0; i < nin; i++) { omap[i] = i; isk[i] = 0; } + for (i = 0; i < un && !uerr; i++) { + Uop *u = &ub[i]; + int a = uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD ? omap[u->a] : 0; + int b = uarity[u->op] > 1 || u->op == U_ST ? omap[u->b] : 0; + int c = uarity[u->op] > 2 ? omap[u->c] : 0; + if (u->op == U_ST) oe(U_ST, a, b, 0, 0); + else omap[u->d] = oe(u->op, a, b, c, u->imm); + } + if (uerr) return uerr; + /* dead code: outputs and stores are live */ + live = calloc(onv + 1, sizeof *live); + for (i = 0; i < nout; i++) { e->out[i] = omap[out[i]]; live[e->out[i]] = 1; } + for (i = on; i--;) { + Uop *u = &ob[i]; + if (u->op != U_ST && !live[u->d]) { u->op = -1; continue; } + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) live[u->a] = 1; + if (uarity[u->op] > 1 || u->op == U_ST) live[u->b] = 1; + if (uarity[u->op] > 2) live[u->c] = 1; + } + free(live); + e->u = malloc((on + 1) * sizeof(Uop)); + for (i = 0; i < on; i++) if (ob[i].op >= 0) e->u[n++] = ob[i]; + e->n = n; e->nv = onv; e->nin = nin; e->nout = nout; + return 0; +} +/* run an installed enhancement on a downward-growing stack; returns the new top */ +static int *xexec(Enh *e, int *sp) +{ + int vb[256], *v = e->nv <= 256 ? vb : malloc(e->nv * sizeof(int)), i, j; + for (j = 0; j < e->nin; j++) v[j] = sp[e->nin - 1 - j]; + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + switch (u->op) { + case U_LI: v[u->d] = u->imm; break; + case U_LD: v[u->d] = mread(v[u->a]); break; + case U_ST: if ((unsigned)v[u->a] < MW) m[v[u->a]] = v[u->b]; break; + default: v[u->d] = ev(u->op, v[u->a], v[u->b], v[u->c]); + } + } + sp += e->nin - e->nout; + for (j = 0; j < e->nout; j++) sp[e->nout - 1 - j] = v[e->out[j]]; + if (v != vb) free(v); + return sp; +} +static void xdump(int slot, Enh *e) +{ + int i; + fprintf(stderr, "enh %d: %d in, %d out, %d ops\n", slot, e->nin, e->nout, e->n); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (u->op == U_ST) fprintf(stderr, " st v%d v%d\n", u->a, u->b); + else if (u->op == U_LI) fprintf(stderr, " v%d = %d\n", u->d, u->imm); + else { fprintf(stderr, " v%d = %s v%d", u->d, unames[u->op], u->a); if (uarity[u->op] > 1) fprintf(stderr, " v%d", u->b); if (uarity[u->op] > 2) fprintf(stderr, " v%d", u->c); fprintf(stderr, "\n"); } + } + for (i = 0; i < e->nout; i++) fprintf(stderr, " out%d = v%d\n", i, e->out[i]); +} +/* registers for the jit: values live in w0..w15, straight-line linear scan. + if they don't fit, reg stays 0 and the jit calls the interpreter instead. */ +static void regalloc(Enh *e) +{ + int *last = malloc(e->nv * sizeof(int)), i, j, k, fr = 0xffff; + signed char *r = malloc(e->nv); + for (i = 0; i < e->nv; i++) { last[i] = -2; r[i] = -1; } + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) last[u->a] = i; + if (uarity[u->op] > 1 || u->op == U_ST) last[u->b] = i; + if (uarity[u->op] > 2) last[u->c] = i; + } + for (i = 0; i < e->nout; i++) last[e->out[i]] = e->n; +#define TAKE(v) do { for (k = 0; k < 16 && !(fr >> k & 1); k++); if (k == 16) goto fail; fr &= ~(1 << k); r[v] = (signed char)k; } while (0) + for (j = 0; j < e->nin; j++) if (last[j] >= -1 && last[j] != -2) TAKE(j); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; int ops[3], no = 0; + if (uarity[u->op] > 0 || u->op == U_ST || u->op == U_LD) ops[no++] = u->a; + if (uarity[u->op] > 1 || u->op == U_ST) ops[no++] = u->b; + if (uarity[u->op] > 2) ops[no++] = u->c; + for (j = 0; j < no; j++) if (last[ops[j]] == i && r[ops[j]] >= 0 && (fr >> r[ops[j]] & 1) == 0) fr |= 1 << r[ops[j]]; + if (u->op != U_ST) TAKE(u->d); + if (u->op != U_ST && last[u->d] == -2) fr |= 1 << r[u->d]; /* never used */ + } +#undef TAKE + free(last); e->reg = r; return; +fail: + free(last); free(r); e->reg = 0; +} +/* the install opcode. descriptor: slot, kind (0 recipe, 1 vm code), inputs, + outputs, payload address, payload length, parameter names (or 0). kind 2 + is an o3 region (below). + returns 0, or -1 bad descriptor, -2 recipe syntax, -4 code doesn't lift, + -5 too big. */ +static int o3install(int d); +static int install(int d) +{ + int slot = mread(d), kind = mread(d + 1), nin = mread(d + 2), nout = mread(d + 3); + int pay = mread(d + 4), len = mread(d + 5), names = mread(d + 6), out[8], r; + Enh ne; + if (kind == 2) return o3install(d); + if ((unsigned)slot >= NENH || (unsigned)nin > 8 || (unsigned)nout > 8 || (kind != 0 && kind != 1)) return -1; + un = 0; unv = nin; uerr = 0; + r = kind == 0 ? parse_recipe(pay, names, nin, nout, out) : lift_vm(pay, len, nin, nout, out); + if (r) { if (trace) fprintf(stderr, "enh %d: install failed (%d)\n", slot, r); return r; } + memset(&ne, 0, sizeof ne); + if ((r = optimize(&ne, nin, out, nout))) return r; + ne.kind = kind; ne.live = 1; + regalloc(&ne); + if (enh[slot].live) { free(enh[slot].u); free(enh[slot].reg); } + enh[slot] = ne; + need_flush = 1; + if (trace) xdump(slot, &enh[slot]); + return 0; +} + +/* ---- o3: optimized regions ---- + o3 code comes from the compiler as a region: a range [lo, hi) of vm words + plus the frame slots that nothing takes the address of, each with one of 7 + registers (install kind 2: [-, 2, lo, hi, n, slot, register, ...]). the region is cut into basic blocks. each + block is lifted to ssa: the vm stack is tracked symbolically, so only what + is left on it at the end of the block touches memory, the slots live in + registers across blocks (VGET reads one at block entry, the block's end + says what each one holds now), the frame pointer is var 0, and enhancements + are spliced in. every block then goes through the optimizer above. a + backend compiles the whole region at once: arm64, llvm at O3, or the + region interpreter below. the region is entered at lo and at the return + points of its calls. a register can stand for several slots (variables + whose scopes don't overlap), and spilling writes it to all of them. calls, + returns, jumps out, and anything a block can't + lift leave it: the slots go back to the frame first, so the code outside + sees the usual memory. stores to its own code drop it; it lifts again on + its next entry. */ +#define ZFP 0xA0000 /* the frame pointer word */ +#define U_VGET U_N /* a var at block entry; imm = var */ +#define U_SLD (U_N + 1) /* the stack word at offset imm from the top at block entry */ +#define RMAXV 8 +#define RMAXE 256 +enum { T_BR, T_CBR, T_JMP, T_CALL, T_RET }; +typedef struct { + int a, n, nv, delta, nso, term, cv, s1, s2, x1, x2; + int vs[RMAXV]; /* each var's value at the end, -1 if unchanged */ + int *so; /* stack words to write at the end: offset, value */ + Uop *u; +} RB; +typedef struct { + int idx, lo, hi, nv, slot[RMAXV], lifted, dead, nonat, nb, ne, maxnv; + int np, ps[32], pv[32]; /* frame slot -> var; vars in scopes that never overlap share one */ + int ent[RMAXE], entb[RMAXE]; + RB *b; + void *nat, *stub[RMAXE]; /* the backend's code */ +} Rg; +#define MAXRG 4096 +static Rg *rgs[MAXRG]; +static int nrg; +static unsigned short o3ent[MW]; /* region + 1 at an entry point */ +static unsigned char o3ei[MW]; /* which of its entries */ +static void rforget(Rg *R); /* the backend drops its code */ +static void rmark(Rg *R); /* the backend watches the region's words */ +static void rcompile(Rg *R, int eager); + +static int nargs(int op) { return op >= U_N ? 0 : uarity[op]; } +static void rclear(Rg *R) +{ + int b; + rforget(R); + for (b = 0; b < R->nb; b++) { free(R->b[b].u); free(R->b[b].so); } + free(R->b); R->b = 0; R->nb = 0; R->lifted = 0; +} +static void rdrop_all(void) { int j; for (j = 0; j < nrg; j++) if (rgs[j]->lifted) rclear(rgs[j]); } + +/* lifting one block */ +static Rg *R_; +static unsigned char *lead_; +static int *bidx_, *wl_, nw_; +static int lv_[RMAXV], lw_[RMAXV]; +#define SB 1100 +static int skv[2 * SB], stp, slo, shi; +static unsigned char skk[2 * SB]; +static int afp[MAXUOP * 4 + 16]; /* value -> 1 + its offset from fp, if it is fp + k */ +static int emap[MAXUOP * 4 + 16]; + +static int rvar(int v) +{ + if (lv_[v] < 0) { lv_[v] = raw(U_VGET, 0, 0, 0, v); if (!v) afp[lv_[v]] = 1; } + return lv_[v]; +} +static int slotvar(int off) { int j; for (j = 0; j < R_->np; j++) if (R_->ps[j] == off) return R_->pv[j]; return 0; } +static int rbin(int op, int x, int y, int z) +{ + int r = oe(op, x, y, z, 0); + if (op == U_ADD && !afp[r]) { + if (afp[x] && isk[y]) afp[r] = afp[x] + kv[y]; + else if (afp[y] && isk[x]) afp[r] = afp[y] + kv[x]; + } + return r; +} +static int rld(int a) +{ + int v; + if (isk[a] && kv[a] == ZFP) return rvar(0); + if (afp[a] && (v = slotvar(afp[a] - 1))) return rvar(v); + return oe(U_LD, a, 0, 0, 0); +} +static int rst(int a, int b) +{ + int v; + if (isk[a] && kv[a] == ZFP) return 0; /* moving the frame: not in here */ + if (afp[a] && (v = slotvar(afp[a] - 1))) { lv_[v] = b; lw_[v] = 1; return 1; } + oe(U_ST, a, b, 0, 0); + return 1; +} +static int sget(int o) +{ + if (o < -SB || o >= SB) { uerr = -6; return 0; } + if (!skk[o + SB]) { + if (o < 0) { uerr = -6; return 0; } + skv[o + SB] = raw(U_SLD, 0, 0, 0, o); skk[o + SB] = 1; + } + if (o < slo) slo = o; + if (o >= shi) shi = o + 1; + return skv[o + SB]; +} +static void sset(int o, int v) +{ + if (o < -SB || o >= SB) { uerr = -6; return; } + skv[o + SB] = v; skk[o + SB] = 1; + if (o < slo) slo = o; + if (o >= shi) shi = o + 1; +} +static int spop(void) { return sget(stp++); } +static void spush(int v) { sset(--stp, v); } +static int rblk(int t) { return t >= R_->lo && t < R_->hi && lead_[t - R_->lo] ? bidx_[t - R_->lo] : -1; } +/* an enhancement, spliced into the block */ +static int rsplice(Enh *e) +{ + int i, j; + for (j = e->nin; j--;) emap[j] = spop(); + for (i = 0; i < e->n && !uerr; i++) { + Uop *u = &e->u[i]; + int na = nargs(u->op), a = na > 0 ? emap[u->a] : 0, b = na > 1 ? emap[u->b] : 0, c = na > 2 ? emap[u->c] : 0; + if (u->op == U_LI) emap[u->d] = K(u->imm); + else if (u->op == U_LD) emap[u->d] = rld(a); + else if (u->op == U_ST) { if (!rst(a, b)) uerr = -4; } + else emap[u->d] = rbin(u->op, a, b, c); + } + for (j = 0; j < e->nout; j++) spush(emap[e->out[j]]); + return uerr; +} +static int lift_block(int bi) +{ + static const int map[] = { U_ADD, U_SUB, U_MUL, U_AND, U_OR, U_XOR, U_SAR, U_LT }; + RB *B = &R_->b[bi]; + int i = B->a, w, k, x, y, t, j, o, n = 0, *live; + on = 0; onv = 0; uerr = 0; + memset(afp, 0, sizeof afp); memset(skk, 0, sizeof skk); + stp = slo = shi = 0; + for (j = 0; j < RMAXV; j++) { lv_[j] = -1; lw_[j] = 0; } + B->term = T_JMP; B->cv = -1; B->s1 = B->s2 = -1; B->x1 = B->x2 = 0; + for (;;) { + if (uerr) return uerr; + if (i != B->a && (t = rblk(i)) >= 0) { B->term = T_BR; B->s1 = t; goto done; } + if (i < R_->lo || i >= R_->hi) goto leave_at; + w = m[i]; + if (w & 1) { spush(K(w >> 1)); i++; continue; } + k = w / 2; + switch (k) { + case 0: B->cv = K(-1); goto done; /* halt */ + case 1: x = spop(); spush(rld(x)); break; + case 2: + x = sget(stp); + if (isk[x] && kv[x] == ZFP) goto leave_at; + x = spop(); y = spop(); rst(x, y); + break; + case 3: /* pick: a constant depth */ + x = sget(stp); + if (!isk[x] || kv[x] < 0 || kv[x] > 1024) goto leave_at; + stp++; spush(sget(stp + kv[x])); + break; + case 4: stp++; break; + case 5: x = sget(stp); y = sget(stp + 1); sset(stp, y); sset(stp + 1, x); break; + case 6: B->cv = spop(); B->term = T_CALL; B->x2 = i + 1; goto done; + case 7: + x = spop(); + if (isk[x] && (t = rblk(kv[x])) >= 0) { B->term = T_BR; B->s1 = t; } + else B->cv = x; + goto done; + case 8: + x = sget(stp); + if (!isk[x]) goto leave_at; + stp++; y = spop(); + if (isk[y]) { /* a known condition */ + if (kv[y]) { i++; continue; } + if ((t = rblk(kv[x])) >= 0) { B->term = T_BR; B->s1 = t; } else B->cv = K(kv[x]); + goto done; + } + B->term = T_CBR; B->cv = y; + B->x1 = kv[x]; B->s1 = rblk(kv[x]); + B->x2 = i + 1; B->s2 = rblk(i + 1); + goto done; + case 9: B->term = T_RET; goto done; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + x = spop(); y = spop(); spush(rbin(map[k - 13], y, x, 0)); + break; + default: + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { if (rsplice(&enh[k - XOP0])) return uerr; break; } + goto leave_at; /* i/o, install, unwired: done the usual way */ + } + i++; + } +leave_at: + B->term = T_JMP; B->cv = K(i); +done: + if (uerr) return uerr; + B->delta = stp; + B->so = malloc((shi - slo + 1) * 2 * sizeof(int)); + B->nso = 0; + for (o = stp > slo ? stp : slo; o < shi; o++) + if (skk[o + SB]) { + x = skv[o + SB]; + if (ob[x].op == U_SLD && ob[x].imm == o) continue; /* still the word that was there */ + if (afp[x] && slotvar(afp[x] - 1)) return -7; /* a register var's address can't wait in memory */ + B->so[2 * B->nso] = o; B->so[2 * B->nso + 1] = x; B->nso++; + } + for (j = 0; j < RMAXV; j++) B->vs[j] = -1; + for (j = 1; j < R_->nv; j++) + if (lw_[j] && !(ob[lv_[j]].op == U_VGET && ob[lv_[j]].imm == j)) B->vs[j] = lv_[j]; + /* dead code: what the block leaves behind and its stores are live */ + live = calloc(onv + 1, sizeof *live); + for (j = 0; j < B->nso; j++) live[B->so[2 * j + 1]] = 1; + for (j = 1; j < R_->nv; j++) if (B->vs[j] >= 0) live[B->vs[j]] = 1; + if (B->term == T_CBR || B->term == T_JMP || B->term == T_CALL) live[B->cv] = 1; + for (i = on; i--;) { + Uop *u = &ob[i]; + if (u->op != U_ST && !live[u->d]) { u->op = -1; continue; } + k = nargs(u->op); + if (k > 0) live[u->a] = 1; + if (k > 1) live[u->b] = 1; + if (k > 2) live[u->c] = 1; + } + free(live); + B->u = malloc((on + 1) * sizeof(Uop)); + for (i = 0; i < on; i++) if (ob[i].op >= 0) B->u[n++] = ob[i]; + B->n = n; B->nv = onv; + if (onv > R_->maxnv) R_->maxnv = onv; + return 0; +} +static void addl(int x, int en) +{ + int e; + if (x < R_->lo || x >= R_->hi) return; + if (!lead_[x - R_->lo]) { lead_[x - R_->lo] = 1; wl_[nw_++] = x; } + if (en) { for (e = 0; e < R_->ne && R_->ent[e] != x; e++); if (e == R_->ne && e < RMAXE) R_->ent[R_->ne++] = x; } +} +/* blocks, then each one lifted and optimized */ +static int rlift(Rg *R) +{ + int n = R->hi - R->lo, L, i, w, k, t, b, e, r = 0, cnt; + if (R->lifted) rclear(R); + R_ = R; + lead_ = calloc(n, 1); bidx_ = malloc(n * sizeof(int)); wl_ = malloc(n * sizeof(int)); nw_ = 0; + R->ne = 0; + addl(R->lo, 1); + while (nw_) { + L = wl_[--nw_]; + for (i = L, cnt = 0;;) { + if (i >= R->hi || (i != L && lead_[i - R->lo])) break; + if (cnt++ >= 1000) { addl(i, 0); break; } + w = m[i]; + if (w & 1) { + if (i + 1 < R->hi && !(m[i + 1] & 1) && (k = m[i + 1] / 2) >= 6 && k <= 8) { + t = w >> 1; + if (k == 6) addl(i + 2, 1); /* a call comes back here */ + else if (k == 7) addl(t, 0); + else { addl(t, 0); addl(i + 2, 0); } + break; + } + i++; + continue; + } + k = w / 2; + if (k == 6) { addl(i + 1, 1); break; } + if (k == 8) { addl(i + 1, 0); break; } + if (k == 0 || k == 7 || k == 9) break; + i++; + } + } + for (i = 0, b = 0; i < n; i++) if (lead_[i]) bidx_[i] = b++; + R->nb = b; R->b = calloc(b, sizeof(RB)); R->maxnv = 0; + for (i = 0; i < n; i++) if (lead_[i]) R->b[bidx_[i]].a = R->lo + i; + for (b = 0; b < R->nb && !r; b++) r = lift_block(b); + for (e = 0; e < R->ne; e++) R->entb[e] = bidx_[R->ent[e] - R->lo]; + free(lead_); free(bidx_); free(wl_); + if (r) { + if (trace) fprintf(stderr, "o3: %d..%d doesn't lift (%d)\n", R->lo, R->hi - 1, r); + R->lifted = 1; rclear(R); return r; + } + for (e = 0; e < R->ne; e++) { o3ent[R->ent[e]] = R->idx + 1; o3ei[R->ent[e]] = e; } + R->lifted = 1; + rmark(R); + if (trace) { + int ops = 0; + for (b = 0; b < R->nb; b++) ops += R->b[b].n; + fprintf(stderr, "o3: %d..%d: %d blocks, %d entries, %d vars, %d micro-ops\n", R->lo, R->hi - 1, R->nb, R->ne, R->nv - 1, ops); + if (getenv("ZYO3DUMP")) + for (b = 0; b < R->nb; b++) { + RB *B = &R->b[b]; + fprintf(stderr, " b%d @%d: %d ops, sp %+d, term %d cv v%d s %d/%d x %d/%d\n", b, B->a, B->n, B->delta, B->term, B->cv, B->s1, B->s2, B->x1, B->x2); + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + if (u->op == U_ST) fprintf(stderr, " st v%d v%d\n", u->a, u->b); + else if (u->op == U_LI) fprintf(stderr, " v%d = %d\n", u->d, u->imm); + else if (u->op == U_VGET) fprintf(stderr, " v%d = var%d\n", u->d, u->imm); + else if (u->op == U_SLD) fprintf(stderr, " v%d = s[%d]\n", u->d, u->imm); + else { fprintf(stderr, " v%d = %s v%d", u->d, unames[u->op], u->a); if (nargs(u->op) > 1) fprintf(stderr, " v%d", u->b); if (nargs(u->op) > 2) fprintf(stderr, " v%d", u->c); fprintf(stderr, "\n"); } + } + for (i = 0; i < B->nso; i++) fprintf(stderr, " s[%d] = v%d\n", B->so[2 * i], B->so[2 * i + 1]); + for (i = 1; i < R->nv; i++) if (B->vs[i] >= 0) fprintf(stderr, " var%d = v%d\n", i, B->vs[i]); + } + } + return 0; +} +/* install kind 2 */ +static int o3install(int d) +{ + int lo = mread(d + 2), hi = mread(d + 3), n = mread(d + 4), i, r; + Rg *R; + if (lo <= 0 || hi <= lo || hi > MW || hi - lo > 1000000 || (unsigned)n > 32 || nrg >= MAXRG) return -1; + R = calloc(1, sizeof *R); + R->idx = nrg; rgs[nrg++] = R; + R->lo = lo; R->hi = hi; R->nv = 1; R->np = n; + for (i = 1; i < RMAXV; i++) R->slot[i] = -1; + for (i = 0; i < n; i++) { /* pairs: frame slot, register 1..7 */ + int s = mread(d + 5 + 2 * i), v = mread(d + 6 + 2 * i); + if ((unsigned)s >= 4096 || v < 1 || v >= RMAXV) { R->dead = 1; return -1; } + R->ps[i] = s; R->pv[i] = v; + if (R->slot[v] < 0) R->slot[v] = s; + if (v >= R->nv) R->nv = v + 1; + } + for (i = 1; i < R->nv; i++) if (R->slot[i] < 0) R->slot[i] = R->ps[0]; + if ((r = rlift(R))) { R->dead = 1; return r; } + rcompile(R, 1); + return 0; +} +/* the region entered at p, lifted again if it has to be, or 0 */ +static Rg *rat(int p) +{ + Rg *R = rgs[o3ent[p] - 1]; + if (R->dead) { o3ent[p] = 0; return 0; } + if (!R->lifted && rlift(R)) { R->dead = 1; o3ent[p] = 0; return 0; } + if (o3ei[p] >= R->ne || R->ent[o3ei[p]] != p) { o3ent[p] = 0; return 0; } + return R; +} + +#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[13]; /* m, s, r, tab, cov, Q, G, &J, store hook, install, enhancement fallback, stack limits */ + +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(0xa9b97bfd); /* stp x29, x30, [sp, #-112]! */ + 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(0xa90467f8); /* stp x24, x25, [sp, #64] */ + E(0xa9056ffa); /* stp x26, x27, [sp, #80] */ + E(0xf90033fc); /* str x28, [sp, #96] */ + E(0xaa0003f7); /* mov x23, x0 */ + ldrx_u(M, ST, 0); + ldrx_u(24, ST, 88); ldrx_u(25, ST, 96); /* x24, x25: the stack limits, as addresses */ + 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(0xa94467f8); /* ldp x24, x25, [sp, #64] */ + E(0xa9456ffa); /* ldp x26, x27, [sp, #80] */ + E(0xf94033fc); /* ldr x28, [sp, #96] */ + E(0xa8c77bfd); /* ldp x29, x30, [sp], #112 */ + E(0xd65f03c0); /* ret */ + { + unsigned *ovd = cp, *ovr; + li(W0, MW + 1); b_to(x_exit); /* data stack overflow */ + ovr = cp; + li(W0, MW + 2); b_to(x_exit); /* return stack overflow */ + x_disp = cp; /* w0 = target: check the stacks, chain through tab[] or fall back to c */ + E(0xeb18029f); /* cmp x20, x24 */ + E(0x54000003 | ((ovd - cp) & 0x7ffff) << 5); /* b.lo data overflow */ + E(0xeb1902bf); /* cmp x21, x25 */ + E(0x54000002 | ((ovr - cp) & 0x7ffff) << 5); /* b.hs return overflow */ + } + 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; + rdrop_all(); + 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 < nrg; j++) + if (rgs[j]->lifted && rgs[j]->lo <= a && a < rgs[j]->hi) { + if (trace) fprintf(stderr, "o3: dropped %d..%d (a store to %d)\n", rgs[j]->lo, rgs[j]->hi - 1, a); + rclear(rgs[j]); + memset(cov, 0, sizeof cov); + 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; + for (j = 0; j < nrg; j++) if (rgs[j]->lifted) rmark(rgs[j]); + 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); +} + +/* one micro-op, operands in registers. tmp is a scratch register for the + remainders; x16 and x17 are scratch too. */ +static void emit_uop(int op, int d, int a, int b, int c, int tmp) +{ + switch (op) { + case U_ADD: op3(0x0b000000, d, a, b); break; + case U_SUB: op3(0x4b000000, d, a, b); break; + case U_MUL: op3(0x1b007c00, d, a, b); break; + case U_SDIV: op3(0x1ac00c00, d, a, b); break; + case U_UDIV: op3(0x1ac00800, d, a, b); break; + case U_SREM: op3(0x1ac00c00, tmp, a, b); E(0x1b008000 | b << 16 | a << 10 | tmp << 5 | d); break; /* msub */ + case U_UREM: op3(0x1ac00800, tmp, a, b); E(0x1b008000 | b << 16 | a << 10 | tmp << 5 | d); break; + case U_AND: op3(0x0a000000, d, a, b); break; + case U_OR: op3(0x2a000000, d, a, b); break; + case U_XOR: op3(0x4a000000, d, a, b); break; + case U_SHL: op3(0x1ac02000, d, a, b); break; + case U_SHR: op3(0x1ac02400, d, a, b); break; + case U_SAR: op3(0x1ac02800, d, a, b); break; + case U_NEG: E(0x4b0003e0 | a << 16 | d); break; + case U_NOT: E(0x2a2003e0 | a << 16 | d); break; + case U_LT: E(0x6b00001f | b << 16 | a << 5); E(0x1a9fa7e0 | d); break; /* cmp; cset lt */ + case U_LTU: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f27e0 | d); break; /* cset lo */ + case U_EQ: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f17e0 | d); break; + case U_NE: E(0x6b00001f | b << 16 | a << 5); E(0x1a9f07e0 | d); break; + case U_MIN: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 11 << 12 | a << 5 | d); break; + case U_MAX: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 12 << 12 | a << 5 | d); break; + case U_MINU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 3 << 12 | a << 5 | d); break; + case U_MAXU: E(0x6b00001f | b << 16 | a << 5); E(0x1a800000 | b << 16 | 8 << 12 | a << 5 | d); break; + case U_MULHS: E(0x9b207c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; /* smull; lsr #32 */ + case U_MULHU: E(0x9ba07c00 | b << 16 | a << 5 | 16); E(0xd360fc00 | 16 << 5 | d); break; + case U_CLZ: E(0x5ac01000 | a << 5 | d); break; + case U_ABS: E(0x7100001f | a << 5); E(0x5a800400 | a << 16 | 10 << 12 | a << 5 | d); break; /* cmp #0; cneg */ + case U_SEL: E(0x7100001f | a << 5); E(0x1a800000 | c << 16 | 1 << 12 | b << 5 | d); break; /* csel ne */ + case U_LD: /* out of range reads 0, like the interpreter */ + E(0x52800011); E(0x7144001f | a << 5); E(0x54000042); ldr_rr(17, M, a, UXTW); movw(d, 17); + break; + case U_ST: E(0x7144001f | a << 5); E(0x54000042); str_rr(b, M, a, UXTW); break; + } +} +/* an enhancement, inlined: inputs from the data stack into w0..w15, the + optimized micro-ops, outputs back. constants are made where they're used, + or folded into the instruction (a fixed address, a small addend). */ +static int ekc[MAXUOP * 4 + 16], ekv[MAXUOP * 4 + 16]; +static void emit_enh_e(Enh *e, int s) +{ + signed char *r = e->reg; + int i, j, delta, na; + if (!r) { /* didn't fit in registers: x0 = data stack, w1 = slot, call the interpreter */ + E(0xaa1403e0); li(W1, s); ldrx_u(X11, ST, 80); blr(X11); E(0xaa0003f4); + return; + } + for (i = 0; i < e->nv; i++) ekc[i] = 0; + for (i = 0; i < e->n; i++) if (e->u[i].op == U_LI) { ekc[e->u[i].d] = 1; ekv[e->u[i].d] = e->u[i].imm; } +#define EOP(x) (ekc[x] ? (li(r[x], ekv[x]), r[x]) : r[x]) + for (j = 0; j < e->nin; j++) if (r[j] >= 0) ldr_u(r[j], SP, 4 * (e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + int d = u->op == U_ST ? 0 : r[u->d], a = 0, b = 0, c = 0; + if (u->op == U_LI) continue; + if (u->op == U_LD && ekc[u->a] && (unsigned)ekv[u->a] < MW) { + if (ekv[u->a] < 4096) ldr_u(d, M, ekv[u->a] * 4); else ldr_rr(d, M, EOP(u->a), UXTW); + continue; + } + if ((u->op == U_ADD || u->op == U_SUB) && ekc[u->b] && ekv[u->b] >= 0 && ekv[u->b] < 4096) { + E((u->op == U_ADD ? 0x11000000 : 0x51000000) | ekv[u->b] << 10 | EOP(u->a) << 5 | d); + continue; + } + na = nargs(u->op); + if (na > 0) a = EOP(u->a); + if (na > 1) b = EOP(u->b); + if (na > 2) c = EOP(u->c); + emit_uop(u->op, d, a, b, c, 16); + } + delta = 4 * (e->nin - e->nout); + if (delta > 0) E(0x91000294 | delta << 10); + if (delta < 0) E(0xd1000294 | (-delta) << 10); + for (j = 0; j < e->nout; j++) str_u(EOP(e->out[j]), SP, 4 * (e->nout - 1 - j)); +#undef EOP +} +static void emit_enh(int s) { emit_enh_e(&enh[s], s); } +/* lit .. lit xop: the enhancement specialized on the literals that feed its + last inputs, so the optimizer sees them as constants (x / 7 becomes a + multiply, lfa(k) a load and an add). 0 if it worked. */ +static int spec_enh(int s, int *ks, int nk, Enh *te) +{ + Enh *e = &enh[s]; + int nin = e->nin - nk, i, j, out[8], na; + static int mp[MAXUOP * 4 + 16]; + if (e->nv > MAXUOP * 4) return -1; + un = 0; unv = nin; uerr = 0; + for (j = 0; j < nin; j++) mp[j] = j; + for (j = 0; j < nk; j++) mp[nin + j] = unew(U_LI, 0, 0, 0, ks[j]); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + na = nargs(u->op); + j = unew(u->op, na > 0 ? mp[u->a] : 0, na > 1 ? mp[u->b] : 0, na > 2 ? mp[u->c] : 0, u->imm); + if (u->op != U_ST) mp[u->d] = j; + } + for (j = 0; j < e->nout; j++) out[j] = mp[e->out[j]]; + memset(te, 0, sizeof *te); + if (uerr || optimize(te, nin, out, e->nout)) return -1; + regalloc(te); + if (!te->reg) { free(te->u); return -1; } + return 0; +} + +/* ---- o3 regions on arm64 ---- + vars live in w0..w7 (w0 is the frame pointer), block values in w8..w14, + w26..w28 and the homes of unused vars. constants have no register: they + are made in a scratch register where they're used (w16, w17, w15), or + folded into the instruction. x15..x17 are scratch. */ +static signed char rreg[MAXUOP * 4 + 16]; +static unsigned char rk[MAXUOP * 4 + 16], rhome[MAXUOP * 4 + 16]; +static int rkv[MAXUOP * 4 + 16], rlast[MAXUOP * 4 + 16]; +static unsigned **rfa; static int *rfb, rnf; /* branches to blocks, fixed up at the end */ + +static void rforget(Rg *R) +{ + int e; + if (R->nat) for (e = 0; e < R->ne; e++) if (tab[R->ent[e]] == R->stub[e]) tab[R->ent[e]] = 0; + R->nat = 0; +} +static void rmark(Rg *R) { int x; for (x = R->lo; x < R->hi; x++) cov[x] = 1; } +static int ralloc(Rg *R, RB *B) +{ + int i, j, k, n = B->n; + unsigned fr = 0x7f00u | 0x1c000000u; /* w8..w14, w26..w28 */ + for (j = R->nv; j < 8; j++) fr |= 1u << j; + for (i = 0; i < B->nv; i++) { rlast[i] = -2; rk[i] = 0; rhome[i] = 0; rreg[i] = -1; } + for (i = 0; i < n; i++) { + Uop *u = &B->u[i]; int na = nargs(u->op); + if (na > 0) rlast[u->a] = i; + if (na > 1) rlast[u->b] = i; + if (na > 2) rlast[u->c] = i; + } + for (j = 0; j < B->nso; j++) rlast[B->so[2 * j + 1]] = n; + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) rlast[B->vs[j]] = n; + if (B->term == T_CBR || B->term == T_JMP || B->term == T_CALL) rlast[B->cv] = n; + for (i = 0; i < n; i++) { + Uop *u = &B->u[i]; int na = nargs(u->op), ops[3], d = u->d; + ops[0] = u->a; ops[1] = u->b; ops[2] = u->c; + for (j = 0; j < na; j++) { int x = ops[j]; if (rlast[x] == i && rreg[x] >= 0 && !rhome[x]) fr |= 1u << rreg[x]; } + if (u->op == U_ST) continue; + if (u->op == U_LI) { rk[d] = 1; rkv[d] = u->imm; continue; } + if (u->op == U_VGET) { rreg[d] = (signed char)u->imm; rhome[d] = 1; continue; } + for (k = 0; k < 32 && !(fr >> k & 1); k++); + if (k == 32) return -1; + fr &= ~(1u << k); rreg[d] = (signed char)k; + if (rlast[d] == -2) fr |= 1u << k; + } + return 0; +} +static int ropr(int x, int s) { if (rk[x]) { li(s, rkv[x]); return s; } return rreg[x]; } +/* w t <-> the data stack word o places from the top at block entry */ +static void rsw(int t, int o, int store) +{ + int by = o * 4; + if (by >= 0 && by < 16384) { if (store) str_u(t, SP, by); else ldr_u(t, SP, by); } + else if (by >= -256 && by < 256) E((store ? 0xb8000000u : 0xb8400000u) | (unsigned)(by & 0x1ff) << 12 | SP << 5 | t); /* stur, ldur */ + else { li(16, by); addx_ext(16, SP, 16, SXTW); if (store) str_u(t, 16, 0); else ldr_u(t, 16, 0); } +} +static void addsp(int by) +{ + if (by > 0 && by < 4096) E(0x91000294 | by << 10); + else if (by < 0 && -by < 4096) E(0xd1000294 | (-by) << 10); + else if (by) { li(16, by); addx_ext(SP, SP, 16, SXTW); } +} +static void rspill(Rg *R) +{ + int v; + for (v = 0; v < R->np; v++) { E(0x11000000 | R->ps[v] << 10 | 16); str_rr(R->pv[v], M, 16, UXTW); } /* add w16, w0, #slot */ +} +static void rload(Rg *R) +{ + int v; + li(16, ZFP); ldr_rr(0, M, 16, UXTW); + for (v = 1; v < R->nv; v++) { E(0x11000000 | R->slot[v] << 10 | 16); ldr_rr(v, M, 16, UXTW); } +} +static void rexitk(Rg *R, int t) { rspill(R); li(W0, t); b_to(x_disp); } +static void rbranch(int b) { rfa[rnf] = cp; rfb[rnf++] = b; E(0x14000000); } +/* m[a] = v, checked like the jit's own stores: a word some translation covers goes through hook */ +static void rstore(int a, int v) +{ + unsigned *p1, *p2, *p3; + int j; + E(0x7144001f | a << 5); /* cmp wa, #MW */ + p1 = cp; E(0x54000002); /* b.hs done */ + ldrx_u(15, ST, 32); + E(0x38604800 | a << 16 | 15 << 5 | 15); /* ldrb w15, [x15, wa, uxtw] */ + p2 = cp; E(0x35000000 | 15); /* cbnz w15, slow */ + str_rr(v, M, a, UXTW); + p3 = cp; E(0x14000000); + cb_fix(p2, cp); + E(0xd10203ff); /* sub sp, sp, #128 */ + for (j = 0; j < 16; j += 2) E(0xa9000000 | (j / 2 * 2) << 15 | (j + 1) << 10 | 31 << 5 | j); /* stp xj, xj+1, [sp, #8j] */ + movw(15, a); movw(1, v); movw(0, 15); + ldrx_u(16, ST, 64); blr(16); + for (j = 0; j < 16; j += 2) E(0xa9400000 | (j / 2 * 2) << 15 | (j + 1) << 10 | 31 << 5 | j); + E(0x910203ff); /* add sp, sp, #128 */ + cb_fix(p1, cp); + *p3 |= (cp - p3) & 0x3ffffff; +} +static void rpmove(Rg *R, RB *B) +{ + int dst[RMAXV], src[RMAXV], n = 0, j, k, x; + for (j = 1; j < R->nv; j++) + if (B->vs[j] >= 0 && !rk[B->vs[j]] && rreg[B->vs[j]] != j) { dst[n] = j; src[n] = rreg[B->vs[j]]; n++; } + while (n) { + for (j = 0; j < n; j++) { for (k = 0; k < n && src[k] != dst[j]; k++); if (k == n) break; } + if (j < n) { movw(dst[j], src[j]); n--; dst[j] = dst[n]; src[j] = src[n]; continue; } + x = src[0]; movw(16, x); /* a cycle: park one */ + for (k = 0; k < n; k++) if (src[k] == x) src[k] = 16; + } + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0 && rk[B->vs[j]]) li(j, rkv[B->vs[j]]); +} +static void emit_uop(int op, int d, int a, int b, int c, int tmp); +static int remit(Rg *R, int bi) +{ + RB *B = &R->b[bi]; + int i, j, d, a, b, c; + unsigned *p; + if (ralloc(R, B)) return -1; + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + switch (u->op) { + case U_LI: case U_VGET: continue; + case U_SLD: rsw(rreg[u->d], u->imm, 0); continue; + case U_LD: + if (rk[u->a] && (unsigned)rkv[u->a] < MW) { /* a fixed address */ + if (rkv[u->a] < 4096) ldr_u(rreg[u->d], M, rkv[u->a] * 4); + else { li(16, rkv[u->a]); ldr_rr(rreg[u->d], M, 16, UXTW); } + continue; + } + break; + case U_ST: a = ropr(u->a, 16); rstore(a, ropr(u->b, 17)); continue; + case U_ADD: case U_SUB: + if (rk[u->b] && rkv[u->b] >= 0 && rkv[u->b] < 4096) { + E((u->op == U_ADD ? 0x11000000 : 0x51000000) | rkv[u->b] << 10 | ropr(u->a, 16) << 5 | rreg[u->d]); + continue; + } + break; + } + d = rreg[u->d]; + a = nargs(u->op) > 0 ? ropr(u->a, 16) : 0; + b = nargs(u->op) > 1 ? ropr(u->b, 17) : 0; + c = nargs(u->op) > 2 ? ropr(u->c, 15) : 0; + emit_uop(u->op, d, a, b, c, 15); + } + for (j = 0; j < B->nso; j++) rsw(ropr(B->so[2 * j + 1], 17), B->so[2 * j], 1); + if (B->term == T_CBR || B->term == T_JMP || B->term == T_CALL) { + if (rk[B->cv]) li(17, rkv[B->cv]); else movw(17, rreg[B->cv]); + } + addsp(B->delta * 4); + rpmove(R, B); + switch (B->term) { + case T_BR: rbranch(B->s1); break; + case T_CBR: + if (B->s1 >= 0) { rfa[rnf] = cp; rfb[rnf++] = B->s1; E(0x34000000 | 17); } /* cbz w17, taken */ + else { p = cp; E(0x35000000 | 17); rexitk(R, B->x1); cb_fix(p, cp); } + if (B->s2 >= 0) rbranch(B->s2); else rexitk(R, B->x2); + break; + case T_CALL: rspill(R); li(16, B->x2); str_post(16, RP, 4); movw(W0, 17); b_to(x_disp); break; + case T_RET: rspill(R); ldr_pre(W0, RP, -4); b_to(x_disp); break; + default: rspill(R); movw(W0, 17); b_to(x_disp); + } + return 0; +} +/* the whole region: entry stubs that load the vars, then the blocks */ +static int rjit(Rg *R, int wr) +{ + unsigned *start = cp, **lab; + int b, e, j, bad = 0; + long need = (long)(R->hi - R->lo) * 96 + (long)R->ne * 32 + 4096; + if (need > (code + CODEW) - cp) return -1; + if (wr) jitwrite(1); + lab = malloc((R->nb + 1) * sizeof *lab); + rfa = malloc((2 * R->nb + R->ne + 4) * sizeof *rfa); rfb = malloc((2 * R->nb + R->ne + 4) * sizeof *rfb); rnf = 0; + for (e = 0; e < R->ne; e++) { R->stub[e] = cp; rload(R); rbranch(R->entb[e]); } + for (b = 0; b < R->nb && !bad; b++) { lab[b] = cp; bad = remit(R, b); } + if (!bad) { + for (j = 0; j < rnf; j++) { + unsigned *at = rfa[j], *to = lab[rfb[j]]; + if ((*at & 0xfc000000u) == 0x14000000u) *at |= (to - at) & 0x3ffffff; else cb_fix(at, to); + } + R->nat = start; + for (e = 0; e < R->ne; e++) tab[R->ent[e]] = R->stub[e]; + syncicache(start, cp); + if (trace) fprintf(stderr, "o3: %d..%d -> %ld bytes of arm64\n", R->lo, R->hi - 1, (long)((char *)cp - (char *)start)); + } else { + cp = start; + if (trace) fprintf(stderr, "o3: %d..%d: a block needs too many registers\n", R->lo, R->hi - 1); + } + free(lab); free(rfa); free(rfb); + if (wr) jitwrite(0); + return bad; +} +static void rcompile(Rg *R, int eager) +{ + if (R->nat || R->nonat) return; + if (rjit(R, eager) && cp - code < CODEW / 2) R->nonat = 1; /* registers, not space: give up on it */ +} + +static int inst_hook(int d) { return install(d); } +static long xrun(long sp, int slot) { return (long)xexec(&enh[slot], (int *)sp); } + +static void *translate(int p) +{ + unsigned *start; + int i = p, n = 0, w, k, t; + if (cp - code > CODEW - 65536 || nbl >= MAXB) flush(); + if (o3ent[p]) { /* an o3 region starts here */ + Rg *R = rat(p); + if (R) { rcompile(R, 0); if (R->nat && tab[p]) return tab[p]; } + } + 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) { + int L = 0, x, s, nk, ks[8], j; + Enh te; + while (L < 8 && i + L < MW && (m[i + L] & 1)) L++; + x = i + L < MW ? m[i + L] : 1; + if (!(x & 1) && (s = x / 2 - XOP0) >= 0 && s < NENH && enh[s].live && enh[s].nin) { + nk = L < enh[s].nin ? L : enh[s].nin; + for (j = 0; j < nk; j++) ks[j] = m[i + L - nk + j] >> 1; + if (!spec_enh(s, ks, nk, &te)) { + for (j = 0; j < L - nk; j++) { li(X9, m[i + j] >> 1); str_pre(X9, SP, -4); } + for (j = 0; j <= L; j++) cov[i + j] = 1; + emit_enh_e(&te, s); + free(te.u); free(te.reg); + i += L + 1; n += L; + continue; + } + } + 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; } + if (k == 21) { /* install: call into c, then return to it so it can flush */ + ldr_u(W0, SP, 0); ldrx_u(X11, ST, 72); blr(X11); str_u(W0, SP, 0); + li(W0, i + 1); b_to(x_exit); i++; break; + } + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { emit_enh(k - XOP0); i++; continue; } + if (k > 20) { E(0x12800000); b_to(x_exit); i++; break; } /* not wired: halt */ + 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). */ +#ifdef ZYLLVM +/* ---- llvm backend ---- + a tiered jit for hosts the arm64 backend doesn't cover. the interpreter + counts how often each block start is reached; a hot block is translated to + llvm ir (same block rules as the arm64 jit: it ends at call, jump, ret or + halt, and keeps going past a jz), optimized at O2 and compiled with orc. + enhancements are inlined as ir. stores into compiled words drop the blocks + that cover them, so self-modifying code still works. */ +#include +#include +#include +#include +#include +#include +static int HOT = 5000; /* runs before a block gets compiled: ZYHOT */ +static const char *lpasses = "default"; /* ZYPASSES */ +#define LMAXB 65536 +typedef int (*Blk)(int *mem, int *regs); +static Blk lt[MW]; /* address -> compiled block */ +static unsigned short hot[MW]; +static unsigned char lcov[MW]; /* 1 if a compiled block covers the word */ +static struct { int a, b; } lbl[LMAXB]; +static int nlbl, llvm_ok, nblocks; +static LLVMOrcLLJITRef jit; +static LLVMOrcThreadSafeContextRef tsc; +static LLVMContextRef ctx; +static LLVMTypeRef i8t, i32t, i64t, ptrt, i1t; +static LLVMBuilderRef bd; +static LLVMValueRef fn_, vm_, vregs, vs, vr; /* function, memory, regs, s and r slots */ +static LLVMModuleRef mod_; + +static unsigned char rcov[MW]; /* 1 on the words of a lifted o3 region */ +static int rdrop(int a); +static void ldrop_all(void) +{ + rdrop_all(); memset(rcov, 0, sizeof rcov); + memset(lt, 0, sizeof lt); memset(lcov, 0, sizeof lcov); memset(hot, 0, sizeof hot); nlbl = 0; + if (trace) fprintf(stderr, "llvm: dropped every block\n"); +} +/* a store to a word some block covers: write it, drop those blocks */ +static int lhook(int a, int v) +{ + int j, x, hit = 0; + if (m[a] == v) return 0; + m[a] = v; + for (j = 0; j < nlbl; j++) + if (lbl[j].a >= 0 && lbl[j].a <= a && a < lbl[j].b) { + lt[lbl[j].a] = 0; hot[lbl[j].a] = 0; + if (trace) fprintf(stderr, "llvm: dropped %d..%d\n", lbl[j].a, lbl[j].b - 1); + lbl[j].a = -1; hit = 1; + } + if (rcov[a] && rdrop(a)) hit = 1; + if (hit) { + memset(lcov, 0, sizeof lcov); + for (j = 0; j < nlbl; j++) if (lbl[j].a >= 0) for (x = lbl[j].a; x < lbl[j].b; x++) lcov[x] = 1; + for (j = 0; j < nrg; j++) if (rgs[j]->lifted) for (x = rgs[j]->lo; x < rgs[j]->hi; x++) lcov[x] = 1; + } + return hit; +} +static int linstall(int d) { return install(d); } + +static LLVMValueRef K32(int v) { return LLVMConstInt(i32t, (unsigned)v, 0); } +static LLVMValueRef cptr(void *p) { return LLVMConstIntToPtr(LLVMConstInt(i64t, (unsigned long long)(size_t)p, 0), ptrt); } +static LLVMValueRef mslot(LLVMValueRef idx) { return LLVMBuildGEP2(bd, i32t, vm_, &idx, 1, ""); } +static LLVMValueRef ld(LLVMValueRef idx) { return LLVMBuildLoad2(bd, i32t, mslot(idx), ""); } +static void st(LLVMValueRef idx, LLVMValueRef v) { LLVMBuildStore(bd, v, mslot(idx)); } +static LLVMValueRef gets(void) { return LLVMBuildLoad2(bd, i32t, vs, ""); } +static void sets(LLVMValueRef v) { LLVMBuildStore(bd, v, vs); } +static LLVMValueRef add(LLVMValueRef a, int k) { return LLVMBuildAdd(bd, a, K32(k), ""); } +/* a load that reads 0 outside memory */ +static LLVMValueRef safeld(LLVMValueRef a) +{ + LLVMValueRef in = LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""); + LLVMValueRef v = ld(LLVMBuildSelect(bd, in, a, K32(0), "")); + return LLVMBuildSelect(bd, in, v, K32(0), ""); +} +static void push(LLVMValueRef v) { LLVMValueRef s = add(gets(), -1); sets(s); st(s, v); } +/* leave the block: write s and r back, return the next vm address */ +static void leave(LLVMValueRef next) +{ + LLVMValueRef r0 = K32(0), r1 = K32(1); + LLVMBuildStore(bd, gets(), LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, vr, ""), LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, "")); + LLVMBuildRet(bd, next); +} +static LLVMBasicBlockRef newbb(void) { return LLVMAppendBasicBlockInContext(ctx, fn_, ""); } +static LLVMValueRef callp(void *f, LLVMTypeRef ret, LLVMTypeRef *at, int n, LLVMValueRef *args) +{ + LLVMTypeRef ft = LLVMFunctionType(ret, at, (unsigned)n, 0); + return LLVMBuildCall2(bd, ft, cptr(f), args, (unsigned)n, ""); +} +/* one micro-op as ir: the same semantics as ev() */ +static LLVMValueRef ir_op(int op, LLVMValueRef a, LLVMValueRef b, LLVMValueRef c) +{ + LLVMValueRef z = K32(0), q, d, t, c1, c2, r = 0; + LLVMTypeRef i64 = i64t; + switch (op) { + case U_ADD: r = LLVMBuildAdd(bd, a, b, ""); break; + case U_SUB: r = LLVMBuildSub(bd, a, b, ""); break; + case U_MUL: r = LLVMBuildMul(bd, a, b, ""); break; + case U_SDIV: case U_SREM: /* /0 and INT_MIN/-1 are defined, like the cpu */ + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + c2 = LLVMBuildAnd(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32((int)0x80000000), ""), LLVMBuildICmp(bd, LLVMIntEQ, b, K32(-1), ""), ""); + d = LLVMBuildSelect(bd, LLVMBuildOr(bd, c1, c2, ""), K32(1), b, ""); + if (op == U_SDIV) { q = LLVMBuildSDiv(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, z, q, ""); } + else { q = LLVMBuildSRem(bd, a, d, ""); r = LLVMBuildSelect(bd, c1, a, LLVMBuildSelect(bd, c2, z, q, ""), ""); } + break; + case U_UDIV: case U_UREM: + c1 = LLVMBuildICmp(bd, LLVMIntEQ, b, z, ""); + d = LLVMBuildSelect(bd, c1, K32(1), b, ""); + if (op == U_UDIV) r = LLVMBuildSelect(bd, c1, z, LLVMBuildUDiv(bd, a, d, ""), ""); + else r = LLVMBuildSelect(bd, c1, a, LLVMBuildURem(bd, a, d, ""), ""); + break; + case U_AND: r = LLVMBuildAnd(bd, a, b, ""); break; + case U_OR: r = LLVMBuildOr(bd, a, b, ""); break; + case U_XOR: r = LLVMBuildXor(bd, a, b, ""); break; + case U_SHL: r = LLVMBuildShl(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SHR: r = LLVMBuildLShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_SAR: r = LLVMBuildAShr(bd, a, LLVMBuildAnd(bd, b, K32(31), ""), ""); break; + case U_NEG: r = LLVMBuildSub(bd, z, a, ""); break; + case U_NOT: r = LLVMBuildNot(bd, a, ""); break; + case U_LT: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), i32t, ""); break; + case U_LTU: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), i32t, ""); break; + case U_EQ: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, b, ""), i32t, ""); break; + case U_NE: r = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntNE, a, b, ""), i32t, ""); break; + case U_MIN: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSLT, a, b, ""), a, b, ""); break; + case U_MAX: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntSGT, a, b, ""), a, b, ""); break; + case U_MINU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntULT, a, b, ""), a, b, ""); break; + case U_MAXU: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntUGT, a, b, ""), a, b, ""); break; + case U_MULHS: case U_MULHU: { + LLVMValueRef x = op == U_MULHS ? LLVMBuildSExt(bd, a, i64, "") : LLVMBuildZExt(bd, a, i64, ""); + LLVMValueRef y = op == U_MULHS ? LLVMBuildSExt(bd, b, i64, "") : LLVMBuildZExt(bd, b, i64, ""); + r = LLVMBuildTrunc(bd, LLVMBuildLShr(bd, LLVMBuildMul(bd, x, y, ""), LLVMConstInt(i64, 32, 0), ""), i32t, ""); + break; } + case U_CLZ: { + unsigned id = LLVMLookupIntrinsicID("llvm.ctlz", 9); + LLVMValueRef f = LLVMGetIntrinsicDeclaration(mod_, id, &i32t, 1), args[2]; + args[0] = a; args[1] = LLVMConstInt(i1t, 0, 0); + r = LLVMBuildCall2(bd, LLVMIntrinsicGetType(ctx, id, &i32t, 1), f, args, 2, ""); + break; } + case U_ABS: t = LLVMBuildICmp(bd, LLVMIntSLT, a, z, ""); r = LLVMBuildSelect(bd, t, LLVMBuildSub(bd, z, a, ""), a, ""); break; + case U_SEL: r = LLVMBuildSelect(bd, LLVMBuildICmp(bd, LLVMIntNE, a, z, ""), b, c, ""); break; + } + return r; +} +/* an enhancement as ir */ +static void ir_enh(Enh *e) +{ + LLVMValueRef *v = calloc(e->nv + 1, sizeof *v), s = gets(); + int i, j; + for (j = 0; j < e->nin; j++) v[j] = ld(add(s, e->nin - 1 - j)); + for (i = 0; i < e->n; i++) { + Uop *u = &e->u[i]; + LLVMValueRef a = u->op == U_LI ? 0 : v[u->a], b = uarity[u->op] > 1 || u->op == U_ST ? v[u->b] : 0, c = uarity[u->op] > 2 ? v[u->c] : 0, r = 0; + switch (u->op) { + case U_LI: r = K32(u->imm); break; + case U_LD: r = safeld(a); break; + case U_ST: { + LLVMBasicBlockRef yes = newbb(), done = newbb(); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), yes, done); + LLVMPositionBuilderAtEnd(bd, yes); st(a, b); LLVMBuildBr(bd, done); + LLVMPositionBuilderAtEnd(bd, done); + break; } + default: r = ir_op(u->op, a, b, c); + } + if (u->op != U_ST) v[u->d] = r; + } + s = add(s, e->nin - e->nout); sets(s); + for (j = 0; j < e->nout; j++) st(add(s, e->nout - 1 - j), v[e->out[j]]); + free(v); +} +static void llvm_init(void) +{ + LLVMErrorRef err; + if (getenv("ZYHOT")) HOT = atoi(getenv("ZYHOT")); + if (HOT < 1) HOT = 1; + if (HOT > 65000) HOT = 65000; + if (getenv("ZYPASSES")) lpasses = getenv("ZYPASSES"); + LLVMInitializeNativeTarget(); LLVMInitializeNativeAsmPrinter(); + if ((err = LLVMOrcCreateLLJIT(&jit, 0))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return; } + tsc = LLVMOrcCreateNewThreadSafeContext(); + ctx = LLVMOrcThreadSafeContextGetContext(tsc); + i1t = LLVMInt1TypeInContext(ctx); i8t = LLVMInt8TypeInContext(ctx); i32t = LLVMInt32TypeInContext(ctx); + i64t = LLVMInt64TypeInContext(ctx); ptrt = LLVMPointerTypeInContext(ctx, 0); + bd = LLVMCreateBuilderInContext(ctx); + llvm_ok = 1; +} +/* compile the block at p; 0 if it couldn't be */ +static Blk lcompile(int p) +{ + char name[32]; LLVMTypeRef pt[2], ft; LLVMValueRef s, a, b, v, r, args[2]; LLVMTypeRef at[2]; + LLVMOrcExecutorAddress addr; LLVMErrorRef err; LLVMPassBuilderOptionsRef po; + int i = p, n = 0, w, k, t, done = 0; + if (!llvm_ok || nlbl >= LMAXB) return 0; + sprintf(name, "b%d_%d", p, nblocks++); + mod_ = LLVMModuleCreateWithNameInContext(name, ctx); + pt[0] = ptrt; pt[1] = ptrt; + ft = LLVMFunctionType(i32t, pt, 2, 0); + fn_ = LLVMAddFunction(mod_, name, ft); + vm_ = LLVMGetParam(fn_, 0); vregs = LLVMGetParam(fn_, 1); + LLVMPositionBuilderAtEnd(bd, newbb()); + vs = LLVMBuildAlloca(bd, i32t, "s"); vr = LLVMBuildAlloca(bd, i32t, "r"); + { LLVMValueRef r0 = K32(0), r1 = K32(1); + sets(LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, ""), "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, ""), ""), vr); } + while (!done) { + if (i >= MW) { leave(K32(MW)); break; } + if (n++ >= 1024) { leave(K32(i)); break; } + w = m[i]; + lcov[i] = 1; + if (w & 1) { + /* a literal followed by call, jump or jz: a known target */ + if (i + 1 < MW && !(m[i + 1] & 1) && (k = m[i + 1] / 2) >= 6 && k <= 8) { + t = w >> 1; lcov[i + 1] = 1; + if (k == 8) { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + s = gets(); a = ld(s); sets(add(s, 1)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, a, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(K32(t)); + LLVMPositionBuilderAtEnd(bd, go); + i += 2; continue; + } + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 2)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(K32(t)); i += 2; break; + } + push(K32(w >> 1)); i++; continue; + } + k = w / 2; + s = gets(); + switch (k) { + case 0: leave(K32(MW)); done = 1; break; + case 1: st(s, safeld(ld(s))); break; + case 2: { + LLVMBasicBlockRef in = newbb(), cv = newbb(), plain = newbb(), out = newbb(), quit = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), in, out); + LLVMPositionBuilderAtEnd(bd, in); + v = LLVMBuildLoad2(bd, i8t, LLVMBuildGEP2(bd, i8t, cptr(lcov), &a, 1, ""), ""); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, LLVMConstInt(i8t, 0, 0), ""), cv, plain); + LLVMPositionBuilderAtEnd(bd, plain); st(a, b); LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, cv); + at[0] = i32t; at[1] = i32t; args[0] = a; args[1] = b; + v = callp((void *)lhook, i32t, at, 2, args); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, K32(0), ""), quit, out); + LLVMPositionBuilderAtEnd(bd, quit); leave(K32(i + 1)); /* a block died: back to the loop */ + LLVMPositionBuilderAtEnd(bd, out); + break; } + case 3: a = ld(s); st(s, safeld(LLVMBuildAdd(bd, add(s, 1), a, ""))); break; + case 4: sets(add(s, 1)); break; + case 5: a = ld(s); b = ld(add(s, 1)); st(s, b); st(add(s, 1), a); break; + case 6: case 7: + a = ld(s); sets(add(s, 1)); + if (k == 6) { r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(i + 1)); LLVMBuildStore(bd, add(r, 1), vr); } + leave(a); done = 1; break; + case 8: { + LLVMBasicBlockRef tk = newbb(), go = newbb(); + a = ld(s); b = ld(add(s, 1)); sets(add(s, 2)); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, b, K32(0), ""), tk, go); + LLVMPositionBuilderAtEnd(bd, tk); leave(a); + LLVMPositionBuilderAtEnd(bd, go); + break; } + case 9: + r = add(LLVMBuildLoad2(bd, i32t, vr, ""), -1); LLVMBuildStore(bd, r, vr); + leave(ld(r)); done = 1; break; + case 10: v = callp((void *)Q, i8t, 0, 0, 0); push(LLVMBuildSExt(bd, v, i32t, "")); break; + case 11: + if (sizeof J == 1) push(LLVMBuildZExt(bd, LLVMBuildLoad2(bd, i8t, cptr(&J), ""), i32t, "")); + else push(LLVMBuildLoad2(bd, i32t, cptr(&J), "")); + break; + case 12: at[0] = i8t; args[0] = LLVMBuildTrunc(bd, ld(s), i8t, ""); callp((void *)G, LLVMVoidTypeInContext(ctx), at, 1, args); sets(add(s, 1)); break; + case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + a = ld(s); b = ld(add(s, 1)); s = add(s, 1); sets(s); + switch (k) { + case 13: v = LLVMBuildAdd(bd, b, a, ""); break; + case 14: v = LLVMBuildSub(bd, b, a, ""); break; + case 15: v = LLVMBuildMul(bd, b, a, ""); break; + case 16: v = LLVMBuildAnd(bd, b, a, ""); break; + case 17: v = LLVMBuildOr(bd, b, a, ""); break; + case 18: v = LLVMBuildXor(bd, b, a, ""); break; + case 19: v = LLVMBuildAShr(bd, b, LLVMBuildAnd(bd, a, K32(31), ""), ""); break; + default: v = LLVMBuildZExt(bd, LLVMBuildICmp(bd, LLVMIntSLT, b, a, ""), i32t, ""); + } + st(s, v); break; + case 21: /* install: then back to the loop, which drops every block */ + at[0] = i32t; args[0] = ld(s); + st(s, callp((void *)linstall, i32t, at, 1, args)); + leave(K32(i + 1)); done = 1; break; + default: + if (k >= XOP0 && k < XOP0 + NENH && enh[k - XOP0].live) { ir_enh(&enh[k - XOP0]); break; } + leave(K32(MW)); done = 1; /* not wired: halt */ + } + i++; + } + lbl[nlbl].a = p; lbl[nlbl++].b = i; + po = LLVMCreatePassBuilderOptions(); + if ((err = LLVMRunPasses(mod_, lpasses, 0, po))) { LLVMConsumeError(err); } + LLVMDisposePassBuilderOptions(po); + if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, LLVMOrcLLJITGetMainJITDylib(jit), LLVMOrcCreateNewThreadSafeModule(mod_, tsc)))) { + char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; + } + if ((err = LLVMOrcLLJITLookup(jit, &addr, name))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; } + if (trace) fprintf(stderr, "llvm: %d..%d compiled\n", p, i - 1); + return (Blk)(size_t)addr; +} +#endif + +/* ---- o3 regions without the arm64 jit: compiled by llvm, or run here ---- */ +#ifndef ZYLLVM +static unsigned char rcov[MW]; /* 1 on the words of a lifted region */ +#endif +static int rvals[MAXUOP * 4 + 16]; +static int rdrop(int a) /* a store landed on region code: drop those regions */ +{ + int j, x, hit = 0; + for (j = 0; j < nrg; j++) + if (rgs[j]->lifted && rgs[j]->lo <= a && a < rgs[j]->hi) { + if (trace) fprintf(stderr, "o3: dropped %d..%d (a store to %d: %d)\n", rgs[j]->lo, rgs[j]->hi - 1, a, m[a]); + rclear(rgs[j]); hit = 1; + } + if (hit) { + memset(rcov, 0, sizeof rcov); + for (j = 0; j < nrg; j++) if (rgs[j]->lifted) for (x = rgs[j]->lo; x < rgs[j]->hi; x++) rcov[x] = 1; + } + return hit; +} +#ifdef ZYLLVM +static int lhook(int a, int v); +#define RSTORE(a, b) do { if ((unsigned)(a) < MW) { if (lcov[a]) lhook(a, b); else m[a] = b; } } while (0) +#else +#define RSTORE(a, b) do { if ((unsigned)(a) < MW) { m[a] = b; if (rcov[a]) rdrop(a); } } while (0) +#endif +/* the region interpreter: ssa values in an array, vars in locals */ +static int rexec(Rg *R, int e, int *ps, int *pr) +{ + int var[RMAXV], nv2[RMAXV], *v = rvals, s = *ps, r = *pr, b = R->entb[e], fp, j, i, t, o; + var[0] = fp = mread(ZFP); + for (j = 1; j < R->nv; j++) var[j] = mread(fp + R->slot[j]); + for (;;) { + RB *B = &R->b[b]; + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + switch (u->op) { + case U_LI: v[u->d] = u->imm; break; + case U_VGET: v[u->d] = var[u->imm]; break; + case U_SLD: v[u->d] = mread(s + u->imm); break; + case U_LD: v[u->d] = mread(v[u->a]); break; + case U_ST: RSTORE(v[u->a], v[u->b]); break; + default: v[u->d] = ev(u->op, v[u->a], v[u->b], v[u->c]); + } + } + for (j = 0; j < B->nso; j++) { o = s + B->so[2 * j]; if ((unsigned)o < MW) m[o] = v[B->so[2 * j + 1]]; } + s += B->delta; + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) nv2[j] = v[B->vs[j]]; + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) var[j] = nv2[j]; + if (B->term == T_BR) { b = B->s1; continue; } + if (B->term == T_CBR) { + if (!v[B->cv]) { if (B->s1 >= 0) { b = B->s1; continue; } t = B->x1; } + else { if (B->s2 >= 0) { b = B->s2; continue; } t = B->x2; } + } else if (B->term == T_JMP) t = v[B->cv]; + else if (B->term == T_CALL) { m[r++] = B->x2; t = v[B->cv]; } + else t = m[--r]; + break; + } + for (j = 0; j < R->np; j++) if ((unsigned)(fp + R->ps[j]) < MW) m[fp + R->ps[j]] = var[R->pv[j]]; + *ps = s; *pr = r; + return t; +} +#ifndef ZYLLVM +static void rforget(Rg *R) { (void)R; } +static void rmark(Rg *R) { int x; for (x = R->lo; x < R->hi; x++) rcov[x] = 1; } +static void rcompile(Rg *R, int eager) { (void)R; (void)eager; } +#endif +#ifdef ZYLLVM + +/* ---- o3 regions in llvm: one function per region, vars in allocas (so + mem2reg makes them ssa across blocks), each block's micro-ops as ir, then + the O3 pipeline. f(mem, regs, entry) returns the next vm address. */ +typedef int (*RFn)(int *mem, int *regs, int ent); +static int nregions; +static LLVMValueRef rvv[RMAXV]; +static void rforget(Rg *R) { R->nat = 0; } +static void rmark(Rg *R) { int x; for (x = R->lo; x < R->hi; x++) rcov[x] = lcov[x] = 1; } +static void rspill_ir(Rg *R) +{ + LLVMValueRef fp = LLVMBuildLoad2(bd, i32t, rvv[0], ""); + int j; + for (j = 0; j < R->np; j++) st(add(fp, R->ps[j]), LLVMBuildLoad2(bd, i32t, rvv[R->pv[j]], "")); +} +static LLVMBasicBlockRef rexit_bb(Rg *R, int t) +{ + LLVMBasicBlockRef here = LLVMGetInsertBlock(bd), x = newbb(); + LLVMPositionBuilderAtEnd(bd, x); + rspill_ir(R); leave(K32(t)); + LLVMPositionBuilderAtEnd(bd, here); + return x; +} +/* m[a] = v, through lhook if some compiled code covers the word */ +static void rstore_ir(LLVMValueRef a, LLVMValueRef b) +{ + LLVMBasicBlockRef in = newbb(), cv = newbb(), plain = newbb(), out = newbb(); + LLVMValueRef v, args[2]; LLVMTypeRef at[2]; + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntULT, a, K32(MW), ""), in, out); + LLVMPositionBuilderAtEnd(bd, in); + v = LLVMBuildLoad2(bd, i8t, LLVMBuildGEP2(bd, i8t, cptr(lcov), &a, 1, ""), ""); + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntNE, v, LLVMConstInt(i8t, 0, 0), ""), cv, plain); + LLVMPositionBuilderAtEnd(bd, plain); st(a, b); LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, cv); + at[0] = i32t; at[1] = i32t; args[0] = a; args[1] = b; + callp((void *)lhook, i32t, at, 2, args); + LLVMBuildBr(bd, out); + LLVMPositionBuilderAtEnd(bd, out); +} +static void *lregion(Rg *R) +{ + char name[40]; LLVMTypeRef pt[3], ft; LLVMValueRef ent, sw, *val, s0, fp, r; + LLVMBasicBlockRef *bb, eb, dflt; + LLVMOrcExecutorAddress addr; LLVMErrorRef err; LLVMPassBuilderOptionsRef po; + int b, i, j, e; + sprintf(name, "o3_%d_%d", R->lo, nregions++); + mod_ = LLVMModuleCreateWithNameInContext(name, ctx); + pt[0] = ptrt; pt[1] = ptrt; pt[2] = i32t; + ft = LLVMFunctionType(i32t, pt, 3, 0); + fn_ = LLVMAddFunction(mod_, name, ft); + vm_ = LLVMGetParam(fn_, 0); vregs = LLVMGetParam(fn_, 1); ent = LLVMGetParam(fn_, 2); + LLVMPositionBuilderAtEnd(bd, newbb()); + vs = LLVMBuildAlloca(bd, i32t, "s"); vr = LLVMBuildAlloca(bd, i32t, "r"); + for (j = 0; j < R->nv; j++) rvv[j] = LLVMBuildAlloca(bd, i32t, ""); + { LLVMValueRef r0 = K32(0), r1 = K32(1); + sets(LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r0, 1, ""), "")); + LLVMBuildStore(bd, LLVMBuildLoad2(bd, i32t, LLVMBuildGEP2(bd, i32t, vregs, &r1, 1, ""), ""), vr); } + bb = malloc(R->nb * sizeof *bb); + for (b = 0; b < R->nb; b++) bb[b] = newbb(); + dflt = newbb(); + sw = LLVMBuildSwitch(bd, ent, dflt, (unsigned)R->ne); + for (e = 0; e < R->ne; e++) { + eb = newbb(); + LLVMAddCase(sw, K32(e), eb); + LLVMPositionBuilderAtEnd(bd, eb); + fp = ld(K32(ZFP)); + LLVMBuildStore(bd, fp, rvv[0]); + for (j = 1; j < R->nv; j++) LLVMBuildStore(bd, safeld(add(fp, R->slot[j])), rvv[j]); + LLVMBuildBr(bd, bb[R->entb[e]]); + } + LLVMPositionBuilderAtEnd(bd, dflt); leave(K32(-1)); + val = calloc(R->maxnv + 1, sizeof *val); + for (b = 0; b < R->nb; b++) { + RB *B = &R->b[b]; + LLVMPositionBuilderAtEnd(bd, bb[b]); + s0 = gets(); + for (i = 0; i < B->n; i++) { + Uop *u = &B->u[i]; + LLVMValueRef a = nargs(u->op) > 0 ? val[u->a] : 0, x = nargs(u->op) > 1 ? val[u->b] : 0, c = nargs(u->op) > 2 ? val[u->c] : 0; + switch (u->op) { + case U_LI: val[u->d] = K32(u->imm); break; + case U_VGET: val[u->d] = LLVMBuildLoad2(bd, i32t, rvv[u->imm], ""); break; + case U_SLD: val[u->d] = ld(add(s0, u->imm)); break; + case U_LD: val[u->d] = safeld(a); break; + case U_ST: rstore_ir(a, x); break; + default: val[u->d] = ir_op(u->op, a, x, c); + } + } + for (j = 0; j < B->nso; j++) st(add(s0, B->so[2 * j]), val[B->so[2 * j + 1]]); + sets(add(s0, B->delta)); + for (j = 1; j < R->nv; j++) if (B->vs[j] >= 0) LLVMBuildStore(bd, val[B->vs[j]], rvv[j]); + switch (B->term) { + case T_BR: LLVMBuildBr(bd, bb[B->s1]); break; + case T_CBR: + LLVMBuildCondBr(bd, LLVMBuildICmp(bd, LLVMIntEQ, val[B->cv], K32(0), ""), + B->s1 >= 0 ? bb[B->s1] : rexit_bb(R, B->x1), B->s2 >= 0 ? bb[B->s2] : rexit_bb(R, B->x2)); + break; + case T_CALL: + r = LLVMBuildLoad2(bd, i32t, vr, ""); st(r, K32(B->x2)); LLVMBuildStore(bd, add(r, 1), vr); + rspill_ir(R); leave(val[B->cv]); + break; + case T_RET: + r = add(LLVMBuildLoad2(bd, i32t, vr, ""), -1); LLVMBuildStore(bd, r, vr); + rspill_ir(R); leave(ld(r)); + break; + default: rspill_ir(R); leave(val[B->cv]); + } + } + free(val); free(bb); + po = LLVMCreatePassBuilderOptions(); + if ((err = LLVMRunPasses(mod_, "default", 0, po))) LLVMConsumeError(err); + LLVMDisposePassBuilderOptions(po); + if ((err = LLVMOrcLLJITAddLLVMIRModule(jit, LLVMOrcLLJITGetMainJITDylib(jit), LLVMOrcCreateNewThreadSafeModule(mod_, tsc)))) { + char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; + } + if ((err = LLVMOrcLLJITLookup(jit, &addr, name))) { char *msg = LLVMGetErrorMessage(err); fprintf(stderr, "llvm: %s\n", msg); LLVMDisposeErrorMessage(msg); return 0; } + if (trace) fprintf(stderr, "o3: %d..%d compiled by llvm\n", R->lo, R->hi - 1); + return (void *)(size_t)addr; +} +static void rcompile(Rg *R, int eager) +{ + (void)eager; + if (R->nat || R->nonat || !llvm_ok) return; + if (!(R->nat = lregion(R))) R->nonat = 1; +} +#endif +#define LD(x) ((unsigned)(x) < MW ? m[x] : 0) +static int run(int p) +{ + int s = DS0, r = RS0, w, a, b, xfer = 1; + unsigned long long steps = 0; +#ifdef ZYLLVM + int regs[2]; + if (!getenv("ZYNOLLVM")) llvm_init(); +#endif + while ((unsigned)p < MW) { + if (xfer && (s < DSLIM || r > RSLIM)) { p = s < DSLIM ? MW + 1 : MW + 2; break; } + if (xfer && o3ent[p]) { /* an o3 region */ + Rg *R = rat(p); + if (R) { +#ifdef ZYLLVM + rcompile(R, 0); + if (R->nat) { regs[0] = s; regs[1] = r; p = ((RFn)R->nat)(m, regs, o3ei[p]); s = regs[0]; r = regs[1]; } + else +#endif + p = rexec(R, o3ei[p], &s, &r); + continue; + } + } +#ifdef ZYLLVM + if (xfer && llvm_ok) { /* at a block start: run it compiled, or count it */ + xfer = 0; + if (!lt[p] && hot[p] < 65535 && ++hot[p] == HOT && !(lt[p] = lcompile(p))) hot[p] = 65535; + if (lt[p]) { + regs[0] = s; regs[1] = r; + p = lt[p](m, regs); + s = regs[0]; r = regs[1]; + if (need_flush) { need_flush = 0; ldrop_all(); } + xfer = 1; + continue; + } + } +#endif + 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) { +#ifdef ZYLLVM + if (lcov[a]) lhook(a, b); else +#else + if (rcov[a]) { m[a] = b; rdrop(a); } else +#endif + 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++; xfer = 1; break; + case 7: p = a; s++; xfer = 1; break; + case 8: if (!b) { p = a; xfer = 1; } s += 2; break; + case 9: p = m[--r]; xfer = 1; 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; + case 21: + m[s] = install(a); +#ifdef ZYLLVM + if (need_flush) { need_flush = 0; ldrop_all(); } +#else + if (need_flush) { need_flush = 0; rdrop_all(); memset(rcov, 0, sizeof rcov); } +#endif + break; + default: + if (w / 2 >= XOP0 && w / 2 < XOP0 + NENH && enh[w / 2 - XOP0].live) s = (int)(xexec(&enh[w / 2 - XOP0], m + s) - m); + else p = MW; /* halt: unwired opcodes and the reserved negative ones */ + } + } + if (trace) fprintf(stderr, "interp: %llu steps\n", steps); + return stopped(p); +} +#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; + S[9] = (long)inst_hook; S[10] = (long)xrun; + S[11] = (long)(m + DSLIM); S[12] = (long)(m + RSLIM); + 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); + if (need_flush) { need_flush = 0; jitwrite(1); flush(); jitwrite(0); } + } + return stopped(p); + } +#else + return run(GORG); +#endif + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/bf.zc b/docs/history/17-o3-boundaries/code/examples/bf.zc new file mode 100644 index 0000000..384025a --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/bf.zc @@ -0,0 +1,50 @@ +// a brainfuck compiler. it turns a brainfuck program into zc source, hands +// that to the compiler that's sitting in memory, and runs the result, which on +// arm64 means native code. runs of + - < > fold into one statement each. +// give it a program after a backtick, or it runs the hello world below. +let out[30000], n, depth; +fn emit(s) { let i = 0; while (s[i]) { out[n] = s[i]; n++; i++; } return 0; } +fn emitn(int v) { if (v >= 10) emitn(v / 10); out[n] = '0' + v % 10; n++; return 0; } +// how many times does c repeat from s[i] +int run(s, int i, int c) { int k = 0; while (s[i + k] == c) k++; return k; } + +fn translate(s) +{ + int i = 0, k; + n = 0; depth = 0; + emit("let t[30000], p = 0;\n"); + while (s[i]) { + switch (s[i]) { + case '+', '-': + k = run(s, i, s[i]); + emit("t[p] = (t[p] "); emit(s[i] == '+' ? "+ " : "- "); emitn(k); emit(") & 255;\n"); + i = i + k; continue; + case '>', '<': + k = run(s, i, s[i]); + emit("p "); emit(s[i] == '>' ? "+= " : "-= "); emitn(k); emit(";\n"); + i = i + k; continue; + case '[': emit("while (t[p]) {\n"); depth++; + case ']': emit("}\n"); depth--; + case '.': emit("putc(t[p]);\n"); + case ',': emit("t[p] = eof() ? 0 : getc() & 255;\n"); + } + i++; + } + emit("return 0;\n"); + out[n] = 0; + return depth; +} +let hello = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."; +let prog[20000]; +fn main() +{ + let src = hello, k = 0, lines = 0, i = 0; + while (!eof() && k < 19999) { let c = getc(); if (c != 10) { prog[k] = c; k++; } } + prog[k] = 0; + if (k) src = prog; + if (translate(src)) { puts("unbalanced brackets\n"); return 1; } + while (out[i]) { if (out[i] == 10) lines++; i++; } + puts("compiled to "); putn(lines); puts(" lines of zc, running it:\n"); + evals(out); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/dump.zc b/docs/history/17-o3-boundaries/code/examples/dump.zc new file mode 100644 index 0000000..6082213 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/dump.zc @@ -0,0 +1,32 @@ +// printing any struct with no printing code: the heap knows each object's +// type, and reflection walks its fields +struct person { *char name; int age; }; +struct item { *char name; int count; *person owner; }; + +fn dump(p) +{ + let t = typeof_obj(p), i = 0; + if (!t) { puts("?"); return 0; } + tprint(t); puts(" { "); + while (i < tnfields(t)) { + let ft = tftype(t, i), v = p[tfoff(t, i)]; + if (i) puts(", "); + puts(tfname(t, i)); puts(": "); + if (tkind(ft) == TY_PTR && telem(ft) == typeof(char)) { putc('"'); puts(v); putc('"'); } + else if (tkind(ft) == TY_PTR) { if (v) dump(v); else puts("null"); } + else putn(v); + i++; + } + puts(" }"); + return 0; +} +fn main() +{ + *person ana = new(person); + ana.name = "ana"; ana.age = 30; + *item lamp = new(item); + lamp.name = "lamp"; lamp.count = 3; lamp.owner = ana; + dump(lamp); putc(10); + free(d*lamp); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/echo.zc b/docs/history/17-o3-boundaries/code/examples/echo.zc new file mode 100644 index 0000000..01f28b0 --- /dev/null +++ b/docs/history/17-o3-boundaries/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/17-o3-boundaries/code/examples/fact.zc b/docs/history/17-o3-boundaries/code/examples/fact.zc new file mode 100644 index 0000000..2a218b2 --- /dev/null +++ b/docs/history/17-o3-boundaries/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/17-o3-boundaries/code/examples/hello.zc b/docs/history/17-o3-boundaries/code/examples/hello.zc new file mode 100644 index 0000000..f36a810 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/hello.zc @@ -0,0 +1 @@ +fn main() { puts("hello, world!\n"); return 0; } diff --git a/docs/history/17-o3-boundaries/code/examples/lang.zc b/docs/history/17-o3-boundaries/code/examples/lang.zc new file mode 100644 index 0000000..e4d91c5 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/lang.zc @@ -0,0 +1,53 @@ +// growing the language from inside a program, while it compiles + +// x |> f calls f(x). on a stack machine that's just "call": the value is +// already on the stack, under f's address. +immediate fn pipe_op() { next(); add_binop("|>", 1, "c"); return 0; } +pipe_op + +// unless (c) stmt +immediate fn unless() +{ + let a; + next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not + a = hole(); op(O_JZ); + substmt(); + setlit(a, here); + return 0; +} +// assert (c): the failure message carries the line it was written on +fn assert_fail(int line) { puts("assertion failed on line "); putn(line); putc(10); halt(); return 0; } +immediate fn assert() +{ + let a, l = tline; + next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")")); + emitseq(useq[0], ulen[0]); // not: the jump below skips the failure when it holds + a = hole(); op(O_JZ); + lit(l); callname(intern("assert_fail")); op(O_DROP); + setlit(a, here); + return 0; +} +// times N { body }: the body pasted N times, at compile time +immediate fn times() +{ + let n, b, i = 0; + next(); n = tv; next(); + b = grab(); + while (i < n) { feed(qdup(b)); i++; } + free(d*b); + return 0; +} + +fn double(x) { return x * 2; } +fn inc(x) { return x + 1; } +fn main() +{ + putn(5 |> double |> inc |> double); putc(10); + unless (1 > 2) puts("one isn't bigger than two\n"); + times 3 { putc('*'); } + putc(10); + assert(double(4) == 8); + assert(inc(1) == 3); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/life.zc b/docs/history/17-o3-boundaries/code/examples/life.zc new file mode 100644 index 0000000..a43d660 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/life.zc @@ -0,0 +1,38 @@ +// conway's life on a 10 x 20 torus, with typed 2d arrays in a struct. +// a glider walks diagonally and wraps around the edges. +const H = 10, W = 20; +struct board { [10][20]int c; }; + +int get(*board b, int y, int x) { return b.c[(y + H) % H][(x + W) % W]; } +fn step(*board from, *board to) +{ + for (int y = 0; y < H; y++) + for (int x = 0; x < W; x++) { + int n = 0; + for (int dy = 0 - 1; dy <= 1; dy++) + for (int dx = 0 - 1; dx <= 1; dx++) + if (dy || dx) n += get(from, y + dy, x + dx); + to.c[y][x] = n == 3 || (n == 2 && from.c[y][x]); + } + return 0; +} +fn show(*board b, int gen) +{ + puts("generation "); putn(gen); putc(10); + for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) putc(b.c[y][x] ? '#' : '.'); putc(10); } + return 0; +} +fn main() +{ + *board a = new(board), b = new(board); + a.c[0][1] = 1; a.c[1][2] = 1; a.c[2][0] = 1; a.c[2][1] = 1; a.c[2][2] = 1; + // two generations a pass, a -> b -> a: owned boards can't be swapped + // through a temporary, since the analyzer can't follow that + for (int g = 0; g <= 40; g += 2) { + if (g % 20 == 0) show(a, g); + step(a, b); + step(b, a); + } + free(d*a); free(d*b); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/lists.zc b/docs/history/17-o3-boundaries/code/examples/lists.zc new file mode 100644 index 0000000..3cf0206 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/lists.zc @@ -0,0 +1,34 @@ +// ownership in practice: a list owns its boxes. nothing here calls free; +// everything is released at the end of the block that owns it. +.u box(v) { let b = new(1); b[0] = v; return u*b; } +.u mklist(cap) { let l = new(cap + 1); l[0] = 0; return u*l; } +// item m*arrives (it was given down), and goes d*on into the borrowed list +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn show(.m l) +{ + let i = 1; + putc('['); + while (i <= l[0]) { if (i > 1) putc(' '); putn(l[i][0]); i++; } + putc(']'); + return 0; +} +.u squares(n) { + let l = mklist(n), i = 0; + while (i < n) { + let b = box(i * i); + push(l, d*b); + i++; + } + return u*l; +} +fn main() +{ + let before = live_objects(); + { + let 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/17-o3-boundaries/code/examples/mandel.zc b/docs/history/17-o3-boundaries/code/examples/mandel.zc new file mode 100644 index 0000000..5810397 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/mandel.zc @@ -0,0 +1,36 @@ +// the mandelbrot set in 16.16 fixed point. the cpu has no fixed-point +// multiply, so one gets wired in: a 32x32 -> 64 bit multiply, keeping the +// middle 32 bits. the jit inlines it as two native multiplies and a shift. +enhance fmul(a, b) micro + "r2 = mul a b; r3 = mulhs a b" + "; r3 = shl r3 16; r2 = shr r2 16; a = or r3 r2"; + +const ONE = 65536, W = 72, H = 28, MAXIT = 40; +let shades = " .,:;-=+*%#@"; + +int escape(int cx, int cy) { + int x = 0, y = 0, i = 0; + while (i < MAXIT) { + int xx = fmul(x, x), yy = fmul(y, y); + if (xx + yy > 4 * ONE) return i; + y = 2 * fmul(x, y) + cy; + x = xx - yy + cx; + i++; + } + return MAXIT; +} +fn main() +{ + int row = 0; + while (row < H) { + int col = 0, cy = (row * 2400 / (H - 1) - 1200) * ONE / 1000; + while (col < W) { + int cx = (col * 3200 / (W - 1) - 2200) * ONE / 1000, it = escape(cx, cy); + putc(it == MAXIT ? '@' : shades[it * 11 / MAXIT]); + col++; + } + putc(10); + row++; + } + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/primes.zc b/docs/history/17-o3-boundaries/code/examples/primes.zc new file mode 100644 index 0000000..26df0b5 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/primes.zc @@ -0,0 +1,38 @@ +// primes below 60000: an o3 sieve over a fixed array, the primes +// gathered into a growable one, then a few questions asked of them. +// with ZYTRACE=1 the o3 lines show each region being lifted and compiled. + +// marks the composites; f[i] ends up 1 for every prime i +o3 int sieve(fixed []int f) +{ + int n = len(f), c = 0; + for (int i = 2; i < n; i++) f[i] = 1; + for (int i = 2; i * i < n; i++) + if (f[i]) for (int j = i * i; j < n; j += i) f[j] = 0; + for (int i = 2; i < n; i++) c += f[i]; + return c; +} +// the largest gap between neighbours, and where it starts +o3 int gap(fixed []int f, *int at) +{ + int n = len(f), last = 2, best = 0, where = 0; + for (int i = 3; i < n; i++) + if (f[i]) { if (i - last > best) { best = i - last; where = last; } last = i; } + *at = where; + return best; +} +fn main() +{ + fixed []int f = new(fixed []int, 60000); + []int ps = new([]int); + int c = sieve(f), at = 0, twins = 0; + for (int i = 2; i < len(f); i++) if (f[i]) push(ps, i); + o3 { for (int k = 1; k < len(ps); k++) if (ps[k] - ps[k - 1] == 2) twins++; } + puts("primes below 60000: "); putn(c); putc(10); + puts("the last five:"); for (int k = len(ps) - 5; k < len(ps); k++) { putc(' '); putn(ps[k]); } putc(10); + puts("twin pairs: "); putn(twins); putc(10); + int g = gap(f, &at); + puts("widest gap: "); putn(g); puts(", after "); putn(at); putc(10); + free(d*f); free(d*ps); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/quine.zc b/docs/history/17-o3-boundaries/code/examples/quine.zc new file mode 100644 index 0000000..23be8cb --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/quine.zc @@ -0,0 +1 @@ +let s="let s=#;fn main(){let i=0;while(s[i]){if(s[i]==35){putc(34);puts(s);putc(34);}else putc(s[i]);i++;}putc(10);return 0;}";fn main(){let i=0;while(s[i]){if(s[i]==35){putc(34);puts(s);putc(34);}else putc(s[i]);i++;}putc(10);return 0;} diff --git a/docs/history/17-o3-boundaries/code/examples/repl.zc b/docs/history/17-o3-boundaries/code/examples/repl.zc new file mode 100644 index 0000000..b7b81b8 --- /dev/null +++ b/docs/history/17-o3-boundaries/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. +let buf[4000]; +fn readchunk() +{ + let 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() +{ + let 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(d*q); + } + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/selfpatch.zc b/docs/history/17-o3-boundaries/code/examples/selfpatch.zc new file mode 100644 index 0000000..074ccec --- /dev/null +++ b/docs/history/17-o3-boundaries/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() +{ + let 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/17-o3-boundaries/code/examples/staged.zc b/docs/history/17-o3-boundaries/code/examples/staged.zc new file mode 100644 index 0000000..5f6342e --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/staged.zc @@ -0,0 +1,35 @@ +// staged code: a program writes a specialized function as source, compiles it +// while running, and calls it. here, polynomials with their coefficients baked +// in as constants, so there's no loop and no array left at runtime. +let buf[2000], n; +fn put(s) { let i = 0; while (s[i]) { buf[n] = s[i]; n++; i++; } return 0; } +fn putnum(int v) { if (v >= 10) putnum(v / 10); buf[n] = '0' + v % 10; n++; return 0; } + +// coefficients c[0] + c[1] x + ... in horner form: ((c3 x + c2) x + c1) x + c0 +fn specialize(*int c, int deg) +{ + n = 0; + put("fn poly(x) { return "); + for (int i = 0; i < deg; i++) put("("); + if (c[deg] < 0) { put("0 - "); putnum(0 - c[deg]); } else putnum(c[deg]); + for (int i = deg - 1; i >= 0; i--) { + put(") * x "); + if (c[i] < 0) { put("- "); putnum(0 - c[i]); } else { put("+ "); putnum(c[i]); } + } + put("; }"); + buf[n] = 0; + return buf; +} +fn main() +{ + [4]int c; + c[0] = 7; c[1] = 0 - 3; c[2] = 0; c[3] = 2; // 2x^3 - 3x + 7 + let src = specialize(c, 3), q = tokens(src); + puts(src); putc(10); + load(q); // compiled now, into the running program + free(d*q); + let f = sval[lookups("poly")]; // and found by name in the compiler's symbol table + for (int x = 0 - 2; x <= 3; x++) { putn(f(x)); putc(' '); } + putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/tree.zc b/docs/history/17-o3-boundaries/code/examples/tree.zc new file mode 100644 index 0000000..90a01d4 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/tree.zc @@ -0,0 +1,28 @@ +// a binary search tree where every node owns its children. there's no free +// anywhere: when the root's block ends, the whole tree goes with it. +struct node { int v; *node left, right; }; + +*node.u leaf(int v) { *node n = new(node); n.v = v; return u*n; } +// n is borrowed; storing a new leaf into it makes n the leaf's owner +fn insert(*node.m n, int v) +{ + if (v < n.v) { if (n.left) insert(n.left, v); else n.left = leaf(v); } + else { if (n.right) insert(n.right, v); else n.right = leaf(v); } + return 0; +} +fn walk(*node n) { if (!n) return 0; walk(n.left); putn(n.v); putc(' '); walk(n.right); return 0; } +int height(*node n) { if (!n) return 0; int l = height(n.left), r = height(n.right); return 1 + (l > r ? l : r); } + +fn main() +{ + let before = live_objects(); + { + *node root = leaf(50); + int x = 7; + for (int i = 0; i < 30; i++) { x = (x * 37 + 11) % 100; insert(root, x); } + walk(root); putc(10); + puts("height "); putn(height(root)); puts(", live objects "); putn(live_objects() - before); putc(10); + } + puts("after the block: "); putn(live_objects() - before); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/typed.zc b/docs/history/17-o3-boundaries/code/examples/typed.zc new file mode 100644 index 0000000..3bba399 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/typed.zc @@ -0,0 +1,44 @@ +// types: structs, a generic container, and looking at it all through reflection +typecheck on; +struct point { int x, y; }; +struct vec { int len, cap; *T items; }; + +*vec.u mkvec(int cap) { + *vec v = new(vec); + v.cap = cap; + v.items = new(T, cap); + return u*v; +} +// x is given away (.d): the vector's memory holds it from now on, and the +// collector looks after it +bool push(*vec v, T.d x) { + if (v.len == v.cap) { free(d*x); return 0; } + v.items[v.len] = d*x; + v.len++; + return 1; +} +fn show(word t) +{ + let i = 0; + tprint(t); puts(" is "); putn(tsize(t)); puts(" words: "); + while (i < tnfields(t)) { if (i) puts(", "); puts(tfname(t, i)); puts(" "); tprint(tftype(t, i)); i++; } + putc(10); + return 0; +} +int main() { + *vec<*point> v = mkvec<*point>(4); + int i = 0; + while (i < 3) { + *point p = new(point); + p.x = i; p.y = i * i; + push(v, d*p); + i++; + } + puts("last: "); putn(v.items[2].y); putc(10); + show(typeof(point)); + show(typeof(*v)); + puts("push is "); tprint(sigof(push)); putc(10); + // generic code is compiled once, so what mkvec stamped is vec + puts("the heap says v is a "); tprint(typeof_obj(v)); puts(", and v.items[0] is a "); tprint(typeof_obj(v.items[0])); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/examples/wiring.zc b/docs/history/17-o3-boundaries/code/examples/wiring.zc new file mode 100644 index 0000000..d5e64f4 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/examples/wiring.zc @@ -0,0 +1,19 @@ +// virtual enhancements: custom opcodes wired into the cpu while compiling. +// the recipes run through the core's optimizer; the jit inlines the result. +enhance popcount(x) micro + "r1 = shr x 1; r1 = and r1 0x55555555; x = sub x r1" + "; r1 = shr x 2; r1 = and r1 0x33333333; x = and x 0x33333333; x = add x r1" + "; r1 = shr x 4; x = add x r1; x = and x 0x0f0f0f0f; x = mul x 0x01010101; x = shr x 24"; +enhance div10(x) micro "x = udiv x 10"; // becomes a multiply-high, no divide +enhance hypot2(a, b) vm { 0 $ * ~ 0 $ * + }; // lifted from vm code +enhance 2 minmax(a, b) micro "r2 = min a b; r1 = max a b; r0 = r2"; +let lo, hi; +fn main() +{ + putn(popcount(0xff00ff)); putc(' '); + putn(div10(12345)); putc(' '); + putn(hypot2(3, 4)); putc(' '); + asm { 9 4 minmax hi ! lo ! } + putn(lo); putc('/'); putn(hi); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/genome.h b/docs/history/17-o3-boundaries/code/genome.h new file mode 100644 index 0000000..46aa7aa --- /dev/null +++ b/docs/history/17-o3-boundaries/code/genome.h @@ -0,0 +1,5262 @@ +#define GORG 786432 +static const int genome[] = { +1966081,1310721,4,1728715,14,864582,870550,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1572913,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,42,1572933, +14,1,1310721,2,3,26,1310721,4,18,0,0,2,1,786486,0,786480, +786482,786484,97,0,98,0,97,32,61,32,115,100,105,118,32,97, +32,98,0,1,0,2,1,786512,0,786506,786508,786510,97,0,98,0, +97,32,61,32,115,114,101,109,32,97,32,98,0,2,0,2, +1,786538,0,786532,786534,786536,97,0,98,0,97,32,61,32,115,104, +108,32,97,32,98,0,3,0,1,1,786560,0,786557,786558,107,0, +114,49,32,61,32,108,100,32,54,53,53,51,54,48,59,32, +107,32,61,32,97,100,100,32,114,49,32,107,0,4,0,2, +1,786602,0,786596,786598,786600,105,0,110,0,105,32,61,32,108,116, +117,32,105,32,110,59,32,105,32,61,32,120,111,114,32,105, +32,49,0,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1573289,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,24,1,1573311,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40, +1573359,16,1966081,1310721,4,1579223,12,20,1573367,14,1,1310721,2,1,26,1310721, +4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1573415,16,1966081,1310721, +4,1579223,12,22,1573423,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +1,28,1310721,4,1310721,2,1835009,40,1573471,16,1966081,1310721,4,1579223,12,0, +1,1573481,14,1,1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1573529,16,1966081,1310721,4,1579223,12,1310721,2,4,1, +1310721,2,3,26,4,1310721,2,2,1310721,2,3,26,2,26,2,1573635, +16,1310721,2,2,1310721,2,3,26,2,26,2,1573255,12,8,1310721,2, +3,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1573547, +14,1,1573643,14,1,1310721,2,5,26,1310721,4,18,1310721,2,29,28, +1310721,4,1310721,2,1835009,40,1573691,16,1966081,1310721,4,1579223,12,1310721,2,4, +1,1310721,2,27,26,4,1310721,2,2,1,40,1573757,16,91,1573255,12, +8,1310721,2,1,1310721,2,2,28,10,3,6,10,4,8,1310721,2, +2,1,40,1573811,16,1573797,14,50,49,52,55,52,56,51,54,52, +56,0,1573775,1573495,12,8,1,1574025,14,3,1573949,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,46,26,10,3,6,10,4,8,1310721,2, +1310721,2,2,21,44,10,3,6,10,4,8,1310721,2,2,1,6, +1,10,28,34,63,38,3,26,1573945,16,1573949,14,1573811,14,1310721,2, +27,26,2,1574017,16,1310721,2,3,26,1310721,2,27,26,1,6,2, +-1,26,1,6,5,6,4,10,8,26,2,1573255,12,8,1573949,14, +1,1574025,14,1,1310721,2,29,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1574073,16,1966081,1310721,4,1579223,12,1310721,2,4,1, +1310721,2,3,26,4,1310721,2,2,1310721,2,3,26,2,26,2,1574153, +16,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1574091,14,1310721,2,3,26,2,1574169,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1574217,16,1966081, +1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1,1310721,2,5, +26,4,1310721,2,2,1310721,2,5,26,2,26,2,1574361,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,1574363,14,1,1574405,16,1310721, +2,5,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1574245,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,1574477,14,1,1310721,2,7,26,1310721,4,18,1310721,2,9, +28,1310721,4,1310721,2,1835009,40,1574525,16,1966081,1310721,4,1579223,12,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,1574681,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,1574563,14,1,1574689,14,1, +1310721,2,9,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009, +40,1574737,16,1966081,1310721,4,1579223,12,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,1574879,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,1574775,14,1, +1574887,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,1835009,40,1575001,16,1966081,1310721,4,1579223,12,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,1575101, +16,1574965,1310721,2,2,10,3,6,10,4,8,1,1575415,14,1310721,2, +9,26,2,1,40,3,36,1575375,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,1575337,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,1575101,14,1574965,1310721,2,7,26,2,10,3,6, +10,4,8,1310721,2,5,26,2,1575415,14,1,1310721,2,11,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1575463,16,1966081,1310721, +4,1579223,12,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,1575555,16,1574965,1310721,2,2,10,3,6,10,4,8,1,1575791, +14,1310721,2,2,1,40,1575617,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,1575703,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,1574967,12,10,3,6,10,4,8,1310721, +2,5,26,2,1575775,16,1,1310721,2,7,26,2,28,1575791,14,1310721, +2,7,26,2,1575791,14,1,1310721,2,9,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1575839,16,1966081,1310721,4,1579223,12,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,1,40,1310721,2,5,26, +4,1310721,2,3,26,2,1,28,1,6,1,10,28,34,63,38, +3,26,1575923,16,1310721,2,2,1575981,14,1310721,2,2,1310721,2,3,26, +2,1575429,12,8,1310721,2,5,26,2,1575971,16,1,1574965,2,28,1575981, +14,1574965,2,1575981,14,1,1310721,2,7,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1576029,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1310721,2,2,1574901,1310721,2,3,26,2,63, +32,26,2,30,1576079,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,9,28,1310721,4,1310721,2,1835009,40,1576199,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,524289,28,1310721,2,3,26,4,1,1310721, +2,5,26,4,1310721,2,3,26,2,1576495,16,1310721,2,7,26,3, +10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,7,26,2, +26,1310721,2,3,26,2,10,40,3,36,1576359,16,1310721,2,7,26, +1310721,2,7,26,2,1310721,2,7,26,2,26,10,3,6,10,4, +8,1576269,14,1310721,2,2,1310721,2,5,26,2,1310721,2,7,26,2, +26,40,1576407,16,1310721,2,7,26,2,1576503,14,1310721,2,5,26,1310721, +2,5,26,2,1310721,2,7,26,2,26,10,3,6,10,4,8, +1310721,2,3,26,1310721,2,3,26,2,1310721,2,7,26,2,28,10, +3,6,10,4,8,1576233,14,1,1576503,14,1,1310721,2,9,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1576551,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,5,26, +1,10,3,6,10,4,8,1310721,2,2,13,26,1576095,1310721,2,3, +26,2,26,2,10,3,6,10,4,8,1310721,2,2,15,26,1, +10,3,6,10,4,8,1576095,1310721,2,3,26,2,26,2,1576711,16, +1576095,1310721,2,3,26,2,26,2,15,26,1310721,2,2,10,3,6, +10,4,8,1576095,1310721,2,3,26,2,26,1310721,2,2,10,3,6, +10,4,8,1,1576751,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1576799,16,1966081,1310721,4,1579223,12,1310721, +2,3,26,4,1310721,2,4,1310721,2,2,15,26,2,1576875,16,1310721, +2,2,15,26,2,13,26,1310721,2,2,13,26,2,10,3,6, +10,4,8,1576913,14,1576095,1310721,2,3,26,2,26,1310721,2,2,13, +26,2,10,3,6,10,4,8,1310721,2,2,13,26,2,1576969,16, +1310721,2,2,13,26,2,15,26,1310721,2,2,15,26,2,10,3, +6,10,4,8,1,1576977,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1577025,16,1966081,1310721,4,1579223,12, +1310721,2,3,26,4,1310721,2,4,1310721,2,2,1,26,1574901,1310721,2, +3,26,2,26,2,10,3,6,10,4,8,1310721,2,2,3,26, +1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,2,5,26, +1,10,3,6,10,4,8,1310721,2,2,7,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,1,10,3,6,10,4,8,1310721,2,2,1577219,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2, +1835009,40,1577267,16,1966081,1310721,4,1579223,12,3,1310721,2,4,524289,1310721,2, +3,26,4,1574901,1,26,3,10,3,6,10,4,8,1310721,2,2, +65,40,1577411,16,1574901,1310721,2,2,26,1574901,1310721,2,2,3,28,26, +2,1574901,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,1577307, +14,1576093,1310721,10,3,6,10,4,8,1576095,1,65,1574703,12,8,1310721, +2,3,26,2,1310721,40,1577673,16,1310721,2,5,26,1310721,2,3,26, +2,524289,28,1576165,12,10,3,6,10,4,8,1310721,2,7,26,1, +10,3,6,10,4,8,1574901,1310721,2,7,26,2,26,2,1310721,2, +5,26,2,40,1577587,16,1310721,2,7,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1577517,14,1310721,2,3,26,2,1310721,2, +7,26,2,1576991,12,1310721,2,7,26,2,1576517,12,8,1310721,2,3, +26,1310721,2,3,26,2,1310721,2,5,26,2,26,10,3,6,10, +4,8,1577439,14,1,1577681,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,9,28,1310721,4,1310721,2,1835009,40,1577729,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,1310721,2,3,26,4,1310721,2,3,26,2, +65,40,1577831,16,1576095,1310721,2,3,26,2,26,2,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1577833,14,1,1577875,16,1310721,2,3,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1577751,14,1310721,2,3,26,2,65,40, +3,36,1577903,16,1,1578153,14,1310721,2,5,26,1576095,1310721,2,3,26, +2,26,2,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2, +3,26,2,1576765,12,8,1310721,2,3,26,2,1310721,2,2,10,40, +1578115,16,1310721,2,3,26,1,6,2,1,6,-1,26,5,6,4, +10,8,8,1310721,2,7,26,1310721,2,5,26,2,1574901,1310721,2,3, +26,2,26,2,26,10,3,6,10,4,8,1310721,2,7,26,2, +1310721,2,3,26,2,1576991,12,1310721,2,3,26,2,1576517,12,8,1577965, +14,1310721,2,5,26,2,1310721,2,2,1576991,12,8,1310721,2,5,26, +2,1578153,14,1,1310721,2,9,26,1310721,4,18,0,1310721,2,11,28, +1310721,4,1310721,2,1835009,40,1578203,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,3,26,2,1310721,2,3,26,4,1574901,1310721,2,3,26, +2,26,2,1310721,2,5,26,4,3,1578875,16,1310721,2,7,26,1310721, +2,2,524289,28,10,3,6,10,4,8,1310721,2,5,26,2,1310721, +2,7,26,2,1576165,12,40,3,36,1578331,16,1578875,14,1310721,2,9, +26,524289,1310721,2,7,26,2,1310721,2,5,26,2,36,26,10,3, +6,10,4,8,1310721,2,9,26,2,5,26,2,1,28,1,6, +1,10,28,34,63,38,1,10,28,1578429,16,3,1578501,14,1310721,2, +9,26,2,3,26,2,1310721,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,1578511,16,3,1578583,14,1310721,2,9,26,2,1,26,2,1310721, +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,1578591,16,1578875,14,1310721, +2,9,26,2,1310721,2,3,26,2,1576765,12,8,1310721,2,9,26, +2,1310721,2,2,40,1578717,16,1310721,2,2,1,26,1,10,3,6, +10,4,8,1310721,2,2,7,26,1,10,3,6,10,4,8,1310721, +2,1310721,2,9,26,2,10,3,6,10,4,8,1578773,14,1310721,2, +9,26,2,1,26,1,10,3,6,10,4,8,1310721,2,9,26, +2,7,26,1,10,3,6,10,4,8,1310721,2,3,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1310721,2,5,26,1310721, +2,5,26,2,1310721,2,5,26,2,26,10,3,6,10,4,8, +1310721,2,2,1310721,2,3,26,2,1576991,12,8,1578257,14,1310721,2,2, +1310721,2,3,26,2,1576991,12,1310721,2,3,26,2,1576517,12,8,1578167, +1310721,2,2,1310721,2,5,26,2,26,10,3,6,10,4,8,1, +1578951,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1578999,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2, +2,524289,13,26,40,3,36,1579065,16,1310721,2,2,1576093,2,40,1, +6,1,10,28,34,63,38,1,10,28,1579067,14,1,1579147,16,1310721, +2,2,7,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,1579149,14,1,1579201,16,1310721,2,2,9,1,10,28,26, +2,3,32,1,6,1,10,28,34,63,38,1,10,28,1579203,14, +1,1579209,14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721, +4,1310721,2,1835009,40,1579257,16,1966081,1310721,4,1579223,12,1579313,14,122,121, +58,32,102,114,97,109,101,32,115,116,97,99,107,32,111,118, +101,114,102,108,111,119,10,0,1579261,1573495,12,8,1573437,12,8,1, +1579335,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1579383,16,1966081,1310721,4,1579223,12,1579435,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,1579387,1573495,12,8,1573437,12,8,1,1579457,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009, +40,1579505,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,13,26, +1310721,2,3,26,4,7,1310721,2,5,26,4,1310721,2,2,1,40, +1579579,16,1310721,2,3,26,13,10,3,6,10,4,8,1574901,1310721,2, +5,26,2,26,2,1310721,2,3,26,2,40,1579649,16,1310721,2,5, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1579579,14, +1310721,2,7,26,1310721,2,5,26,2,1577695,12,10,3,6,10,4, +8,1310721,2,7,26,2,1,6,1,10,28,34,63,38,3,26, +1579747,16,1576163,2,1,6,1,10,28,34,63,38,1,10,28,1579749, +14,1,1579793,16,1584157,12,8,1310721,2,7,26,1310721,2,5,26,2, +1577695,12,10,3,6,10,4,8,1310721,2,7,26,2,1,6,1, +10,28,34,63,38,3,26,1579833,16,1579349,12,8,1310721,2,9,26, +1310721,2,7,26,2,13,26,10,3,6,10,4,8,1310721,2,7, +26,2,5,26,3,10,3,6,10,4,8,1310721,2,7,26,2, +7,26,1310721,2,9,26,2,1459366445,36,10,3,6,10,4,8,1310721, +2,7,26,2,9,26,1,10,3,6,10,4,8,1310721,2,7, +26,2,11,26,1,1310721,2,2,28,3,28,10,3,6,10,4, +8,1310721,2,9,26,2,1580019,14,1,1310721,2,11,26,1310721,4,18, +1310721,2,7,28,1310721,4,1310721,2,1835009,40,1580067,16,1966081,1310721,4,1579223, +12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1579471,12,1310721,2, +5,26,4,1310721,2,5,26,2,3,1,10,28,26,1310721,2,3, +26,2,10,3,6,10,4,8,1310721,2,5,26,2,1,1310721,2, +5,26,2,13,1,10,28,26,2,13,28,1574703,12,8,1310721,2, +5,26,2,1580205,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1580253,16,1966081,1310721,4,1579223,12,1310721,2, +4,1310721,2,2,1,1580033,12,1580277,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1580325,16,1966081,1310721,4, +1579223,12,1310721,2,4,1310721,2,2,1578965,12,1,6,1,10,28,34, +63,38,3,26,1580371,16,1,1580399,14,1310721,2,2,13,1,10,28, +26,2,13,28,1580399,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1580447,16,1966081,1310721,4,1579223,12,1310721, +2,4,1310721,2,2,1578965,12,1,6,1,10,28,34,63,38,3, +26,1580493,16,3,1580537,14,1310721,2,2,3,1,10,28,26,2,1, +40,1,6,1,10,28,34,63,38,1,10,28,1580547,16,1,1580571, +14,1310721,2,2,3,1,10,28,26,2,1580571,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1580619,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,13,28,1310721,2,3, +26,4,1310721,2,3,26,2,1,26,2,13,28,1310721,2,5,26, +4,1,1310721,2,7,26,4,1310721,2,3,26,2,5,26,5,10, +3,6,10,4,8,1310721,2,7,26,2,1310721,2,5,26,2,40, +1580935,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,1578965,12,1580875,16,1310721, +2,9,26,2,5,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,1580877,14,1,1580897,16,1310721,2,9,26,2,1580585,12,8, +1310721,2,7,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1580715,14,1310721,2,3,26,2,1578169,12,8,1,1580959,14,1,1310721, +2,11,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1581007,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1578965,12,1581039, +16,1310721,2,2,1580585,12,8,1,1581047,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1581095,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1578965,12, +1581163,16,1310721,2,2,5,1,10,28,26,1310721,2,3,26,2,10, +3,6,10,4,8,1310721,2,2,1581175,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1581223,16,1966081,1310721, +4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4, +9,1310721,2,5,26,2,1580033,12,1310721,2,7,26,4,1310721,2,3, +26,2,1310721,2,9,26,4,1310721,2,9,26,2,9,40,1581335,16, +1310721,2,9,26,9,10,3,6,10,4,8,1310721,2,11,26,1310721, +2,9,26,2,1310721,2,2,30,1580219,12,10,3,6,10,4,8, +1310721,2,7,26,2,1,26,1310721,2,3,26,2,10,3,6,10, +4,8,1310721,2,7,26,2,3,26,1310721,2,9,26,2,10,3, +6,10,4,8,1310721,2,7,26,2,5,26,1310721,2,11,26,2, +1310721,2,7,26,2,1581061,12,10,3,6,10,4,8,1310721,2,7, +26,2,7,26,1310721,2,2,10,3,6,10,4,8,1310721,2,7, +26,2,1581547,14,1,1310721,2,13,26,1310721,4,18,1310721,2,17,28, +1310721,4,1310721,2,1835009,40,1581595,16,1966081,1310721,4,1579223,12,1310721,2,3, +26,4,1310721,2,4,1310721,2,2,3,26,2,1310721,2,5,26,4, +1310721,2,2,5,26,2,1310721,2,9,26,4,1,1310721,2,11,26, +4,1310721,2,3,26,2,1310721,2,5,26,2,10,40,3,36,1581705, +16,1,1582259,14,1310721,2,5,26,2,1310721,2,3,26,2,40,1581777, +16,1310721,2,5,26,1310721,2,5,26,2,1310721,2,5,26,2,26, +10,3,6,10,4,8,1581705,14,1310721,2,7,26,1310721,2,5,26, +2,1310721,2,2,7,26,2,30,1580219,12,10,3,6,10,4,8, +1310721,2,15,26,1310721,2,2,1,26,2,1310721,2,2,7,26,2, +30,10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,9,26, +2,1310721,2,15,26,2,1574491,12,8,1310721,2,11,26,2,1310721,2, +15,26,2,40,1582161,16,1310721,2,13,26,1310721,2,7,26,2,1310721, +2,11,26,2,26,2,10,3,6,10,4,8,1310721,2,13,26, +2,1578965,12,1582075,16,1310721,2,13,26,2,5,1,10,28,26,2, +1310721,2,9,26,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1582077,14,1,1582123,16, +1310721,2,13,26,2,5,1,10,28,26,1310721,2,7,26,2,10, +3,6,10,4,8,1310721,2,11,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1581907,14,1310721,2,2,5,26,1310721,2,7, +26,2,1310721,2,2,1581061,12,10,3,6,10,4,8,1310721,2,2, +3,26,1310721,2,5,26,2,10,3,6,10,4,8,1310721,2,9, +26,2,1580973,12,8,1,1582259,14,1,1310721,2,17,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1582307,16,1966081,1310721,4,1579223, +12,1310721,2,3,26,4,1310721,2,4,1582349,14,122,121,58,32,105, +110,100,101,120,32,0,1582327,1573495,12,8,1310721,2,2,1573657,12,8, +1582419,14,32,111,117,116,32,111,102,32,114,97,110,103,101,32, +40,108,101,110,103,116,104,32,0,1582373,1573495,12,8,1310721,2,3, +26,2,1573657,12,8,1582453,14,41,10,0,1582447,1573495,12,8,1573437,12, +8,1,1582475,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1582523,16,1966081,1310721,4,1579223,12,1310721,2,3, +26,4,1310721,2,4,1310721,2,3,26,2,1,40,1582563,16,3,1582613, +14,1310721,2,3,26,2,1310721,2,2,1,26,2,40,3,36,1, +6,1,10,28,34,63,38,1,10,28,1582645,16,1310721,2,3,26, +2,1310721,2,2,1,26,2,1582273,12,8,1310721,2,2,5,26,2, +1310721,2,3,26,2,1310721,2,2,7,26,2,30,26,1582689,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1582737,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4, +1310721,2,2,1310721,2,2,1,26,2,3,26,1581561,12,8,1310721,2, +2,5,26,2,1310721,2,2,1,26,2,26,1310721,2,3,26,2, +10,3,6,10,4,8,1310721,2,3,26,2,1310721,2,2,5,26, +2,1581061,12,8,1310721,2,2,1,26,1310721,2,2,1,26,2,3, +26,10,3,6,10,4,8,1,1582903,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1582951,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,1,26,2,1,6,1,10, +28,34,63,38,3,26,1583009,16,3,1,10,28,1,1582273,12,8, +1310721,2,2,1,26,1310721,2,2,1,26,2,3,28,10,3,6, +10,4,8,1310721,2,2,5,26,2,1310721,2,2,1,26,2,26, +2,1583081,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1583129,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1310721,2,2,1,26,2,1310721,2,2,7,26,2, +30,1310721,2,5,26,4,1310721,2,3,26,2,1,40,1583221,16,1310721, +2,3,26,1,10,3,6,10,4,8,1310721,2,2,1310721,2,3, +26,2,1581561,12,8,1310721,2,3,26,2,1310721,2,2,7,26,2, +30,1310721,2,5,26,2,10,40,1583353,16,1310721,2,2,5,26,2, +1310721,2,5,26,2,26,1,1310721,2,3,26,2,1310721,2,2,7, +26,2,30,1310721,2,5,26,2,28,1574703,12,8,1310721,2,2,1, +26,1310721,2,3,26,2,10,3,6,10,4,8,1,1583393,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1583441,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26, +2,1583465,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1583513,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,3,26,2,1583537,14,1,1310721,2,3,26,1310721,4,18,0, +0,0,0,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1583593,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,1578965,12,1,6,1,10, +28,34,63,38,3,26,1583639,16,3,1583683,14,1310721,2,2,9,1, +10,28,26,2,5,32,1,6,1,10,28,34,63,38,1,10, +28,1583693,16,1,1583837,14,1310721,2,2,9,1,10,28,26,1310721,2, +2,9,1,10,28,26,2,5,34,10,3,6,10,4,8,1583551, +2,32769,40,1583813,16,2031617,1583551,2,26,1310721,2,2,10,3,6,10, +4,8,1583551,1,6,2,1,6,3,26,5,6,4,10,8,8, +1583829,14,1583553,3,10,3,6,10,4,8,1,1583837,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1583885, +16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,1310721,2,3,26,2,40,1583971,16,1310721,2,2,2,1583559,12,8, +1310721,2,1,6,2,1,6,3,26,5,6,4,10,8,8,1583901, +14,1,1583979,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1584027,16,1966081,1310721,4,1579223,12,1583551,2,1584135, +16,1583551,1,6,2,1,6,-1,26,5,6,4,10,8,8,1310721, +2,2031617,1583551,2,26,2,10,3,6,10,4,8,1310721,2,2,1310721, +2,2,1310721,2,2,13,1,10,28,26,2,26,13,28,1583851,12, +8,1584027,14,1,1584143,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1584191,16,1966081,1310721,4,1579223,12,1, +1310721,2,5,26,4,1583551,1,10,3,6,10,4,8,1583553,1,10, +3,6,10,4,8,1725417,12,8,1583993,12,8,1583553,2,1584429,16,1583553, +1,10,3,6,10,4,8,1310721,2,524289,10,3,6,10,4,8, +1310721,2,2,1310721,40,1584425,16,1310721,2,2,5,26,2,7,28,1, +6,1,10,28,34,63,38,3,26,1584379,16,1310721,2,2,13,26, +1310721,2,2,1310721,2,2,1,26,2,26,1583851,12,8,1310721,2,1310721, +2,2,1310721,2,2,1,26,2,26,10,3,6,10,4,8,1583993, +12,8,1584289,14,1584247,14,1310721,2,524289,10,3,6,10,4,8,1310721, +2,2,1310721,40,1584705,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,1584603,16,1310721,2,2,1578169,12,8, +1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1310721,2,1578167,2,10,3,6,10,4,8,1584701,14,1310721,2,2, +5,26,2,7,28,1,6,1,10,28,34,63,38,3,26,1584667, +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,1584447,14, +1576159,1,6,2,1,6,3,26,5,6,4,10,8,8,1576161,1576161, +2,1310721,2,5,26,2,26,10,3,6,10,4,8,1310721,2,5, +26,2,1584779,14,1,1310721,2,7,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1584827,16,1966081,1310721,4,1579223,12,524289,1310721,2, +4,1,1310721,2,3,26,4,1310721,2,2,1310721,40,1584955,16,1310721,2, +2,5,26,2,3,32,1584915,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,1584847,14,1310721,2,3, +26,2,1584971,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1585019,16,1966081,1310721,4,1579223,12,63,1310721,2, +4,1310721,2,2,1,10,40,1585101,16,1576095,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,1585103,14,1,1585141,16,1310721,2,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1585027,14,1576095,1310721,2,2,26,2, +1,6,1,10,28,34,63,38,3,26,1585183,16,1,1585201,14,1574901, +1310721,2,2,26,2,1585201,14,1,1310721,2,3,26,1310721,4,18,0, +0,0,0,0,0,0,0,0,0,0,0,792620,113,64,33,36, +95,126,99,106,122,114,44,63,46,43,45,42,38,124,94,62, +60,37,0,1,0,0,0,0,1,0,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,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,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,1, +28,1310721,4,1310721,2,1835009,40,1590621,16,1966081,1310721,4,1579223,12,1590645,14, +122,99,58,32,108,105,110,101,32,0,1590625,1573495,12,8,1585295,2, +1573657,12,8,1590673,14,58,32,0,1590667,1573495,12,8,1590583,1,6,2, +1,6,3,26,5,6,4,10,8,8,1,1590717,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1590765, +16,1966081,1310721,4,1579223,12,21,1573255,12,8,1590583,2,41,40,3,36, +1590869,16,1590855,14,122,99,58,32,116,111,111,32,109,97,110,121, +32,101,114,114,111,114,115,44,32,115,116,111,112,112,105,110, +103,10,0,1590793,1573495,12,8,1573437,12,8,1,1590877,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1590925, +16,1966081,1310721,4,1579223,12,1590939,14,122,99,58,32,0,1590929,1573495,12, +8,1590583,2,1573657,12,8,1590583,2,3,28,1,6,1,10,28,34, +63,38,3,26,1591021,16,1591009,14,32,101,114,114,111,114,10,0, +1590993,1573495,12,8,1591051,14,1591043,14,32,101,114,114,111,114,115,10, +0,1591025,1573495,12,8,1573437,12,8,1,1591065,14,1,1310721,2,1,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1591113,16,1966081, +1310721,4,1579223,12,1310721,2,4,1590587,12,8,1310721,2,2,1573495,12,8, +21,1573255,12,8,1573437,12,8,1,1591159,14,1,1310721,2,3,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1591207,16,1966081,1310721, +4,1579223,12,1310721,2,4,1590585,2,1,6,1,10,28,34,63,38, +3,26,1591291,16,1587703,2,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1591293,14,1,1591321,16, +1590587,12,8,1310721,2,2,1573495,12,8,1590731,12,8,1,1591329,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1591377,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4, +1590585,2,1,6,1,10,28,34,63,38,3,26,1591471,16,1587703,2, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1591473,14,1,1591535,16,1590587,12,8,1310721,2,2, +1573495,12,8,1591505,14,58,32,0,1591499,1573495,12,8,1310721,2,3,26, +2,1573495,12,8,1590731,12,8,1,1591543,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1591591,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,1591173,12,8,1590585,3,10,3, +6,10,4,8,1585289,2,1,28,1,6,1,10,28,34,63,38, +3,26,1591663,16,1590891,12,8,1604999,12,8,1,1591677,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1591725, +16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,1310721,2,3,26,2,1591343,12,8,1590585,3,10,3,6,10,4, +8,1585289,2,1,28,1,6,1,10,28,34,63,38,3,26,1591817, +16,1590891,12,8,1604999,12,8,1,1591831,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1591879,16,1966081,1310721, +4,1579223,12,1310721,2,4,1587565,2,1591923,16,1587569,2,1,6,1,10, +28,34,63,38,1,10,28,1591925,14,1,1591941,16,1310721,2,2,1591173, +12,8,1,1591949,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1591997,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1587565,2,1592051,16,1587569,2,1,6,1,10, +28,34,63,38,1,10,28,1592053,14,1,1592085,16,1466881,1310721,2,2, +26,2,1310721,2,3,26,2,1591343,12,8,1,1592093,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1592141, +16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2,3,26,4,1310721, +2,2,2,1592249,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,1592159,14,1310721,2,3,26, +2,16385,3,28,32,1592273,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,9,28,1310721,4,1310721,2,1835009,40,1592321,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,1592107,12,1310721,2,3,26,4,3,1592511,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,1592427,16,1592511,14,1310721,2,5,26,2,1310721,2,2,1574183,12,1592465, +16,1310721,2,5,26,2,1592791,14,1310721,2,3,26,1310721,2,3,26, +2,3,26,16385,3,28,32,10,3,6,10,4,8,1592347,14,1310721, +2,7,26,1310721,2,2,1574039,12,10,3,6,10,4,8,1585217,2, +1310721,2,7,26,2,26,5,26,1409025,40,3,36,1592619,16,1592611,14, +115,116,114,105,110,103,32,112,111,111,108,32,102,117,108,108, +0,1592577,1591079,12,8,1585217,2,1,26,1,10,3,6,10,4,8, +1310721,2,5,26,1585217,2,3,26,10,3,6,10,4,8,1310721,2, +5,26,2,1310721,2,2,1310721,2,7,26,2,3,26,1574491,12,8, +1585217,1585217,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,1592791,14,1,1310721,2,9,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1592839,16,1966081,1310721, +4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4, +1585219,2,1310721,2,7,26,4,1585219,2,8193,40,3,36,1592943,16,1592935, +14,115,121,109,98,111,108,32,116,97,98,108,101,32,102,117, +108,108,0,1592899,1591079,12,8,1585219,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,1559041,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,1593289,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1593337,16,1966081,1310721,4,1579223,12,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,1593623,16,1310721,2,3,26,2,1585223, +2,40,3,36,1593427,16,3,1593489,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,1593499,16,3,1593561,14,1417729,1310721,2, +3,26,2,26,2,15,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1593579,16,1310721,2, +3,26,2,1593637,14,1310721,2,3,26,1458689,1310721,2,3,26,2,26, +2,3,28,10,3,6,10,4,8,1593375,14,3,1,10,28,1593637, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1593685,16,1966081,1310721,4,1579223,12,1310721,2,4,1585219,2,1310721, +2,2,10,40,1593783,16,1585219,1,6,2,1,6,-1,26,5,6, +4,10,8,8,1409537,1585219,2,26,2,3,1,10,28,26,1458689,1585219, +2,26,2,10,3,6,10,4,8,1593691,14,1,1593791,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1593839,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1592287,12,1593303, +12,1593865,14,1,1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1593913,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1585227,2,1310721,2,5,26,4,1310721,2,5,26,2, +1593991,16,1585227,1491457,1310721,2,5,26,2,26,2,10,3,6,10,4, +8,1594133,14,1585225,1,6,2,1,6,3,26,5,6,4,10,8, +8,1310721,2,5,26,1585225,2,10,3,6,10,4,8,1310721,2,5, +26,2,16385,40,3,36,1594133,16,1594125,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,1594069,1591079,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,1594217,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1594265,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1310721,2,2,1594427,16,1475073,1310721,2,2,26,2,1310721, +2,3,26,2,1594811,12,8,1310721,2,5,26,1491457,1310721,2,2,26, +2,10,3,6,10,4,8,1491457,1310721,2,2,26,1585227,2,10,3, +6,10,4,8,1585227,1310721,2,2,10,3,6,10,4,8,1310721,2, +1310721,2,5,26,2,10,3,6,10,4,8,1594281,14,1,1594435,14, +1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1594483,16,1966081,1310721,4,1579223,12,1310721,2,4,1587703,2,1594503,16, +1,1594629,14,1587549,2,1587553,2,40,3,36,1594565,16,1594557,14,112,114, +111,103,114,97,109,32,116,111,111,32,98,105,103,0,1594525,1591079, +12,8,1587549,2,1587551,2,26,1310721,2,2,10,3,6,10,4,8, +1587549,1,6,2,1,6,3,26,5,6,4,10,8,8,1,1594629, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1594677,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2, +1310721,2,2,26,3,26,1594449,12,8,1,1594715,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1594763,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1310721,2,2,26,1594449, +12,8,1,1594797,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1594845,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1587703,2,1594875,16,1,1594933,14,1310721,2,2, +1587551,2,26,1310721,2,3,26,2,1310721,2,3,26,2,26,3,26, +10,3,6,10,4,8,1,1594933,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1594981,16,1966081,1310721,4, +1579223,12,1310721,2,4,1310721,2,2,1594643,12,8,15,1594729,12,8,1, +1595015,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1595063,16,1966081,1310721,4,1579223,12,1587549,2,1310721,2,4, +2097153,3,28,1594643,12,8,1310721,2,2,1595097,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1595145,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,3,1585295,2,1592805,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,1595221,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1595269,16,1966081,1310721,4, +1579223,12,1310721,2,4,1442305,1310721,2,2,26,2,3,32,1595319,16,1425921, +1310721,2,2,26,2,1594643,12,8,1,1595395,14,1587703,2,1595333,16,1, +1595395,14,1450497,1310721,2,2,26,1587549,2,1450497,1310721,2,2,26,2,1593879, +12,10,3,6,10,4,8,2097153,3,28,1594643,12,8,1,1595395,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +1835009,40,1595443,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1593303, +12,1310721,2,3,26,4,1310721,2,3,26,2,1,40,1595517,16,1310721, +2,3,26,1310721,2,2,1595111,12,10,3,6,10,4,8,1310721,2, +3,26,2,1595235,12,8,13,1594729,12,8,1,1595549,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1595597, +16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,1594643,12,8,3,1594729,12, +8,1310721,2,2,1595649,16,1310721,2,2,1594643,12,8,27,1594729,12,8, +1,1595657,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1595705,16,1966081,1310721,4,1579223,12,1310721,2,4,1558017, +1310721,2,2,26,2,33,32,1595903,16,1310721,2,3,26,1587761,2,1593303, +12,10,3,6,10,4,8,1310721,2,3,26,2,1,40,3,36, +1595847,16,1417729,1310721,2,3,26,2,26,2,13,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1595849,14,1,1595903,16,1467905,1310721,2,2,26,2,1594643,12,8,45, +1425921,1310721,2,3,26,2,26,2,26,1594729,12,8,1,1595925,14,1467905, +1310721,2,2,26,2,1595563,12,1595925,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1595973,16,1966081,1310721,4, +1579223,12,1589483,1,10,3,6,10,4,8,1589485,3,10,3,6,10, +4,8,1587903,1,10,3,6,10,4,8,1,1596029,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1596077, +16,1966081,1310721,4,1579223,12,1589483,2,1596127,16,1589483,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1589467,1589483,2,26,2,1596187,14,1589485, +2,17,40,1596179,16,1589485,1,6,2,1,6,3,26,5,6,4, +10,8,8,1589485,2,3,28,1596187,14,1,1596187,14,1,1310721,2,1, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1596235,16, +1966081,1310721,4,1579223,12,1310721,2,4,1558017,1310721,2,2,26,1558017,1310721,2, +2,26,2,1558017,1310721,2,2,26,2,3585,32,28,10,3,6,10, +4,8,1587769,2,1,6,1,10,28,34,63,38,3,26,1596327,16, +3,1596361,14,1473025,1310721,2,2,26,2,1,6,1,10,28,34,63, +38,1,10,28,1596371,16,3,1596405,14,1587903,2,65,40,3,36,1, +6,1,10,28,34,63,38,1,10,28,1596415,16,1,1596627,14,1310721, +2,3,26,1596043,12,10,3,6,10,4,8,1310721,2,3,26,2, +1,6,1,10,28,34,63,38,3,26,1596479,16,1,1596627,14,1558017, +1310721,2,2,26,1558017,1310721,2,2,26,2,1310721,2,3,26,2,513, +30,26,10,3,6,10,4,8,1587775,1587903,2,26,1467905,1310721,2,2, +26,2,10,3,6,10,4,8,1587839,1587903,2,26,1310721,2,3,26, +2,10,3,6,10,4,8,1587903,1,6,2,1,6,3,26,5, +6,4,10,8,8,1,1596627,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1596675,16,1966081,1310721,4,1579223, +12,1310721,2,4,1587769,2,1,6,1,10,28,34,63,38,3,26, +1596715,16,3,1596781,14,1556993,1310721,2,2,26,2,1,26,2,23,28, +1,6,1,10,28,34,63,38,1,10,28,1,6,1,10,28, +34,63,38,1,10,28,1596791,16,3,1596851,14,1556993,1310721,2,2,26, +2,7,26,2,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1596861,16,1,1597091,14,1310721,2, +3,26,1590513,2,1611819,12,10,3,6,10,4,8,1587563,1,6,2, +1,6,3,26,5,6,4,10,8,8,1558017,1310721,2,3,26,2, +26,33,10,3,6,10,4,8,1310721,2,3,26,2,1596201,12,8, +1590515,2,1611819,12,8,1587563,1,6,2,1,6,3,26,5,6,4, +10,8,8,1558017,1310721,2,3,26,2,3,26,26,33,10,3,6, +10,4,8,1310721,2,3,26,2,3,26,1596201,12,8,1589487,1310721,2, +2,26,1310721,2,3,26,2,10,3,6,10,4,8,1,1597091,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2, +1835009,40,1597139,16,1966081,1310721,4,1579223,12,1310721,2,4,1589487,1310721,2,2, +26,2,1310721,2,3,26,4,1310721,2,3,26,2,1,6,1,10, +28,34,63,38,3,26,1597207,16,1,1597339,14,1310721,2,2,1595671,12, +8,3,1594729,12,8,5,1594643,12,8,27,1594729,12,8,3,1594729,12, +8,1310721,2,3,26,2,1595671,12,8,5,1594729,12,8,1310721,2,2, +1595671,12,8,3,1594729,12,8,3,1594729,12,8,1310721,2,3,26,2, +3,26,1595671,12,8,5,1594729,12,8,1,1597339,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1597387,16, +1966081,1310721,4,1579223,12,1310721,2,9,26,4,1310721,2,7,26,4,1310721, +2,5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2,11, +26,4,1587551,2,1597459,16,3,1597503,14,1310721,2,2,1310721,2,3,26, +2,40,3,36,1,6,1,10,28,34,63,38,1,10,28,1597513, +16,1,1597845,14,1589307,1,26,1,10,3,6,10,4,8,1589307,3, +26,5,10,3,6,10,4,8,1589307,5,26,1310721,2,2,10,3, +6,10,4,8,1589307,7,26,1310721,2,3,26,2,10,3,6,10, +4,8,1589307,9,26,1310721,2,9,26,2,10,3,6,10,4,8, +1310721,2,11,26,2,1310721,2,9,26,2,40,1597829,16,1589307,11,1310721, +2,11,26,2,26,1310721,2,11,26,2,26,26,1310721,2,5,26, +2,1310721,2,11,26,2,26,2,10,3,6,10,4,8,1589307,13, +1310721,2,11,26,2,26,1310721,2,11,26,2,26,26,1310721,2,7, +26,2,1310721,2,11,26,2,26,2,10,3,6,10,4,8,1310721, +2,11,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1597633,14,1589307,1572879,12,8,1,1597845,14,1,1310721,2,13,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1597893,16,1966081,1310721,4, +1579223,12,1,1310721,2,4,1310721,2,2,1589305,2,40,1598067,16,1310721,2, +3,26,1587905,1310721,2,2,135,30,26,10,3,6,10,4,8,1310721, +2,3,26,2,1,26,2,1310721,2,3,26,2,3,26,2,1310721, +2,3,26,2,7,26,1310721,2,3,26,2,71,26,1310721,2,3, +26,2,5,26,2,1597353,12,8,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1597901,14,1589305,1,10,3,6,10,4, +8,1,1598091,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28, +1310721,4,1310721,2,1835009,40,1598139,16,1966081,1310721,4,1579223,12,1310721,2,4, +1595029,12,1310721,2,3,26,4,15,1594729,12,8,1310721,2,5,26,1587549, +2,10,3,6,10,4,8,1310721,2,2,2,1598251,16,1310721,2,2, +2,1594449,12,8,1310721,2,1,6,2,1,6,3,26,5,6,4, +10,8,8,1598191,14,1,1594449,12,8,1310721,2,3,26,2,1587549,2, +1594811,12,8,1310721,2,5,26,2,1594643,12,8,1,1598303,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40, +1598351,16,1966081,1310721,4,1579223,12,1585301,2,1,28,1,6,1,10,28, +34,63,38,3,26,1598557,16,1585307,2,1598397,16,3,1598423,14,1573381,12, +1,6,1,10,28,34,63,38,1,10,28,1598455,16,1585299,3,1, +10,28,10,3,6,10,4,8,1,1598857,14,1585299,1573325,12,511,32, +10,3,6,10,4,8,1585299,2,193,28,1,6,1,10,28,34, +63,38,3,26,1598553,16,1585307,3,10,3,6,10,4,8,1585299,3, +1,10,28,10,3,6,10,4,8,1,1598857,14,1598789,14,1585301,2, +7,28,1,6,1,10,28,34,63,38,3,26,1598703,16,1585299,1585305, +2,1585303,2,5,38,26,2,1585303,2,7,32,17,30,38,511,32, +10,3,6,10,4,8,1585299,2,1598677,16,1585303,1,6,2,1,6, +3,26,5,6,4,10,8,8,1598699,14,1585299,3,1,10,28,10, +3,6,10,4,8,1598789,14,1585299,1585303,2,2,511,32,10,3,6, +10,4,8,1585299,2,1598767,16,1585303,1,6,2,1,6,3,26,5, +6,4,10,8,8,1598789,14,1585299,3,1,10,28,10,3,6,10, +4,8,1585299,2,21,28,1,6,1,10,28,34,63,38,3,26, +1598849,16,1585297,1,6,2,1,6,3,26,5,6,4,10,8,8, +1,1598857,14,1,1310721,2,1,26,1310721,4,18,1310721,2,13,28,1310721, +4,1310721,2,1835009,40,1598905,16,1966081,1310721,4,1579223,12,1310721,2,7,26, +4,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1585309,1, +6,2,1,6,3,26,5,6,4,10,8,8,1585309,2,65,40, +3,36,1599049,16,1599041,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, +1598989,1591079,12,8,1310721,2,9,26,1540609,1585309,2,65,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,1585289,2,10, +3,6,10,4,8,1310721,2,9,26,2,13,26,1585291,2,10,3, +6,10,4,8,1310721,2,9,26,2,15,26,1585293,2,10,3,6, +10,4,8,1310721,2,9,26,2,17,26,1585299,2,10,3,6,10, +4,8,1310721,2,9,26,2,19,26,1585301,2,10,3,6,10,4, +8,1310721,2,9,26,2,21,26,1585303,2,10,3,6,10,4,8, +1310721,2,9,26,2,25,26,1585297,2,10,3,6,10,4,8,1310721, +2,9,26,2,27,26,1585295,2,10,3,6,10,4,8,1310721,2, +9,26,2,29,26,1587515,2,10,3,6,10,4,8,1310721,2,9, +26,2,63,26,1585305,2,10,3,6,10,4,8,1310721,2,11,26, +1,10,3,6,10,4,8,1310721,2,11,26,2,1587515,2,40,1599889, +16,1310721,2,9,26,2,31,1310721,2,11,26,2,9,30,26,26, +1587517,1310721,2,11,26,2,26,2,10,3,6,10,4,8,1310721,2, +9,26,2,33,1310721,2,11,26,2,9,30,26,26,1587525,1310721,2, +11,26,2,26,2,10,3,6,10,4,8,1310721,2,9,26,2, +35,1310721,2,11,26,2,9,30,26,26,1587533,1310721,2,11,26,2, +26,2,10,3,6,10,4,8,1310721,2,9,26,2,37,1310721,2, +11,26,2,9,30,26,26,1587541,1310721,2,11,26,2,26,2,10, +3,6,10,4,8,1310721,2,11,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1599599,14,1587515,1,10,3,6,10,4,8, +1310721,2,2,3,28,1,6,1,10,28,34,63,38,3,26,1599981, +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,1600069,16,1585301,1,10,3,6,10,4,8,1585307, +1,10,3,6,10,4,8,1585297,3,10,3,6,10,4,8,1598317, +12,8,1310721,2,2,5,28,1,6,1,10,28,34,63,38,3, +26,1600165,16,1585301,5,10,3,6,10,4,8,1585303,1310721,2,3,26, +2,10,3,6,10,4,8,1585297,3,10,3,6,10,4,8,1598317, +12,8,1310721,2,2,7,28,1,6,1,10,28,34,63,38,3, +26,1600277,16,1585301,7,10,3,6,10,4,8,1585305,1310721,2,3,26, +2,10,3,6,10,4,8,1585303,1,10,3,6,10,4,8,1585297, +3,10,3,6,10,4,8,1598317,12,8,1,1600285,14,1,1310721,2, +13,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1600333, +16,1966081,1310721,4,1579223,12,1540609,1585309,2,65,30,26,1310721,2,4,1, +1310721,2,3,26,4,1585289,1310721,2,2,11,26,2,10,3,6,10, +4,8,1585291,1310721,2,2,13,26,2,10,3,6,10,4,8,1585293, +1310721,2,2,15,26,2,10,3,6,10,4,8,1585299,1310721,2,2, +17,26,2,10,3,6,10,4,8,1585301,1310721,2,2,19,26,2, +10,3,6,10,4,8,1585303,1310721,2,2,21,26,2,10,3,6, +10,4,8,1585297,1310721,2,2,25,26,2,10,3,6,10,4,8, +1585295,1310721,2,2,27,26,2,10,3,6,10,4,8,1587515,1310721,2, +2,29,26,2,10,3,6,10,4,8,1585305,1310721,2,2,63,26, +2,10,3,6,10,4,8,1310721,2,3,26,2,1587515,2,40,1600897, +16,1587517,1310721,2,3,26,2,26,1310721,2,2,31,1310721,2,3,26, +2,9,30,26,26,2,10,3,6,10,4,8,1587525,1310721,2,3, +26,2,26,1310721,2,2,33,1310721,2,3,26,2,9,30,26,26, +2,10,3,6,10,4,8,1587533,1310721,2,3,26,2,26,1310721,2, +2,35,1310721,2,3,26,2,9,30,26,26,2,10,3,6,10, +4,8,1587541,1310721,2,3,26,2,26,1310721,2,2,37,1310721,2,3, +26,2,9,30,26,26,2,10,3,6,10,4,8,1310721,2,3, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1600623,14, +1585309,1,6,2,1,6,-1,26,5,6,4,10,8,8,1310721,2, +2,23,26,2,1600959,16,1310721,2,2,3,26,2,1580973,12,8,1, +1600967,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4, +1310721,2,1835009,40,1601015,16,1966081,1310721,4,1579223,12,1310721,2,4,1601065,14, +43,45,42,47,37,61,60,62,33,38,124,94,126,63,58,46, +64,35,36,0,1601025,1310721,2,3,26,4,1310721,2,3,26,2,2, +1601181,16,1310721,2,3,26,2,2,1310721,2,2,28,1,6,1,10, +28,34,63,38,3,26,1601143,16,3,1601189,14,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1601077,14,1,1601189, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721, +2,1835009,40,1601237,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721, +2,4,1,1310721,2,5,26,4,1310721,2,5,26,2,1585235,2,40, +1601667,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,1601453,16,1310721,2,7,26,2,1310721, +2,9,26,2,26,2,1585311,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,1601455,14,1,1601497,16,1310721,2,9,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1601343,14,1310721,2,9,26, +2,1310721,2,2,28,1,6,1,10,28,34,63,38,3,26,1601617, +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,1601619,14,1,1601629,16,3,1601675,14,1310721,2, +5,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1601265, +14,1,1601675,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1601723,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,97,40,3,36,1601789,16,1310721,2,2,115,10,40,3, +36,1,6,1,10,28,34,63,38,1,10,28,1601791,14,1,1601797, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1601845,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2, +195,40,3,36,1601911,16,1310721,2,2,245,10,40,3,36,1,6, +1,10,28,34,63,38,1,10,28,1601913,14,1,1601923,16,3,1602007, +14,1310721,2,2,131,40,3,36,1601983,16,1310721,2,2,181,10,40, +3,36,1,6,1,10,28,34,63,38,1,10,28,1601985,14,1, +1,6,1,10,28,34,63,38,1,10,28,1602017,16,3,1602069,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,1602075,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1602123,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1601689,12,1602157,16,1310721, +2,2,97,28,1602339,14,1310721,2,2,195,40,3,36,1602217,16,1310721, +2,2,205,10,40,3,36,1,6,1,10,28,34,63,38,1, +10,28,1602219,14,1,1602241,16,1310721,2,2,195,28,21,26,1602339,14, +1310721,2,2,131,40,3,36,1602301,16,1310721,2,2,141,10,40,3, +36,1,6,1,10,28,34,63,38,1,10,28,1602303,14,1,1602325, +16,1310721,2,2,131,28,21,26,1602339,14,3,1,10,28,1602339,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1602387,16,1966081,1310721,4,1579223,12,1585299,2,1310721,2,4,1598317,12, +8,1310721,2,2,185,28,1,6,1,10,28,34,63,38,1,10, +28,1602449,16,1310721,2,2,1602687,14,1310721,2,1585299,2,10,3,6,10, +4,8,1598317,12,8,1310721,2,2,221,28,1,6,1,10,28,34, +63,38,3,26,1602515,16,21,1602687,14,1310721,2,2,233,28,1,6, +1,10,28,34,63,38,3,26,1602555,16,19,1602687,14,1310721,2,2, +229,28,1,6,1,10,28,34,63,38,3,26,1602595,16,27,1602687, +14,1310721,2,2,97,28,1,6,1,10,28,34,63,38,3,26, +1602635,16,1,1602687,14,1310721,2,2,203,28,1,6,1,10,28,34, +63,38,3,26,1602675,16,55,1602687,14,1310721,2,2,1602687,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1602735,16,1966081,1310721,4,1579223,12,1310721,2,4,1585299,2,1,40,3,36, +1602791,16,1585299,2,1600981,12,1,6,1,10,28,34,63,38,1,10, +28,1602793,14,1,1602837,16,1310721,2,2,1585299,2,1601203,12,1,6,1, +10,28,34,63,38,1,10,28,1602839,14,1,1602909,16,1585311,1310721,2, +2,26,1585299,2,10,3,6,10,4,8,1310721,2,1,6,2,1, +6,3,26,5,6,4,10,8,8,1598317,12,8,1602741,14,1585311,1310721, +2,2,26,1,10,3,6,10,4,8,1585289,9,10,3,6,10, +4,8,1585291,1585311,1592287,12,10,3,6,10,4,8,1,1602977,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009, +40,1603025,16,1966081,1310721,4,1579223,12,1,1310721,2,4,1585293,3,10,3, +6,10,4,8,3,1603701,16,1585299,2,65,28,1,6,1,10,28, +34,63,38,3,26,1603093,16,3,1603143,14,1585299,2,19,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1603153,16,3,1603203,14,1585299,2,21,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1603213,16,3,1603263,14,1585299,2,27,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1603293, +16,1598317,12,8,1585293,1,10,3,6,10,4,8,1603055,14,1585299,2, +95,28,1,6,1,10,28,34,63,38,1,10,28,1603331,16,1603701, +14,1598317,12,8,1585299,2,95,28,1,6,1,10,28,34,63,38, +3,26,1603477,16,1585299,2,1,40,3,36,1603441,16,1585299,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,1603443,14,1,1603457,16,1598317,12,8,1603369,14, +1585293,1,10,3,6,10,4,8,1603049,14,1585299,2,85,28,1,6, +1,10,28,34,63,38,3,26,1603645,16,1598317,12,8,1585299,2,1, +40,3,36,1603619,16,1585299,2,85,28,1,6,1,10,28,34,63, +38,3,26,1603609,16,1598317,12,8,1585299,2,95,28,1,6,1,10, +28,34,63,38,3,26,1603605,16,1603619,14,1603615,14,1598317,12,8,1603515, +14,1598317,12,8,1585293,1,10,3,6,10,4,8,1603049,14,1585295,1585297, +2,10,3,6,10,4,8,1585311,1,26,95,10,3,6,10,4, +8,3,1602701,12,8,1,1604985,14,1603049,14,1585295,1585297,2,10,3,6, +10,4,8,1585299,2,1,40,1603769,16,1585289,1,10,3,6,10,4, +8,1585291,1,10,3,6,10,4,8,1,1604985,14,1585299,2,1601689,12, +1604191,16,1310721,2,3,26,1,10,3,6,10,4,8,1585299,2,97, +28,1,6,1,10,28,34,63,38,3,26,1604079,16,1598317,12,8, +1585299,2,241,28,1,6,1,10,28,34,63,38,3,26,1603879,16, +3,1603929,14,1585299,2,177,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1604079,16,1598317,12, +8,1310721,2,5,26,1585299,2,1602089,12,10,3,6,10,4,1,40, +3,36,1604033,16,1310721,2,3,26,1310721,2,3,26,2,33,30,1310721, +2,5,26,2,26,10,3,6,10,4,8,1598317,12,8,1603939,14, +1585289,3,10,3,6,10,4,8,1585291,1310721,2,3,26,2,10,3, +6,10,4,8,1,1604985,14,1585299,2,1601689,12,1604145,16,1310721,2,3, +26,1310721,2,3,26,2,21,30,1585299,2,26,97,28,10,3,6, +10,4,8,1598317,12,8,1604079,14,1585289,3,10,3,6,10,4,8, +1585291,1310721,2,3,26,2,10,3,6,10,4,8,1,1604985,14,1585299, +2,1601811,12,1604401,16,1585299,2,1601811,12,1604221,16,3,1604251,14,1585299,2, +1601689,12,1,6,1,10,28,34,63,38,1,10,28,1604335,16,1310721, +2,2,2001,40,1604325,16,1585311,1310721,2,2,26,1585299,2,10,3,6, +10,4,8,1310721,2,1,6,2,1,6,3,26,5,6,4,10, +8,8,1598317,12,8,1604203,14,1585311,1310721,2,2,26,1,10,3,6, +10,4,8,1585289,5,10,3,6,10,4,8,1585291,1585311,1592287,12,10, +3,6,10,4,8,1,1604985,14,1585299,2,79,28,1,6,1,10, +28,34,63,38,3,26,1604575,16,1598317,12,8,1585291,1602353,12,10,3, +6,10,4,8,1585299,2,79,28,1,6,1,10,28,34,63,38, +1,10,28,1604547,16,1604539,14,98,97,100,32,99,104,97,114,97, +99,116,101,114,32,108,105,116,101,114,97,108,0,1604495,1591557,12, +8,1598317,12,8,1585289,3,10,3,6,10,4,8,1,1604985,14,1585299, +2,69,28,1,6,1,10,28,34,63,38,3,26,1604867,16,1598317, +12,8,1585299,2,1,40,3,36,1604685,16,1585299,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,1604687,14,1,1604795,16,1310721,2,3,26,1602353,12,10, +3,6,10,4,8,1310721,2,2,2001,40,1604791,16,1585311,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,1604613,14,1598317,12,8, +1585311,1310721,2,2,26,1,10,3,6,10,4,8,1585289,7,10,3, +6,10,4,8,1585291,1585311,1592287,12,10,3,6,10,4,8,1,1604985, +14,1585311,1,26,1585299,2,10,3,6,10,4,8,1598317,12,8,1585311, +1,26,2,1600981,12,1604921,16,3,1602701,12,1604985,14,1585311,3,26,1, +10,3,6,10,4,8,1585289,9,10,3,6,10,4,8,1585291,1585311, +1592287,12,10,3,6,10,4,8,1,1604985,14,1,1310721,2,7,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1605033,16,1966081, +1310721,4,1579223,12,3,1310721,2,4,1587515,2,1605373,16,1585289,1587517,1,26, +2,10,3,6,10,4,8,1585291,1587525,1,26,2,10,3,6,10, +4,8,1585293,1587533,1,26,2,10,3,6,10,4,8,1585295,1587541,1, +26,2,10,3,6,10,4,8,1310721,2,2,1587515,2,40,1605339,16, +1587517,1310721,2,2,3,28,26,1587517,1310721,2,2,26,2,10,3,6, +10,4,8,1587525,1310721,2,2,3,28,26,1587525,1310721,2,2,26,2, +10,3,6,10,4,8,1587533,1310721,2,2,3,28,26,1587533,1310721,2, +2,26,2,10,3,6,10,4,8,1587541,1310721,2,2,3,28,26, +1587541,1310721,2,2,26,2,10,3,6,10,4,8,1310721,2,1,6, +2,1,6,3,26,5,6,4,10,8,8,1605137,14,1587515,1,6, +2,1,6,-1,26,5,6,4,10,8,8,1,1605383,14,1605919,12, +1605383,14,1,1310721,2,3,26,1310721,4,18,1310721,2,11,28,1310721,4, +1310721,2,1835009,40,1605431,16,1966081,1310721,4,1579223,12,1310721,2,4,1587515,2, +1310721,2,2,10,40,3,36,1605785,16,1310721,2,3,26,1585289,2,10, +3,6,10,4,8,1310721,2,5,26,1585291,2,10,3,6,10,4, +8,1310721,2,7,26,1585293,2,10,3,6,10,4,8,1310721,2,9, +26,1585295,2,10,3,6,10,4,8,1605919,12,8,1587517,1587515,2,26, +1585289,2,10,3,6,10,4,8,1587525,1587515,2,26,1585291,2,10,3, +6,10,4,8,1587533,1587515,2,26,1585293,2,10,3,6,10,4,8, +1587541,1587515,2,26,1585295,2,10,3,6,10,4,8,1587515,1,6,2, +1,6,3,26,5,6,4,10,8,8,1585289,1310721,2,3,26,2, +10,3,6,10,4,8,1585291,1310721,2,5,26,2,10,3,6,10, +4,8,1585293,1310721,2,7,26,2,10,3,6,10,4,8,1585295,1310721, +2,9,26,2,10,3,6,10,4,8,1605437,14,1587511,1587517,1310721,2, +2,26,2,10,3,6,10,4,8,1587513,1587525,1310721,2,2,26,2, +10,3,6,10,4,8,1,1605845,14,1,1310721,2,11,26,1310721,4, +18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1605893,16,1966081,1310721,4, +1579223,12,1,1605397,12,1605905,14,1,1310721,2,1,26,1310721,4,18,1310721, +2,7,28,1310721,4,1310721,2,1835009,40,1605953,16,1966081,1310721,4,1579223,12, +1310721,2,1540609,1585309,2,65,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,1606035,16,1602991,12,8,1,1606411,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,1606323,16,1310721,2,3,26,1310721,2,2,3,26, +2,10,3,6,10,4,8,1585289,1310721,2,3,26,2,3,1310721,2, +5,26,2,7,30,26,26,2,10,3,6,10,4,8,1585291,1310721, +2,3,26,2,5,1310721,2,5,26,2,7,30,26,26,2,10, +3,6,10,4,8,1585295,1310721,2,3,26,2,7,1310721,2,5,26, +2,7,30,26,26,2,10,3,6,10,4,8,1585293,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,1606411,14,1310721,2,2,9,26,2,1, +6,1,10,28,34,63,38,3,26,1606397,16,1585289,1,10,3,6, +10,4,8,1585291,1,10,3,6,10,4,8,1,1606411,14,1600299,12, +8,1,1606411,14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1606459,16,1966081,1310721,4,1579223,12,1310721,2,4, +1585289,2,9,28,1,6,1,10,28,34,63,38,3,26,1606555,16, +1585291,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,1606557,14,1,1606563,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1606611,16,1966081,1310721,4,1579223,12,1310721,2,4,1585289,2,5,28, +1,6,1,10,28,34,63,38,3,26,1606707,16,1585291,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,1606709,14,1,1606715,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1606763,16, +1966081,1310721,4,1579223,12,1310721,2,4,1585289,2,9,28,1,6,1,10, +28,34,63,38,3,26,1606807,16,3,1606857,14,1585289,2,5,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1606919,16,1585291,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,1606921,14,1,1606937,16,1604999,12,8,3,1606945,14,1,1606945,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1606993,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1606729,12, +1,6,1,10,28,34,63,38,3,26,1607227,16,1590585,2,1,6, +1,10,28,34,63,38,3,26,1607111,16,1587703,2,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1607113,14,1,1607173,16,1590587,12,8,1607147,14,101,120,112,101,99, +116,101,100,32,0,1607127,1573495,12,8,1310721,2,2,1573495,12,8,1590731, +12,8,1590585,3,10,3,6,10,4,8,1585289,2,1,28,1,6, +1,10,28,34,63,38,3,26,1607227,16,1590891,12,8,1,1607235,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1607283,16,1966081,1310721,4,1579223,12,1585291,2,1310721,2,4,1585289,2, +5,28,1,6,1,10,28,34,63,38,1,10,28,1607371,16,1607363, +14,101,120,112,101,99,116,101,100,32,97,32,110,97,109,101, +0,1607331,1591557,12,8,1604999,12,8,1310721,2,2,1607389,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1607437, +16,1966081,1310721,4,1579223,12,1310721,2,4,1585237,2,1310721,2,3,26,4, +3,1608511,16,1310721,2,2,2,65,28,1,6,1,10,28,34,63, +38,3,26,1607533,16,1310721,2,1,6,2,1,6,3,26,5,6, +4,10,8,8,1607463,14,1310721,2,2,2,1,6,1,10,28,34, +63,38,3,26,1607569,16,1608511,14,1310721,2,5,26,1,10,3,6, +10,4,8,1310721,2,2,1310721,2,5,26,2,26,2,1607687,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,1607689,14,1,1607777,16,1585311,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,1607591,14, +1585311,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,1585311,1,26,2,91,28,1,6,1,10,28,34,63, +38,3,26,1607921,16,1585311,3,26,2,1601689,12,1,6,1,10,28, +34,63,38,1,10,28,1607923,14,1,10,3,6,10,4,8,1585311, +1310721,2,7,26,2,26,2,1601689,12,1608251,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,1585311,1310721,2,11,26,2,26,2,1608125,16,1310721, +2,9,26,1310721,2,9,26,2,21,30,1585311,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,1608011,14,1310721,2, +7,26,2,1608173,16,1310721,2,9,26,1,1310721,2,9,26,2,28, +10,3,6,10,4,8,1542657,1585237,2,26,1310721,2,9,26,2,1310721, +2,9,26,2,26,3,26,10,3,6,10,4,8,1585237,1,6, +2,1,6,3,26,5,6,4,10,8,8,1608507,14,1310721,2,5, +26,2,3,28,1,6,1,10,28,34,63,38,3,26,1608353,16, +1310721,2,13,26,1585311,1,26,2,1608541,12,10,3,6,10,4,1, +40,3,36,1,6,1,10,28,34,63,38,1,10,28,1608355,14, +1,1608433,16,1542657,1585237,2,26,1310721,2,13,26,2,1310721,2,13,26, +2,26,10,3,6,10,4,8,1585237,1,6,2,1,6,3,26, +5,6,4,10,8,8,1608507,14,1542657,1585237,2,26,-3,10,3,6, +10,4,8,1542657,1585237,2,3,26,26,1585311,1592287,12,10,3,6,10, +4,8,1585237,1585237,2,5,26,10,3,6,10,4,8,1607457,14,1310721, +2,3,26,2,1608527,14,1,1310721,2,15,26,1310721,4,18,1310721,2, +5,28,1310721,4,1310721,2,1835009,40,1608575,16,1966081,1310721,4,1579223,12,1310721, +2,4,1,1310721,2,3,26,4,1585239,2,1310721,2,3,26,2,26, +2,1608717,16,1585239,2,1310721,2,3,26,2,26,2,1310721,2,2,28, +1,6,1,10,28,34,63,38,3,26,1608679,16,1310721,2,3,26, +2,1608731,14,1310721,2,3,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1608593,14,3,1,10,28,1608731,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1608779,16, +1966081,1310721,4,1579223,12,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,1609225,16,1542657,1310721,2,2,26,2,-3,28,1,6, +1,10,28,34,63,38,3,26,1609173,16,1310721,2,7,26,1542657,1310721, +2,2,3,26,26,2,1593303,12,10,3,6,10,4,8,1310721,2, +7,26,2,1,40,1608983,16,1310721,2,7,26,1542657,1310721,2,2,3, +26,26,2,1595111,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,1609047, +16,1310721,2,7,26,2,1595235,12,8,1609143,14,1417729,1310721,2,7,26, +2,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1609121, +16,45,1425921,1310721,2,7,26,2,26,2,26,1594729,12,8,1609143,14, +1425921,1310721,2,7,26,2,26,2,1594643,12,8,1310721,2,1310721,2,2, +5,26,10,3,6,10,4,8,1609221,14,1542657,1310721,2,2,26,2, +1594449,12,8,1310721,2,1,6,2,1,6,3,26,5,6,4,10, +8,8,1608823,14,1,1609233,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1609281,16,1966081,1310721,4,1579223,12, +1310721,2,4,1,1310721,2,3,26,4,1310721,2,3,26,2,1585235,2, +40,1609411,16,1547777,1310721,2,3,26,2,26,2,1310721,2,2,28,1, +6,1,10,28,34,63,38,3,26,1609373,16,1,1609473,14,1310721,2, +3,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1609299, +14,1547777,1585235,2,26,1310721,2,2,10,3,6,10,4,8,1585235,1, +6,2,1,6,3,26,5,6,4,10,8,8,1,1609473,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1609521,16,1966081,1310721,4,1579223,12,1310721,2,4,1585229,2,1310721,2,3, +26,4,1310721,2,3,26,2,1609655,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, +1609651,16,1310721,2,3,26,2,1609669,14,1609541,14,3,1,10,28,1609669, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1609717,16,1966081,1310721,4,1579223,12,1310721,2,4,1585231,2,1310721, +2,3,26,4,1310721,2,3,26,2,1609851,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,1609847,16,1310721,2,3,26,2,1609865,14,1609737,14,3,1,10, +28,1609865,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1609913,16,1966081,1310721,4,1579223,12,1310721,2,4,1585233, +2,1310721,2,3,26,4,1310721,2,3,26,2,1610047,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,1610043,16,1310721,2,3,26,2,1610061,14,1609933,14,3, +1,10,28,1610061,14,1,1310721,2,5,26,1310721,4,18,1310721,2,15, +28,1310721,4,1310721,2,1835009,40,1610109,16,1966081,1310721,4,1579223,12,1310721,2, +5,26,4,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1592287,12, +1310721,2,7,26,4,1310721,2,7,26,2,1609487,12,1310721,2,9,26, +4,1310721,2,9,26,2,1,40,1610249,16,1310721,2,9,26,1585229,2, +10,3,6,10,4,8,1585229,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,1610473, +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,1609247,12,8,1310721,2,9, +26,2,1611101,14,1547009,1310721,2,9,26,2,26,1310721,2,5,26,2, +1607403,12,10,3,6,10,4,8,1547137,1310721,2,9,26,2,26,1585237, +2,1547009,1310721,2,9,26,2,26,2,28,10,3,6,10,4,8, +1310721,2,7,26,2,1609247,12,8,1310721,2,13,26,1310721,2,2,1574039, +12,10,3,6,10,4,8,1585311,2001,26,1310721,2,2,1310721,2,13, +26,2,1574491,12,8,1585311,2001,1310721,2,13,26,2,26,26,123,10, +3,6,10,4,8,1585311,2003,1310721,2,13,26,2,26,26,1,10, +3,6,10,4,8,1310721,2,11,26,1585311,2001,26,1592287,12,10,3, +6,10,4,8,1310721,2,3,26,2,17,40,3,36,1610757,16,3, +1610813,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,1610823,16, +3,1610879,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,1610889, +16,3,1610945,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, +1611085,16,1310721,2,11,26,2,1609879,12,1,40,1611029,16,1547457,1585233,2, +26,1310721,2,11,26,2,10,3,6,10,4,8,1585233,1,6,2, +1,6,3,26,5,6,4,10,8,8,1547585,1310721,2,11,26,2, +1609879,12,26,1310721,2,9,26,2,10,3,6,10,4,8,1310721,2, +11,26,2,1609247,12,8,1310721,2,9,26,2,1611101,14,1,1310721,2, +15,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1611149, +16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,1592287,12,1310721,2,5,26,4,1310721,2,5,26,2,1609683,12,1310721, +2,7,26,4,1310721,2,7,26,2,1,40,1611279,16,1310721,2,7, +26,1585231,2,10,3,6,10,4,8,1585231,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,1607403,12,10,3,6,10,4,8,1547393,1310721,2, +7,26,2,26,1585237,2,1547329,1310721,2,7,26,2,26,2,28,10, +3,6,10,4,8,1310721,2,5,26,2,1609247,12,8,1310721,2,7, +26,2,1611435,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28, +1310721,4,1310721,2,1835009,40,1611483,16,1966081,1310721,4,1579223,12,1310721,2,5, +26,4,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1592287,12,11, +1310721,2,3,26,2,1592805,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,1611601,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1611649,16,1966081,1310721,4,1579223,12, +1310721,2,4,1587557,2,1310721,2,3,26,4,1310721,2,3,26,2,1587559, +2,10,40,1611791,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,1611787,16,1310721,2, +3,26,2,1611805,14,1611669,14,3,1,10,28,1611805,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1611853, +16,1966081,1310721,4,1579223,12,1310721,2,4,1587557,2,1310721,2,3,26,4, +1587557,2,1025,40,3,36,1611933,16,1611925,14,116,111,111,32,109,97, +110,121,32,108,111,99,97,108,115,0,1611893,1591079,12,8,1587557,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,1587563,2,10,3,6,10,4,8,1468929,1310721,2,3,26, +2,26,1587561,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, +1556993,1310721,2,3,26,2,26,1587687,2,10,3,6,10,4,8,1558017, +1310721,2,3,26,2,26,1,10,3,6,10,4,8,1589487,1310721,2, +3,26,2,26,1,10,3,6,10,4,8,1310721,2,3,26,2, +1612295,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1612343,16,1966081,1310721,4,1579223,12,1310721,2,4,1469953,1310721, +2,2,26,2,11,28,1,6,1,10,28,34,63,38,3,26, +1612421,16,1310721,2,1470977,1310721,2,2,26,2,10,3,6,10,4,8, +1612349,14,1310721,2,2,1612433,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1612481,16,1966081,1310721,4,1579223,12, +1310721,2,4,1469953,1310721,2,2,26,2,1,28,1,6,1,10,28, +34,63,38,1,10,28,1612531,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1612579,16,1966081,1310721,4,1579223, +12,1310721,2,4,1472001,1310721,2,2,26,3,10,3,6,10,4,8, +1587565,2,1,6,1,10,28,34,63,38,3,26,1612643,16,1,1613019, +14,1310721,2,3,26,1310721,2,2,1612309,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,1612827,16,1310721,2,2,1612813,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,1612755,1591963,12,8,1,1613019,14,1469953,1310721,2, +3,26,2,26,2,7,28,1,6,1,10,28,34,63,38,3, +26,1612919,16,1468929,1310721,2,3,26,2,26,2,1587561,2,40,1,6, +1,10,28,34,63,38,1,10,28,1612921,14,1,1613011,16,1468929,1310721, +2,3,26,2,26,1587561,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,1613019,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1613067,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,3,28,1,6,1, +10,28,34,63,38,3,26,1613257,16,1613249,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, +1613111,1591845,12,8,1310721,2,2,5,40,3,36,1613291,16,1310721,2,2, +5,28,1612545,12,8,1,1613299,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1613347,16,1966081,1310721,4,1579223, +12,1310721,2,4,1467905,1310721,2,2,26,2,1595563,12,8,3,1594729,12, +8,1587671,2,1595409,12,8,9,1594729,12,8,1,1613405,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1613453, +16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587557,2, +1310721,2,5,26,4,1587565,2,1,6,1,10,28,34,63,38,3, +26,1613517,16,3,1613563,14,1587569,2,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1613573,16,1, +1614133,14,1310721,2,5,26,2,1587559,2,10,40,1614125,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,1613661,16,1613573,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,1613755,16,1310721,2,5,26,2,1613313,12,8,1614121,14,1310721,2,7, +26,2,5,28,1,6,1,10,28,34,63,38,3,26,1614001,16, +1310721,2,5,26,2,1613989,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,1613807,1591963,12,8,1614121,14,1310721,2,7,26,2,7,28,1, +6,1,10,28,34,63,38,3,26,1614121,16,1310721,2,5,26,2, +1614113,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, +1614053,1591963,12,8,1613573,14,1,1614133,14,1,1310721,2,9,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1614181,16,1966081,1310721,4, +1579223,12,1310721,2,4,1310721,2,2,1587557,2,40,1614423,16,1587565,2,1614249, +16,1474049,1310721,2,2,26,2,1,6,1,10,28,34,63,38,1, +10,28,1614251,14,1,1614313,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,1614315,14,1,1614389,16,1466881,1310721,2,2,26,2,1614381,14,109, +32,111,98,106,101,99,116,32,105,115,32,110,101,118,101,114, +32,117,115,101,100,0,1614335,1591343,12,8,1310721,2,1,6,2,1, +6,3,26,5,6,4,10,8,8,1614187,14,1,1614431,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40, +1614479,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1310721,2,3, +26,4,1587769,2,1614775,16,1310721,2,3,26,2,1587557,2,40,1614775,16, +1310721,2,5,26,1558017,1310721,2,3,26,2,26,2,17,38,15,32, +10,3,6,10,4,8,1558017,1310721,2,3,26,2,26,2,33,32, +1614633,16,1310721,2,5,26,2,1,6,1,10,28,34,63,38,1, +10,28,1614635,14,1,1614673,16,1589483,2,17,40,1,6,1,10,28, +34,63,38,1,10,28,1614675,14,1,1614737,16,1589467,1589483,2,26,1310721, +2,5,26,2,10,3,6,10,4,8,1589483,1,6,2,1,6, +3,26,5,6,4,10,8,8,1310721,2,3,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1614509,14,1310721,2,3,26,1587559, +2,10,3,6,10,4,8,1310721,2,2,1614147,12,8,1587561,2,3, +1613419,12,8,1310721,2,3,26,2,1310721,2,2,40,1614975,16,1468929,1310721, +2,3,26,2,26,2,1587561,2,40,3,36,1614937,16,1469953,1310721,2, +3,26,2,26,9,10,3,6,10,4,8,1468929,1310721,2,3,26, +2,26,1587561,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,1614823,14,1587557, +1310721,2,2,10,3,6,10,4,8,1,1615003,14,1,1310721,2,7, +26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1615051,16, +1966081,1310721,4,1579223,12,1587585,2,1310721,2,4,1587559,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,1587559,2,10,3,6,10,4,8,1310721, +2,5,26,2,3,26,1587557,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,1587557,2,40,1615417,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,1615199,14,1587585,1310721,2,5, +26,2,1507841,28,10,3,6,10,4,8,1587585,2,16001,40,3,36, +1615541,16,1615533,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,1615465,1591079,12,8,1310721,2,2,1615553,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1615601,16,1966081,1310721,4,1579223,12,1310721,2,4,1587585,1310721,2,2,10, +3,6,10,4,8,1,1615635,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,1835009,40,1615683,16,1966081,1310721,4,1579223, +12,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,1587557,2,10, +40,1615807,16,1310721,2,7,26,1587557,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,1616065,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,1615841,14, +1,1616073,14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1616121,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,1,28,1,6,1,10,28,34,63,38,3,26,1616167,16, +3,1616219,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,1616225,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009, +40,1616273,16,1966081,1310721,4,1579223,12,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,1587557,2,10,40,1616397,16,1310721,2,7,26,1587557,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,1617021,16,1310721,2,9,26,1469953,1310721,2,5,26,2,26,2, +10,3,6,10,4,8,1310721,2,9,26,2,1616087,12,1616557,16,1310721, +2,3,26,2,1,26,2,1616087,12,1,6,1,10,28,34,63, +38,1,10,28,1616559,14,1,1616639,16,1310721,2,3,26,2,1,26, +2,9,28,1,6,1,10,28,34,63,38,3,26,1616635,16,1469953, +1310721,2,5,26,2,26,9,10,3,6,10,4,8,1616949,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,1616699,16,3,1616777,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,1616787,16,3,1616931,14,1310721,2,9,26,2,11,28, +1,6,1,10,28,34,63,38,3,26,1616907,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,1616909,14,1,1,6,1,10,28,34,63,38,1,10, +28,1616949,16,1310721,2,5,26,2,1617035,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,1616431,14,3,1, +10,28,1617035,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1617083,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,1,28,1,6,1,10,28,34,63,38,3,26,1617145, +16,1617139,14,101,109,112,116,121,0,1617127,1617471,14,1310721,2,2,3, +28,1,6,1,10,28,34,63,38,3,26,1617193,16,1617187,14,109, +0,1617183,1617471,14,1310721,2,2,5,28,1,6,1,10,28,34,63, +38,3,26,1617241,16,1617235,14,117,0,1617231,1617471,14,1310721,2,2,7, +28,1,6,1,10,28,34,63,38,3,26,1617289,16,1617283,14,100, +0,1617279,1617471,14,1310721,2,2,9,28,1,6,1,10,28,34,63, +38,3,26,1617355,16,1617349,14,103,105,118,101,110,32,97,119,97, +121,0,1617327,1617471,14,1310721,2,2,11,28,1,6,1,10,28,34, +63,38,3,26,1617441,16,1617435,14,111,119,110,101,100,32,98,121, +32,97,32,99,111,110,116,97,105,110,101,114,0,1617393,1617471,14, +1617463,14,98,111,114,114,111,119,101,100,0,1617445,1617471,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40, +1617519,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26, +4,1310721,2,4,1587565,2,1,6,1,10,28,34,63,38,3,26, +1617579,16,3,1617605,14,1590585,2,1,6,1,10,28,34,63,38,1, +10,28,1617615,16,3,1617641,14,1587703,2,1,6,1,10,28,34,63, +38,1,10,28,1617651,16,1,1617871,14,1590587,12,8,1466881,1310721,2,2, +26,2,1573495,12,8,1617685,14,58,32,0,1617679,1573495,12,8,1310721,2, +5,26,2,1573495,12,8,1617757,14,32,40,111,110,101,32,112,97, +116,104,32,108,101,97,118,101,115,32,105,116,32,0,1617713,1573495, +12,8,1310721,2,3,26,2,1617049,12,1573495,12,8,1617811,14,44,32, +97,110,111,116,104,101,114,32,0,1617789,1573495,12,8,1469953,1310721,2, +2,26,2,1617049,12,1573495,12,8,1617849,14,41,0,1617845,1573495,12,8, +1590731,12,8,1,1617871,14,1,1310721,2,7,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,0,0,0,0,0,0,0,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,5,28,1310721,4,1310721,2,1835009,40,1618051,16,1966081,1310721,4,1579223, +12,1310721,2,3,26,4,1310721,2,4,1310721,2,3,26,2,1310721,2, +2,3,26,2,40,3,36,1618105,16,1,1618153,14,1310721,2,2,5, +7,1310721,2,3,26,2,1310721,2,2,1,26,2,28,30,26,26, +2,1618153,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1618201,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1310721,2,2,7,7,1310721,2,3,26,2,1310721,2, +2,1,26,2,28,30,26,26,2,1618265,14,1,1310721,2,5,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1618313,16,1966081, +1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,9, +7,1310721,2,3,26,2,1310721,2,2,1,26,2,28,30,26,26, +2,1618377,14,1,1310721,2,5,26,1310721,4,18,1310721,2,9,28,1310721, +4,1310721,2,1835009,40,1618425,16,1966081,1310721,4,1579223,12,1310721,2,4,1567233, +1617885,2,26,1310721,2,3,26,4,1587559,2,1310721,2,5,26,4,1617885, +2,7,26,7,1587557,2,1587559,2,28,30,26,1572353,1567233,28,40,3, +36,1618581,16,1618573,14,116,111,111,32,109,97,110,121,32,98,114, +101,97,107,115,32,102,111,114,32,116,104,101,32,97,110,97, +108,121,122,101,114,0,1618507,1591079,12,8,1310721,2,3,26,2,1, +26,1310721,2,2,10,3,6,10,4,8,1310721,2,3,26,2,3, +26,1587559,2,10,3,6,10,4,8,1310721,2,3,26,2,5,26, +1587557,2,10,3,6,10,4,8,1310721,2,7,26,1310721,2,3,26, +2,7,26,10,3,6,10,4,8,1310721,2,5,26,2,1587557,2, +40,1618925,16,1310721,2,7,26,2,1,26,1469953,1310721,2,5,26,2, +26,2,10,3,6,10,4,8,1310721,2,7,26,2,3,26,1470977, +1310721,2,5,26,2,26,2,10,3,6,10,4,8,1310721,2,7, +26,2,5,26,1468929,1310721,2,5,26,2,26,2,10,3,6,10, +4,8,1310721,2,7,26,1310721,2,7,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,1618707,14,1617885,1310721,2,7,26,2,1567233,28,10,3, +6,10,4,8,1310721,2,3,26,2,1618969,14,1,1310721,2,9,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1619017,16,1966081, +1310721,4,1579223,12,1310721,2,4,1618015,2,129,40,3,36,1619115,16,1619107, +14,116,111,111,32,109,97,110,121,32,112,97,116,104,115,32, +102,111,114,32,116,104,101,32,97,110,97,108,121,122,101,114, +0,1619043,1591079,12,8,1617887,1618015,2,26,1310721,2,2,10,3,6,10, +4,8,1618015,1,6,2,1,6,3,26,5,6,4,10,8,8, +1,1619177,14,1,1310721,2,3,26,1310721,4,18,1310721,2,11,28,1310721, +4,1310721,2,1835009,40,1619225,16,1966081,1310721,4,1579223,12,1310721,2,5,26, +4,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1310721,2,5,26, +2,1618017,12,1310721,2,7,26,4,1310721,2,3,26,2,1310721,2,5, +26,2,1618017,12,1310721,2,9,26,4,1310721,2,7,26,2,1616087,12, +1619373,16,1310721,2,9,26,2,1616087,12,1,6,1,10,28,34,63, +38,1,10,28,1619375,14,1,1619385,16,3,1619697,14,1310721,2,7,26, +2,1310721,2,9,26,2,28,1,6,1,10,28,34,63,38,3, +26,1619523,16,1310721,2,2,1310721,2,5,26,2,1618279,12,1310721,2,3, +26,2,1310721,2,5,26,2,1618279,12,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1619525, +14,1,1619689,16,1310721,2,7,26,2,11,28,1,6,1,10,28, +34,63,38,1,10,28,1619575,16,3,1619663,14,1310721,2,2,1310721,2, +5,26,2,1618167,12,1310721,2,3,26,2,1310721,2,5,26,2,1618167, +12,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,1619691,14,1,1619697,14,1,1310721,2,11,26,1310721,4,18,1310721, +2,21,28,1310721,4,1310721,2,1835009,40,1619745,16,1966081,1310721,4,1579223,12, +1310721,2,3,26,4,1310721,2,4,1587559,2,1310721,2,5,26,4,1618015, +2,1,6,1,10,28,34,63,38,3,26,1619809,16,1,1621281,14, +1310721,2,5,26,2,1310721,2,2,40,1621273,16,1310721,2,9,26,1617887, +1,26,2,10,3,6,10,4,8,1310721,2,13,26,1310721,2,9, +26,2,1310721,2,5,26,2,1618017,12,10,3,6,10,4,8,1310721, +2,15,26,1,10,3,6,10,4,8,1310721,2,17,26,3,10, +3,6,10,4,8,1310721,2,19,26,3,1,10,28,10,3,6, +10,4,8,1310721,2,7,26,1,10,3,6,10,4,8,1310721,2, +7,26,2,1618015,2,40,1620451,16,1310721,2,11,26,1617887,1310721,2,7, +26,2,26,2,1310721,2,5,26,2,1618017,12,10,3,6,10,4, +8,1310721,2,11,26,2,9,28,1,6,1,10,28,34,63,38, +3,26,1620111,16,3,1620167,14,1310721,2,11,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,1620193,16,1310721,2,15,26,3,10,3,6,10,4,8, +1310721,2,11,26,2,5,28,1,6,1,10,28,34,63,38,3, +26,1620237,16,3,1620293,14,1310721,2,11,26,2,13,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1620319,16,1310721,2,17,26,1,10,3,6,10,4,8,1310721, +2,9,26,2,1617887,1310721,2,7,26,2,26,2,1310721,2,5,26, +2,1619191,12,1,6,1,10,28,34,63,38,3,26,1620413,16,1310721, +2,19,26,1310721,2,7,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,1619997, +14,1469953,1310721,2,5,26,2,26,1310721,2,13,26,2,10,3,6, +10,4,8,1470977,1310721,2,5,26,2,26,1310721,2,9,26,2,1310721, +2,5,26,2,1618167,12,10,3,6,10,4,8,1468929,1310721,2,5, +26,2,26,1310721,2,9,26,2,1310721,2,5,26,2,1618279,12,10, +3,6,10,4,8,1310721,2,19,26,2,1,40,1620793,16,1310721,2, +13,26,2,1616087,12,1620789,16,1310721,2,7,26,1,10,3,6,10, +4,8,1310721,2,7,26,2,1618015,2,40,1620789,16,1617887,1310721,2,7, +26,2,26,2,1310721,2,5,26,2,1618017,12,9,28,1,6,1, +10,28,34,63,38,3,26,1620751,16,1469953,1310721,2,5,26,2,26, +9,10,3,6,10,4,8,1310721,2,7,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1620645,14,1621235,14,1310721,2,15,26, +2,1620843,16,1310721,2,17,26,2,1,6,1,10,28,34,63,38, +1,10,28,1620845,14,1,1620881,16,1469953,1310721,2,5,26,2,26,9, +10,3,6,10,4,8,1621235,14,1587565,2,1620939,16,1590585,2,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1620941,14,1,1620995,16,1587703,2,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1620997, +14,1,1621235,16,1590587,12,8,1466881,1310721,2,5,26,2,26,2,1573495, +12,8,1621039,14,58,32,0,1621033,1573495,12,8,1310721,2,3,26,2, +1573495,12,8,1621111,14,32,40,111,110,101,32,112,97,116,104,32, +108,101,97,118,101,115,32,105,116,32,0,1621067,1573495,12,8,1310721, +2,13,26,2,1617049,12,1573495,12,8,1621165,14,44,32,97,110,111, +116,104,101,114,32,0,1621143,1573495,12,8,1617887,1310721,2,19,26,2, +26,2,1310721,2,5,26,2,1618017,12,1617049,12,1573495,12,8,1621221,14, +41,0,1621217,1573495,12,8,1590731,12,8,1310721,2,5,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1619809,14,1,1621281,14,1, +1310721,2,21,26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009, +40,1621329,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3, +26,4,1310721,2,4,1587559,2,1310721,2,7,26,4,1,1310721,2,9, +26,4,1587565,2,1,6,1,10,28,34,63,38,3,26,1621415,16, +1,1621775,14,1310721,2,7,26,2,1310721,2,3,26,2,40,1621759,16, +1310721,2,11,26,1310721,2,2,1310721,2,7,26,2,1618017,12,10,3, +6,10,4,8,1469953,1310721,2,7,26,2,26,2,9,28,1,6, +1,10,28,34,63,38,3,26,1621651,16,1310721,2,11,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1621569,16,3,1621625,14, +1310721,2,11,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,1,6,1,10, +28,34,63,38,1,10,28,1621653,14,1,1621721,16,1310721,2,9,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1310721,2,5, +26,2,1621721,16,1310721,2,7,26,2,1613313,12,8,1310721,2,7,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1621415,14,1310721, +2,9,26,2,1621775,14,1,1310721,2,13,26,1310721,4,18,1310721,2, +11,28,1310721,4,1310721,2,1835009,40,1621823,16,1966081,1310721,4,1579223,12,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,1587565,2,1,6,1,10,28,34,63,38, +3,26,1621935,16,3,1621981,14,1587569,2,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1621991,16, +1,1623357,14,1310721,2,7,26,2,1587557,2,10,40,1622037,16,1310721,2, +7,26,1587557,2,10,3,6,10,4,8,1310721,2,5,26,2,1310721, +2,7,26,2,40,1623349,16,1310721,2,9,26,1469953,1310721,2,5,26, +2,26,2,10,3,6,10,4,8,1310721,2,9,26,2,1616087,12, +1622171,16,1310721,2,3,26,2,1310721,2,5,26,2,1618017,12,1616087,12, +1,6,1,10,28,34,63,38,1,10,28,1622173,14,1,1622261,16, +1310721,2,3,26,2,1310721,2,5,26,2,1618017,12,9,28,1,6, +1,10,28,34,63,38,3,26,1622257,16,1469953,1310721,2,5,26,2, +26,9,10,3,6,10,4,8,1623311,14,1310721,2,9,26,2,1310721, +2,3,26,2,1310721,2,5,26,2,1618017,12,28,1,6,1,10, +28,34,63,38,1,10,28,1622329,16,3,1622415,14,1468929,1310721,2,5, +26,2,26,2,1310721,2,3,26,2,1310721,2,5,26,2,1618279,12, +28,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,1,10,28,1622425,16,3,1622577,14,1310721,2,9,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1622553,16,1470977, +1310721,2,5,26,2,26,2,1310721,2,3,26,2,1310721,2,5,26, +2,1618167,12,28,1,6,1,10,28,34,63,38,1,10,28,1, +6,1,10,28,34,63,38,1,10,28,1622555,14,1,1,6,1, +10,28,34,63,38,1,10,28,1623311,16,1310721,2,9,26,2,9, +28,1,6,1,10,28,34,63,38,3,26,1622625,16,3,1622681,14, +1310721,2,9,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,1622915,16,1310721,2, +5,26,2,1622903,14,105,115,32,103,105,118,101,110,32,97,119, +97,121,32,105,110,115,105,100,101,32,97,32,108,111,111,112, +32,116,104,97,116,32,99,111,109,101,115,32,98,97,99,107, +32,97,114,111,117,110,100,32,116,111,32,105,116,59,32,103, +105,118,101,32,105,116,32,97,119,97,121,32,111,110,32,97, +32,112,97,116,104,32,116,104,97,116,32,108,101,97,118,101, +115,32,116,104,101,32,108,111,111,112,0,1622699,1591963,12,8,1623311, +14,1590585,2,1,6,1,10,28,34,63,38,3,26,1622993,16,1587703, +2,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1622995,14,1,1623311,16,1590587,12,8,1466881,1310721, +2,5,26,2,26,2,1573495,12,8,1623205,14,58,32,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,32,40,105,116,32,119,101,110,116,32,102,114,111,109, +32,0,1623031,1573495,12,8,1310721,2,3,26,2,1310721,2,5,26,2, +1618017,12,1617049,12,1573495,12,8,1623261,14,32,116,111,32,0,1623251,1573495, +12,8,1310721,2,9,26,2,1617049,12,1573495,12,8,1623297,14,41,0, +1623293,1573495,12,8,1590731,12,8,1310721,2,5,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1622037,14,1,1623357,14,1,1310721,2, +11,26,1310721,4,18,1310721,2,19,28,1310721,4,1310721,2,1835009,40,1623405, +16,1966081,1310721,4,1579223,12,1310721,2,11,26,4,1310721,2,9,26,4, +1310721,2,7,26,4,1310721,2,5,26,4,1310721,2,3,26,4,1310721, +2,4,1310721,2,13,26,1615017,12,10,3,6,10,4,8,1618015,1, +10,3,6,10,4,8,1310721,2,3,26,2,1623531,16,1507841,1310721,2, +2,26,1618983,12,8,1310721,2,7,26,2,1623565,16,1507841,1310721,2,13, +26,2,26,1618983,12,8,1310721,2,9,26,2,1310721,2,11,26,2, +1619711,12,8,1310721,2,7,26,2,1623637,16,1507841,1310721,2,13,26,2, +26,1310721,2,9,26,2,3,1621295,12,8,1310721,2,15,26,1,10, +3,6,10,4,8,1310721,2,3,26,2,1623719,16,1310721,2,15,26, +1507841,1310721,2,2,26,1310721,2,9,26,2,1,1621295,12,10,3,6, +10,4,8,1310721,2,15,26,2,1623837,16,1310721,2,17,26,1595029,12, +10,3,6,10,4,8,15,1594729,12,8,1310721,2,5,26,2,1587549, +2,1594811,12,8,1507841,1310721,2,2,26,1310721,2,9,26,2,3,1621295, +12,8,1310721,2,17,26,2,1587549,2,1594811,12,8,1623857,14,1310721,2, +5,26,2,1587549,2,1594811,12,8,1587569,1310721,2,3,26,2,1623879,16, +3,1623911,14,1310721,2,7,26,2,1,6,1,10,28,34,63,38, +1,10,28,10,3,6,10,4,8,1,1623931,14,1,1310721,2,19, +26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1623979,16, +1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587565,2,1, +6,1,10,28,34,63,38,3,26,1624033,16,1310721,2,2,1625003,14, +1310721,2,2,5,40,1624149,16,1624131,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,1624051,1591845,12,8,1310721,2,2,1625003,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,1624413,16,1310721,2,5,26, +2,1624401,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,1624295,1591963,12,8,1624991,14,1310721,2, +7,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1624541, +16,1310721,2,5,26,2,1624529,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,1624465,1591963,12,8,1624991,14,1310721,2, +7,26,2,1,28,1,6,1,10,28,34,63,38,3,26,1624649, +16,1310721,2,5,26,2,1624637,14,105,115,110,39,116,32,97,110, +32,111,119,110,101,100,32,111,98,106,101,99,116,0,1624593,1591963, +12,8,1624991,14,1310721,2,7,26,2,9,28,1,6,1,10,28, +34,63,38,3,26,1624771,16,1310721,2,5,26,2,1624759,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,1624701,1591963,12,8,1624991, +14,1310721,2,3,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1624871,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,1624873,14,1,1624955,16,1310721,2,5,26,2,1624943,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,1624891,1591963,12,8,1624991,14,1469953,1310721,2, +5,26,2,26,1310721,2,3,26,2,10,3,6,10,4,8,1310721, +2,2,1625003,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28, +1310721,4,1310721,2,1835009,40,1625051,16,1966081,1310721,4,1579223,12,1310721,2,3, +26,4,1310721,2,4,1587565,2,1,6,1,10,28,34,63,38,3, +26,1625101,16,1,1626535,14,1310721,2,2,3,28,1,6,1,10,28, +34,63,38,3,26,1625345,16,1310721,2,3,26,2,5,28,1,6, +1,10,28,34,63,38,1,10,28,1625339,16,1625331,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,1625179,1591845,12,8,1,1626535,14, +1310721,2,2,5,40,1625365,16,3,1625421,14,1310721,2,2,5,28,1612447, +12,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1625431,16,1,1626535,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,1612309,12,26,2,9,28,1,6,1,10,28,34,63,38, +3,26,1625631,16,1310721,2,5,26,2,1625617,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,1625559,1591963,12,8,1,1626535,14,1310721, +2,3,26,2,3,10,40,3,36,1625859,16,1310721,2,7,26,2, +7,28,1,6,1,10,28,34,63,38,3,26,1625837,16,1310721,2, +5,26,2,1625823,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,1625707, +1591963,12,8,1,1626535,14,1310721,2,5,26,2,1612545,12,8,1,1626535, +14,1310721,2,7,26,2,7,28,1,6,1,10,28,34,63,38, +3,26,1625959,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,1626535,14,1310721,2,7,26,2,3,28,1,6,1,10,28,34, +63,38,3,26,1626087,16,1310721,2,5,26,2,1626075,14,105,115,32, +109,59,32,119,114,105,116,101,32,100,42,120,32,116,111,32, +103,105,118,101,32,105,116,32,97,119,97,121,0,1626011,1591963,12, +8,1626527,14,1310721,2,7,26,2,5,28,1,6,1,10,28,34, +63,38,3,26,1626263,16,1310721,2,5,26,2,1626251,14,105,115,32, +117,59,32,119,114,105,116,101,32,100,42,120,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,1626139,1591963,12,8,1626527,14,1310721,2,7,26,2, +11,28,1,6,1,10,28,34,63,38,3,26,1626433,16,1310721,2, +5,26,2,1626421,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,1626315,1591963,12,8,1626527,14, +1310721,2,5,26,2,1626519,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,1626447,1591963,12,8,1, +1626535,14,1,1310721,2,9,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1626583,16,1966081,1310721,4,1579223,12,1310721,2,4,1467905,1310721, +2,2,26,2,1595563,12,8,3,1594729,12,8,1556993,1310721,2,2,26, +2,1,26,2,23,28,1,6,1,10,28,34,63,38,3,26, +1626685,16,5,1594643,12,8,27,1594729,12,8,3,1594729,12,8,1587673,2, +1595409,12,8,1587769,2,1626737,16,1587699,2,1658673,12,1,6,1,10,28, +34,63,38,1,10,28,1626739,14,1,1626763,16,1587699,2,1594643,12,8, +1590517,2,1595409,12,8,1,1626771,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,15,28,1310721,4,1310721,2,1835009,40,1626819,16,1966081,1310721,4,1579223, +12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1587565,2, +1,6,1,10,28,34,63,38,3,26,1626879,16,1,1630325,14,1310721, +2,9,26,3,1,10,28,10,3,6,10,4,8,1310721,2,5, +26,2,5,40,3,36,1626973,16,1310721,2,5,26,2,5,28,1612447, +12,1,6,1,10,28,34,63,38,1,10,28,1626975,14,1,1627013, +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,1627105,16,1469953,1310721,2, +9,26,2,1612309,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,1627107,14, +1,1627197,16,1310721,2,9,26,2,1627183,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,1627125,1591963,12,8,1,1630325,14,1310721,2, +2,3,28,1,6,1,10,28,34,63,38,3,26,1628669,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,1627347,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,1627349,14,1,1627553,16,1310721,2,7,26, +2,1616087,12,1,6,1,10,28,34,63,38,3,26,1627519,16,1310721, +2,3,26,2,1627507,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,1627405,1591963,12,8,1627547,14,1469953, +1310721,2,3,26,2,26,1,10,3,6,10,4,8,1,1630325,14, +1310721,2,7,26,2,1616087,12,1,6,1,10,28,34,63,38,3, +26,1627721,16,1310721,2,3,26,2,1627707,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,1627605,1591963,12, +8,1,1630325,14,1310721,2,5,26,2,3,28,1,6,1,10,28, +34,63,38,3,26,1627919,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,1558017,1310721,2,3,26,2,26,2,31,32,1627913,16,1469953,1310721,2, +3,26,2,26,1558017,1310721,2,3,26,2,26,2,31,32,10,3, +6,10,4,8,1,1630325,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,1628077,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,1628079,14,1,1628299,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,1558017, +1310721,2,3,26,2,26,2,31,32,1628293,16,1469953,1310721,2,3,26, +2,26,1558017,1310721,2,3,26,2,26,2,31,32,10,3,6,10, +4,8,1,1630325,14,1310721,2,13,26,2,5,28,1,6,1,10, +28,34,63,38,3,26,1628519,16,1310721,2,9,26,2,1628507,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,1628351,1591963,12, +8,1628663,14,1310721,2,9,26,2,1628655,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,1628533,1591963,12,8,1,1630325,14,1310721,2, +2,7,28,1,6,1,10,28,34,63,38,3,26,1629993,16,1310721, +2,11,26,1310721,2,3,26,2,1612309,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,1612545,12,8,1310721,2,5,26,2,3, +28,1,6,1,10,28,34,63,38,3,26,1628849,16,1310721,2,3, +26,2,1626549,12,8,1,1630325,14,1310721,2,9,26,2,1,40,1628873, +16,1,1630325,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,1629035,16,1310721,2,9,26,2,1629023,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,1628961, +1591963,12,8,1629987,14,1310721,2,13,26,2,13,28,1,6,1,10, +28,34,63,38,3,26,1629163,16,1310721,2,9,26,2,1629151,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,1629087, +1591963,12,8,1629987,14,1310721,2,7,26,2,13,28,1,6,1,10, +28,34,63,38,3,26,1629489,16,1310721,2,13,26,2,5,28,1, +6,1,10,28,34,63,38,3,26,1629413,16,1310721,2,9,26,2, +1629401,14,105,115,32,117,59,32,105,116,32,104,97,115,32,116, +111,32,108,101,97,118,101,32,116,104,114,111,117,103,104,32, +116,104,101,32,98,108,111,99,107,32,97,98,111,118,101,44, +32,110,111,116,32,105,110,116,111,32,97,32,98,111,114,114, +111,119,101,100,32,111,98,106,101,99,116,0,1629253,1591963,12,8, +1629485,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,1626549,12,8,1629987,14,1310721,2,13,26,2,1310721,2,7, +26,2,28,1,6,1,10,28,34,63,38,1,10,28,1629695,16, +1310721,2,9,26,2,1629683,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,1629551,1591963,12,8,1629987,14,1468929, +1310721,2,9,26,2,26,2,1468929,1310721,2,11,26,2,26,2,40, +1629879,16,1310721,2,9,26,2,1629867,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,1629747,1591963,12,8,1629987,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,1626549,12, +8,1,1630325,14,1310721,2,9,26,2,1,40,3,36,1630317,16,1469953, +1310721,2,9,26,2,26,2,7,28,1,6,1,10,28,34,63, +38,3,26,1630119,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,1630317,14,1310721,2,9,26,2,1630309,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,1630133,1591963,12,8,1,1630325,14,1,1310721,2,15,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1630373,16,1966081,1310721,4, +1579223,12,1310721,2,4,1587565,2,1,6,1,10,28,34,63,38,3, +26,1630413,16,1,1631339,14,1310721,2,3,26,3,1,10,28,10,3, +6,10,4,8,1310721,2,2,5,40,3,36,1630499,16,1310721,2,2, +5,28,1612447,12,1,6,1,10,28,34,63,38,1,10,28,1630501, +14,1,1630535,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,1630627,16,1469953,1310721, +2,3,26,2,1612309,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,1630629, +14,1,1630719,16,1310721,2,3,26,2,1630705,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,1630647,1591963,12,8,1,1631339,14,1587567, +2,1630975,16,1310721,2,3,26,2,1,40,3,36,1630969,16,1469953,1310721, +2,3,26,2,26,2,5,28,1,6,1,10,28,34,63,38, +3,26,1630853,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, +1630969,14,1310721,2,3,26,2,1630961,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,117,42,120,39,0,1630867,1591963,12,8,1,1631339,14,1310721, +2,2,3,28,1,6,1,10,28,34,63,38,3,26,1631139,16, +1631127,14,114,101,116,117,114,110,115,32,97,32,110,101,119,32, +111,98,106,101,99,116,59,32,103,105,118,101,32,116,104,101, +32,102,117,110,99,116,105,111,110,32,97,32,46,117,32,114, +101,116,117,114,110,32,116,121,112,101,0,1631013,1591845,12,8,1631331, +14,1310721,2,3,26,2,1,40,3,36,1631331,16,1310721,2,3,26, +2,1631323,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,104,111,115,101,32,114,101,116,117,114,110,32,116, +121,112,101,32,105,115,110,39,116,32,46,117,0,1631175,1591963,12, +8,1,1631339,14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1631387,16,1966081,1310721,4,1579223,12,1310721,2,4, +1587565,2,1,6,1,10,28,34,63,38,3,26,1631427,16,1,1632055, +14,1310721,2,2,3,28,1,6,1,10,28,34,63,38,3,26, +1631467,16,3,1632055,14,1310721,2,2,5,40,1631487,16,3,1631543,14,1310721, +2,2,5,28,1612447,12,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1631553,16,1,1632055,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,1631695,16,1468929,1310721,2,3,26,2,26,2,1587561,2,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1631697,14,1,1631763,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,1632055,14,1469953,1310721,2,3,26,2,26, +2,5,28,1,6,1,10,28,34,63,38,3,26,1631927,16,1310721, +2,3,26,2,1631915,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,1631821,1591963,12,8,1632047,14,1310721,2,3,26,2, +1632039,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,1631941,1591963,12,8,1,1632055,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1632103,16,1966081,1310721, +4,1579223,12,1310721,2,4,1310721,2,2,3,28,1,6,1,10,28, +34,63,38,3,26,1632259,16,1632247,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,1632147,1591845,12,8,1632293, +14,1310721,2,2,5,40,3,36,1632293,16,1310721,2,2,5,28,1612545, +12,8,1,1632301,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1632349,16,1966081,1310721,4,1579223,12,1310721,2, +4,1587683,2,1310721,2,3,26,4,1587683,2,1310721,2,2,26,1310721,40, +3,36,1632449,16,1632441,14,116,104,101,32,116,121,112,101,32,97, +114,101,97,32,105,115,32,102,117,108,108,0,1632397,1591079,12,8, +1587683,1587683,2,1310721,2,2,26,10,3,6,10,4,8,1310721,2,3, +26,2,1,1310721,2,2,1574703,12,8,1310721,2,3,26,2,1632515,14, +1,1310721,2,5,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2, +1835009,40,1632563,16,1966081,1310721,4,1579223,12,1310721,2,7,26,4,1310721,2, +5,26,4,1310721,2,3,26,4,1310721,2,4,15,1310721,2,7,26, +2,26,1632315,12,1310721,2,9,26,4,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,1310721,2,5,26,2,10,3,6,10,4,8,1587685,2,2049, +40,3,36,1632789,16,1632781,14,116,111,111,32,109,97,110,121,32, +116,121,112,101,115,0,1632751,1591079,12,8,1277953,1587685,2,26,1310721,2, +9,26,2,10,3,6,10,4,8,1587685,1,6,2,1,6,3, +26,5,6,4,10,8,8,1310721,2,9,26,2,1632863,14,1,1310721, +2,11,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40, +1632911,16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2,3,26,4, +1310721,2,3,26,2,1587685,2,40,1633157,16,1310721,2,5,26,1277953,1310721, +2,3,26,2,26,2,10,3,6,10,4,8,1310721,2,5,26, +2,1,26,2,11,28,1,6,1,10,28,34,63,38,3,26, +1633099,16,1310721,2,5,26,2,9,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,1633101,14,1,1633119,16,1310721,2,5,26,2,1633237,14,1310721, +2,3,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1632929,14,1310721,2,5,26,11,3,1,1,1632529,12,10,3,6,10, +4,8,1310721,2,5,26,2,9,26,1310721,2,2,10,3,6,10, +4,8,1310721,2,5,26,2,1633237,14,1,1310721,2,7,26,1310721,4, +18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1633285,16,1966081,1310721,4, +1579223,12,1310721,2,3,26,4,1310721,2,4,1,1310721,2,5,26,4, +1310721,2,5,26,2,1587685,2,40,1633621,16,1310721,2,7,26,1277953,1310721, +2,5,26,2,26,2,10,3,6,10,4,8,1310721,2,7,26, +2,1,26,2,13,28,1,6,1,10,28,34,63,38,3,26, +1633483,16,1310721,2,7,26,2,9,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,1633485,14,1,1633563,16,1310721,2,7,26,2,7,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,1633565,14,1,1633583,16, +1310721,2,7,26,2,1633757,14,1310721,2,5,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1633313,14,1310721,2,7,26,13,1310721, +2,3,26,2,1310721,2,2,1637519,12,30,1,1,1632529,12,10,3, +6,10,4,8,1310721,2,7,26,2,9,26,1310721,2,2,10,3, +6,10,4,8,1310721,2,7,26,2,7,26,1310721,2,3,26,2, +10,3,6,10,4,8,1310721,2,7,26,2,1633757,14,1,1310721,2, +9,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1633805, +16,1966081,1310721,4,1579223,12,1310721,2,7,26,4,1310721,2,5,26,4, +1310721,2,3,26,4,1310721,2,4,1,1310721,2,9,26,4,1310721,2, +9,26,2,1587685,2,40,1634479,16,1310721,2,13,26,1277953,1310721,2,9, +26,2,26,2,10,3,6,10,4,8,1310721,2,13,26,2,1, +26,2,15,28,1,6,1,10,28,34,63,38,3,26,1634023,16, +1310721,2,13,26,2,9,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,1634025,14,1,1634103,16,1310721,2,13,26,2,7,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,1634105,14,1,1634183,16,1310721,2, +13,26,2,11,26,2,1310721,2,7,26,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1634185,14,1,1634441,16,1310721,2,11,26,1,10,3,6,10,4, +8,1310721,2,11,26,2,1310721,2,3,26,2,40,1634337,16,1310721,2, +13,26,2,15,1310721,2,11,26,2,26,26,2,1310721,2,5,26, +2,1310721,2,11,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,1634339,14, +1,1634381,16,1310721,2,11,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1634211,14,1310721,2,11,26,2,1310721,2,3,26,2, +28,1,6,1,10,28,34,63,38,3,26,1634441,16,1310721,2,13, +26,2,1634679,14,1310721,2,9,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1633853,14,1310721,2,13,26,15,3,1,1310721,2, +3,26,2,1632529,12,10,3,6,10,4,8,1310721,2,13,26,2, +9,26,1310721,2,2,10,3,6,10,4,8,1310721,2,13,26,2, +7,26,1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,13, +26,2,11,26,1310721,2,7,26,2,10,3,6,10,4,8,1310721, +2,13,26,2,15,26,1310721,2,5,26,2,1310721,2,3,26,2, +1574491,12,8,1310721,2,13,26,2,1634679,14,1,1310721,2,15,26,1310721, +4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1634727,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1,1310721,2,5,26, +4,1310721,2,5,26,2,1587685,2,40,1635063,16,1310721,2,7,26,1277953, +1310721,2,5,26,2,26,2,10,3,6,10,4,8,1310721,2,7, +26,2,1,26,2,23,28,1,6,1,10,28,34,63,38,3, +26,1634925,16,1310721,2,7,26,2,9,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,1634927,14,1,1635005,16,1310721,2,7,26,2,7,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,1635007,14,1,1635025, +16,1310721,2,7,26,2,1635179,14,1310721,2,5,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1634755,14,1310721,2,7,26,23, +3,1,1,1632529,12,10,3,6,10,4,8,1310721,2,7,26,2, +9,26,1310721,2,2,10,3,6,10,4,8,1310721,2,7,26,2, +7,26,1310721,2,3,26,2,10,3,6,10,4,8,1310721,2,7, +26,2,1635179,14,1,1310721,2,9,26,1310721,4,18,1310721,2,9,28, +1310721,4,1310721,2,1835009,40,1635227,16,1966081,1310721,4,1579223,12,1310721,2,3, +26,4,1310721,2,4,1,1310721,2,5,26,4,1310721,2,5,26,2, +1587685,2,40,1635483,16,1310721,2,7,26,1277953,1310721,2,5,26,2,26, +2,10,3,6,10,4,8,1310721,2,7,26,2,1,26,2,19, +28,1,6,1,10,28,34,63,38,3,26,1635425,16,1310721,2,7, +26,2,7,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,1635427,14, +1,1635445,16,1310721,2,7,26,2,1635571,14,1310721,2,5,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1635255,14,1310721,2,7, +26,19,3,1310721,2,3,26,2,1,1632529,12,10,3,6,10,4, +8,1310721,2,7,26,2,7,26,1310721,2,2,10,3,6,10,4, +8,1310721,2,7,26,2,1635571,14,1,1310721,2,9,26,1310721,4,18, +1310721,2,15,28,1310721,4,1310721,2,1835009,40,1635619,16,1966081,1310721,4,1579223, +12,1310721,2,5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721, +2,7,26,4,1310721,2,7,26,2,1587685,2,40,1636159,16,1310721,2, +11,26,1277953,1310721,2,7,26,2,26,2,10,3,6,10,4,8, +1310721,2,11,26,2,1,26,2,17,28,1,6,1,10,28,34, +63,38,3,26,1635827,16,1310721,2,11,26,2,11,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,1635829,14,1,1636121,16,1310721,2,13,26, +1310721,2,11,26,2,13,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, +5,26,2,40,1636017,16,1310721,2,13,26,2,3,1310721,2,9,26, +2,26,26,2,1310721,2,3,26,2,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,1636019,14,1,1636061,16,1310721,2,9,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1635891,14,1310721,2, +9,26,2,1310721,2,5,26,2,28,1,6,1,10,28,34,63, +38,3,26,1636121,16,1310721,2,11,26,2,1636433,14,1310721,2,7,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1635657,14,1310721, +2,13,26,1310721,2,5,26,2,3,26,1632315,12,10,3,6,10, +4,8,1310721,2,13,26,2,1,26,1310721,2,5,26,2,10,3, +6,10,4,8,1310721,2,13,26,2,3,26,1310721,2,3,26,2, +1310721,2,5,26,2,1574491,12,8,1310721,2,11,26,17,1,1310721,2, +2,5,26,2,1,1632529,12,10,3,6,10,4,8,1310721,2,11, +26,2,7,26,3,1,10,28,10,3,6,10,4,8,1310721,2, +11,26,2,11,26,1310721,2,2,10,3,6,10,4,8,1310721,2, +11,26,2,13,26,1310721,2,13,26,2,10,3,6,10,4,8, +1310721,2,11,26,2,1636433,14,1,1310721,2,15,26,1310721,4,18,1310721, +2,33,28,1310721,4,1310721,2,1835009,40,1636481,16,1966081,1310721,4,1579223,12, +1310721,2,4,1,1310721,2,13,26,4,1310721,2,2,1,26,2,17, +28,1,6,1,10,28,34,63,38,1,10,28,1636547,16,3,1636589, +14,1310721,2,2,7,26,2,1,40,3,36,1,6,1,10,28, +34,63,38,1,10,28,1636603,16,1310721,2,2,1637505,14,1310721,2,2, +7,26,2,5,1,10,28,28,1,6,1,10,28,34,63,38, +3,26,1636773,16,1636731,14,97,32,115,116,114,117,99,116,32,99, +97,110,39,116,32,99,111,110,116,97,105,110,32,105,116,115, +101,108,102,32,98,121,32,118,97,108,117,101,0,1636653,1591173,12, +8,1310721,2,2,7,26,1,10,3,6,10,4,8,1310721,2,2, +1637505,14,1310721,2,2,7,26,5,1,10,28,10,3,6,10,4, +8,1310721,2,3,26,1310721,2,2,11,26,2,10,3,6,10,4, +8,1310721,2,7,26,1310721,2,3,26,2,11,26,2,10,3,6, +10,4,8,1310721,2,5,26,1310721,2,3,26,2,9,26,2,10, +3,6,10,4,8,1310721,2,17,26,1,17,1574703,12,8,1310721,2, +17,26,1310721,2,2,13,26,2,3,26,1310721,2,2,13,26,2, +1,26,2,1574491,12,8,1310721,2,11,26,1310721,2,7,26,2,7, +30,3,26,1632315,12,10,3,6,10,4,8,1310721,2,9,26,1, +10,3,6,10,4,8,1310721,2,9,26,2,1310721,2,7,26,2, +40,1637397,16,1310721,2,15,26,1310721,2,5,26,2,1310721,2,9,26, +2,1310721,2,9,26,2,26,3,26,26,2,1310721,2,17,26,1637691, +12,10,3,6,10,4,8,1310721,2,11,26,2,1310721,2,9,26, +2,7,30,26,1310721,2,5,26,2,1310721,2,9,26,2,1310721,2, +9,26,2,26,26,2,10,3,6,10,4,8,1310721,2,11,26, +2,1310721,2,9,26,2,7,30,3,26,26,1310721,2,15,26,2, +10,3,6,10,4,8,1310721,2,11,26,2,1310721,2,9,26,2, +7,30,5,26,26,1310721,2,13,26,2,10,3,6,10,4,8, +1310721,2,13,26,1310721,2,13,26,2,1310721,2,15,26,2,1637519,12, +26,10,3,6,10,4,8,1310721,2,9,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1637037,14,1310721,2,2,9,26,1310721, +2,11,26,2,10,3,6,10,4,8,1310721,2,2,3,26,1310721, +2,13,26,2,10,3,6,10,4,8,1310721,2,2,7,26,1310721, +2,7,26,2,10,3,6,10,4,8,1310721,2,2,1637505,14,1, +1310721,2,33,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1637553,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26, +2,17,28,1,6,1,10,28,34,63,38,3,26,1637641,16,1310721, +2,2,7,26,2,1,40,1,6,1,10,28,34,63,38,1, +10,28,1637643,14,1,1637659,16,1310721,2,2,1636447,12,8,1310721,2,2, +3,26,2,1637677,14,1,1310721,2,3,26,1310721,4,18,1310721,2,61, +28,1310721,4,1310721,2,1835009,40,1637725,16,1966081,1310721,4,1579223,12,1310721,2, +3,26,4,1310721,2,4,1310721,2,2,1,26,2,1310721,2,5,26, +4,1310721,2,5,26,2,19,28,1,6,1,10,28,34,63,38, +3,26,1637869,16,1310721,2,3,26,2,1310721,2,2,7,26,2,26, +2,1637861,16,1310721,2,3,26,2,1310721,2,2,7,26,2,26,2, +1638675,14,1587687,2,1638675,14,1310721,2,5,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1637941,16,1310721,2,2,9,26,2,1310721, +2,3,26,2,1637691,12,1632877,12,1638675,14,1310721,2,5,26,2,13, +28,1,6,1,10,28,34,63,38,3,26,1638025,16,1310721,2,2, +9,26,2,1310721,2,3,26,2,1637691,12,1310721,2,2,7,26,2, +1633251,12,1638675,14,1310721,2,5,26,2,15,28,1,6,1,10,28, +34,63,38,3,26,1638315,16,1310721,2,9,26,1310721,2,2,7,26, +2,10,3,6,10,4,8,1310721,2,7,26,1,10,3,6,10, +4,8,1310721,2,7,26,2,1310721,2,9,26,2,40,1638251,16,1310721, +2,11,26,1310721,2,7,26,2,26,1310721,2,2,15,1310721,2,7, +26,2,26,26,2,1310721,2,3,26,2,1637691,12,10,3,6,10, +4,8,1310721,2,7,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1638117,14,1310721,2,2,9,26,2,1310721,2,3,26,2, +1637691,12,1310721,2,9,26,2,1310721,2,11,26,1310721,2,2,11,26, +2,1633771,12,1638675,14,1310721,2,5,26,2,17,28,1,6,1,10, +28,34,63,38,3,26,1638391,16,1310721,2,2,11,26,2,1,6, +1,10,28,34,63,38,1,10,28,1638393,14,1,1638663,16,1310721,2, +59,26,1310721,2,2,13,26,2,10,3,6,10,4,8,1310721,2, +9,26,1310721,2,59,26,2,1,26,2,10,3,6,10,4,8, +1310721,2,7,26,1,10,3,6,10,4,8,1310721,2,7,26,2, +1310721,2,9,26,2,40,1638625,16,1310721,2,11,26,1310721,2,7,26, +2,26,1310721,2,59,26,2,3,1310721,2,7,26,2,26,26,2, +1310721,2,3,26,2,1637691,12,10,3,6,10,4,8,1310721,2,7, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1638487,14, +1310721,2,2,11,26,2,1310721,2,11,26,1310721,2,9,26,2,1635585, +12,1638675,14,1310721,2,2,1638675,14,1,1310721,2,61,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1638723,16,1966081,1310721,4,1579223, +12,1310721,2,4,1310721,2,2,1,26,2,3,28,1,6,1,10, +28,34,63,38,3,26,1638775,16,3,1638833,14,1310721,2,2,1,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,1638843,16,3,1638901,14,1310721,2,2, +1,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,1638907,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1638955,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26,2,13,28, +1,6,1,10,28,34,63,38,3,26,1639007,16,3,1639065,14,1310721, +2,2,1,26,2,17,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1639071,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1639119,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26,2, +11,28,1,6,1,10,28,34,63,38,3,26,1639171,16,3,1639229, +14,1310721,2,2,1,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1639235,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1639283,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1, +26,2,13,28,1,6,1,10,28,34,63,38,3,26,1639349,16, +1310721,2,2,9,26,2,1632877,12,1639361,14,1310721,2,2,1639361,14,1, +1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1639409,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26, +2,11,28,1,6,1,10,28,34,63,38,3,26,1639461,16,3, +1639519,14,1310721,2,2,1,26,2,13,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1639539, +16,1310721,2,2,9,26,2,1639549,14,1587687,2,1639549,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1639597, +16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2, +2,1310721,2,3,26,2,28,1,6,1,10,28,34,63,38,3, +26,1639661,16,3,1639715,14,1310721,2,2,1587687,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1639725,16,3,1639783,14,1310721,2,3,26,2,1587687,2,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1639793,16,3,1640865,14,1310721,2,2,1638689,12,1639847,16,1310721, +2,3,26,2,1638689,12,1,6,1,10,28,34,63,38,1,10, +28,1639849,14,1,1639859,16,3,1640865,14,1310721,2,3,26,1310721,2,3, +26,2,1639249,12,10,3,6,10,4,8,1310721,2,2,1,26,2, +11,28,1,6,1,10,28,34,63,38,3,26,1639999,16,1310721,2, +3,26,2,1,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,1640001,14,1, +1640325,16,1310721,2,2,9,26,2,1587687,2,28,1,6,1,10,28, +34,63,38,3,26,1640053,16,3,1640117,14,1310721,2,3,26,2,9, +26,2,1587687,2,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1640127,16,3,1640187,14,1310721, +2,2,9,26,2,1587695,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1640197,16,3, +1640261,14,1310721,2,3,26,2,9,26,2,1587695,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1640271,16,3,1640865,14,1310721,2,2,9,26,2,1310721,2,3, +26,2,9,26,2,28,1,6,1,10,28,34,63,38,3,26, +1640865,14,1310721,2,2,1,26,2,11,28,1,6,1,10,28,34, +63,38,3,26,1640371,16,3,1640429,14,1310721,2,2,1,26,2,15, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1640439,16,3,1640497,14,1310721,2,2,1,26, +2,23,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1640531,16,1587701,2,1,6,1,10, +28,34,63,38,1,10,28,1640533,14,1,1640543,16,3,1640865,14,1310721, +2,2,1,26,2,23,28,1,6,1,10,28,34,63,38,3, +26,1640649,16,1310721,2,3,26,2,1,26,2,23,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1640651,14,1,1640731,16,1310721,2,2,9,26,2,1310721,2,3, +26,2,9,26,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1640733,14,1,1640821,16, +1310721,2,2,7,26,2,1640759,16,3,1640817,14,1310721,2,3,26,2, +7,26,2,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1640865,14,1310721,2,2,1310721,2,3, +26,2,28,1,6,1,10,28,34,63,38,3,26,1640865,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009, +40,1640913,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3, +26,4,1310721,2,4,1310721,2,2,1,26,2,19,28,1,6,1, +10,28,34,63,38,3,26,1641151,16,1310721,2,7,26,1310721,2,2, +7,26,2,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2, +7,26,2,26,2,1,6,1,10,28,34,63,38,3,26,1641109, +16,1310721,2,5,26,2,1310721,2,7,26,2,26,1310721,2,3,26, +2,10,3,6,10,4,8,3,1641955,14,1310721,2,5,26,2,1310721, +2,7,26,2,26,2,1310721,2,3,26,2,1639563,12,1641955,14,1310721, +2,3,26,1310721,2,3,26,2,1639249,12,10,3,6,10,4,8, +1310721,2,2,1,26,2,11,28,1,6,1,10,28,34,63,38, +3,26,1641291,16,1310721,2,3,26,2,1,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,1641293,14,1,1641395,16,1310721,2,3,26,2,9,26,2, +1587687,2,28,1,6,1,10,28,34,63,38,3,26,1641349,16,3, +1641955,14,1310721,2,2,9,26,2,1310721,2,3,26,2,9,26,2, +1310721,2,5,26,2,1640879,12,1641955,14,1310721,2,2,1,26,2,17, +28,1,6,1,10,28,34,63,38,3,26,1641473,16,1310721,2,2, +11,26,2,1,6,1,10,28,34,63,38,1,10,28,1641475,14, +1,1641545,16,1310721,2,3,26,2,1,26,2,17,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1641547,14,1,1641627,16,1310721,2,3,26,2,11,26,2,1310721, +2,2,11,26,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1641629,14,1,1641929,16, +1310721,2,11,26,1310721,2,2,13,26,2,10,3,6,10,4,8, +1310721,2,13,26,1310721,2,3,26,2,13,26,2,10,3,6,10, +4,8,1310721,2,9,26,1310721,2,11,26,2,1,26,2,10,3, +6,10,4,8,1310721,2,7,26,1,10,3,6,10,4,8,1310721, +2,7,26,2,1310721,2,9,26,2,40,1641923,16,1310721,2,11,26, +2,3,1310721,2,7,26,2,26,26,2,1310721,2,13,26,2,3, +1310721,2,7,26,2,26,26,2,1310721,2,5,26,2,1640879,12,1, +6,1,10,28,34,63,38,3,26,1641885,16,1,1641955,14,1310721,2, +7,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1641759, +14,3,1641955,14,1310721,2,2,1310721,2,3,26,2,1639563,12,1641955,14, +1,1310721,2,15,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2, +1835009,40,1642003,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1, +26,2,1310721,2,3,26,4,1310721,2,3,26,2,11,28,1,6, +1,10,28,34,63,38,3,26,1642097,16,85,1573255,12,8,1310721,2, +2,9,26,2,1641969,12,1643211,14,1310721,2,3,26,2,23,28,1, +6,1,10,28,34,63,38,3,26,1642215,16,1310721,2,2,7,26, +2,1642177,16,1642169,14,102,105,120,101,100,32,0,1642155,1573495,12,8, +1642187,14,91,93,0,1642181,1573495,12,8,1310721,2,2,9,26,2,1641969, +12,1643211,14,1310721,2,3,26,2,13,28,1,6,1,10,28,34, +63,38,3,26,1642307,16,183,1573255,12,8,1310721,2,2,7,26,2, +1573657,12,8,187,1573255,12,8,1310721,2,2,9,26,2,1641969,12,1643211, +14,1310721,2,3,26,2,15,28,1,6,1,10,28,34,63,38, +3,26,1642861,16,1310721,2,2,9,26,2,1587687,2,28,1,6,1, +10,28,34,63,38,3,26,1642409,16,1642397,14,102,110,0,1642391,1573495, +12,8,1642427,14,1310721,2,2,9,26,2,1641969,12,8,1310721,2,2, +11,26,2,3,32,1642465,16,1642457,14,46,117,0,1642451,1573495,12,8, +81,1573255,12,8,1310721,2,5,26,1,10,3,6,10,4,8,1310721, +2,5,26,2,1310721,2,2,7,26,2,40,1642847,16,1310721,2,5, +26,2,1642555,16,1642547,14,44,32,0,1642541,1573495,12,8,1310721,2,2, +15,1310721,2,5,26,2,26,26,2,1641969,12,8,1310721,2,5,26, +2,25,40,1642673,16,1310721,2,2,1310721,2,5,26,2,1662085,12,3, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1642675,14,1,1642697,16,1642689,14,46,109,0, +1642683,1573495,12,8,1310721,2,5,26,2,25,40,1642785,16,1310721,2,2, +1310721,2,5,26,2,1662085,12,5,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1642787,14, +1,1642809,16,1642801,14,46,100,0,1642795,1573495,12,8,1310721,2,5,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1642495,14,83, +1573255,12,8,1,1643211,14,1310721,2,2,5,26,2,1642899,16,1310721,2, +2,5,26,2,1573495,12,8,1642915,14,1642907,14,63,0,1642903,1573495,12, +8,1310721,2,3,26,2,17,28,1,6,1,10,28,34,63,38, +3,26,1642991,16,1310721,2,2,11,26,2,1,6,1,10,28,34, +63,38,1,10,28,1642993,14,1,1643203,16,1310721,2,7,26,1310721,2, +2,13,26,2,10,3,6,10,4,8,121,1573255,12,8,1310721,2, +5,26,1,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2, +7,26,2,1,26,2,40,1643195,16,1310721,2,5,26,2,1643123,16, +1643115,14,44,32,0,1643109,1573495,12,8,1310721,2,7,26,2,3,1310721, +2,5,26,2,26,26,2,1641969,12,8,1310721,2,5,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1643059,14,125,1573255,12, +8,1,1643211,14,1,1310721,2,9,26,1310721,4,18,1310721,2,7,28, +1310721,4,1310721,2,1835009,40,1643259,16,1966081,1310721,4,1579223,12,1310721,2,5, +26,4,1310721,2,3,26,4,1310721,2,4,1587697,2,1,6,1,10, +28,34,63,38,3,26,1643319,16,3,1643365,14,1587569,2,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1643375,16,3,1643401,14,1587703,2,1,6,1,10,28,34,63, +38,1,10,28,1643411,16,3,1643437,14,1590585,2,1,6,1,10,28, +34,63,38,1,10,28,1643447,16,1,1643611,14,1590587,12,8,1643483,14, +116,121,112,101,32,101,114,114,111,114,58,32,0,1643457,1573495,12, +8,1310721,2,2,1573495,12,8,1643531,14,58,32,101,120,112,101,99, +116,101,100,32,0,1643507,1573495,12,8,1310721,2,3,26,2,1641969,12, +8,1643573,14,44,32,103,111,116,32,0,1643559,1573495,12,8,1310721,2, +5,26,2,1641969,12,8,1590731,12,8,1,1643611,14,1,1310721,2,7, +26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2,1835009,40,1643659,16, +1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721, +2,4,1310721,2,2,1643701,16,3,1643747,14,1587697,2,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1643757,16,3,1643803,14,1587569,2,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1643813,16,3, +1643839,14,1587703,2,1,6,1,10,28,34,63,38,1,10,28,1643849, +16,3,1643875,14,1590585,2,1,6,1,10,28,34,63,38,1,10, +28,1643885,16,1,1644001,14,1590587,12,8,1643921,14,116,121,112,101,32, +101,114,114,111,114,58,32,0,1643895,1573495,12,8,1310721,2,3,26, +2,1573495,12,8,1643963,14,44,32,103,111,116,32,0,1643949,1573495,12, +8,1310721,2,5,26,2,1641969,12,8,1590731,12,8,1,1644001,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1644049,16,1966081,1310721,4,1579223,12,1310721,2,4,1587721,2,1310721,2,3, +26,4,1310721,2,3,26,2,1644183,16,1310721,2,3,26,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1587705,1310721,2,3,26,2, +26,2,1310721,2,2,28,1,6,1,10,28,34,63,38,3,26, +1644179,16,1310721,2,3,26,2,1644197,14,1644069,14,3,1,10,28,1644197, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1644245,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2, +1590545,2,28,1,6,1,10,28,34,63,38,3,26,1644293,16,3, +1644475,14,1310721,2,2,1644015,12,1,40,3,36,1644321,16,3,1644475,14, +1310721,2,2,1611615,12,1,40,3,36,1644349,16,1,1644475,14,1310721,2, +3,26,1310721,2,2,1593303,12,10,3,6,10,4,8,1310721,2,3, +26,2,1,40,3,36,1644467,16,1417729,1310721,2,3,26,2,26,2, +15,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1644469,14,1,1644475,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1644523,16, +1966081,1310721,4,1579223,12,1587733,2,1606425,12,1644559,16,1585291,1587731,2,10,3, +6,10,4,8,1,1644577,14,1587731,2,1606959,12,8,1,1644577,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,53,28,1310721,4,1310721,2,1835009, +40,1644625,16,1966081,1310721,4,1579223,12,1645003,12,1310721,2,4,1587599,2,1606425, +12,1644977,16,1604999,12,8,1310721,2,3,26,1,10,3,6,10,4, +8,1587601,2,1606425,12,1,6,1,10,28,34,63,38,3,26,1644897, +16,3,1644897,16,1310721,2,3,26,2,49,40,3,36,1644787,16,1644779, +14,116,111,111,32,109,97,110,121,32,112,97,114,97,109,101, +116,101,114,115,0,1644739,1591079,12,8,1310721,2,5,26,1310721,2,3, +26,2,26,1644591,12,10,3,6,10,4,8,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1587611,2,1606729,12, +1,6,1,10,28,34,63,38,3,26,1644893,16,1644897,14,1644707,14, +1587601,2,1606959,12,8,1310721,2,1310721,2,2,1310721,2,3,26,2,1310721, +2,5,26,1310721,2,3,26,2,1310721,2,3,26,2,26,1633771,12, +10,3,6,10,4,8,1644635,14,1310721,2,2,1644989,14,1,1310721,2, +53,26,1310721,4,18,1310721,2,27,28,1310721,4,1310721,2,1835009,40,1645037, +16,1966081,1310721,4,1579223,12,1,1310721,2,23,26,4,1587623,2,1606729,12, +1645073,16,1645003,12,1632877,12,1646967,14,1587607,2,1606729,12,1645263,16,1587609,2, +1606729,12,1645111,16,1645003,12,1,1634693,12,1646967,14,1310721,2,1685483,12,10, +3,6,10,4,8,1587609,2,1606959,12,8,1310721,2,5,26,1645003,12, +10,3,6,10,4,8,1310721,2,2,1,40,1645239,16,1645231,14,97, +32,110,101,103,97,116,105,118,101,32,97,114,114,97,121,32, +108,101,110,103,116,104,0,1645183,1591173,12,8,1310721,2,5,26,2, +1310721,2,2,1633251,12,1646967,14,1590545,2,1606577,12,1645497,16,1604999,12,8, +1310721,2,5,26,1645003,12,10,3,6,10,4,8,1310721,2,5,26, +2,1,26,2,23,28,1,6,1,10,28,34,63,38,3,26, +1645375,16,1310721,2,5,26,2,9,26,2,3,1634693,12,1646967,14,1310721, +2,5,26,2,1,26,2,13,28,1,6,1,10,28,34,63, +38,1,10,28,1645483,16,1645475,14,111,110,108,121,32,97,114,114, +97,121,115,32,99,97,110,32,98,101,32,102,105,120,101,100, +0,1645425,1591173,12,8,1310721,2,5,26,2,1646967,14,1587639,2,1606577,12, +1645653,16,1604999,12,8,1587599,2,1606425,12,1,6,1,10,28,34,63, +38,3,26,1645645,16,1645637,14,102,110,32,97,115,32,97,32,116, +121,112,101,32,110,101,101,100,115,32,105,116,115,32,112,97, +114,97,109,101,116,101,114,115,58,32,102,110,40,105,110,116, +41,0,1645551,1591557,12,8,1587687,2,1646967,14,1585289,2,5,28,1,6, +1,10,28,34,63,38,1,10,28,1645739,16,1645723,14,101,120,112, +101,99,116,101,100,32,97,32,116,121,112,101,0,1645691,1591557,12, +8,1587687,2,1646967,14,1310721,2,1585291,2,10,3,6,10,4,8,1310721, +2,25,26,1310721,2,2,1644015,12,10,3,6,10,4,8,1310721,2, +25,26,2,1,40,3,36,1645841,16,1604999,12,8,1310721,2,25,26, +2,1310721,2,2,1635193,12,1646967,14,1310721,2,3,26,1310721,2,2,1593303, +12,10,3,6,10,4,8,1587723,2,1645993,16,1310721,2,3,26,2, +1,40,1645903,16,3,1645967,14,1417729,1310721,2,3,26,2,26,2,15, +28,1,6,1,10,28,34,63,38,1,10,28,1,6,1,10, +28,34,63,38,1,10,28,1,6,1,10,28,34,63,38,1, +10,28,1645995,14,1,1646033,16,1587721,2,17,40,1,6,1,10,28, +34,63,38,1,10,28,1646035,14,1,1646121,16,1587705,1587721,2,26,1310721, +2,2,10,3,6,10,4,8,1587721,1,6,2,1,6,3,26, +5,6,4,10,8,8,1604999,12,8,1587721,2,3,28,1310721,2,2, +1635193,12,1646967,14,1310721,2,3,26,2,1,40,1646145,16,3,1646209,14, +1417729,1310721,2,3,26,2,26,2,15,28,1,6,1,10,28,34, +63,38,1,10,28,1,6,1,10,28,34,63,38,1,10,28, +1646265,16,1310721,2,2,1646249,14,105,115,110,39,116,32,97,32,116, +121,112,101,0,1646223,1591691,12,8,1587687,2,1646967,14,1604999,12,8,1310721, +2,5,26,1425921,1310721,2,3,26,2,26,2,10,3,6,10,4, +8,1310721,2,5,26,2,1,26,2,21,28,1,6,1,10,28, +34,63,38,1,10,28,1646367,16,1310721,2,5,26,2,1646967,14,1587729, +2,1606959,12,8,3,1646789,16,1310721,2,23,26,2,17,40,3,36, +1646465,16,1646457,14,116,111,111,32,109,97,110,121,32,116,121,112, +101,32,97,114,103,117,109,101,110,116,115,0,1646409,1591557,12,8, +1310721,2,7,26,1310721,2,23,26,2,26,1644591,12,10,3,6,10, +4,8,1310721,2,7,26,1310721,2,23,26,2,26,2,1637519,12,3, +28,1,6,1,10,28,34,63,38,1,10,28,1646715,16,1646707,14, +116,121,112,101,32,97,114,103,117,109,101,110,116,115,32,104, +97,118,101,32,116,111,32,98,101,32,111,110,101,32,119,111, +114,100,32,40,97,32,112,111,105,110,116,101,114,44,32,97, +32,110,117,109,98,101,114,44,32,111,114,32,97,32,112,97, +114,97,109,101,116,101,114,41,0,1646561,1591173,12,8,1310721,2,23, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1587611,2, +1606729,12,1,6,1,10,28,34,63,38,3,26,1646785,16,1646789,14, +1646377,14,1644489,12,8,1310721,2,23,26,2,1310721,2,5,26,2,7, +26,2,28,1,6,1,10,28,34,63,38,1,10,28,1646929,16, +1310721,2,2,1646921,14,119,114,111,110,103,32,110,117,109,98,101, +114,32,111,102,32,116,121,112,101,32,97,114,103,117,109,101, +110,116,115,0,1646859,1591343,12,8,1310721,2,5,26,2,1310721,2,7, +26,1310721,2,23,26,2,1635585,12,1646967,14,1,1310721,2,27,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1647015,16,1966081,1310721, +4,1579223,12,1585289,2,9,28,1,6,1,10,28,34,63,38,3, +26,1647653,16,1585291,2,1587607,2,28,1,6,1,10,28,34,63,38, +3,26,1647087,16,3,1647139,14,1585291,2,1587637,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1647149,16,3,1647769,14,1585291,2,1587623,2,28,1,6,1,10,28, +34,63,38,3,26,1647647,16,1310721,2,1,10,3,6,10,4,8, +1310721,2,2,7,40,1647379,16,1310721,2,2,1605397,12,8,1587511,2,9, +28,1,6,1,10,28,34,63,38,3,26,1647315,16,1587513,2,1587623, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1647317,14,1,1,6,1,10,28,34, +63,38,3,26,1647345,16,1647379,14,1310721,2,1,6,2,1,6,3, +26,5,6,4,10,8,8,1647201,14,1310721,2,2,1605397,12,8,1587511, +2,5,28,1,6,1,10,28,34,63,38,3,26,1647519,16,1587513, +2,1644211,12,1647441,16,3,1647493,14,1587513,2,1587639,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,1647521,14,1, +1647531,16,3,1647643,14,1587511,2,9,28,1,6,1,10,28,34,63, +38,3,26,1647619,16,1587513,2,1587607,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1647621, +14,1,1,6,1,10,28,34,63,38,1,10,28,1647769,14,1, +1647769,14,1585289,2,5,28,1,6,1,10,28,34,63,38,1,10, +28,1647693,16,1,1647769,14,1585291,2,1587639,2,28,1,6,1,10,28, +34,63,38,3,26,1647733,16,3,1647763,14,1585291,2,1644211,12,1,6, +1,10,28,34,63,38,1,10,28,1647769,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1647817,16,1966081, +1310721,4,1579223,12,1587725,1,10,3,6,10,4,8,1587727,1,10,3, +6,10,4,8,1587637,2,1606425,12,1,6,1,10,28,34,63,38, +3,26,1647899,16,1587725,1644591,12,10,3,6,10,4,8,1587637,2,1606729, +12,1648135,16,1585291,2,1587653,2,28,1,6,1,10,28,34,63,38, +3,26,1647965,16,1587727,3,10,3,6,10,4,8,1648129,14,1585291,2, +1587657,2,28,1,6,1,10,28,34,63,38,3,26,1648019,16,1587727, +5,10,3,6,10,4,8,1648129,14,1585291,2,1587655,2,28,1,6, +1,10,28,34,63,38,3,26,1648073,16,1587727,7,10,3,6,10, +4,8,1648129,14,1648121,14,97,32,116,97,103,32,105,115,32,46, +117,44,32,46,109,32,111,114,32,46,100,0,1648077,1591557,12,8, +1604999,12,8,1,1648143,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +21,28,1310721,4,1310721,2,1835009,40,1648191,16,1966081,1310721,4,1579223,12,1, +1310721,2,7,26,4,1524225,1310721,2,9,26,4,1,1310721,2,15,26, +4,1,1310721,2,17,26,4,1604999,12,8,1310721,2,1607249,12,10,3, +6,10,4,8,1587729,2,1606425,12,1648659,16,1604999,12,8,1587721,1,10, +3,6,10,4,8,3,1648475,16,1587721,2,17,40,3,36,1648383,16, +1648375,14,116,111,111,32,109,97,110,121,32,116,121,112,101,32, +112,97,114,97,109,101,116,101,114,115,0,1648325,1591557,12,8,1587705, +1587721,2,26,1607249,12,10,3,6,10,4,8,1587721,1,6,2,1, +6,3,26,5,6,4,10,8,8,1587611,2,1606729,12,1,6,1, +10,28,34,63,38,3,26,1648471,16,1648475,14,1648299,14,1644489,12,8, +1310721,2,17,26,3,10,3,6,10,4,8,1310721,2,3,26,21, +1,1310721,2,2,1,1632529,12,10,3,6,10,4,8,1310721,2,3, +26,2,7,26,1587721,2,10,3,6,10,4,8,1310721,2,13,26, +1587721,2,1632315,12,10,3,6,10,4,8,1310721,2,13,26,2,1587705, +1587721,2,1574491,12,8,1310721,2,3,26,2,13,26,1310721,2,13,26, +2,10,3,6,10,4,8,1648729,14,1310721,2,3,26,17,1,1310721, +2,2,1,1632529,12,10,3,6,10,4,8,1310721,2,3,26,2, +7,26,5,1,10,28,10,3,6,10,4,8,1310721,2,5,26, +1310721,2,2,15,1310721,2,3,26,2,1592805,12,10,3,6,10,4, +8,1587603,2,1606959,12,8,1587605,2,1606425,12,1,6,1,10,28,34, +63,38,3,26,1649107,16,1310721,2,19,26,1644591,12,10,3,6,10, +4,8,3,1649093,16,1310721,2,7,26,2,2001,40,3,36,1648909,16, +1648901,14,116,111,111,32,109,97,110,121,32,102,105,101,108,100, +115,0,1648869,1591079,12,8,1310721,2,9,26,2,1310721,2,7,26,2, +1310721,2,7,26,2,26,26,1607249,12,10,3,6,10,4,8,1310721, +2,9,26,2,1310721,2,7,26,2,1310721,2,7,26,2,26,3, +26,26,1310721,2,19,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,1587611,2, +1606729,12,1,6,1,10,28,34,63,38,3,26,1649089,16,1649093,14, +1648837,14,1587613,2,1606959,12,8,1648781,14,1604999,12,8,1310721,2,17,26, +2,1649313,16,1310721,2,13,26,1310721,2,7,26,2,1310721,2,7,26, +2,26,1632315,12,10,3,6,10,4,8,1310721,2,13,26,2,1310721, +2,9,26,2,1310721,2,7,26,2,1310721,2,7,26,2,26,1574491, +12,8,1310721,2,3,26,2,9,26,1310721,2,13,26,2,10,3, +6,10,4,8,1310721,2,3,26,2,11,26,1310721,2,7,26,2, +10,3,6,10,4,8,1587721,1,10,3,6,10,4,8,1650023,14, +1310721,2,13,26,1310721,2,7,26,2,7,30,3,26,1632315,12,10, +3,6,10,4,8,1310721,2,11,26,1,10,3,6,10,4,8, +1310721,2,11,26,2,1310721,2,7,26,2,40,1649915,16,1310721,2,19, +26,1310721,2,9,26,2,1310721,2,11,26,2,1310721,2,11,26,2, +26,3,26,26,2,10,3,6,10,4,8,1310721,2,19,26,2, +1310721,2,3,26,2,28,1,6,1,10,28,34,63,38,3,26, +1649653,16,1649621,14,97,32,115,116,114,117,99,116,32,99,97,110, +39,116,32,99,111,110,116,97,105,110,32,105,116,115,101,108, +102,32,98,121,32,118,97,108,117,101,59,32,117,115,101,32, +97,32,112,111,105,110,116,101,114,0,1649513,1591173,12,8,1310721,2, +19,26,1587687,2,10,3,6,10,4,8,1310721,2,13,26,2,1310721, +2,11,26,2,7,30,26,1310721,2,9,26,2,1310721,2,11,26, +2,1310721,2,11,26,2,26,26,2,10,3,6,10,4,8,1310721, +2,13,26,2,1310721,2,11,26,2,7,30,3,26,26,1310721,2, +19,26,2,10,3,6,10,4,8,1310721,2,13,26,2,1310721,2, +11,26,2,7,30,5,26,26,1310721,2,15,26,2,10,3,6, +10,4,8,1310721,2,15,26,1310721,2,15,26,2,1310721,2,19,26, +2,1637519,12,26,10,3,6,10,4,8,1310721,2,11,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1649377,14,1310721,2,3, +26,2,9,26,1310721,2,13,26,2,10,3,6,10,4,8,1310721, +2,3,26,2,3,26,1310721,2,15,26,2,10,3,6,10,4, +8,1310721,2,3,26,2,7,26,1310721,2,7,26,2,10,3,6, +10,4,8,1587613,2,1606729,12,8,1310721,2,5,26,2,1650049,14,1, +1310721,2,21,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009, +40,1650097,16,1966081,1310721,4,1579223,12,1604999,12,8,1310721,2,1607249,12,10, +3,6,10,4,8,1587615,2,1606959,12,8,1310721,2,2,15,1644591,12, +1592805,12,8,1587613,2,1606959,12,8,1,1650169,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1650217,16,1966081, +1310721,4,1579223,12,1604999,12,8,1587751,2,1606577,12,1650255,16,1587697,3,10, +3,6,10,4,8,1650359,14,1587753,2,1606577,12,1650287,16,1587697,1,10, +3,6,10,4,8,1650359,14,1650351,14,116,121,112,101,99,104,101, +99,107,32,111,110,32,111,114,32,116,121,112,101,99,104,101, +99,107,32,111,102,102,0,1650291,1591557,12,8,1604999,12,8,1587613,2, +1606959,12,8,1,1650383,14,1,1310721,2,1,26,1310721,4,18,1310721,2, +7,28,1310721,4,1310721,2,1835009,40,1650431,16,1966081,1310721,4,1579223,12,1310721, +2,3,26,4,1310721,2,4,1,1310721,2,5,26,4,1310721,2,2, +1636447,12,8,1310721,2,5,26,2,1310721,2,2,7,26,2,40,1650617, +16,1310721,2,2,9,26,2,1310721,2,5,26,2,7,30,26,2, +1310721,2,3,26,2,28,1,6,1,10,28,34,63,38,3,26, +1650579,16,1310721,2,5,26,2,1650631,14,1310721,2,5,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1650471,14,3,1,10,28, +1650631,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1650679,16,1966081,1310721,4,1579223,12,1587599,2,1606959,12,8, +1646981,12,1650751,16,1587637,2,1606425,12,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1650753,14,1, +1650781,16,1310721,2,1644591,12,10,3,6,10,4,8,1650943,14,1310721,2, +3,26,1615017,12,10,3,6,10,4,8,1587703,1,6,2,1,6, +3,26,5,6,4,10,8,8,1310721,2,5,26,1681059,12,10,3, +6,10,4,8,1663385,12,8,1310721,2,1587699,2,10,3,6,10,4, +8,1587703,1,6,2,1,6,-1,26,5,6,4,10,8,8,1310721, +2,3,26,2,1615649,12,8,1310721,2,3,26,2,1615567,12,8,1587601, +2,1606959,12,8,1310721,2,2,1650965,14,1,1310721,2,7,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1651013,16,1966081,1310721,4, +1579223,12,1587599,2,1606959,12,8,1310721,2,1681059,12,10,3,6,10,4, +8,1590511,3,1,10,28,10,3,6,10,4,8,1587769,2,1651103,16, +1587587,2,1,6,1,10,28,34,63,38,1,10,28,1651105,14,1, +1651163,16,1587589,2,3,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1651165,14,1,1651205,16, +1589487,1587591,2,26,2,1,6,1,10,28,34,63,38,1,10,28, +1651207,14,1,1651229,16,1590511,1587591,2,10,3,6,10,4,8,1663385,12, +8,1310721,2,2,1613033,12,8,1587699,2,1651257,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1651305,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,26,2,23,28,1, +6,1,10,28,34,63,38,3,26,1651389,16,1310721,2,2,7,26, +2,1,6,1,10,28,34,63,38,1,10,28,1651391,14,1,1651477, +16,1651469,14,97,32,102,105,120,101,100,32,97,114,114,97,121, +32,99,97,110,39,116,32,103,114,111,119,32,111,114,32,115, +104,114,105,110,107,0,1651399,1591173,12,8,1,1651485,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1651533, +16,1966081,1310721,4,1579223,12,1604999,12,8,1310721,2,1650979,12,10,3,6, +10,4,8,1587601,2,1606959,12,8,1310721,2,2,1,26,2,13,28, +1,6,1,10,28,34,63,38,3,26,1651639,16,9,1594729,12,8, +1310721,2,2,7,26,2,1594643,12,8,1651949,14,1310721,2,2,1,26, +2,23,28,1,6,1,10,28,34,63,38,3,26,1651685,16,3, +1651739,14,1310721,2,2,1587687,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1651781,14,108, +101,110,32,110,101,101,100,115,32,97,110,32,97,114,114,97, +121,0,1651743,1310721,2,2,1643625,12,8,1590511,2,1,40,3,36,1651851, +16,9,1594729,12,8,1589487,1590511,2,26,2,3,26,1595671,12,8,3, +1594729,12,8,1651949,14,1587769,2,1651921,16,1310721,2,2,1,26,2,23, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1651923,14,1,1651939,16,3,1594729,12,8,1651949, +14,1590547,2,1595409,12,8,1587699,1587689,2,10,3,6,10,4,8,1, +1651975,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1652023,16,1966081,1310721,4,1579223,12,1604999,12,8,1310721,2, +1650979,12,10,3,6,10,4,8,1587601,2,1606959,12,8,1310721,2,2, +1,26,2,23,28,1,6,1,10,28,34,63,38,3,26,1652105, +16,3,1652159,14,1310721,2,2,1587687,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1652195, +14,99,97,112,32,110,101,101,100,115,32,97,32,91,93,84, +0,1652163,1310721,2,2,1643625,12,8,1590549,2,1595409,12,8,1587699,1587689,2, +10,3,6,10,4,8,1,1652245,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1652293,16,1966081,1310721,4, +1579223,12,1604999,12,8,1310721,2,1650979,12,10,3,6,10,4,8,1310721, +2,2,1651271,12,8,1310721,2,2,1,26,2,23,28,1,6,1, +10,28,34,63,38,3,26,1652439,16,1310721,2,2,9,26,2,1637519, +12,3,28,1,6,1,10,28,34,63,38,1,10,28,1,6, +1,10,28,34,63,38,1,10,28,1652441,14,1,1652563,16,1652555,14, +112,117,115,104,32,116,97,107,101,115,32,111,110,101,45,119, +111,114,100,32,101,108,101,109,101,110,116,115,59,32,117,115, +101,32,114,101,115,105,122,101,32,102,111,114,32,115,116,114, +117,99,116,115,0,1652449,1591173,12,8,1587611,2,1606959,12,8,1310721,2, +3,26,1681059,12,10,3,6,10,4,8,1663385,12,8,1310721,2,3, +26,2,5,1625017,12,8,1310721,2,2,1,26,2,23,28,1,6, +1,10,28,34,63,38,3,26,1652727,16,1310721,2,2,9,26,2, +1587699,2,1639563,12,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1652729,14,1,1652771,16,1652747,14, +112,117,115,104,0,1652737,1310721,2,2,9,26,2,1587699,2,1643225,12, +8,1587769,2,1652841,16,1310721,2,2,1,26,2,23,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1652843,14,1,1652889,16,1310721,2,2,9,26,2,1658673,12,1, +6,1,10,28,34,63,38,1,10,28,1652891,14,1,1652923,16,1310721, +2,2,9,26,2,1594643,12,8,1590517,2,1595409,12,8,1587601,2,1606959, +12,8,1590555,2,1595409,12,8,1587699,1587689,2,10,3,6,10,4,8, +1,1652969,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1653017,16,1966081,1310721,4,1579223,12,1604999,12,8,1310721, +2,1650979,12,10,3,6,10,4,8,1310721,2,2,1651271,12,8,1587601, +2,1606959,12,8,1590557,2,1595409,12,8,1587699,1310721,2,2,1639375,12,10, +3,6,10,4,8,1310721,2,2,1,26,2,23,28,1,6,1, +10,28,34,63,38,3,26,1653165,16,1587699,1310721,2,2,9,26,2, +10,3,6,10,4,8,1,1653173,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1653221,16,1966081,1310721,4, +1579223,12,1604999,12,8,1310721,2,1650979,12,10,3,6,10,4,8,1310721, +2,2,1651271,12,8,1587611,2,1606959,12,8,1310721,2,3,26,1681059,12, +10,3,6,10,4,8,1663385,12,8,1310721,2,3,26,2,1613033,12, +8,1587601,2,1606959,12,8,1590559,2,1595409,12,8,1587699,1587689,2,10,3, +6,10,4,8,1,1653361,14,1,1310721,2,5,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1653409,16,1966081,1310721,4,1579223,12, +1604999,12,8,1310721,2,1650645,12,10,3,6,10,4,8,1310721,2,2, +1637519,12,1594643,12,8,1587699,1587689,2,10,3,6,10,4,8,1,1653477, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1653525,16,1966081,1310721,4,1579223,12,1604999,12,8,1310721,2,1650645, +12,10,3,6,10,4,8,1310721,2,2,1594643,12,8,1587699,1587687,2, +10,3,6,10,4,8,1,1653589,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1653637,16,1966081,1310721,4, +1579223,12,1587683,1277953,2049,26,10,3,6,10,4,8,1587685,1,10,3, +6,10,4,8,1587687,1,3,1653693,14,119,111,114,100,0,1653683,1592287, +12,1,1632529,12,10,3,6,10,4,8,1587689,3,3,1653735,14,105, +110,116,0,1653727,1592287,12,1,1632529,12,10,3,6,10,4,8,1587691, +5,3,1653779,14,99,104,97,114,0,1653769,1592287,12,1,1632529,12,10, +3,6,10,4,8,1587693,7,3,1653823,14,98,111,111,108,0,1653813, +1592287,12,1,1632529,12,10,3,6,10,4,8,1587695,9,1,1653867,14, +118,111,105,100,0,1653857,1592287,12,1,1632529,12,10,3,6,10,4, +8,1587687,2,5,26,2,15,1587687,2,1592805,12,8,1587689,2,5,26, +2,15,1587689,2,1592805,12,8,1587691,2,5,26,2,15,1587691,2,1592805, +12,8,1587693,2,5,26,2,15,1587693,2,1592805,12,8,1587695,2,5, +26,2,15,1587695,2,1592805,12,8,1587729,1654011,14,60,0,1654007,1592287,12, +10,3,6,10,4,8,1587731,1654039,14,62,0,1654035,1592287,12,10,3, +6,10,4,8,1587733,1654069,14,62,62,0,1654063,1592287,12,10,3,6, +10,4,8,1587735,1654099,14,60,61,0,1654093,1592287,12,10,3,6,10, +4,8,1587737,1654129,14,62,61,0,1654123,1592287,12,10,3,6,10,4, +8,1587739,1654159,14,61,61,0,1654153,1592287,12,10,3,6,10,4,8, +1587741,1654189,14,33,61,0,1654183,1592287,12,10,3,6,10,4,8,1587743, +1654217,14,43,0,1654213,1592287,12,10,3,6,10,4,8,1587745,1654255,14, +115,116,114,117,99,116,0,1654241,1592287,12,10,3,6,10,4,8, +1587747,1654289,14,116,121,112,101,0,1654279,1592287,12,10,3,6,10,4, +8,1587749,1654333,14,116,121,112,101,99,104,101,99,107,0,1654313,1592287, +12,10,3,6,10,4,8,1587751,1654363,14,111,110,0,1654357,1592287,12, +10,3,6,10,4,8,1587753,1654395,14,111,102,102,0,1654387,1592287,12, +10,3,6,10,4,8,1587755,1654427,14,110,101,119,0,1654419,1592287,12, +10,3,6,10,4,8,1587757,1654463,14,110,101,119,95,116,0,1654451, +1592287,12,10,3,6,10,4,8,1590513,1654501,14,35,105,116,101,109, +115,0,1654487,1592287,12,10,3,6,10,4,8,1590515,1654535,14,35,108, +101,110,0,1654525,1592287,12,10,3,6,10,4,8,1590517,1654573,14,102, +97,116,116,101,110,0,1654559,1592287,12,10,3,6,10,4,8,1587759, +1654603,14,111,51,0,1654597,1592287,12,10,3,6,10,4,8,1587761,1654635, +14,108,102,97,0,1654627,1592287,12,10,3,6,10,4,8,1587763,1654675, +14,111,117,116,115,105,100,101,0,1654659,1592287,12,10,3,6,10, +4,8,1587765,1654715,14,110,101,119,95,114,97,119,0,1654699,1592287,12, +10,3,6,10,4,8,1587767,1654747,14,111,111,98,0,1654739,1592287,12, +10,3,6,10,4,8,1590545,1654783,14,102,105,120,101,100,0,1654771, +1592287,12,10,3,6,10,4,8,1590547,1654817,14,100,108,101,110,0, +1654807,1592287,12,10,3,6,10,4,8,1590549,1654851,14,100,99,97,112, +0,1654841,1592287,12,10,3,6,10,4,8,1590551,1654885,14,100,110,101, +119,0,1654875,1592287,12,10,3,6,10,4,8,1590553,1654917,14,100,97, +116,0,1654909,1592287,12,10,3,6,10,4,8,1590555,1654953,14,100,112, +117,115,104,0,1654941,1592287,12,10,3,6,10,4,8,1590557,1654987,14, +100,112,111,112,0,1654977,1592287,12,10,3,6,10,4,8,1590559,1655027, +14,100,114,101,115,105,122,101,0,1655011,1592287,12,10,3,6,10, +4,8,1590519,1,26,1655059,14,42,0,1655055,1592287,12,10,3,6,10, +4,8,1590519,3,26,1655091,14,47,0,1655087,1592287,12,10,3,6,10, +4,8,1590519,5,26,1655123,14,37,0,1655119,1592287,12,10,3,6,10, +4,8,1590519,7,26,1655155,14,38,0,1655151,1592287,12,10,3,6,10, +4,8,1590519,9,26,1655187,14,124,0,1655183,1592287,12,10,3,6,10, +4,8,1590519,11,26,1655219,14,94,0,1655215,1592287,12,10,3,6,10, +4,8,1590519,13,26,1655253,14,60,60,0,1655247,1592287,12,10,3,6, +10,4,8,1590519,15,26,1587733,2,10,3,6,10,4,8,1590543,17, +10,3,6,10,4,8,1,1655317,14,1,1310721,2,1,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1655365,16,1966081,1310721,4, +1579223,12,1310721,2,4,1,1310721,2,3,26,4,1310721,2,3,26,2, +1590543,2,40,1655495,16,1590519,1310721,2,3,26,2,26,2,1310721,2,2, +28,1,6,1,10,28,34,63,38,3,26,1655457,16,3,1655503,14, +1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10,8, +8,1655383,14,1,1655503,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +9,28,1310721,4,1310721,2,1835009,40,1655551,16,1966081,1310721,4,1579223,12,1310721, +2,5,26,4,1310721,2,3,26,4,1310721,2,4,1546753,1310721,2,2, +26,2,1310721,2,7,26,4,1310721,2,3,26,1310721,2,3,26,2, +1639249,12,10,3,6,10,4,8,1310721,2,5,26,1310721,2,5,26, +2,1639249,12,10,3,6,10,4,8,1547137,1310721,2,2,26,2,1, +40,1655863,16,1310721,2,3,26,2,1638921,12,1,6,1,10,28,34, +63,38,3,26,1655785,16,1310721,2,5,26,2,1638921,12,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1655787,14,1,1655837,14,38,38,32,97,110,100,32,124,124, +32,110,101,101,100,32,115,99,97,108,97,114,115,0,1655791,1310721, +2,3,26,2,1643625,12,8,1587693,2,1658289,14,1310721,2,7,26,2, +1587739,2,28,1,6,1,10,28,34,63,38,3,26,1655909,16,3, +1655967,14,1310721,2,7,26,2,1587741,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1656157, +16,1310721,2,3,26,2,1310721,2,5,26,2,1639563,12,1,6,1, +10,28,34,63,38,3,26,1656089,16,1310721,2,5,26,2,1310721,2, +3,26,2,1639563,12,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1656091,14,1,1656149,16,1656121, +14,99,111,109,112,97,114,105,115,111,110,0,1656099,1310721,2,3, +26,2,1310721,2,5,26,2,1643225,12,8,1587693,2,1658289,14,1310721,2, +7,26,2,1587729,2,28,1,6,1,10,28,34,63,38,3,26, +1656203,16,3,1656261,14,1310721,2,7,26,2,1587731,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1656271,16,3,1656329,14,1310721,2,7,26,2,1587735,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1656339,16,3,1656397,14,1310721,2,7,26,2,1587737,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1656827,16,1310721,2,3,26,2,1587687,2,28, +1,6,1,10,28,34,63,38,3,26,1656447,16,3,1656505,14,1310721, +2,5,26,2,1587687,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1656515,16,3,1656597, +14,1310721,2,3,26,2,1638689,12,1656573,16,1310721,2,5,26,2,1638689, +12,1,6,1,10,28,34,63,38,1,10,28,1656575,14,1,1, +6,1,10,28,34,63,38,1,10,28,1656607,16,3,1656741,14,1310721, +2,3,26,2,1,26,2,11,28,1,6,1,10,28,34,63, +38,3,26,1656717,16,1310721,2,5,26,2,1,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,1656719,14,1,1,6,1,10,28,34,63,38,1, +10,28,1,6,1,10,28,34,63,38,3,26,1656819,16,1656791,14, +99,111,109,112,97,114,105,115,111,110,0,1656769,1310721,2,3,26, +2,1310721,2,5,26,2,1643225,12,8,1587693,2,1658289,14,1310721,2,7, +26,2,1587743,2,28,1,6,1,10,28,34,63,38,3,26,1657375, +16,1310721,2,3,26,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1657019,16,1310721,2,5,26,2,1638689,12,1656935,16, +3,1656993,14,1310721,2,5,26,2,1587687,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,1657021,14,1,1657039,16, +1310721,2,3,26,2,1658289,14,1310721,2,5,26,2,1,26,2,11, +28,1,6,1,10,28,34,63,38,3,26,1657123,16,1310721,2,3, +26,2,1638689,12,1,6,1,10,28,34,63,38,1,10,28,1657125, +14,1,1657143,16,1310721,2,5,26,2,1658289,14,1310721,2,3,26,2, +1587687,2,28,1,6,1,10,28,34,63,38,3,26,1657189,16,3, +1657247,14,1310721,2,5,26,2,1587687,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1657259, +16,1587687,2,1658289,14,1310721,2,3,26,2,1638689,12,1657317,16,1310721,2, +5,26,2,1638689,12,1,6,1,10,28,34,63,38,1,10,28, +1657319,14,1,1657331,16,1587689,2,1658289,14,1657339,14,43,0,1657335,1310721,2, +3,26,2,1310721,2,5,26,2,1643225,12,8,1587687,2,1658289,14,1310721, +2,7,26,2,1587631,2,28,1,6,1,10,28,34,63,38,3, +26,1657943,16,1310721,2,3,26,2,1,26,2,11,28,1,6,1, +10,28,34,63,38,3,26,1657525,16,1310721,2,5,26,2,1,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,1657527,14,1,1657539,16,1587689,2,1658289, +14,1310721,2,3,26,2,1,26,2,11,28,1,6,1,10,28, +34,63,38,3,26,1657691,16,1310721,2,5,26,2,1638689,12,1657607,16, +3,1657665,14,1310721,2,5,26,2,1587687,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,1657693,14,1,1657711,16, +1310721,2,3,26,2,1658289,14,1310721,2,3,26,2,1587687,2,28,1, +6,1,10,28,34,63,38,3,26,1657757,16,3,1657815,14,1310721,2, +5,26,2,1587687,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1657827,16,1587687,2,1658289, +14,1310721,2,3,26,2,1638689,12,1657885,16,1310721,2,5,26,2,1638689, +12,1,6,1,10,28,34,63,38,1,10,28,1657887,14,1,1657899, +16,1587689,2,1658289,14,1657907,14,45,0,1657903,1310721,2,3,26,2,1310721, +2,5,26,2,1643225,12,8,1587687,2,1658289,14,1310721,2,7,26,2, +1655331,12,1658279,16,1310721,2,3,26,2,1587687,2,28,1,6,1,10, +28,34,63,38,3,26,1658007,16,3,1658065,14,1310721,2,5,26,2, +1587687,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1658077,16,1587687,2,1658289,14,1310721,2, +3,26,2,1638689,12,1658135,16,1310721,2,5,26,2,1638689,12,1,6, +1,10,28,34,63,38,1,10,28,1658137,14,1,1658149,16,1587689,2, +1658289,14,1310721,2,3,26,2,1638689,12,1658197,16,1310721,2,3,26,1310721, +2,5,26,2,10,3,6,10,4,8,1,1658253,14,97,114,105, +116,104,109,101,116,105,99,32,110,101,101,100,115,32,110,117, +109,98,101,114,115,0,1658203,1310721,2,3,26,2,1643625,12,8,1587687, +2,1658289,14,1587687,2,1658289,14,1,1310721,2,9,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1658337,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,1,26,2,1658361,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1658409,16,1966081, +1310721,4,1579223,12,1310721,2,4,1310721,2,2,1637519,12,1658431,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1658479,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,5,26,2, +1658503,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1658551,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2, +2,7,26,2,1658575,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1658623,16,1966081,1310721,4,1579223,12,1310721, +2,4,1310721,2,2,1636447,12,8,1310721,2,2,7,26,2,1658659,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2, +1835009,40,1658707,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1, +26,2,1310721,2,3,26,4,1310721,2,3,26,2,11,28,1,6, +1,10,28,34,63,38,3,26,1658779,16,3,1658835,14,1310721,2,3, +26,2,23,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1658845,16,3,1659163,14,1310721,2, +3,26,2,13,28,1,6,1,10,28,34,63,38,3,26,1658903, +16,1310721,2,2,9,26,2,1658673,12,1659163,14,1310721,2,3,26,2, +17,28,1,6,1,10,28,34,63,38,3,26,1658999,16,1310721,2, +2,11,26,2,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1659001,14,1,1659155,16,1310721,2, +7,26,1310721,2,2,1658589,12,10,3,6,10,4,8,1310721,2,5, +26,1,10,3,6,10,4,8,1310721,2,5,26,2,1310721,2,7, +26,2,40,1659155,16,1310721,2,2,1310721,2,5,26,2,1661615,12,1658673, +12,1659117,16,3,1659163,14,1310721,2,5,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1659057,14,1,1659163,14,1,1310721,2,9, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1659211,16, +1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2, +1310721,2,3,26,2,65,1659277,12,8,1310721,2,2,1659263,14,1,1310721, +2,5,26,1310721,4,18,1310721,2,17,28,1310721,4,1310721,2,1835009,40, +1659311,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26, +4,1310721,2,4,1310721,2,5,26,2,1,10,40,3,36,1659367,16, +3,1659419,14,1310721,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,1659429,16,3, +1659481,14,1310721,2,2,1578965,12,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1659491,16,1,1660611, +14,1310721,2,3,26,2,1,26,2,23,28,1,6,1,10,28, +34,63,38,3,26,1659795,16,1310721,2,3,26,2,9,26,2,1658673, +12,1659789,16,1310721,2,15,26,1310721,2,3,26,2,9,26,2,1637519, +12,10,3,6,10,4,8,1310721,2,9,26,1310721,2,2,1,26, +2,10,3,6,10,4,8,1310721,2,13,26,1,10,3,6,10, +4,8,1310721,2,13,26,2,1310721,2,9,26,2,40,1659789,16,1310721, +2,2,5,26,2,1310721,2,13,26,2,1310721,2,15,26,2,30, +26,1310721,2,3,26,2,9,26,2,1310721,2,5,26,2,3,28, +1660625,12,8,1310721,2,13,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1659653,14,1,1660611,14,1310721,2,3,26,2,1,26, +2,11,28,1,6,1,10,28,34,63,38,1,10,28,1659847,16, +3,1659895,14,1310721,2,2,3,1,10,28,26,2,1,40,3,36, +1,6,1,10,28,34,63,38,1,10,28,1659905,16,1,1660611,14, +1310721,2,7,26,1310721,2,3,26,2,9,26,2,10,3,6,10, +4,8,1310721,2,9,26,1,1310721,2,2,3,1,10,28,26,2, +28,3,28,10,3,6,10,4,8,1310721,2,15,26,1310721,2,7, +26,2,1637519,12,10,3,6,10,4,8,1310721,2,15,26,2,3, +40,1660061,16,1310721,2,15,26,3,10,3,6,10,4,8,1310721,2, +7,26,2,1587687,2,28,1,6,1,10,28,34,63,38,3,26, +1660107,16,3,1660169,14,1310721,2,7,26,2,1,26,2,19,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1660207,16,1310721,2,2,3,1,10,28,26,1,10, +3,6,10,4,8,1660321,14,1310721,2,9,26,2,1310721,2,15,26, +2,10,40,1660283,16,1310721,2,2,3,1,10,28,26,1310721,2,7, +26,2,1,1633251,12,10,3,6,10,4,8,1660321,14,1310721,2,2, +3,1,10,28,26,1310721,2,7,26,2,10,3,6,10,4,8, +1310721,2,2,1580291,12,1310721,2,9,26,2,10,40,1660397,16,1310721,2, +2,1310721,2,9,26,2,26,1,1310721,2,2,1580291,12,1310721,2,9, +26,2,28,1574703,12,8,1310721,2,7,26,2,1658673,12,1660603,16,1310721, +2,11,26,1310721,2,9,26,2,1310721,2,15,26,2,44,10,3, +6,10,4,8,1310721,2,13,26,1,10,3,6,10,4,8,1310721, +2,13,26,2,1310721,2,11,26,2,40,1660603,16,1310721,2,2,1310721, +2,13,26,2,1310721,2,15,26,2,30,26,1310721,2,7,26,2, +1310721,2,5,26,2,3,28,1660625,12,8,1310721,2,13,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1660479,14,1,1660611,14, +1,1310721,2,17,26,1310721,4,18,1310721,2,19,28,1310721,4,1310721,2, +1835009,40,1660659,16,1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2, +3,26,4,1310721,2,4,1310721,2,3,26,2,1,26,2,1310721,2, +7,26,4,1310721,2,7,26,2,11,28,1,6,1,10,28,34, +63,38,3,26,1660755,16,3,1660811,14,1310721,2,7,26,2,23,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1660855,16,1310721,2,2,1,26,2,1310721,2,3, +26,2,1310721,2,5,26,2,1659277,12,1661489,14,1310721,2,7,26,2, +13,28,1,6,1,10,28,34,63,38,3,26,1661123,16,1310721,2, +11,26,1310721,2,3,26,2,7,26,2,10,3,6,10,4,8, +1310721,2,17,26,1310721,2,3,26,2,9,26,2,1637519,12,10,3, +6,10,4,8,1310721,2,9,26,1,10,3,6,10,4,8,1310721, +2,9,26,2,1310721,2,11,26,2,40,1661117,16,1310721,2,2,1310721, +2,9,26,2,1310721,2,17,26,2,30,26,1310721,2,3,26,2, +9,26,2,1310721,2,5,26,2,1660625,12,8,1310721,2,9,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1660991,14,1,1661489, +14,1310721,2,7,26,2,17,28,1,6,1,10,28,34,63,38, +3,26,1661223,16,1310721,2,3,26,2,11,26,2,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1661225,14,1,1661481,16,1310721,2,11,26,1310721,2,3,26,2,1658589, +12,10,3,6,10,4,8,1310721,2,9,26,1,10,3,6,10, +4,8,1310721,2,9,26,2,1310721,2,11,26,2,40,1661481,16,1310721, +2,13,26,1310721,2,3,26,2,1310721,2,9,26,2,1661731,12,10, +3,6,10,4,8,1310721,2,15,26,1310721,2,3,26,2,1310721,2, +9,26,2,1661615,12,10,3,6,10,4,8,1310721,2,2,1310721,2, +13,26,2,26,1310721,2,15,26,2,1310721,2,5,26,2,1660625,12, +8,1310721,2,9,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1661285,14,1,1661489,14,1,1310721,2,19,26,1310721,4,18,1310721, +2,5,28,1310721,4,1310721,2,1835009,40,1661537,16,1966081,1310721,4,1579223,12, +1310721,2,3,26,4,1310721,2,4,1310721,2,2,1636447,12,8,1310721,2, +2,9,26,2,1310721,2,3,26,2,7,30,26,2,1661601,14,1, +1310721,2,5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009, +40,1661649,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4, +1310721,2,2,1636447,12,8,1310721,2,2,9,26,2,1310721,2,3,26, +2,7,30,3,26,26,2,1661717,14,1,1310721,2,5,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1661765,16,1966081,1310721,4, +1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,1636447,12,8, +1310721,2,2,9,26,2,1310721,2,3,26,2,7,30,5,26,26, +2,1661833,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1661881,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,9,26,2,1661905,14,1,1310721,2,3,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1661953,16,1966081,1310721,4,1579223,12, +1310721,2,4,1310721,2,2,7,26,2,1661977,14,1,1310721,2,3,26, +1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1662025,16,1966081, +1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,15, +1310721,2,3,26,2,26,26,2,1662071,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1662119,16,1966081,1310721, +4,1579223,12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,11,26, +2,13,38,1310721,2,3,26,2,1310721,2,3,26,2,26,38,7, +32,1662185,14,1,1310721,2,5,26,1310721,4,18,1310721,2,3,28,1310721, +4,1310721,2,1835009,40,1662233,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,11,26,2,3,32,1662261,14,1,1310721,2,3,26,1310721,4, +18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1662309,16,1966081,1310721,4, +1579223,12,1310721,2,4,1310721,2,2,1,26,2,17,28,1,6,1, +10,28,34,63,38,1,10,28,1662363,16,3,1662417,14,1310721,2,2, +11,26,2,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1662427,16,1,1662451,14,1310721,2,2, +13,26,2,1,26,2,1662451,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,5,28,1310721,4,1310721,2,1835009,40,1662499,16,1966081,1310721,4,1579223, +12,1310721,2,3,26,4,1310721,2,4,1310721,2,2,13,26,2,3, +1310721,2,3,26,2,26,26,2,1662551,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,59,28,1310721,4,1310721,2,1835009,40,1662599,16,1966081,1310721, +4,1579223,12,1310721,2,4,1585219,2,1310721,2,3,26,4,3,1,10, +28,1310721,2,5,26,4,1310721,2,3,26,2,1662895,16,1310721,2,3, +26,1,6,2,1,6,-1,26,5,6,4,10,8,8,1417729,1310721, +2,3,26,2,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1662799,16,1425921,1310721,2,3,26,2,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,1662801,14,1,1662851,16,1442305,1310721,2,3,26,2, +26,2,3,32,1,6,1,10,28,34,63,38,1,10,28,1662853, +14,1,1662891,16,1310721,2,5,26,1310721,2,3,26,2,10,3,6, +10,4,8,1662895,14,1662637,14,1310721,2,5,26,2,1,40,1662919,16, +1,1663173,14,1559041,1310721,2,5,26,2,26,2,1662959,16,1559041,1310721,2, +5,26,2,26,2,1663173,14,1310721,2,55,26,1434113,1310721,2,5,26, +2,26,2,3,38,63,32,10,3,6,10,4,8,1310721,2,57, +26,1,10,3,6,10,4,8,1310721,2,57,26,2,1310721,2,55, +26,2,40,1663125,16,1310721,2,7,26,1310721,2,57,26,2,26,1587687, +2,10,3,6,10,4,8,1310721,2,57,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1663025,14,1587687,2,1310721,2,55,26, +2,1310721,2,7,26,1434113,1310721,2,5,26,2,26,2,1633771,12,1663173, +14,1,1310721,2,59,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1663221,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2, +1593805,12,1310721,2,3,26,4,1310721,2,3,26,2,1,40,1663271,16, +3,1663335,14,1417729,1310721,2,3,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,1663345,16,1,1663371,14,1425921,1310721,2,3,26,2,26,2, +1662565,12,1663371,14,1,1310721,2,5,26,1310721,4,18,1310721,2,1,28, +1310721,4,1310721,2,1835009,40,1663419,16,1966081,1310721,4,1579223,12,1587587,2,1663483, +16,1587699,2,1638921,12,1,6,1,10,28,34,63,38,3,26,1663467, +16,3,1594729,12,8,1587587,1,10,3,6,10,4,8,1,1663491,14, +1,1310721,2,1,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2, +1835009,40,1663539,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2, +4,1425921,1310721,2,2,26,2,1310721,2,5,26,4,1587593,2,1310721,2, +7,26,4,1587593,1310721,2,3,26,2,10,3,6,10,4,8,1587595, +1,10,3,6,10,4,8,1587699,1587687,2,10,3,6,10,4,8, +1587701,1,10,3,6,10,4,8,1310721,2,5,26,2,1,6,12, +10,8,8,1587593,1310721,2,7,26,2,10,3,6,10,4,8,1310721, +2,9,26,1587595,2,10,3,6,10,4,8,1587587,1,10,3,6, +10,4,8,1587589,1,10,3,6,10,4,8,1310721,2,9,26,2, +1663783,14,1,1310721,2,11,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1663831,16,1966081,1310721,4,1579223,12,1587593,2,1663931,16,1663923, +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,1663843,1591173,12,8,1,1663939,14, +1,1310721,2,1,26,1310721,4,18,1310721,2,17,28,1310721,4,1310721,2, +1835009,40,1663987,16,1966081,1310721,4,1579223,12,1310721,2,7,26,4,1310721,2, +5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2,9,26, +4,1587599,2,1606959,12,8,1587601,2,1606425,12,1,6,1,10,28,34, +63,38,3,26,1664603,16,3,1664603,16,1310721,2,11,26,1681059,12,10, +3,6,10,4,8,1663385,12,8,1310721,2,15,26,1587699,2,10,3, +6,10,4,8,1310721,2,11,26,2,1310721,2,2,1310721,2,9,26, +2,1310721,2,9,26,2,26,38,7,32,1625017,12,8,1310721,2,7, +26,2,1664241,16,1310721,2,15,26,2,1658673,12,1,6,1,10,28, +34,63,38,1,10,28,1664243,14,1,1664297,16,1310721,2,15,26,2, +1594643,12,8,1590517,2,1595409,12,8,1587699,1310721,2,15,26,2,10,3, +6,10,4,8,1310721,2,3,26,2,1664365,16,1310721,2,9,26,2, +1310721,2,3,26,2,7,26,2,40,1,6,1,10,28,34,63, +38,1,10,28,1664367,14,1,1664529,16,1310721,2,13,26,1310721,2,3, +26,2,15,1310721,2,9,26,2,26,26,2,10,3,6,10,4, +8,1310721,2,13,26,2,1587699,2,1310721,2,5,26,2,1640879,12,1, +6,1,10,28,34,63,38,3,26,1664529,16,1664493,14,97,114,103, +117,109,101,110,116,0,1664475,1310721,2,13,26,2,1310721,2,5,26, +2,1637691,12,1587699,2,1643225,12,8,1310721,2,9,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1587611,2,1606729,12,1,6,1, +10,28,34,63,38,3,26,1664599,16,1664603,14,1664077,14,1587601,2,1606959, +12,8,1310721,2,9,26,2,1664629,14,1,1310721,2,17,26,1310721,4, +18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1664677,16,1966081,1310721,4, +1579223,12,1310721,2,1644591,12,10,3,6,10,4,8,1310721,2,2,1, +26,2,23,28,1,6,1,10,28,34,63,38,3,26,1665063,16, +1310721,2,2,9,26,2,1637519,12,1594643,12,8,1587611,2,1606729,12,1664821, +16,1310721,2,3,26,1681059,12,10,3,6,10,4,8,1663385,12,8, +1310721,2,3,26,2,1613033,12,8,1664957,14,1,1594643,12,8,1310721,2, +2,7,26,2,1664957,16,1664949,14,97,32,102,105,120,101,100,32, +97,114,114,97,121,32,110,101,101,100,115,32,105,116,115,32, +108,101,110,103,116,104,58,32,110,101,119,40,102,105,120,101, +100,32,91,93,84,44,32,110,41,0,1664849,1591173,12,8,1310721,2, +2,1594643,12,8,1587601,2,1606959,12,8,1590551,2,1595409,12,8,1587587,1, +10,3,6,10,4,8,1587589,1,10,3,6,10,4,8,1587699,1310721, +2,2,10,3,6,10,4,8,1587701,1,10,3,6,10,4,8, +3,1665583,14,1587769,2,1665311,16,1587611,2,1606729,12,1665197,16,1310721,2,3, +26,1681059,12,10,3,6,10,4,8,1663385,12,8,1310721,2,3,26, +2,1613033,12,8,1310721,2,2,1637519,12,3,28,1,6,1,10,28, +34,63,38,1,10,28,1665193,16,1310721,2,2,1637519,12,1594643,12,8, +31,1594729,12,8,1665213,14,1310721,2,2,1637519,12,1594643,12,8,1587601,2, +1606959,12,8,1587765,2,1595409,12,8,1587587,1,10,3,6,10,4,8, +1587589,1,10,3,6,10,4,8,1587699,1310721,2,2,1632877,12,10,3, +6,10,4,8,1587701,1,10,3,6,10,4,8,3,1665583,14,1587611, +2,1606729,12,1665455,16,1310721,2,3,26,1681059,12,10,3,6,10,4, +8,1663385,12,8,1310721,2,3,26,2,1613033,12,8,1310721,2,2,1637519, +12,3,28,1,6,1,10,28,34,63,38,1,10,28,1665433,16, +1310721,2,2,1637519,12,1594643,12,8,31,1594729,12,8,1310721,2,2,1, +1633251,12,1594643,12,8,1665483,14,1310721,2,2,1637519,12,1594643,12,8,1310721, +2,2,1594643,12,8,1587601,2,1606959,12,8,1587757,2,1595409,12,8,1587587, +1,10,3,6,10,4,8,1587589,1,10,3,6,10,4,8,1587699, +1310721,2,2,1632877,12,10,3,6,10,4,8,1587701,1,10,3,6, +10,4,8,3,1665583,14,1,1310721,2,5,26,1310721,4,18,1310721,2, +27,28,1310721,4,1310721,2,1835009,40,1665631,16,1966081,1310721,4,1579223,12,1310721, +2,4,1,1310721,2,5,26,4,1,1310721,2,7,26,4,1559041,1310721, +2,2,26,2,1310721,2,9,26,4,1409537,1310721,2,2,26,2,1587755, +2,28,1,6,1,10,28,34,63,38,3,26,1665787,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,1665789,14,1,1666117,16, +1605859,12,8,1587511,2,9,28,1,6,1,10,28,34,63,38,3, +26,1665949,16,1587513,2,1587623,2,28,1,6,1,10,28,34,63,38, +3,26,1665871,16,3,1665923,14,1587513,2,1587607,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,1665951,14,1,1665969, +16,1604999,12,8,1664643,12,1667095,14,1587511,2,5,28,1,6,1,10, +28,34,63,38,3,26,1666097,16,1587513,2,1644211,12,1666019,16,3,1666071, +14,1587513,2,1587639,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,1666099,14,1,1666117,16,1604999,12,8,1664643,12, +1667095,14,1587769,2,1666189,16,1409537,1310721,2,2,26,2,1587755,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1666191,14,1,1666293,16,1310721,2,5,26,1587765,2,1593303, +12,10,3,6,10,4,8,1310721,2,5,26,2,1,40,3,36, +1666271,16,1310721,2,1310721,2,5,26,2,10,3,6,10,4,8,1310721, +2,5,26,1,10,3,6,10,4,8,1442305,1310721,2,2,26,2, +5,32,1666389,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,1666427,14,1442305,1310721,2,2,26,1442305, +1310721,2,2,26,2,9,34,10,3,6,10,4,8,1310721,2,11, +26,1,17,1574703,12,8,1590581,2,1666489,16,1310721,2,11,26,1590565,1590581, +2,1574491,12,8,1590581,1,10,3,6,10,4,8,1310721,2,3,26, +1,10,3,6,10,4,8,1587769,2,1666581,16,1442305,1310721,2,2,26, +2,1025,32,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1666583,14,1,1666653,16,1409537,1310721,2, +2,26,2,1587671,2,28,1,6,1,10,28,34,63,38,1,10, +28,1,6,1,10,28,34,63,38,1,10,28,1666655,14,1,1666681, +16,1310721,2,3,26,3,10,3,6,10,4,8,1310721,2,3,26, +1310721,2,5,26,2,1310721,2,9,26,2,1310721,2,11,26,1310721,2, +3,26,2,1663953,12,10,3,6,10,4,8,1442305,1310721,2,2,26, +2,5,32,1666843,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,1666845,14,1,1666925,16, +1409537,1310721,2,2,26,2,1666917,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,1666865,1591343,12,8,1310721,2,2,1595235,12,8,13,1594729,12,8, +1587587,1,10,3,6,10,4,8,1587589,1,10,3,6,10,4,8, +1587701,1,10,3,6,10,4,8,1587699,1587687,2,10,3,6,10,4, +8,1310721,2,9,26,2,1667067,16,1587699,1310721,2,9,26,2,9,26, +2,1310721,2,11,26,1637691,12,10,3,6,10,4,8,1310721,2,7, +26,2,1667087,16,3,1667095,14,1,1667095,14,1,1310721,2,27,26,1310721, +4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1667143,16,1966081,1310721, +4,1579223,12,1310721,2,4,1434113,1310721,2,2,26,2,31,32,1310721,2, +3,26,4,1434113,1310721,2,2,26,2,9,38,31,32,1310721,2,5, +26,4,1,1310721,2,7,26,4,1587599,2,1606959,12,8,1587601,2,1606425, +12,1,6,1,10,28,34,63,38,3,26,1667385,16,3,1667385,16, +1310721,2,9,26,1681059,12,10,3,6,10,4,8,1663385,12,8,1310721, +2,9,26,2,1613033,12,8,1310721,2,7,26,1,6,2,1,6, +3,26,5,6,4,10,8,8,1587611,2,1606729,12,1,6,1,10, +28,34,63,38,3,26,1667381,16,1667385,14,1667259,14,1587601,2,1606959,12, +8,1310721,2,7,26,2,1310721,2,3,26,2,28,1,6,1,10, +28,34,63,38,1,10,28,1667513,16,1409537,1310721,2,2,26,2,1667505, +14,119,114,111,110,103,32,110,117,109,98,101,114,32,111,102, +32,105,110,112,117,116,115,0,1667459,1591343,12,8,1587587,1,10,3, +6,10,4,8,1587589,1,10,3,6,10,4,8,1587699,1587687,2,10, +3,6,10,4,8,1587701,1,10,3,6,10,4,8,1442305,1310721,2, +2,26,2,129,32,1667635,16,1450497,1310721,2,2,26,2,3,28,1595235, +12,8,13,1594729,12,8,1,1667833,14,45,1425921,1310721,2,2,26,2, +26,1594729,12,8,1310721,2,5,26,2,1,28,1,6,1,10,28, +34,63,38,3,26,1667703,16,1,1594643,12,8,1310721,2,5,26,2, +3,10,40,1667825,16,1409537,1310721,2,2,26,2,1667817,14,108,101,97, +118,101,115,32,115,101,118,101,114,97,108,32,118,97,108,117, +101,115,59,32,117,115,101,32,105,116,32,102,114,111,109,32, +97,115,109,0,1667739,1591343,12,8,1,1667833,14,1,1310721,2,11,26, +1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1667881,16,1966081, +1310721,4,1579223,12,1587587,1,10,3,6,10,4,8,1587589,1,10,3, +6,10,4,8,1587701,1,10,3,6,10,4,8,1590561,1,10,3, +6,10,4,8,1585289,2,3,28,1,6,1,10,28,34,63,38, +3,26,1668093,16,1585291,2,1594643,12,8,1587701,1585291,2,1,28,1,6, +1,10,28,34,63,38,3,26,10,3,6,10,4,8,1590561,3, +10,3,6,10,4,8,1590563,1585291,2,10,3,6,10,4,8,1587699, +1587689,2,10,3,6,10,4,8,1604999,12,8,1,1670763,14,1585289,2, +7,28,1,6,1,10,28,34,63,38,3,26,1668169,16,1585291,2, +1598105,12,8,1604999,12,8,1587699,1587691,2,1632877,12,10,3,6,10,4, +8,1,1670763,14,1585289,2,9,28,1,6,1,10,28,34,63,38, +3,26,1668421,16,1585291,2,1587599,2,28,1,6,1,10,28,34,63, +38,3,26,1668289,16,1604999,12,8,1310721,2,7,26,1681059,12,10,3, +6,10,4,8,1587601,2,1606959,12,8,1310721,2,7,26,2,1670763,14, +1585291,2,1587603,2,28,1,6,1,10,28,34,63,38,3,26,1668331, +16,1683915,12,1670763,14,1668381,14,101,120,112,101,99,116,101,100,32, +97,110,32,101,120,112,114,101,115,115,105,111,110,0,1668335,1591557, +12,8,1,1594643,12,8,1587699,1587687,2,10,3,6,10,4,8,1, +1670763,14,1585289,2,5,28,1,6,1,10,28,34,63,38,1,10, +28,1668545,16,1668505,14,101,120,112,101,99,116,101,100,32,97,110, +32,101,120,112,114,101,115,115,105,111,110,0,1668459,1591557,12,8, +1,1594643,12,8,1587699,1587687,2,10,3,6,10,4,8,1,1670763,14, +1310721,2,1585291,2,10,3,6,10,4,8,1310721,2,3,26,1310721,2, +2,1611615,12,10,3,6,10,4,8,1310721,2,3,26,2,1,40, +3,36,1669011,16,1604999,12,8,1587565,2,1,6,1,10,28,34,63, +38,3,26,1668691,16,1310721,2,3,26,2,1612447,12,1,6,1,10, +28,34,63,38,1,10,28,1668693,14,1,1668841,16,1310721,2,2,1668833, +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, +1668707,1591343,12,8,1310721,2,3,26,2,1595671,12,8,1587699,1556993,1310721,2, +3,26,2,26,2,10,3,6,10,4,8,1473025,1310721,2,3,26, +2,26,2,1668913,16,1,1670763,14,1587587,3,10,3,6,10,4,8, +1587589,3,10,3,6,10,4,8,1587591,1310721,2,3,26,2,10,3, +6,10,4,8,1310721,2,3,26,2,1612447,12,1669005,16,5,1310721,2, +3,26,2,26,1670763,14,1,1670763,14,1310721,2,5,26,1310721,2,2, +1593303,12,10,3,6,10,4,8,1310721,2,5,26,2,1,40,3, +36,1669129,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,1669131,14,1,1669287,16,1442305,1310721,2,5,26,2,26,2,33, +32,1,6,1,10,28,34,63,38,3,26,1669267,16,1310721,2,2, +1669259,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,1669189,1591691,12,8,1310721,2,5,26,2,3,1663505, +12,1670763,14,1310721,2,5,26,2,1,40,3,36,1669375,16,1417729,1310721, +2,5,26,2,26,2,15,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1669377,14,1, +1669477,16,1310721,2,2,1669437,14,105,115,32,97,32,116,121,112,101, +44,32,110,111,116,32,97,32,118,97,108,117,101,0,1669391,1591691, +12,8,1,1594643,12,8,1587699,1587687,2,10,3,6,10,4,8,1, +1670763,14,1604999,12,8,1587699,1587687,2,10,3,6,10,4,8,1310721,2, +5,26,2,1,40,3,36,1669589,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,1669591,14,1,1669741,16,1425921,1310721,2, +5,26,2,26,2,1594643,12,8,1587699,1587689,2,10,3,6,10,4, +8,1587701,1425921,1310721,2,5,26,2,26,2,1,28,1,6,1,10, +28,34,63,38,3,26,10,3,6,10,4,8,1590561,3,10,3, +6,10,4,8,1590563,1425921,1310721,2,5,26,2,26,2,10,3,6, +10,4,8,1,1670763,14,1310721,2,5,26,2,1,40,3,36,1669829, +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, +1669831,14,1,1669945,16,1425921,1310721,2,5,26,2,26,2,1594643,12,8, +1559041,1310721,2,5,26,2,26,2,1669907,16,1587699,1559041,1310721,2,5,26, +2,26,2,10,3,6,10,4,8,1587587,3,10,3,6,10,4, +8,1587589,5,10,3,6,10,4,8,1,1670763,14,1310721,2,5,26, +2,1,40,3,36,1670033,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,1670035,14,1,1670117,16,1425921,1310721,2,5,26, +2,26,2,1594643,12,8,1559041,1310721,2,5,26,2,26,2,1670111,16, +1587699,1559041,1310721,2,5,26,2,26,2,10,3,6,10,4,8,1, +1670763,14,1310721,2,5,26,2,1,40,3,36,1670205,16,1417729,1310721,2, +5,26,2,26,2,13,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1670207,14,1,1670229, +16,1310721,2,5,26,2,1667109,12,1670763,14,1310721,2,5,26,2,1, +40,1670277,16,1310721,2,5,26,1310721,2,2,1595111,12,10,3,6,10, +4,8,1587729,2,1606425,12,1670335,16,1442305,1310721,2,5,26,2,26,2, +257,32,1,6,1,10,28,34,63,38,1,10,28,1670337,14,1, +1670659,16,1604999,12,8,1590581,1,10,3,6,10,4,8,3,1670537,16, +1590581,2,17,40,3,36,1670445,16,1670437,14,116,111,111,32,109,97, +110,121,32,116,121,112,101,32,97,114,103,117,109,101,110,116, +115,0,1670389,1591557,12,8,1590565,1590581,2,26,1644591,12,10,3,6,10, +4,8,1590581,1,6,2,1,6,3,26,5,6,4,10,8,8, +1587611,2,1606729,12,1,6,1,10,28,34,63,38,3,26,1670533,16, +1670537,14,1670363,14,1644489,12,8,1587599,2,1606425,12,1,6,1,10,28, +34,63,38,3,26,1670659,16,1670651,14,101,120,112,101,99,116,101, +100,32,40,32,97,102,116,101,114,32,116,104,101,32,116,121, +112,101,32,97,114,103,117,109,101,110,116,115,0,1670579,1591557,12, +8,1587599,2,1606425,12,1670689,16,1310721,2,5,26,2,1665597,12,1670763,14, +1310721,2,5,26,2,1595235,12,8,1559041,1310721,2,5,26,2,26,2, +1670755,16,1587699,1559041,1310721,2,5,26,2,26,2,10,3,6,10,4, +8,1,1670763,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1670811,16,1966081,1310721,4,1579223,12,1310721,2,3, +26,4,1310721,2,4,1587587,2,1,6,1,10,28,34,63,38,3, +26,1670943,16,1670935,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,1670859,1591557,12,8,1587589, +2,3,28,1,6,1,10,28,34,63,38,3,26,1671005,16,1587565, +2,1,6,1,10,28,34,63,38,1,10,28,1671007,14,1,1671045, +16,1587591,2,1612447,12,1,6,1,10,28,34,63,38,1,10,28, +1671047,14,1,1671147,16,1587591,2,1671139,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,1671059,1591963,12,8,1587699,2,1638689,12,1671165,16,3,1671221,14,1587699,2, +1,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,1671231,16,3,1671283,14,1587699, +2,1587687,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1671361,14,43,43,32,97,110, +100,32,45,45,32,110,101,101,100,32,97,32,110,117,109,98, +101,114,32,111,114,32,97,32,112,111,105,110,116,101,114,0, +1671287,1587699,2,1643625,12,8,1587587,1,10,3,6,10,4,8,1587589,1, +10,3,6,10,4,8,1587701,1,10,3,6,10,4,8,1,1594643, +12,8,7,1594729,12,8,3,1594729,12,8,1310721,2,2,1671523,16,1, +1594643,12,8,7,1594729,12,8,1310721,2,3,26,2,1594643,12,8,27, +1594729,12,8,5,1594643,12,8,7,1594729,12,8,5,1594729,12,8,1671587, +14,1310721,2,3,26,2,1594643,12,8,27,1594729,12,8,1,1594643,12, +8,7,1594729,12,8,5,1594643,12,8,7,1594729,12,8,5,1594729,12, +8,11,1594729,12,8,9,1594729,12,8,1,1671611,14,1,1310721,2,5, +26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009,40,1671659,16, +1966081,1310721,4,1579223,12,1310721,2,4,3,1,10,28,1310721,2,9,26, +4,1604999,12,8,1310721,2,3,26,1607249,12,10,3,6,10,4,8, +1663385,12,8,1310721,2,2,3,28,1,6,1,10,28,34,63,38, +3,26,1671889,16,1671877,14,117,115,101,32,97,32,102,105,101,108, +100,32,111,102,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,1671757,1591845,12,8,1671953,14,1310721,2,2,5,40,3,36,1671953, +16,1310721,2,2,5,28,1612545,12,8,1310721,2,9,26,1310721,2,2, +5,28,10,3,6,10,4,8,1310721,2,5,26,1587699,2,10,3, +6,10,4,8,1310721,2,5,26,2,1,26,2,11,28,1,6, +1,10,28,34,63,38,3,26,1672057,16,1310721,2,5,26,1310721,2, +5,26,2,9,26,2,10,3,6,10,4,8,1310721,2,5,26, +2,1,26,2,17,28,1,6,1,10,28,34,63,38,1,10, +28,1672407,16,1590585,2,1,6,1,10,28,34,63,38,3,26,1672181, +16,1587703,2,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1672183,14,1,1672351,16,1590587,12,8, +93,1573255,12,8,1310721,2,3,26,2,1573495,12,8,1672245,14,58,32, +116,104,97,116,39,115,32,97,32,0,1672221,1573495,12,8,1587699,2, +1641969,12,8,1672337,14,44,32,110,111,116,32,97,32,115,116,114, +117,99,116,32,111,114,32,97,32,112,111,105,110,116,101,114, +32,116,111,32,111,110,101,0,1672267,1573495,12,8,1590731,12,8,1587699, +1587687,2,10,3,6,10,4,8,1587587,3,10,3,6,10,4,8, +1587589,9,10,3,6,10,4,8,1,1672963,14,1310721,2,7,26,1310721, +2,5,26,2,1310721,2,3,26,2,1650397,12,10,3,6,10,4, +8,1310721,2,7,26,2,1,40,1672695,16,1590585,2,1,6,1,10, +28,34,63,38,3,26,1672547,16,1587703,2,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1672549, +14,1,1672639,16,1590587,12,8,1310721,2,5,26,2,1641969,12,8,1672609, +14,32,104,97,115,32,110,111,32,102,105,101,108,100,32,0, +1672579,1573495,12,8,1310721,2,3,26,2,1573495,12,8,1590731,12,8,1587699, +1587687,2,10,3,6,10,4,8,1587587,3,10,3,6,10,4,8, +1587589,9,10,3,6,10,4,8,1,1672963,14,1310721,2,5,26,2, +9,26,2,1310721,2,7,26,2,7,30,5,26,26,2,1672789,16, +1310721,2,5,26,2,9,26,2,1310721,2,7,26,2,7,30,5, +26,26,2,1594643,12,8,27,1594729,12,8,1587699,1310721,2,5,26,2, +9,26,2,1310721,2,7,26,2,7,30,3,26,26,2,10,3, +6,10,4,8,1587587,3,10,3,6,10,4,8,1587701,1,10,3, +6,10,4,8,1310721,2,9,26,2,1,40,3,36,1672939,16,1587589, +7,10,3,6,10,4,8,1587591,1310721,2,9,26,2,10,3,6, +10,4,8,1672955,14,1587589,9,10,3,6,10,4,8,1,1672963,14, +1,1310721,2,11,26,1310721,4,18,1310721,2,33,28,1310721,4,1310721,2, +1835009,40,1673011,16,1966081,1310721,4,1579223,12,1667847,12,1310721,2,4,3,1676731, +16,1585289,2,5,28,1,6,1,10,28,34,63,38,3,26,1673115, +16,1585291,2,1587647,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1673117,14,1,1673201,16, +1604999,12,8,1310721,2,7,26,1644591,12,10,3,6,10,4,8,1663385, +12,8,1587699,1310721,2,7,26,2,10,3,6,10,4,8,1587589,1, +10,3,6,10,4,8,1673021,14,1585289,2,9,28,1,6,1,10, +28,34,63,38,1,10,28,1673245,16,1310721,2,2,1676743,14,1585291,2, +1587607,2,28,1,6,1,10,28,34,63,38,3,26,1675947,16,1310721, +2,31,26,1,10,3,6,10,4,8,1587769,2,1673339,16,1587587,2, +1,6,1,10,28,34,63,38,1,10,28,1673341,14,1,1673399,16, +1587589,2,3,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1673401,14,1,1673441,16,1589487,1587591, +2,26,2,1,6,1,10,28,34,63,38,1,10,28,1673443,14, +1,1673477,16,1310721,2,31,26,1589487,1587591,2,26,2,10,3,6,10, +4,8,1604999,12,8,1663385,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,1673669,16,1673657,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,1673555,1591845,12,8, +1673733,14,1310721,2,2,5,40,3,36,1673733,16,1310721,2,2,5,28, +1612545,12,8,1310721,2,3,26,1310721,2,2,5,28,10,3,6,10, +4,8,1587699,2,1,26,2,23,28,1,6,1,10,28,34,63, +38,3,26,1674921,16,1310721,2,9,26,1587699,2,9,26,2,10,3, +6,10,4,8,1310721,2,31,26,2,1673857,16,1587763,2,1593303,12,1, +40,3,36,1,6,1,10,28,34,63,38,1,10,28,1673859,14, +1,1673871,16,9,1594729,12,8,1310721,2,1681059,12,10,3,6,10,4, +8,1663385,12,8,1310721,2,2,1613033,12,8,1587699,2,1638689,12,1673927,16, +3,1673979,14,1587699,2,1587687,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1674039,14,97, +110,32,105,110,100,101,120,32,104,97,115,32,116,111,32,98, +101,32,97,32,110,117,109,98,101,114,0,1673983,1587699,2,1643625,12, +8,1587609,2,1606959,12,8,1310721,2,29,26,1587763,2,1593303,12,10,3, +6,10,4,8,1310721,2,31,26,2,1674147,16,1310721,2,29,26,2, +1,40,3,36,1,6,1,10,28,34,63,38,1,10,28,1674149, +14,1,1674219,16,1417729,1310721,2,29,26,2,26,2,13,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1674221,14,1,1674501,16,1,1594643,12,8,7,1594729,12,8, +1310721,2,31,26,2,3,26,1595671,12,8,3,1594729,12,8,45,1425921, +1310721,2,29,26,2,26,2,26,1594729,12,8,1310721,2,29,26,1595029, +12,10,3,6,10,4,8,17,1594729,12,8,1310721,2,31,26,2, +3,26,1595671,12,8,3,1594729,12,8,1587767,2,1595409,12,8,1310721,2, +29,26,2,1587549,2,1594811,12,8,1310721,2,31,26,2,1595671,12,8, +3,1594729,12,8,11,1594729,12,8,1310721,2,9,26,2,1637519,12,3, +28,1,6,1,10,28,34,63,38,1,10,28,1674489,16,1310721,2, +9,26,2,1637519,12,1594643,12,8,31,1594729,12,8,27,1594729,12,8, +1674917,14,1587769,2,1674553,16,1310721,2,29,26,2,1,40,3,36,1, +6,1,10,28,34,63,38,1,10,28,1674555,14,1,1674625,16,1417729, +1310721,2,29,26,2,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1674627,14, +1,1674907,16,1,1594643,12,8,7,1594729,12,8,5,1594643,12,8,7, +1594729,12,8,3,1594729,12,8,45,1425921,1310721,2,29,26,2,26,2, +26,1594729,12,8,1310721,2,29,26,1595029,12,10,3,6,10,4,8, +17,1594729,12,8,3,1594643,12,8,7,1594729,12,8,3,1594729,12,8, +1587767,2,1595409,12,8,1310721,2,29,26,2,1587549,2,1594811,12,8,11, +1594729,12,8,5,1594643,12,8,27,1594729,12,8,3,1594729,12,8,11, +1594729,12,8,1310721,2,9,26,2,1637519,12,3,28,1,6,1,10, +28,34,63,38,1,10,28,1674895,16,1310721,2,9,26,2,1637519,12, +1594643,12,8,31,1594729,12,8,27,1594729,12,8,1674917,14,1590553,2,1595409, +12,8,1675787,14,1587699,2,1639085,12,1674939,16,3,1674991,14,1587699,2,1587687, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1675075,14,111,110,108,121,32,112,111, +105,110,116,101,114,115,32,97,110,100,32,97,114,114,97,121, +115,32,99,97,110,32,98,101,32,105,110,100,101,120,101,100, +0,1674995,1587699,2,1643625,12,8,1310721,2,9,26,1587699,2,1639375,12,10, +3,6,10,4,8,1310721,2,5,26,1,3,28,10,3,6,10, +4,8,1587699,2,1,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1675221,16,1587699,2,7,26,2,1,10,40,1,6,1, +10,28,34,63,38,1,10,28,1675223,14,1,1675257,16,1310721,2,5, +26,1587699,2,7,26,2,10,3,6,10,4,8,1590561,1,10,3, +6,10,4,8,1310721,2,1681059,12,10,3,6,10,4,8,1663385,12, +8,1310721,2,2,1613033,12,8,1310721,2,5,26,2,1,40,3,36, +1675363,16,1590561,2,1,6,1,10,28,34,63,38,1,10,28,1675365, +14,1,1675455,16,1590563,2,1,40,1675387,16,3,1675429,14,1590563,2,1310721, +2,5,26,2,40,3,36,1,6,1,10,28,34,63,38,1, +10,28,1,6,1,10,28,34,63,38,1,10,28,1675457,14,1, +1675555,16,1675547,14,116,104,101,32,105,110,100,101,120,32,105,115, +32,111,117,116,32,111,102,32,114,97,110,103,101,32,102,111, +114,32,116,104,105,115,32,97,114,114,97,121,0,1675465,1591173,12, +8,1587699,2,1638689,12,1675573,16,3,1675625,14,1587699,2,1587687,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1675685,14,97,110,32,105,110,100,101,120,32,104, +97,115,32,116,111,32,98,101,32,97,32,110,117,109,98,101, +114,0,1675629,1587699,2,1643625,12,8,1587609,2,1606959,12,8,1310721,2,9, +26,2,1637519,12,3,28,1,6,1,10,28,34,63,38,1,10, +28,1675779,16,1310721,2,9,26,2,1637519,12,1594643,12,8,31,1594729,12, +8,27,1594729,12,8,1587587,3,10,3,6,10,4,8,1587699,1310721,2, +9,26,2,10,3,6,10,4,8,1587701,1,10,3,6,10,4, +8,1310721,2,3,26,2,1,40,3,36,1675909,16,1587589,7,10,3, +6,10,4,8,1587591,1310721,2,3,26,2,10,3,6,10,4,8, +1675925,14,1587589,9,10,3,6,10,4,8,1310721,2,1,10,3,6, +10,4,8,1673021,14,1585291,2,1587637,2,28,1,6,1,10,28,34, +63,38,3,26,1675987,16,3,1676039,14,1585291,2,1587617,2,28,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1676073,16,1310721,2,1310721,2,2,1671625,12,10,3,6,10, +4,8,1673021,14,1585291,2,1587599,2,28,1,6,1,10,28,34,63, +38,3,26,1676575,16,1663385,12,8,1310721,2,2,1613033,12,8,1310721,2, +11,26,1,10,3,6,10,4,8,1587699,2,1,26,2,15,28, +1,6,1,10,28,34,63,38,3,26,1676213,16,1310721,2,11,26, +1587699,2,10,3,6,10,4,8,1676317,14,1587699,2,1587687,2,28,1, +6,1,10,28,34,63,38,3,26,1676305,14,111,110,108,121,32, +102,117,110,99,116,105,111,110,115,32,99,97,110,32,98,101, +32,99,97,108,108,101,100,0,1676247,1587699,2,1643625,12,8,1310721,2, +13,26,1,17,1574703,12,8,1310721,2,5,26,1,1310721,2,11,26, +2,1310721,2,13,26,1587769,2,1663953,12,10,3,6,10,4,8,1310721, +2,5,26,2,1594643,12,8,7,1594729,12,8,13,1594729,12,8,11, +1594729,12,8,9,1594729,12,8,1587587,1,10,3,6,10,4,8,1587589, +1,10,3,6,10,4,8,1310721,2,1,10,3,6,10,4,8, +1587701,1,10,3,6,10,4,8,1587699,1587687,2,10,3,6,10,4, +8,1310721,2,11,26,2,1676571,16,1587699,1310721,2,11,26,2,9,26, +2,1310721,2,13,26,1637691,12,10,3,6,10,4,8,1673021,14,1585291, +2,1587619,2,28,1,6,1,10,28,34,63,38,3,26,1676643,16, +1604999,12,8,1310721,2,3,3,1670777,12,10,3,6,10,4,8,1673021, +14,1585291,2,1587621,2,28,1,6,1,10,28,34,63,38,3,26, +1676717,16,1604999,12,8,1310721,2,3,3,1,10,28,1670777,12,10,3, +6,10,4,8,1673021,14,1310721,2,2,1676743,14,1673021,14,1310721,2,2, +1676743,14,1,1310721,2,33,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1676791,16,1966081,1310721,4,1579223,12,1585289,2,5,28,1, +6,1,10,28,34,63,38,3,26,1677003,16,1585291,2,1587657,2,28, +1,6,1,10,28,34,63,38,3,26,1676863,16,3,1676915,14,1585291, +2,1587653,2,28,1,6,1,10,28,34,63,38,3,26,1,6, +1,10,28,34,63,38,1,10,28,1676925,16,3,1676977,14,1585291,2, +1587655,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,1677005,14,1,1677225,16,1310721,2,5,26,3,10,3,6, +10,4,8,1585291,2,1587657,2,28,1,6,1,10,28,34,63,38, +3,26,1677087,16,1310721,2,5,26,5,10,3,6,10,4,8,1585291, +2,1587655,2,28,1,6,1,10,28,34,63,38,3,26,1677143,16, +1310721,2,5,26,7,10,3,6,10,4,8,1604999,12,8,1587623,2, +1606959,12,8,1310721,2,1676757,12,10,3,6,10,4,8,1663385,12,8, +1587589,1,10,3,6,10,4,8,1310721,2,2,1310721,2,5,26,2, +1623945,12,1678623,14,1585289,2,9,28,1,6,1,10,28,34,63,38, +3,26,1678613,16,1585291,2,1587623,2,28,1,6,1,10,28,34,63, +38,3,26,1677591,16,1604999,12,8,1310721,2,1676757,12,10,3,6,10, +4,8,1663385,12,8,1310721,2,2,1613033,12,8,1587699,2,1,26,2, +11,28,1,6,1,10,28,34,63,38,3,26,1677379,16,3,1677431, +14,1587699,2,1587687,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1677503,14,111,110,108, +121,32,112,111,105,110,116,101,114,115,32,99,97,110,32,98, +101,32,100,101,114,101,102,101,114,101,110,99,101,100,0,1677435, +1587699,2,1643625,12,8,1587699,1587699,2,1639375,12,10,3,6,10,4,8, +1587587,3,10,3,6,10,4,8,1587589,9,10,3,6,10,4,8, +1587701,1,10,3,6,10,4,8,1,1678623,14,1585291,2,1587625,2,28, +1,6,1,10,28,34,63,38,3,26,1678107,16,1604999,12,8,1310721, +2,1676757,12,10,3,6,10,4,8,1587587,2,1,6,1,10,28, +34,63,38,3,26,1677733,16,1587699,2,1638921,12,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1677735,14,1,1677811,16,1677803,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,1677743,1591557,12,8,1587587,2,1677873,16,1587589,2,3, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1677875,14,1,1677919,16,1558017,1587591,2,26,2, +33,32,1,6,1,10,28,34,63,38,1,10,28,1677921,14,1, +1677997,16,1677989,14,97,110,32,111,51,32,118,97,114,105,97,98, +108,101,32,104,97,115,32,110,111,32,97,100,100,114,101,115, +115,0,1677929,1591173,12,8,1310721,2,2,5,40,3,36,1678031,16,1310721, +2,2,5,28,1612545,12,8,1587587,1,10,3,6,10,4,8,1587589, +1,10,3,6,10,4,8,1587701,1,10,3,6,10,4,8,1587699, +1587699,2,1632877,12,10,3,6,10,4,8,1,1678623,14,1585291,2,1587619, +2,28,1,6,1,10,28,34,63,38,3,26,1678165,16,1604999,12, +8,1676757,12,8,1,3,1670777,12,1678623,14,1585291,2,1587621,2,28,1, +6,1,10,28,34,63,38,3,26,1678229,16,1604999,12,8,1676757,12, +8,1,3,1,10,28,1670777,12,1678623,14,1310721,2,3,26,1585291,2, +1609683,12,10,3,6,10,4,8,1310721,2,3,26,2,1,40,3, +36,1678613,16,1604999,12,8,1310721,2,1676757,12,10,3,6,10,4,8, +1663385,12,8,1310721,2,2,1613033,12,8,1547329,1310721,2,3,26,2,26, +2,1547393,1310721,2,3,26,2,26,2,1608745,12,8,1590561,1,10,3, +6,10,4,8,1310721,2,3,26,2,3,10,40,3,36,1678423,16, +1587699,1587693,2,10,3,6,10,4,8,1678559,14,1587699,2,1587687,2,28, +1,6,1,10,28,34,63,38,1,10,28,1678559,16,1587699,2,1638689, +12,1678529,14,116,104,105,115,32,111,112,101,114,97,116,111,114, +32,110,101,101,100,115,32,97,32,110,117,109,98,101,114,0, +1678471,1587699,2,1643625,12,8,1587699,1587689,2,10,3,6,10,4,8,1587587, +1,10,3,6,10,4,8,1587589,1,10,3,6,10,4,8,1587701, +1,10,3,6,10,4,8,1,1678623,14,1672977,12,1678623,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40, +1678671,16,1966081,1310721,4,1579223,12,1310721,2,4,1676757,12,1310721,2,3,26, +4,1585289,2,9,28,1,6,1,10,28,34,63,38,3,26,1679633, +16,1310721,2,5,26,1585291,2,1609487,12,10,3,6,10,4,8,1310721, +2,5,26,2,1,40,1678783,16,1310721,2,3,26,2,1679649,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,1678855,16,1310721,2,3,26, +2,1679649,14,1604999,12,8,1663385,12,8,1310721,2,3,26,2,1613033,12, +8,1310721,2,13,26,1587699,2,10,3,6,10,4,8,1547137,1310721,2, +5,26,2,26,2,3,1,10,28,28,1,6,1,10,28,34, +63,38,3,26,1679155,16,1310721,2,9,26,1595029,12,10,3,6,10, +4,8,17,1594729,12,8,1310721,2,3,26,1310721,2,7,26,2,3, +26,1678637,12,10,3,6,10,4,8,1663385,12,8,1310721,2,3,26, +2,1613033,12,8,1547329,3,26,2,1547393,3,26,2,1608745,12,8,1310721, +2,11,26,1595029,12,10,3,6,10,4,8,15,1594729,12,8,1310721, +2,9,26,2,1587549,2,1594811,12,8,1,1594643,12,8,1310721,2,11, +26,2,1587549,2,1594811,12,8,1679501,14,1547137,1310721,2,5,26,2,26, +2,5,1,10,28,28,1,6,1,10,28,34,63,38,3,26, +1679403,16,1310721,2,9,26,1595029,12,10,3,6,10,4,8,17,1594729, +12,8,3,1594643,12,8,1310721,2,11,26,1595029,12,10,3,6,10, +4,8,15,1594729,12,8,1310721,2,9,26,2,1587549,2,1594811,12,8, +1310721,2,3,26,1310721,2,7,26,2,3,26,1678637,12,10,3,6, +10,4,8,1663385,12,8,1310721,2,3,26,2,1613033,12,8,1547329,3, +26,2,1547393,3,26,2,1608745,12,8,1310721,2,11,26,2,1587549,2, +1594811,12,8,1679501,14,1310721,2,3,26,1310721,2,7,26,2,3,26, +1678637,12,10,3,6,10,4,8,1663385,12,8,1310721,2,3,26,2, +1613033,12,8,1547009,1310721,2,5,26,2,26,2,1547137,1310721,2,5,26, +2,26,2,1608745,12,8,1587699,1310721,2,5,26,2,1310721,2,13,26, +2,1587699,2,1655517,12,10,3,6,10,4,8,1587587,1,10,3,6, +10,4,8,1587589,1,10,3,6,10,4,8,1310721,2,3,26,1, +10,3,6,10,4,8,1587701,1,10,3,6,10,4,8,1590561,1, +10,3,6,10,4,8,1678691,14,1310721,2,3,26,2,1679649,14,1, +1310721,2,15,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009, +40,1679697,16,1966081,1310721,4,1579223,12,11,1594729,12,8,3,1594643,12,8, +7,1594729,12,8,11,1594729,12,8,5,1594729,12,8,1,1679745,14,1, +1310721,2,1,26,1310721,4,18,1310721,2,23,28,1310721,4,1310721,2,1835009, +40,1679793,16,1966081,1310721,4,1579223,12,1310721,2,4,1587569,2,1310721,2,13, +26,4,1587557,2,1310721,2,15,26,4,1663385,12,8,1310721,2,2,1613033, +12,8,1604999,12,8,1310721,2,3,26,1595029,12,10,3,6,10,4, +8,17,1594729,12,8,1310721,2,7,26,1615017,12,10,3,6,10,4, +8,1310721,2,17,26,1681059,12,10,3,6,10,4,8,1663385,12,8, +1310721,2,21,26,1587699,2,10,3,6,10,4,8,1310721,2,17,26, +2,3,28,1,6,1,10,28,34,63,38,1,10,28,1680017,16, +1310721,2,17,26,2,1613033,12,8,1310721,2,11,26,1587569,2,10,3, +6,10,4,8,1310721,2,9,26,1615017,12,10,3,6,10,4,8, +1310721,2,5,26,1595029,12,10,3,6,10,4,8,15,1594729,12,8, +1587627,2,1606959,12,8,1310721,2,3,26,2,1587549,2,1594811,12,8,1310721, +2,7,26,2,1615649,12,8,1587569,1310721,2,13,26,2,10,3,6, +10,4,8,1310721,2,19,26,1681059,12,10,3,6,10,4,8,1663385, +12,8,1310721,2,19,26,2,3,28,1,6,1,10,28,34,63, +38,1,10,28,1680253,16,1310721,2,19,26,2,1613033,12,8,1310721,2, +9,26,2,1310721,2,11,26,2,1310721,2,5,26,2,1587569,2,1310721, +2,15,26,2,1680391,14,101,110,100,115,32,116,104,101,32,116, +119,111,32,115,105,100,101,115,32,111,102,32,63,58,32,105, +110,32,100,105,102,102,101,114,101,110,116,32,115,116,97,116, +101,115,0,1680301,1623371,12,8,1310721,2,7,26,2,1615567,12,8,1310721, +2,21,26,2,1587699,2,1639563,12,1,6,1,10,28,34,63,38, +3,26,1680521,16,1587699,2,1310721,2,21,26,2,1639563,12,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1680523,14,1,1680593,16,1680571,14,116,104,101,32,116,119,111, +32,115,105,100,101,115,32,111,102,32,63,58,0,1680531,1310721,2, +21,26,2,1587699,2,1643225,12,8,1310721,2,21,26,2,1587687,2,28, +1,6,1,10,28,34,63,38,1,10,28,1680659,16,1587699,1310721,2, +21,26,2,10,3,6,10,4,8,1587587,1,10,3,6,10,4, +8,1587589,1,10,3,6,10,4,8,1587701,1,10,3,6,10,4, +8,1310721,2,17,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1680805,16,1310721,2,19,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, +1680807,14,1,1680817,16,3,1681045,14,1310721,2,17,26,2,3,28,1, +6,1,10,28,34,63,38,3,26,1680861,16,3,1680917,14,1310721,2, +19,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,1681037,16,1681029,14,98,111, +116,104,32,115,105,100,101,115,32,111,102,32,63,58,32,104, +97,118,101,32,116,111,32,98,101,32,110,101,119,32,111,98, +106,101,99,116,115,44,32,111,114,32,110,101,105,116,104,101, +114,0,1680925,1591845,12,8,1,1681045,14,1,1310721,2,23,26,1310721,4, +18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1681093,16,1966081,1310721,4, +1579223,12,3,1678637,12,1310721,2,4,1585289,2,9,28,1,6,1,10, +28,34,63,38,1,10,28,1681149,16,1310721,2,2,1683407,14,1585291,2, +1587659,2,28,1,6,1,10,28,34,63,38,3,26,1681197,16,1310721, +2,2,1679759,12,1683407,14,1585291,2,1587615,2,28,1,6,1,10,28, +34,63,38,3,26,1682243,16,1587587,2,1,6,1,10,28,34,63, +38,3,26,1681323,16,1681315,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,1681263,1591557,12,8,1310721,2,3,26,1587589,2,10,3,6,10,4, +8,1310721,2,5,26,1587591,2,10,3,6,10,4,8,1310721,2,11, +26,1587699,2,10,3,6,10,4,8,1310721,2,11,26,2,1638921,12, +1681547,16,1681539,14,97,32,119,104,111,108,101,32,115,116,114,117, +99,116,32,111,114,32,97,114,114,97,121,32,99,97,110,39, +116,32,98,101,32,97,115,115,105,103,110,101,100,59,32,97, +115,115,105,103,110,32,105,116,115,32,102,105,101,108,100,115, +0,1681417,1591173,12,8,1604999,12,8,1310721,2,7,26,1587769,2,1681629,16, +1310721,2,3,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,1681631,14,1,1681681, +16,1558017,1310721,2,5,26,2,26,2,33,32,1,6,1,10,28, +34,63,38,1,10,28,1681683,14,1,1681749,16,1473025,1310721,2,5,26, +2,26,2,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1681751,14,1,10,3,6,10,4, +8,1310721,2,7,26,2,1681785,16,9,1594729,12,8,1310721,2,9,26, +1681059,12,10,3,6,10,4,8,1663385,12,8,1310721,2,11,26,2, +1587699,2,1639563,12,1,6,1,10,28,34,63,38,3,26,1681905,16, +1681883,14,97,115,115,105,103,110,109,101,110,116,0,1681861,1310721,2, +11,26,2,1587699,2,1643225,12,8,1310721,2,7,26,2,1681979,16,1, +1594643,12,8,7,1594729,12,8,1310721,2,5,26,2,1595671,12,8,5, +1594729,12,8,1310721,2,5,26,2,1597105,12,8,1682133,14,1587769,2,1682049, +16,1310721,2,3,26,2,7,28,1,6,1,10,28,34,63,38, +1,10,28,1,6,1,10,28,34,63,38,1,10,28,1682051,14, +1,1682095,16,1310721,2,11,26,2,1658673,12,1,6,1,10,28,34, +63,38,1,10,28,1682097,14,1,1682127,16,1310721,2,11,26,2,1594643, +12,8,1590517,2,1595409,12,8,1679663,12,8,1587587,1,10,3,6,10, +4,8,1587589,1,10,3,6,10,4,8,1587699,1310721,2,11,26,2, +10,3,6,10,4,8,1587701,1,10,3,6,10,4,8,1310721,2, +3,26,2,1310721,2,5,26,2,1310721,2,9,26,2,1626785,12,1683407, +14,1310721,2,7,26,1585291,2,1609879,12,10,3,6,10,4,8,1310721, +2,7,26,2,1,40,3,36,1683395,16,1587587,2,1,6,1,10, +28,34,63,38,3,26,1682385,16,1682377,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,1682325,1591557,12,8,1587589,2,3,28,1,6,1,10, +28,34,63,38,3,26,1682447,16,1587565,2,1,6,1,10,28,34, +63,38,1,10,28,1682449,14,1,1682487,16,1587591,2,1612447,12,1,6, +1,10,28,34,63,38,1,10,28,1682489,14,1,1682609,16,1587591,2, +1682601,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,1682501,1591963,12,8,1310721,2,11,26,1587699,2,10,3, +6,10,4,8,1604999,12,8,1310721,2,5,26,1587769,2,1682709,16,1587589, +2,3,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1682711,14,1,1682755,16,1558017,1587591,2, +26,2,33,32,1,6,1,10,28,34,63,38,1,10,28,1682757, +14,1,1682817,16,1473025,1587591,2,26,2,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1682819,14, +1,10,3,6,10,4,8,1310721,2,5,26,2,1682939,16,1310721,2, +5,26,1587591,2,10,3,6,10,4,8,9,1594729,12,8,1310721,2, +5,26,2,1595671,12,8,3,1594729,12,8,1310721,2,5,26,1310721,2, +5,26,2,3,26,10,3,6,10,4,8,1682963,14,1,1594643,12, +8,7,1594729,12,8,3,1594729,12,8,1587587,1,10,3,6,10,4, +8,1310721,2,9,26,1681059,12,10,3,6,10,4,8,1663385,12,8, +1310721,2,9,26,2,1613033,12,8,1547009,1547585,1310721,2,7,26,2,26, +2,26,2,1547137,1547585,1310721,2,7,26,2,26,2,26,2,1608745,12, +8,1310721,2,3,26,1547585,1310721,2,7,26,2,26,2,1310721,2,11, +26,2,1587699,2,1655517,12,10,3,6,10,4,8,1310721,2,11,26, +2,1310721,2,3,26,2,1639563,12,1,6,1,10,28,34,63,38, +3,26,1683249,16,1683221,14,99,111,109,112,111,117,110,100,32,97, +115,115,105,103,110,109,101,110,116,0,1683181,1310721,2,11,26,2, +1310721,2,3,26,2,1643225,12,8,1310721,2,5,26,2,1683311,16,1, +1594643,12,8,7,1594729,12,8,1310721,2,5,26,2,3,28,1595671,12, +8,5,1594729,12,8,1683317,14,1679663,12,8,1587587,1,10,3,6,10, +4,8,1587589,1,10,3,6,10,4,8,1587699,1310721,2,11,26,2, +10,3,6,10,4,8,1587701,1,10,3,6,10,4,8,1,1683407, +14,1310721,2,2,1683407,14,1,1310721,2,13,26,1310721,4,18,1310721,2, +3,28,1310721,4,1310721,2,1835009,40,1683455,16,1966081,1310721,4,1579223,12,1585289, +2,9,28,1,6,1,10,28,34,63,38,3,26,1683619,16,1585291, +2,1587613,2,28,1,6,1,10,28,34,63,38,3,26,1683527,16, +3,1683579,14,1585291,2,1587603,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1683589,16,3, +1683615,14,1646981,12,1,6,1,10,28,34,63,38,1,10,28,1683901, +14,1585289,2,5,28,1,6,1,10,28,34,63,38,1,10,28, +1683659,16,3,1683697,14,1585291,2,1611615,12,1,40,3,36,1,6,1, +10,28,34,63,38,1,10,28,1683707,16,1,1683901,14,1646981,12,1683721, +16,3,1683901,14,1310721,2,1585291,2,1593303,12,10,3,6,10,4,8, +1310721,2,2,1,40,3,36,1683825,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,1683827,14,1,1683893,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,1683895,14,1,1683901,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,9,28,1310721,4,1310721,2,1835009,40,1683949, +16,1966081,1310721,4,1579223,12,1587557,2,1310721,2,4,1,1310721,2,3,26, +4,1,1310721,2,5,26,4,1587689,2,1310721,2,7,26,4,1604999,12, +8,1587561,1,6,2,1,6,3,26,5,6,4,10,8,8,1587571, +1,6,2,1,6,3,26,5,6,4,10,8,8,1587605,2,1606425, +12,1,6,1,10,28,34,63,38,3,26,1684431,16,1585289,2,1, +28,1,6,1,10,28,34,63,38,3,26,1684155,16,1684147,14,109, +105,115,115,105,110,103,32,125,0,1684127,1591557,12,8,1683421,12,1684173, +16,1686451,12,8,1684059,14,1310721,2,3,26,1681059,12,10,3,6,10, +4,8,1663385,12,8,1587613,2,1606729,12,1684265,16,9,1594729,12,8,1310721, +2,3,26,2,1632069,12,8,1310721,2,3,26,1,10,3,6,10, +4,8,1684059,14,1587605,2,1606425,12,1,6,1,10,28,34,63,38, +3,26,1684381,16,1684373,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,1684301,1591557,12,8,1310721,2, +5,26,3,10,3,6,10,4,8,1310721,2,7,26,1587699,2,10, +3,6,10,4,8,1684059,14,1604999,12,8,1310721,2,5,26,2,1684489, +16,1310721,2,3,26,1310721,2,3,26,2,1631353,12,10,3,6,10, +4,8,1684497,14,1,1594643,12,8,1310721,2,2,1614445,12,8,1587561,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1587571,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1587587,1,10,3,6,10, +4,8,1587589,1,10,3,6,10,4,8,1587699,1310721,2,7,26,2, +10,3,6,10,4,8,1587701,1,10,3,6,10,4,8,1310721,2, +3,26,2,1684653,14,1,1310721,2,9,26,1310721,4,18,1310721,2,5, +28,1310721,4,1310721,2,1835009,40,1684701,16,1966081,1310721,4,1579223,12,1585289,2, +3,28,1,6,1,10,28,34,63,38,3,26,1684769,16,1310721,2, +1585291,2,10,3,6,10,4,8,1604999,12,8,1310721,2,2,1685469,14, +1587631,2,1606729,12,1684793,16,1,1684667,12,28,1685469,14,1585289,2,9,28, +1,6,1,10,28,34,63,38,3,26,1684885,16,1585291,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,1684887,14,1,1684909,16,1604999,12,8, +1684667,12,-1,36,1685469,14,1587599,2,1606729,12,1684961,16,1310721,2,1685483,12, +10,3,6,10,4,8,1587601,2,1606959,12,8,1310721,2,2,1685469,14, +1585289,2,5,28,1,6,1,10,28,34,63,38,3,26,1685409,16, +1310721,2,3,26,1585291,2,1593303,12,10,3,6,10,4,8,1310721,2, +3,26,2,1,40,3,36,1685377,16,1417729,1310721,2,3,26,2,26, +2,9,28,1,6,1,10,28,34,63,38,3,26,1685093,16,3, +1685155,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,1685165,16,3,1685279,14,1417729,1310721,2,3,26,2,26,2,3,28, +1,6,1,10,28,34,63,38,3,26,1685255,16,1442305,1310721,2,3, +26,2,26,2,3,32,1,6,1,10,28,34,63,38,1,10, +28,1685257,14,1,1,6,1,10,28,34,63,38,1,10,28,1685289, +16,3,1685351,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,1685379,14, +1,1685409,16,1604999,12,8,1425921,1310721,2,3,26,2,26,2,1685469,14, +1685453,14,101,120,112,101,99,116,101,100,32,97,32,99,111,110, +115,116,97,110,116,0,1685413,1591557,12,8,1,1685469,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1685517, +16,1966081,1310721,4,1579223,12,1684667,12,1310721,2,4,1585289,2,9,28,1, +6,1,10,28,34,63,38,3,26,1686171,16,1310721,2,3,26,1585291, +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,1685665,16,1604999,12,8, +1310721,2,1310721,2,2,1684667,12,26,10,3,6,10,4,8,1686167,14, +1310721,2,3,26,2,1546753,9,26,2,28,1,6,1,10,28,34, +63,38,3,26,1685747,16,1604999,12,8,1310721,2,1310721,2,2,1684667,12, +28,10,3,6,10,4,8,1686167,14,1310721,2,3,26,2,1546753,1, +26,2,28,1,6,1,10,28,34,63,38,3,26,1685829,16,1604999, +12,8,1310721,2,1310721,2,2,1684667,12,30,10,3,6,10,4,8, +1686167,14,1310721,2,3,26,2,1546753,31,26,2,28,1,6,1,10, +28,34,63,38,3,26,1685911,16,1604999,12,8,1310721,2,1310721,2,2, +1684667,12,34,10,3,6,10,4,8,1686167,14,1310721,2,3,26,2, +1546753,27,26,2,28,1,6,1,10,28,34,63,38,3,26,1685993, +16,1604999,12,8,1310721,2,1310721,2,2,1684667,12,32,10,3,6,10, +4,8,1686167,14,1310721,2,3,26,2,1546753,11,26,2,28,1,6, +1,10,28,34,63,38,3,26,1686075,16,1604999,12,8,1310721,2,1310721, +2,2,1684667,12,48,10,3,6,10,4,8,1686167,14,1310721,2,3, +26,2,1546753,13,26,2,28,1,6,1,10,28,34,63,38,3, +26,1686157,16,1604999,12,8,1310721,2,1310721,2,2,1684667,12,38,10,3, +6,10,4,8,1686167,14,1310721,2,2,1686183,14,1685527,14,1310721,2,2, +1686183,14,1,1310721,2,5,26,1310721,4,18,1310721,2,1,28,1310721,4, +1310721,2,1835009,40,1686231,16,1966081,1310721,4,1579223,12,1585289,2,1,28,1, +6,1,10,28,34,63,38,1,10,28,1686319,16,1587613,2,1606425,12, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1686321,14,1,1686379,16,1587605,2,1606425,12,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1686381,14,1,1686395,16,1604999,12,8,1686231,14,1587613,2,1606425, +12,1686413,16,1604999,12,8,1590585,1,10,3,6,10,4,8,1,1686437, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721, +2,1835009,40,1686485,16,1966081,1310721,4,1579223,12,1590585,2,1686501,16,1686197,12, +1686973,14,1585289,2,5,28,1,6,1,10,28,34,63,38,3,26, +1686571,16,1585291,2,1611615,12,1,40,1,6,1,10,28,34,63,38, +1,10,28,1686573,14,1,1686755,16,1310721,2,1585291,2,1593303,12,10,3, +6,10,4,8,1310721,2,2,1,40,3,36,1686681,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,1686683,14,1,1686729,16,1442305, +1310721,2,2,26,2,17,32,1,6,1,10,28,34,63,38,1, +10,28,1686731,14,1,1686755,16,1310721,2,2,1,1663505,12,8,1,1686973, +14,1646981,12,1686777,16,3,1687403,12,8,1,1686973,14,1585289,2,9,28, +1,6,1,10,28,34,63,38,3,26,1686901,16,1585291,2,1587613,2, +28,1,6,1,10,28,34,63,38,3,26,1686855,16,1604999,12,8, +1,1686973,14,1585291,2,1587603,2,28,1,6,1,10,28,34,63,38, +3,26,1686901,16,1686987,12,8,1,1686973,14,1310721,2,3,26,1681059,12, +10,3,6,10,4,8,1663385,12,8,9,1594729,12,8,1587613,2,1606959, +12,8,1310721,2,3,26,2,1632069,12,8,1,1686973,14,1,1310721,2, +5,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1687021, +16,1966081,1310721,4,1579223,12,1587557,2,1310721,2,4,1587603,2,1606959,12,8, +1587561,1,6,2,1,6,3,26,5,6,4,10,8,8,1587605,2, +1606425,12,1,6,1,10,28,34,63,38,3,26,1687175,16,1585289,2, +1,28,1,6,1,10,28,34,63,38,3,26,1687165,16,1687157,14, +109,105,115,115,105,110,103,32,125,0,1687137,1591557,12,8,1686451,12, +8,1687069,14,1310721,2,2,1614445,12,8,1604999,12,8,1587561,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1,1687229,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1687277, +16,1966081,1310721,4,1579223,12,1587557,2,1310721,2,4,1587603,2,1606425,12,1687307, +16,1686987,12,1687389,14,1587561,1,6,2,1,6,3,26,5,6,4, +10,8,8,1686451,12,8,1310721,2,2,1614445,12,8,1587561,1,6,2, +1,6,-1,26,5,6,4,10,8,8,1,1687389,14,1,1310721,2, +3,26,1310721,4,18,1310721,2,15,28,1310721,4,1310721,2,1835009,40,1687437, +16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2,11,26,4,1, +1310721,2,13,26,4,1310721,2,2,1687633,16,1647783,12,8,1310721,2,11, +26,1587725,2,10,3,6,10,4,8,1310721,2,13,26,1587727,2,10, +3,6,10,4,8,1310721,2,11,26,2,1587695,2,28,1,6,1, +10,28,34,63,38,3,26,1687633,16,1687625,14,97,32,118,97,114, +105,97,98,108,101,32,99,97,110,39,116,32,98,101,32,118, +111,105,100,0,1687575,1591173,12,8,1587769,2,1687647,16,3,1687673,14,1587773, +2,1,6,1,10,28,34,63,38,1,10,28,1687729,16,1310721,2, +2,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1687731,14,1,1687797,16,1687789,14,111,51,32, +118,97,114,105,97,98,108,101,115,32,110,101,101,100,32,97, +32,116,121,112,101,0,1687739,1591173,12,8,3,1688939,16,1310721,2,3, +26,1607249,12,10,3,6,10,4,8,1310721,2,5,26,1310721,2,3, +26,2,1611819,12,10,3,6,10,4,8,1558017,1310721,2,5,26,2, +26,1310721,2,13,26,2,10,3,6,10,4,8,1587769,2,1687911,16, +3,1687937,14,1587773,2,1,6,1,10,28,34,63,38,1,10,28, +1687981,16,1558017,1310721,2,5,26,2,26,1310721,2,13,26,2,33,34, +10,3,6,10,4,8,1587607,2,1606729,12,1688207,16,1310721,2,9,26, +1685483,12,10,3,6,10,4,8,1587609,2,1606959,12,8,1310721,2,11, +26,2,1,6,1,10,28,34,63,38,3,26,1688085,16,1310721,2, +11,26,1587687,2,10,3,6,10,4,8,1473025,1310721,2,5,26,2, +26,3,10,3,6,10,4,8,1556993,1310721,2,5,26,2,26,1310721, +2,11,26,2,1310721,2,9,26,2,1633251,12,10,3,6,10,4, +8,1587563,1587563,2,1556993,1310721,2,5,26,2,26,2,1637519,12,26,10, +3,6,10,4,8,1688487,14,1310721,2,11,26,2,1688261,16,1310721,2, +11,26,2,1638921,12,1,6,1,10,28,34,63,38,1,10,28, +1688263,14,1,1688369,16,1473025,1310721,2,5,26,2,26,3,10,3,6, +10,4,8,1556993,1310721,2,5,26,2,26,1310721,2,11,26,2,10, +3,6,10,4,8,1587563,1587563,2,1310721,2,11,26,2,1637519,12,26, +10,3,6,10,4,8,1688487,14,1587563,1,6,2,1,6,3,26, +5,6,4,10,8,8,1310721,2,11,26,2,1688447,16,1556993,1310721,2, +5,26,2,26,1310721,2,11,26,2,10,3,6,10,4,8,1587769, +2,1688487,16,1310721,2,5,26,2,1596201,12,8,1310721,2,5,26,2, +1596641,12,8,1587615,2,1606729,12,1688899,16,1473025,1310721,2,5,26,2,26, +2,1688629,16,1688621,14,97,110,32,97,114,114,97,121,32,111,114, +32,97,32,115,116,114,117,99,116,32,99,97,110,39,116,32, +98,101,32,105,110,105,116,105,97,108,105,122,101,100,32,119, +105,116,104,32,61,0,1688523,1591173,12,8,1310721,2,7,26,1681059,12, +10,3,6,10,4,8,1663385,12,8,1310721,2,5,26,2,1595671,12, +8,5,1594729,12,8,1310721,2,5,26,2,1597105,12,8,1310721,2,11, +26,2,1688809,16,1310721,2,11,26,2,1587699,2,1639563,12,1,6,1, +10,28,34,63,38,3,26,1688805,16,1688783,14,105,110,105,116,105, +97,108,105,122,101,114,0,1688759,1310721,2,11,26,2,1587699,2,1643225, +12,8,1688871,14,1587699,2,1638689,12,1,6,1,10,28,34,63,38, +3,26,1688871,16,1556993,1310721,2,5,26,2,26,1587699,2,10,3,6, +10,4,8,3,1310721,2,5,26,2,1310721,2,7,26,2,1626785,12, +8,1587611,2,1606729,12,1,6,1,10,28,34,63,38,3,26,1688935, +16,1688939,14,1687797,14,1587613,2,1606959,12,8,1,1688957,14,1,1310721,2, +15,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1689005, +16,1966081,1310721,4,1579223,12,1663797,12,8,1604999,12,8,1,1687403,12,1689029, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,21,28,1310721,4,1310721, +2,1835009,40,1689077,16,1966081,1310721,4,1579223,12,1587557,2,1310721,2,15,26, +4,1663797,12,8,1604999,12,8,1587599,2,1606959,12,8,1310721,2,5,26, +1681059,12,10,3,6,10,4,8,1663385,12,8,1310721,2,5,26,2, +1613033,12,8,1587601,2,1606959,12,8,1310721,2,1595029,12,10,3,6,10, +4,8,17,1594729,12,8,1310721,2,11,26,1587569,2,10,3,6,10, +4,8,1310721,2,7,26,1615017,12,10,3,6,10,4,8,1687243,12, +8,1310721,2,13,26,1587569,2,10,3,6,10,4,8,1310721,2,9, +26,1615017,12,10,3,6,10,4,8,1587645,2,1606577,12,1689565,16,1604999, +12,8,1310721,2,3,26,1595029,12,10,3,6,10,4,8,15,1594729, +12,8,1310721,2,2,1587549,2,1594811,12,8,1310721,2,7,26,2,1615649, +12,8,1587569,1310721,2,11,26,2,10,3,6,10,4,8,1687243,12, +8,1310721,2,9,26,2,1310721,2,13,26,2,1310721,2,3,26,2, +1587569,2,1310721,2,15,26,2,1689553,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,1689459,1623371,12,8,1690097,14,1618015,1, +10,3,6,10,4,8,1310721,2,13,26,2,1689615,16,1507841,1310721,2, +9,26,2,26,1618983,12,8,1310721,2,11,26,2,1689649,16,1507841,1310721, +2,7,26,2,26,1618983,12,8,1310721,2,15,26,2,1689757,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,1689663,1619711, +12,8,1310721,2,13,26,2,1689811,16,1507841,1310721,2,9,26,2,26, +1310721,2,15,26,2,3,1621295,12,8,1310721,2,17,26,1,10,3, +6,10,4,8,1310721,2,11,26,2,1689897,16,1310721,2,17,26,1507841, +1310721,2,7,26,2,26,1310721,2,15,26,2,1,1621295,12,10,3, +6,10,4,8,1310721,2,17,26,2,1690015,16,1310721,2,19,26,1595029, +12,10,3,6,10,4,8,15,1594729,12,8,1310721,2,2,1587549,2, +1594811,12,8,1507841,1310721,2,7,26,2,26,1310721,2,15,26,2,3, +1621295,12,8,1310721,2,19,26,2,1587549,2,1594811,12,8,1690031,14,1310721, +2,2,1587549,2,1594811,12,8,1587569,1310721,2,13,26,2,1690053,16,3, +1690085,14,1310721,2,11,26,2,1,6,1,10,28,34,63,38,1, +10,28,10,3,6,10,4,8,1310721,2,7,26,2,1615567,12,8, +1,1690121,14,1,1310721,2,21,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1690169,16,1966081,1310721,4,1579223,12,1310721,2,3,26, +4,1310721,2,4,1552897,1587579,2,17,30,26,1310721,2,5,26,4,1587579, +2,121,40,3,36,1690283,16,1690275,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,1690227,1591079,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,1587561,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,1587571,2,10,3,6, +10,4,8,1310721,2,5,26,2,11,26,1587557,2,10,3,6,10, +4,8,1310721,2,5,26,2,13,26,1617885,2,10,3,6,10,4, +8,1587579,1,6,2,1,6,3,26,5,6,4,10,8,8,1, +1690535,14,1,1310721,2,7,26,1310721,4,18,1310721,2,15,28,1310721,4, +1310721,2,1835009,40,1690583,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4, +1310721,2,4,1,1310721,2,13,26,4,1587579,1,6,2,1,6,-1, +26,5,6,4,10,8,8,1310721,2,5,26,1552897,1587579,2,17,30, +26,10,3,6,10,4,8,1310721,2,11,26,1310721,2,5,26,2, +11,26,2,10,3,6,10,4,8,1618015,1,10,3,6,10,4, +8,1310721,2,3,26,2,1,40,3,36,1690765,16,1507841,1310721,2,3, +26,2,26,1618983,12,8,1310721,2,7,26,1567233,1310721,2,5,26,2, +13,26,2,26,10,3,6,10,4,8,1310721,2,9,26,1567233,1617885, +2,26,10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,9, +26,2,40,1690957,16,1310721,2,7,26,2,3,26,1618983,12,8,1310721, +2,7,26,1310721,2,7,26,2,7,26,7,1310721,2,7,26,2, +5,26,2,1310721,2,7,26,2,3,26,2,28,30,26,10,3, +6,10,4,8,1690833,14,1310721,2,11,26,2,1691081,14,108,101,97, +118,101,115,32,116,104,101,32,108,111,111,112,32,105,110,32, +100,105,102,102,101,114,101,110,116,32,115,116,97,116,101,115, +32,111,110,32,100,105,102,102,101,114,101,110,116,32,112,97, +116,104,115,0,1690971,1619711,12,8,1587569,1618015,2,1,10,40,10,3, +6,10,4,8,1310721,2,7,26,1567233,1310721,2,5,26,2,13,26, +2,26,10,3,6,10,4,8,1310721,2,7,26,2,1310721,2,9, +26,2,40,1691449,16,1310721,2,7,26,2,3,26,1310721,2,11,26, +2,1,1621295,12,1691321,16,1310721,2,7,26,2,1,26,2,1587549,2, +1594811,12,8,1310721,2,7,26,2,3,26,1310721,2,11,26,2,3, +1621295,12,8,1310721,2,13,26,1595029,12,1310721,2,13,26,2,1593879,12, +10,3,6,10,4,8,15,1594729,12,8,1691371,14,1310721,2,13,26, +1310721,2,7,26,2,1,26,2,1310721,2,13,26,2,1593879,12,10, +3,6,10,4,8,1310721,2,7,26,1310721,2,7,26,2,7,26, +7,1310721,2,7,26,2,5,26,2,1310721,2,7,26,2,3,26, +2,28,30,26,10,3,6,10,4,8,1691153,14,1310721,2,2,1, +40,3,36,1691483,16,1310721,2,2,1587549,2,1594811,12,8,1310721,2,3, +26,2,1,40,3,36,1691537,16,1507841,1310721,2,3,26,2,26,1310721, +2,11,26,2,3,1621295,12,8,1310721,2,13,26,2,1587549,2,1594231, +12,8,1617885,1310721,2,5,26,2,13,26,2,10,3,6,10,4, +8,1,1691595,14,1,1310721,2,15,26,1310721,4,18,1310721,2,13,28, +1310721,4,1310721,2,1835009,40,1691643,16,1966081,1310721,4,1579223,12,1587549,2,1310721, +2,4,3,1,10,28,1310721,2,7,26,4,1,1310721,2,11,26, +4,1663797,12,8,1604999,12,8,1310721,2,5,26,1615017,12,10,3,6, +10,4,8,1587599,2,1606959,12,8,1585289,2,3,28,1,6,1,10, +28,34,63,38,3,26,1691791,16,1585291,2,1,6,1,10,28,34, +63,38,1,10,28,1691793,14,1,1691919,16,1605859,12,8,1587511,2,9, +28,1,6,1,10,28,34,63,38,3,26,1691891,16,1587513,2,1587601, +2,28,1,6,1,10,28,34,63,38,3,26,1,6,1,10, +28,34,63,38,1,10,28,1691893,14,1,1691919,16,1310721,2,11,26, +3,10,3,6,10,4,8,1310721,2,9,26,1681059,12,10,3,6, +10,4,8,1663385,12,8,1310721,2,9,26,2,1613033,12,8,1587601,2, +1606959,12,8,1310721,2,3,26,1595029,12,10,3,6,10,4,8,17, +1594729,12,8,1310721,2,11,26,2,1,6,1,10,28,34,63,38, +3,26,1692071,16,1587569,2,1,6,1,10,28,34,63,38,1,10, +28,1692073,14,1,1692101,16,1310721,2,7,26,1615017,12,10,3,6,10, +4,8,1310721,2,2,1310721,2,5,26,2,1690135,12,8,1687243,12,8, +1310721,2,5,26,2,1621789,12,8,1310721,2,2,1594947,12,8,1310721,2, +3,26,2,1310721,2,7,26,2,1690549,12,8,1310721,2,5,26,2, +1615567,12,8,1,1692207,14,1,1310721,2,13,26,1310721,4,18,1310721,2, +19,28,1310721,4,1310721,2,1835009,40,1692255,16,1966081,1310721,4,1579223,12,1587557, +2,1310721,2,4,3,1,10,28,1310721,2,5,26,4,1,1310721,2, +17,26,4,1663797,12,8,1604999,12,8,1587599,2,1606959,12,8,1587561,1, +6,2,1,6,3,26,5,6,4,10,8,8,1587641,2,1606577,12, +1692367,16,1688971,12,8,1692483,14,1646981,12,1692387,16,3,1687403,12,8,1692483, +14,1587613,2,1606425,12,1,6,1,10,28,34,63,38,3,26,1692473, +16,1310721,2,15,26,1681059,12,10,3,6,10,4,8,1663385,12,8, +9,1594729,12,8,1310721,2,15,26,2,1632069,12,8,1587613,2,1606959,12, +8,1310721,2,3,26,1615017,12,10,3,6,10,4,8,1310721,2,7, +26,1587549,2,10,3,6,10,4,8,1587613,2,1606425,12,1,6,1, +10,28,34,63,38,3,26,1692803,16,1585289,2,3,28,1,6,1, +10,28,34,63,38,3,26,1692625,16,1585291,2,1,6,1,10,28, +34,63,38,1,10,28,1692627,14,1,1692753,16,1605859,12,8,1587511,2, +9,28,1,6,1,10,28,34,63,38,3,26,1692725,16,1587513,2, +1587613,2,28,1,6,1,10,28,34,63,38,3,26,1,6,1, +10,28,34,63,38,1,10,28,1692727,14,1,1692753,16,1310721,2,17, +26,3,10,3,6,10,4,8,1310721,2,15,26,1681059,12,10,3, +6,10,4,8,1663385,12,8,1310721,2,15,26,2,1613033,12,8,1692833, +14,3,1594643,12,8,1310721,2,17,26,3,10,3,6,10,4,8, +1587613,2,1606959,12,8,1310721,2,9,26,1595029,12,10,3,6,10,4, +8,17,1594729,12,8,1310721,2,17,26,2,1,6,1,10,28,34, +63,38,3,26,1692939,16,1587569,2,1,6,1,10,28,34,63,38, +1,10,28,1692941,14,1,1692969,16,1310721,2,5,26,1615017,12,10,3, +6,10,4,8,1310721,2,11,26,1595029,12,10,3,6,10,4,8, +15,1594729,12,8,1310721,2,13,26,1587549,2,10,3,6,10,4,8, +1587601,2,1606425,12,1,6,1,10,28,34,63,38,3,26,1693111,16, +1310721,2,15,26,1681059,12,10,3,6,10,4,8,1663385,12,8,9, +1594729,12,8,1310721,2,15,26,2,1632069,12,8,1587601,2,1606959,12,8, +1310721,2,7,26,2,1594947,12,8,1310721,2,11,26,2,1587549,2,1594811, +12,8,1310721,2,13,26,2,1310721,2,3,26,2,1690135,12,8,1687243, +12,8,1310721,2,3,26,2,1621789,12,8,1310721,2,13,26,2,1594947, +12,8,1310721,2,9,26,2,1310721,2,5,26,2,1690549,12,8,1310721, +2,3,26,2,1615567,12,8,1310721,2,2,1614445,12,8,1587561,1,6, +2,1,6,-1,26,5,6,4,10,8,8,1,1693311,14,1,1310721, +2,19,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40, +1693359,16,1966081,1310721,4,1579223,12,1663797,12,8,1604999,12,8,1587613,2,1606959, +12,8,1587579,2,1587581,2,10,40,3,36,1693485,16,1693471,14,98,114, +101,97,107,32,111,117,116,115,105,100,101,32,97,32,108,111, +111,112,32,111,114,32,97,32,115,119,105,116,99,104,0,1693405, +1591173,12,8,1,1693737,14,1310721,2,1552897,1587579,2,3,28,17,30,26, +10,3,6,10,4,8,1310721,2,2,9,26,2,1587571,2,28,1, +6,1,10,28,34,63,38,1,10,28,1693653,16,1693639,14,98,114, +101,97,107,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,1693565,1591173,12,8,1,1693737,14,1310721,2,2,5,26,2, +3,26,1,1613419,12,8,1587569,2,1693699,16,1595029,12,1618391,12,8,1693705, +14,1595029,12,8,15,1594729,12,8,1587569,1,10,3,6,10,4,8, +1,1693737,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28,1310721, +4,1310721,2,1835009,40,1693785,16,1966081,1310721,4,1579223,12,1587579,2,3,28, +1310721,2,4,1663797,12,8,1604999,12,8,1587613,2,1606959,12,8,1310721,2, +2,1587581,2,40,3,36,1693913,16,1552897,1310721,2,2,17,30,26,2, +3,1,10,28,28,1,6,1,10,28,34,63,38,3,26,1, +6,1,10,28,34,63,38,1,10,28,1693915,14,1,1693953,16,1310721, +2,1,6,2,1,6,-1,26,5,6,4,10,8,8,1693821,14, +1310721,2,2,1587581,2,40,1694035,16,1694021,14,99,111,110,116,105,110, +117,101,32,111,117,116,115,105,100,101,32,97,32,108,111,111, +112,0,1693973,1591173,12,8,1,1694311,14,1310721,2,3,26,1552897,1310721,2, +2,17,30,26,10,3,6,10,4,8,1310721,2,3,26,2,9, +26,2,1587571,2,28,1,6,1,10,28,34,63,38,1,10,28, +1694215,16,1694201,14,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,1694121,1591173,12,8, +1,1694311,14,1310721,2,3,26,2,7,26,2,1621789,12,8,1310721,2, +3,26,2,5,26,2,3,26,1,1613419,12,8,1310721,2,3,26, +2,1,26,2,1594947,12,8,1587569,1,10,3,6,10,4,8,1, +1694311,14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1694359,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4, +1310721,2,4,1587557,2,1310721,2,5,26,4,1310721,2,2,1615649,12,8, +1587569,1310721,2,3,26,2,10,3,6,10,4,8,1587561,1,6,2, +1,6,3,26,5,6,4,10,8,8,1587605,2,1606425,12,1,6, +1,10,28,34,63,38,3,26,1694539,16,1587661,2,1606577,12,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1694541,14,1,1694599,16,1587663,2,1606577,12,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1694601,14,1,1694683,16,1585289,2,1,28,1,6,1,10,28,34, +63,38,3,26,1694673,16,1694661,14,109,105,115,115,105,110,103,32, +125,0,1694641,1591557,12,8,1694683,14,1686451,12,8,1694453,14,1310721,2,5, +26,2,1614445,12,8,1587561,1,6,2,1,6,-1,26,5,6,4, +10,8,8,1587569,2,1694753,16,1595029,12,1618391,12,8,15,1594729,12,8, +1587569,1,10,3,6,10,4,8,1,1694777,14,1,1310721,2,7,26, +1310721,4,18,1310721,2,23,28,1310721,4,1310721,2,1835009,40,1694825,16,1966081, +1310721,4,1579223,12,1587557,2,1310721,2,4,3,1,10,28,1310721,2,11, +26,4,3,1,10,28,1310721,2,21,26,4,1663797,12,8,1604999,12, +8,1587599,2,1606959,12,8,1310721,2,5,26,1681059,12,10,3,6,10, +4,8,1663385,12,8,1310721,2,5,26,2,1613033,12,8,1587601,2,1606959, +12,8,1587561,1,6,2,1,6,3,26,5,6,4,10,8,8, +1310721,2,3,26,1,1611819,12,10,3,6,10,4,8,1587563,1,6, +2,1,6,3,26,5,6,4,10,8,8,1467905,1310721,2,3,26, +2,26,2,1595563,12,8,5,1594729,12,8,1310721,2,9,26,1587569,2, +10,3,6,10,4,8,1310721,2,7,26,1615017,12,10,3,6,10, +4,8,3,1,10,28,1310721,2,7,26,2,1690135,12,8,1587603,2, +1606959,12,8,1587605,2,1606425,12,1,6,1,10,28,34,63,38,3, +26,1695849,16,1585289,2,1,28,1,6,1,10,28,34,63,38,3, +26,1695243,16,1695231,14,109,105,115,115,105,110,103,32,125,0,1695211, +1591557,12,8,1695849,14,1587661,2,1606577,12,1695565,16,1604999,12,8,1310721,2, +17,26,1,10,3,6,10,4,8,3,1695453,16,1310721,2,19,26, +1685483,12,10,3,6,10,4,8,1467905,1310721,2,3,26,2,26,2, +1595563,12,8,3,1594729,12,8,1310721,2,19,26,2,1594643,12,8,29, +1594729,12,8,1310721,2,17,26,1595029,12,1310721,2,17,26,2,1593879,12, +10,3,6,10,4,8,17,1594729,12,8,1587611,2,1606729,12,1,6, +1,10,28,34,63,38,3,26,1695449,16,1695453,14,1695283,14,1587627,2, +1606959,12,8,1310721,2,15,26,1595029,12,10,3,6,10,4,8,15, +1594729,12,8,1310721,2,17,26,2,1587549,2,1594231,12,8,1310721,2,7, +26,2,1310721,2,9,26,2,1694325,12,8,1310721,2,15,26,2,1587549, +2,1594811,12,8,1695845,14,1587663,2,1606577,12,1695783,16,1604999,12,8,1587627, +2,1606959,12,8,1310721,2,11,26,2,1,40,3,36,1695677,16,1695669, +14,97,32,115,119,105,116,99,104,32,104,97,115,32,111,110, +101,32,100,101,102,97,117,108,116,0,1695619,1591173,12,8,1310721,2, +13,26,1595029,12,10,3,6,10,4,8,15,1594729,12,8,1310721,2, +11,26,1587549,2,10,3,6,10,4,8,1310721,2,7,26,2,1310721, +2,9,26,2,1694325,12,8,1310721,2,13,26,2,1587549,2,1594811,12, +8,1695845,14,1695837,14,101,120,112,101,99,116,101,100,32,99,97, +115,101,32,111,114,32,100,101,102,97,117,108,116,0,1695787,1591557, +12,8,1695143,14,1604999,12,8,1310721,2,7,26,2,1615649,12,8,1587569, +1310721,2,9,26,2,10,3,6,10,4,8,1310721,2,11,26,2, +1,40,3,36,1695959,16,1310721,2,11,26,2,1594947,12,8,3,1, +10,28,3,1,10,28,1690549,12,8,1696017,14,1310721,2,21,26,1595029, +12,10,3,6,10,4,8,15,1594729,12,8,1310721,2,21,26,2, +1310721,2,7,26,2,1690549,12,8,1310721,2,7,26,2,1615567,12,8, +1310721,2,2,1614445,12,8,1587561,1,6,2,1,6,-1,26,5,6, +4,10,8,8,1,1696081,14,1,1310721,2,23,26,1310721,4,18,1310721, +2,3,28,1310721,4,1310721,2,1835009,40,1696129,16,1966081,1310721,4,1579223,12, +1663797,12,8,1604999,12,8,1587577,2,1,6,1,10,28,34,63,38, +3,26,1696233,16,1696225,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, +1696173,1591173,12,8,1587571,2,1696329,16,1696321,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, +1696245,1591173,12,8,1587613,2,1606425,12,1696371,16,1,1594643,12,8,1310721,2, +1,10,3,6,10,4,8,1696703,14,1310721,2,1681059,12,10,3,6, +10,4,8,1663385,12,8,1587597,2,1587695,2,28,1,6,1,10,28, +34,63,38,3,26,1696481,16,1696461,14,114,101,116,117,114,110,32, +118,97,108,117,101,0,1696435,1587695,2,1587699,2,1643225,12,8,1696599,14, +1587597,2,1696547,16,1587597,2,1587699,2,1639563,12,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1696549, +14,1,1696599,16,1696583,14,114,101,116,117,114,110,32,118,97,108, +117,101,0,1696557,1587597,2,1587699,2,1643225,12,8,1587769,2,1696637,16,1587597, +2,1,6,1,10,28,34,63,38,1,10,28,1696639,14,1,1696677, +16,1587597,2,1658673,12,1,6,1,10,28,34,63,38,1,10,28, +1696679,14,1,1696703,16,1587597,2,1594643,12,8,1590517,2,1595409,12,8,1587613, +2,1606959,12,8,1310721,2,2,1630339,12,8,3,1,1613419,12,8,1587573, +1587549,2,1587573,2,1593879,12,10,3,6,10,4,8,2097153,3,28,1594643, +12,8,15,1594729,12,8,1587569,1,10,3,6,10,4,8,1,1696805, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721, +2,1835009,40,1696853,16,1966081,1310721,4,1579223,12,1663797,12,8,1604999,12,8, +1587603,2,1606425,12,1,6,1,10,28,34,63,38,3,26,1696943,16, +1587773,3,10,3,6,10,4,8,3,1687403,12,8,1587773,1,10,3, +6,10,4,8,1,1697879,14,1587769,2,1696957,16,3,1697003,14,1587577,2, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1697015,16,1686987,12,1697879,14,1310721,2,1587549,2,5, +26,10,3,6,10,4,8,1310721,2,2,1594643,12,8,15,1594729,12, +8,1587769,3,10,3,6,10,4,8,1595939,12,8,1310721,2,7,26, +1587557,2,10,3,6,10,4,8,1310721,2,9,26,1587557,2,10,3, +6,10,4,8,1310721,2,3,26,1587559,2,10,3,6,10,4,8, +1310721,2,3,26,2,1310721,2,9,26,2,40,1697289,16,1558017,1310721,2, +3,26,2,26,2,33,32,1697251,16,1310721,2,3,26,2,1596201,12, +8,1310721,2,3,26,2,1596641,12,8,1310721,2,3,26,2,1597105,12, +8,1310721,2,3,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1697153,14,1686987,12,8,1587769,1,10,3,6,10,4,8,1589305, +2,21,40,1697527,16,1310721,2,5,26,1587905,1589305,2,135,30,26,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,1587549,2,10,3, +6,10,4,8,1310721,2,5,26,2,5,26,1587903,2,10,3,6, +10,4,8,1310721,2,5,26,2,7,26,1587775,1587903,2,1574491,12,8, +1310721,2,5,26,2,71,26,1587839,1587903,2,1574491,12,8,1589305,1,6, +2,1,6,3,26,5,6,4,10,8,8,1587557,1310721,2,7,26, +2,10,3,6,10,4,8,1310721,2,3,26,1587559,2,10,3,6, +10,4,8,1310721,2,3,26,2,1310721,2,9,26,2,40,1697871,16, +1558017,1310721,2,3,26,2,26,1558017,1310721,2,3,26,2,26,2,1558017, +1310721,2,3,26,2,26,2,3585,32,28,10,3,6,10,4,8, +1589487,1310721,2,3,26,2,26,1,10,3,6,10,4,8,1558017,1310721, +2,3,26,2,26,2,33,32,1697763,16,1556993,1310721,2,3,26,2, +26,2,1658673,12,1,6,1,10,28,34,63,38,1,10,28,1697765, +14,1,1697833,16,1310721,2,3,26,2,1595671,12,8,3,1594729,12,8, +1556993,1310721,2,3,26,2,26,2,1594643,12,8,1590517,2,1595409,12,8, +9,1594729,12,8,1310721,2,3,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1697575,14,1,1697879,14,1,1310721,2,11,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1697927,16,1966081,1310721, +4,1579223,12,1587565,2,1310721,2,4,1663797,12,8,1604999,12,8,1587565,1, +10,3,6,10,4,8,1687243,12,8,1587565,1310721,2,2,10,3,6, +10,4,8,1,1697999,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +21,28,1310721,4,1310721,2,1835009,40,1698047,16,1966081,1310721,4,1579223,12,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,1587603,2,1606959,12,8,1587605,2,1606425,12, +1,6,1,10,28,34,63,38,3,26,1700323,16,1585289,2,1,28, +1,6,1,10,28,34,63,38,3,26,1698259,16,1698251,14,117,110, +116,101,114,109,105,110,97,116,101,100,32,97,115,109,32,98, +108,111,99,107,0,1698205,1591557,12,8,1585289,2,3,28,1,6,1, +10,28,34,63,38,3,26,1698311,16,1585291,2,1594643,12,8,1604999,12, +8,1698137,14,1585289,2,7,28,1,6,1,10,28,34,63,38,3, +26,1698363,16,1585291,2,1598105,12,8,1604999,12,8,1698137,14,1587629,2,1606425, +12,1698481,16,1604999,12,8,1585289,2,3,28,1,6,1,10,28,34, +63,38,1,10,28,1698461,16,1698453,14,35,32,110,101,101,100,115, +32,97,32,110,117,109,98,101,114,0,1698419,1591557,12,8,1585291,2, +1594449,12,8,1604999,12,8,1698137,14,1587631,2,1606425,12,1698603,16,1604999,12, +8,1585289,2,3,28,1,6,1,10,28,34,63,38,3,26,1698561, +16,1585293,2,1,6,1,10,28,34,63,38,1,10,28,1698563,14, +1,1698591,16,1,1585291,2,28,1594643,12,8,1604999,12,8,1698599,14,29, +1594729,12,8,1698137,14,1587627,2,1606425,12,1698793,16,1604999,12,8,1310721,2, +2,129,40,3,36,1698691,16,1698683,14,116,111,111,32,109,97,110, +121,32,97,115,109,32,108,97,98,101,108,115,0,1698643,1591079,12, +8,1310721,2,13,26,2,1310721,2,2,26,1607249,12,10,3,6,10, +4,8,1310721,2,15,26,2,1310721,2,2,26,1587549,2,10,3,6, +10,4,8,1310721,2,1,6,2,1,6,3,26,5,6,4,10, +8,8,1698137,14,1585291,2,1,26,2,1698863,16,1585291,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,1698865,14,1,1698935,16,1310721,2,9,26,1585291,2, +1,26,2,1608541,12,10,3,6,10,4,1,40,3,36,1,6, +1,10,28,34,63,38,1,10,28,1698937,14,1,1698967,16,1310721,2, +9,26,2,1594729,12,8,1604999,12,8,1698137,14,1585289,2,5,28,1, +6,1,10,28,34,63,38,1,10,28,1699047,16,1699039,14,98,97, +100,32,116,111,107,101,110,32,105,110,32,97,115,109,0,1699005, +1591557,12,8,1310721,2,5,26,1585291,2,1611615,12,10,3,6,10,4, +8,1310721,2,5,26,2,1,40,3,36,1699143,16,1558017,1310721,2,5, +26,2,26,2,33,32,1,6,1,10,28,34,63,38,1,10, +28,1699145,14,1,1699211,16,1473025,1310721,2,5,26,2,26,2,1,6, +1,10,28,34,63,38,3,26,1,6,1,10,28,34,63,38, +1,10,28,1699213,14,1,1699291,16,1699283,14,97,115,109,32,99,97, +110,39,116,32,114,101,97,99,104,32,97,110,32,111,51,32, +118,97,114,105,97,98,108,101,0,1699221,1591173,12,8,1310721,2,5, +26,2,1,40,3,36,1699373,16,1472001,1310721,2,5,26,2,26,3, +10,3,6,10,4,8,1467905,1310721,2,5,26,2,26,2,1595563,12, +8,1604999,12,8,1698137,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,1699567,16,1310721,2,13,26,2,1310721, +2,5,26,2,26,2,1585291,2,28,1,6,1,10,28,34,63, +38,3,26,1699529,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,1699423,14,1310721,2,7,26,2,1,40,3,36, +1699629,16,1310721,2,15,26,2,1310721,2,7,26,2,26,2,1594643,12, +8,1604999,12,8,1698137,14,1310721,2,11,26,1585291,2,1593303,12,10,3, +6,10,4,8,1310721,2,11,26,2,1,40,3,36,1699745,16,1417729, +1310721,2,11,26,2,26,2,13,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1699747,14, +1,1699787,16,45,1425921,1310721,2,11,26,2,26,2,26,1594729,12,8, +1604999,12,8,1698137,14,1310721,2,11,26,2,1,40,3,36,1699877,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, +1699879,14,1,1699951,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,1699953,14,1,1699989,16,1425921,1310721,2,11,26,2, +26,2,1594643,12,8,1604999,12,8,1698137,14,1310721,2,11,26,2,1, +40,3,36,1700077,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,1700079,14,1,1700109,16,1310721,2,11,26,2,1595235,12, +8,1604999,12,8,1698137,14,1310721,2,3,26,2,501,40,3,36,1700203, +16,1700195,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,1700135,1591079,12,8,1310721,2,17,26,2,1310721,2,3,26,2,26, +1585291,2,10,3,6,10,4,8,1310721,2,19,26,2,1310721,2,3, +26,2,26,1595029,12,10,3,6,10,4,8,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1604999,12,8,1698137, +14,1604999,12,8,1310721,2,5,26,1,10,3,6,10,4,8,1310721, +2,5,26,2,1310721,2,3,26,2,40,1700777,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,1700591,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,1700553,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,1700427,14,1310721,2,7,26,2,1,40,1700685,16, +1310721,2,17,26,2,1310721,2,5,26,2,26,2,1700677,14,117,110, +107,110,111,119,110,32,110,97,109,101,32,105,110,32,97,115, +109,0,1700637,1591343,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,1594811,12, +8,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1700351,14,1,1700785,14,1,1310721,2,21,26,1310721,4,18,1310721, +2,1,28,1310721,4,1310721,2,1835009,40,1700833,16,1966081,1310721,4,1579223,12, +1604999,12,8,1698013,12,8,1587595,1,10,3,6,10,4,8,1,1700869, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721, +2,1835009,40,1700917,16,1966081,1310721,4,1579223,12,1,1310721,2,4,1,1310721, +2,3,26,4,1587603,2,1606425,12,1,6,1,10,28,34,63,38, +3,26,1701003,16,1700995,14,101,120,112,101,99,116,101,100,32,123, +0,1700973,1591557,12,8,1604999,12,8,3,1701425,16,1585289,2,1,28,1, +6,1,10,28,34,63,38,3,26,1701097,16,1701089,14,117,110,116, +101,114,109,105,110,97,116,101,100,32,113,117,111,116,101,0, +1701051,1591557,12,8,1587603,2,1606425,12,1701143,16,1310721,2,3,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1587605,2,1606425,12,1701227, +16,1310721,2,3,26,2,1,6,1,10,28,34,63,38,3,26, +1701193,16,1701425,14,1310721,2,3,26,1,6,2,1,6,-1,26,5, +6,4,10,8,8,1310721,2,2,5401,40,3,36,1701287,16,1701279,14, +113,117,111,116,101,32,116,111,111,32,108,111,110,103,0,1701249, +1591079,12,8,1524225,1310721,2,2,7,30,26,1585289,2,10,3,6,10, +4,8,1524225,1310721,2,2,7,30,3,26,26,1585291,2,10,3,6, +10,4,8,1524225,1310721,2,2,7,30,5,26,26,1585295,2,10,3, +6,10,4,8,1310721,2,1,6,2,1,6,3,26,5,6,4, +10,8,8,1604999,12,8,1701009,14,1604999,12,8,1310721,2,5,26,1310721, +2,2,7,30,3,26,1580219,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,7,30,1574491,12,8,1310721,2, +5,26,2,1701549,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7, +28,1310721,4,1310721,2,1835009,40,1701597,16,1966081,1310721,4,1579223,12,1310721,2, +4,1310721,2,2,1,26,2,7,30,3,26,1310721,2,3,26,4, +1310721,2,3,26,2,1580219,12,1310721,2,5,26,4,1310721,2,5,26, +2,1310721,2,2,1310721,2,3,26,2,1574491,12,8,1310721,2,5,26, +2,1701705,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721, +4,1310721,2,1835009,40,1701753,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721, +2,2,1,26,2,7,30,3,26,1310721,2,3,26,4,1310721,2, +3,26,2,1580219,12,1310721,2,5,26,4,1310721,2,5,26,2,1310721, +2,2,1310721,2,3,26,2,1574491,12,8,1310721,2,5,26,2,1701861, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721, +2,1835009,40,1701909,16,1966081,1310721,4,1579223,12,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,1702027,16,1310721,2,2,1310721,2,5,26,2,26,2,1594449, +12,8,1310721,2,5,26,1,6,2,1,6,3,26,5,6,4, +10,8,8,1701937,14,1,1702035,14,1,1310721,2,7,26,1310721,4,18, +1310721,2,9,28,1310721,4,1310721,2,1835009,40,1702083,16,1966081,1310721,4,1579223, +12,1604999,12,8,1310721,2,1700883,12,10,3,6,10,4,8,1310721,2, +3,26,1595029,12,10,3,6,10,4,8,15,1594729,12,8,1310721,2, +5,26,1587549,2,10,3,6,10,4,8,1310721,2,7,26,1310721,2, +2,1,26,2,7,30,3,26,10,3,6,10,4,8,1310721,2, +2,1310721,2,7,26,2,1701875,12,8,1310721,2,2,1580973,12,8,1310721, +2,3,26,2,1587549,2,1594811,12,8,1310721,2,5,26,2,1594643,12, +8,1587675,2,1595409,12,8,1587595,3,10,3,6,10,4,8,1,1702309, +14,1,1310721,2,9,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721, +2,1835009,40,1702357,16,1966081,1310721,4,1579223,12,1310721,2,4,1,1310721,2, +3,26,4,5,1310721,2,2,1,1,1598871,12,8,1604999,12,8,1585289, +2,1,28,1,6,1,10,28,34,63,38,1,10,28,1702653,16, +1310721,2,3,26,2,5401,40,3,36,1702499,16,1702491,14,116,111,111, +32,109,97,110,121,32,116,111,107,101,110,115,0,1702459,1591079,12, +8,1524225,1310721,2,3,26,2,7,30,26,1585289,2,10,3,6,10, +4,8,1524225,1310721,2,3,26,2,7,30,3,26,26,1585291,2,10, +3,6,10,4,8,1524225,1310721,2,3,26,2,7,30,5,26,26, +1585295,2,10,3,6,10,4,8,1310721,2,3,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1604999,12,8,1702399,14,1600299,12, +8,1310721,2,5,26,1310721,2,3,26,2,7,30,3,26,1580219,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,7,30,1574491,12,8,1310721,2,5,26,2,1702789, +14,1,1310721,2,7,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721, +2,1835009,40,1702837,16,1966081,1310721,4,1579223,12,1310721,2,4,3,1310721,2, +2,3,3,1598871,12,8,1604999,12,8,1,1702875,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1702923,16, +1966081,1310721,4,1579223,12,8181,1310721,2,4,8181,1580219,12,1310721,2,3,26, +4,1,1310721,2,5,26,4,1573381,12,1,6,1,10,28,34,63, +38,3,26,1703481,16,1310721,2,7,26,1573325,12,511,32,10,3,6, +10,4,8,1310721,2,7,26,2,193,28,1,6,1,10,28,34, +63,38,3,26,1703057,16,1703481,14,1310721,2,5,26,2,5,38,5, +26,1310721,2,2,40,3,36,1703245,16,1310721,2,9,26,1310721,2,2, +1310721,2,2,26,13,26,1580219,12,10,3,6,10,4,8,1310721,2, +9,26,2,1310721,2,3,26,2,1310721,2,2,1574491,12,8,1310721,2, +3,26,2,1580973,12,8,1310721,2,3,26,1310721,2,9,26,2,10, +3,6,10,4,8,1310721,2,1310721,2,2,1310721,2,2,26,13,26, +10,3,6,10,4,8,1310721,2,11,26,1310721,2,5,26,2,5, +38,10,3,6,10,4,8,1310721,2,5,26,2,7,32,1,6, +1,10,28,34,63,38,3,26,1703353,16,1310721,2,3,26,2,1310721, +2,11,26,2,26,1,10,3,6,10,4,8,1310721,2,3,26, +2,1310721,2,11,26,2,26,1310721,2,3,26,2,1310721,2,11,26, +2,26,2,1310721,2,7,26,2,1310721,2,5,26,2,7,32,17, +30,48,34,10,3,6,10,4,8,1310721,2,5,26,1,6,2, +1,6,3,26,5,6,4,10,8,8,1702959,14,1310721,2,3,26, +2,1310721,2,5,26,2,5,38,26,1310721,2,3,26,2,1310721,2, +5,26,2,5,38,26,2,1574901,1310721,2,5,26,2,7,32,17, +30,26,2,3,28,32,10,3,6,10,4,8,1310721,2,5,26, +2,7,32,1,28,1,6,1,10,28,34,63,38,3,26,1703659, +16,1310721,2,3,26,2,1310721,2,5,26,2,5,38,26,1,10, +3,6,10,4,8,1310721,2,3,26,2,1310721,2,5,26,2,5, +38,3,26,26,1,10,3,6,10,4,8,1310721,2,3,26,2, +1703719,14,1,1310721,2,13,26,1310721,4,18,1310721,2,3,28,1310721,4, +1310721,2,1835009,40,1703767,16,1966081,1310721,4,1579223,12,1,1310721,2,4,1585289, +2,1,28,1,6,1,10,28,34,63,38,1,10,28,1703975,16, +1587729,2,1606425,12,1703855,16,1310721,2,1,6,2,1,6,3,26,5, +6,4,10,8,8,1703939,14,1587731,2,1606425,12,1703901,16,1310721,2,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1703939,14,1587733,2, +1606425,12,1703939,16,1310721,2,1310721,2,2,5,28,10,3,6,10,4, +8,1604999,12,8,1310721,2,2,1,10,40,3,36,1703971,16,1,1703983, +14,1703775,14,1,1703983,14,1,1310721,2,3,26,1310721,4,18,1310721,2, +17,28,1310721,4,1310721,2,1835009,40,1704031,16,1966081,1310721,4,1579223,12,1310721, +2,5,26,4,1310721,2,3,26,4,1310721,2,4,1,1310721,2,7, +26,4,1,1310721,2,9,26,4,1,1310721,2,11,26,4,1604999,12, +8,1587601,2,1606425,12,1,6,1,10,28,34,63,38,3,26,1704843, +16,1310721,2,7,26,3,10,3,6,10,4,8,1310721,2,13,26, +3,10,3,6,10,4,8,1585289,2,1,28,1,6,1,10,28, +34,63,38,1,10,28,1704749,16,1587599,2,1606425,12,1704259,16,1310721,2, +13,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1704739, +14,1587601,2,1606425,12,1704347,16,1310721,2,13,26,1,6,2,1,6, +-1,26,5,6,4,10,8,8,1310721,2,13,26,2,1,6,1, +10,28,34,63,38,3,26,1704343,16,1704749,14,1704739,14,1310721,2,13, +26,2,3,28,1,6,1,10,28,34,63,38,3,26,1704419,16, +1587611,2,1606425,12,1,6,1,10,28,34,63,38,1,10,28,1704421, +14,1,1704579,16,1310721,2,7,26,2,25,10,40,3,36,1704519,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,5,28,48,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,11,26,1,10,3,6,10,4,8,1704739, +14,1310721,2,13,26,2,3,28,1,6,1,10,28,34,63,38, +3,26,1704651,16,1587637,2,1606425,12,1,6,1,10,28,34,63,38, +1,10,28,1704653,14,1,1704739,16,1604999,12,8,1587653,2,1606577,12,1704701, +16,1310721,2,11,26,3,10,3,6,10,4,8,1704735,14,1587655,2, +1606577,12,1704735,16,1310721,2,11,26,5,10,3,6,10,4,8,1704175, +14,1604999,12,8,1704175,14,1310721,2,7,26,2,25,10,40,3,36, +1704843,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,5,28,48,26,10, +3,6,10,4,8,1604999,12,8,1587603,2,1606425,12,1,6,1,10, +28,34,63,38,3,26,1704935,16,1587613,2,1606425,12,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1704937,14,1,1704947,16,1,1705441,14,1310721,2,15,26,1310721,2,3, +26,2,1593303,12,10,3,6,10,4,8,1310721,2,15,26,2,1, +40,1705005,16,3,1705043,14,1310721,2,15,26,2,1585221,2,40,1,6, +1,10,28,34,63,38,1,10,28,1705053,16,3,1705117,14,1417729,1310721, +2,15,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,1705127,16, +3,1705169,14,1442305,1310721,2,15,26,2,26,2,3,32,1,6,1, +10,28,34,63,38,1,10,28,1705207,16,1310721,2,15,26,1310721,2, +3,26,2,1595111,12,10,3,6,10,4,8,1442305,1310721,2,15,26, +2,26,2,5,32,1,6,1,10,28,34,63,38,3,26,1705373, +16,1434113,1310721,2,15,26,2,26,1310721,2,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,15,26,2,26,1442305,1310721,2,15, +26,2,26,2,5,34,513,34,10,3,6,10,4,8,1310721,2, +5,26,2,1705433,16,1442305,1310721,2,15,26,2,26,1442305,1310721,2,15, +26,2,26,2,1025,34,10,3,6,10,4,8,1,1705441,14,1, +1310721,2,17,26,1310721,4,18,1310721,2,19,28,1310721,4,1310721,2,1835009, +40,1705489,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4, +1,1310721,2,5,26,4,1590585,2,1310721,2,7,26,4,1590583,2,1310721, +2,9,26,4,1,1310721,2,11,26,4,1,1310721,2,13,26,4, +1587703,1,6,2,1,6,3,26,5,6,4,10,8,8,1310721,2, +2,1310721,2,3,26,2,1,1,1598871,12,8,1604999,12,8,1585289,2, +1,28,1,6,1,10,28,34,63,38,1,10,28,1706783,16,1587603, +2,1606425,12,1705713,16,1310721,2,5,26,1,6,2,1,6,3,26, +5,6,4,10,8,8,1706773,14,1587605,2,1606425,12,1705807,16,1310721,2, +5,26,1,6,2,1,6,-1,26,5,6,4,10,8,8,1310721, +2,11,26,1,10,3,6,10,4,8,1310721,2,13,26,1,10, +3,6,10,4,8,1706773,14,1310721,2,5,26,2,1,10,40,3, +36,1706773,16,1587613,2,1606425,12,1705891,16,1310721,2,11,26,1,10,3, +6,10,4,8,1310721,2,13,26,1,10,3,6,10,4,8,1706773, +14,1587637,2,1606425,12,1706029,16,1605859,12,8,1587511,2,5,28,1,6, +1,10,28,34,63,38,3,26,1705997,16,1587513,2,1587657,2,28,1, +6,1,10,28,34,63,38,3,26,1,6,1,10,28,34,63, +38,1,10,28,1705999,14,1,1706025,16,1310721,2,11,26,3,10,3, +6,10,4,8,1706773,14,1587759,2,1606577,12,1706067,16,1310721,2,13,26, +3,10,3,6,10,4,8,1706773,14,1585289,2,5,28,1,6,1, +10,28,34,63,38,3,26,1706773,16,1605859,12,8,1587511,2,9,28, +1,6,1,10,28,34,63,38,3,26,1706193,16,1587513,2,1587599,2, +28,1,6,1,10,28,34,63,38,3,26,1,6,1,10,28, +34,63,38,1,10,28,1706195,14,1,1706313,16,1310721,2,15,26,1585291, +2,10,3,6,10,4,8,1604999,12,8,1310721,2,11,26,2,1310721, +2,15,26,2,1310721,2,13,26,2,1703997,12,8,1310721,2,11,26, +1,10,3,6,10,4,8,1310721,2,13,26,1,10,3,6,10, +4,8,1705629,14,1587511,2,9,28,1,6,1,10,28,34,63,38, +3,26,1706401,16,1587513,2,1587729,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1706403,14, +1,1706773,16,1310721,2,15,26,1585291,2,10,3,6,10,4,8,1604999, +12,8,1310721,2,17,26,1,10,3,6,10,4,8,1585289,2,1, +28,1,6,1,10,28,34,63,38,1,10,28,1706677,16,1587729,2, +1606425,12,1706543,16,1310721,2,17,26,1,6,2,1,6,3,26,5, +6,4,10,8,8,1706639,14,1587731,2,1606425,12,1706593,16,1310721,2,17, +26,1,6,2,1,6,-1,26,5,6,4,10,8,8,1706639,14, +1587733,2,1606425,12,1706639,16,1310721,2,17,26,1310721,2,17,26,2,5, +28,10,3,6,10,4,8,1604999,12,8,1310721,2,17,26,2,1, +10,40,3,36,1706673,16,1706677,14,1706459,14,1587599,2,1606425,12,1706769,16, +1310721,2,11,26,2,1310721,2,15,26,2,1310721,2,13,26,2,1703997, +12,8,1310721,2,11,26,1,10,3,6,10,4,8,1310721,2,13, +26,1,10,3,6,10,4,8,1705629,14,1604999,12,8,1705629,14,1600299, +12,8,1587703,1,6,2,1,6,-1,26,5,6,4,10,8,8, +1590585,1310721,2,7,26,2,10,3,6,10,4,8,1590583,1310721,2,9, +26,2,10,3,6,10,4,8,1,1706873,14,1,1310721,2,19,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1706921,16,1966081, +1310721,4,1579223,12,1702889,12,1310721,2,4,7,1310721,2,2,1705455,12,8, +7,1310721,2,2,1,1,1598871,12,8,1604999,12,8,1722469,12,8,1585221, +2,1722569,12,8,1600299,12,8,1310721,2,2,1580973,12,8,1,1707011,14, +1,1310721,2,3,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1707059,16,1966081,1310721,4,1579223,12,1548801,1587583,2,49,30,26,1310721, +2,4,1587583,2,61,40,3,36,1707159,16,1707151,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,1707097,1591079,12,8,1587583,1,6,2,1, +6,3,26,5,6,4,10,8,8,1310721,2,2,1,26,1587557,2, +10,3,6,10,4,8,1310721,2,2,3,26,1587559,2,10,3,6, +10,4,8,1310721,2,2,5,26,1587561,2,10,3,6,10,4,8, +1310721,2,2,7,26,1587563,2,10,3,6,10,4,8,1310721,2,2, +9,26,1587565,2,10,3,6,10,4,8,1310721,2,2,11,26,1587567, +2,10,3,6,10,4,8,1310721,2,2,13,26,1587569,2,10,3, +6,10,4,8,1310721,2,2,15,26,1587571,2,10,3,6,10,4, +8,1310721,2,2,17,26,1587573,2,10,3,6,10,4,8,1310721,2, +2,19,26,1587575,2,10,3,6,10,4,8,1310721,2,2,21,26, +1587577,2,10,3,6,10,4,8,1310721,2,2,23,26,1587579,2,10, +3,6,10,4,8,1310721,2,2,25,26,1587581,2,10,3,6,10, +4,8,1310721,2,2,27,26,1587587,2,10,3,6,10,4,8,1310721, +2,2,29,26,1587589,2,10,3,6,10,4,8,1310721,2,2,31, +26,1587591,2,10,3,6,10,4,8,1310721,2,2,33,26,1587593,2, +10,3,6,10,4,8,1310721,2,2,35,26,1587595,2,10,3,6, +10,4,8,1310721,2,2,37,26,1587585,2,10,3,6,10,4,8, +1310721,2,2,39,26,1587597,2,10,3,6,10,4,8,1310721,2,2, +41,26,1587721,2,10,3,6,10,4,8,1310721,2,2,43,26,1587699, +2,10,3,6,10,4,8,1310721,2,2,45,26,1587705,5,1574491,12, +8,1,1707787,14,1,1310721,2,3,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1707835,16,1966081,1310721,4,1579223,12,1587583,1,6, +2,1,6,-1,26,5,6,4,10,8,8,1310721,2,1548801,1587583,2, +49,30,26,10,3,6,10,4,8,1587557,1310721,2,2,1,26,2, +10,3,6,10,4,8,1587559,1310721,2,2,3,26,2,10,3,6, +10,4,8,1587561,1310721,2,2,5,26,2,10,3,6,10,4,8, +1587563,1310721,2,2,7,26,2,10,3,6,10,4,8,1587565,1310721,2, +2,9,26,2,10,3,6,10,4,8,1587567,1310721,2,2,11,26, +2,10,3,6,10,4,8,1587569,1310721,2,2,13,26,2,10,3, +6,10,4,8,1587571,1310721,2,2,15,26,2,10,3,6,10,4, +8,1587573,1310721,2,2,17,26,2,10,3,6,10,4,8,1587575,1310721, +2,2,19,26,2,10,3,6,10,4,8,1587577,1310721,2,2,21, +26,2,10,3,6,10,4,8,1587579,1310721,2,2,23,26,2,10, +3,6,10,4,8,1587581,1310721,2,2,25,26,2,10,3,6,10, +4,8,1587587,1310721,2,2,27,26,2,10,3,6,10,4,8,1587589, +1310721,2,2,29,26,2,10,3,6,10,4,8,1587591,1310721,2,2, +31,26,2,10,3,6,10,4,8,1587593,1310721,2,2,33,26,2, +10,3,6,10,4,8,1587595,1310721,2,2,35,26,2,10,3,6, +10,4,8,1587585,1310721,2,2,37,26,2,10,3,6,10,4,8, +1587597,1310721,2,2,39,26,2,10,3,6,10,4,8,1587721,1310721,2, +2,41,26,2,10,3,6,10,4,8,1587699,1310721,2,2,43,26, +2,10,3,6,10,4,8,1587705,1310721,2,2,45,26,5,1574491,12, +8,1,1708491,14,1,1310721,2,3,26,1310721,4,18,1310721,2,5,28, +1310721,4,1310721,2,1835009,40,1708539,16,1966081,1310721,4,1579223,12,1310721,2,3, +26,4,1310721,2,4,1587559,1587557,2,10,3,6,10,4,8,1587561,3, +10,3,6,10,4,8,1587563,1,10,3,6,10,4,8,1587565,1310721, +2,2,1708647,16,1585287,2,1,6,1,10,28,34,63,38,1,10, +28,1708649,14,1,10,3,6,10,4,8,1587567,1310721,2,3,26,2, +10,3,6,10,4,8,1587597,1,10,3,6,10,4,8,1587569,3, +10,3,6,10,4,8,1587571,1,10,3,6,10,4,8,1587573,1, +10,3,6,10,4,8,1587577,3,10,3,6,10,4,8,1587581,1587579, +2,10,3,6,10,4,8,1587587,1,10,3,6,10,4,8,1587589, +1,10,3,6,10,4,8,1,1708823,14,1,1310721,2,5,26,1310721, +4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1708871,16,1966081,1310721, +4,1579223,12,1310721,1594643,12,8,3,1594729,12,8,1587575,1595029,12,10,3, +6,10,4,8,29,1594729,12,8,1310721,1594643,12,8,5,1594729,12,8, +1587769,2,1708943,16,1,1709061,14,1310721,1594643,12,8,3,1594729,12,8,1835009, +1594643,12,8,41,1594729,12,8,1310721,2,1595029,12,10,3,6,10,4, +8,17,1594729,12,8,1966081,1594643,12,8,1310721,1594643,12,8,5,1594729,12, +8,1587665,2,1595409,12,8,1310721,2,2,1587549,2,1594811,12,8,1,1709061, +14,1,1310721,2,3,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1709109,16,1966081,1310721,4,1579223,12,1,1594643,12,8,1587573,2, +1587549,2,1594231,12,8,1310721,1594643,12,8,3,1594729,12,8,1587563,2,1594643, +12,8,27,1594729,12,8,1310721,1594643,12,8,5,1594729,12,8,19,1594729, +12,8,1587575,2,1587563,2,1594811,12,8,1587577,1,10,3,6,10,4, +8,1587557,1587559,2,10,3,6,10,4,8,1,1709245,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1709293, +16,1966081,1310721,4,1579223,12,1587603,2,1606959,12,8,1587605,2,1606425,12,1, +6,1,10,28,34,63,38,3,26,1709459,16,1585289,2,1,28,1, +6,1,10,28,34,63,38,3,26,1709449,16,1709441,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, +1709371,1591557,12,8,1686451,12,8,1709303,14,1587559,2,1614147,12,8,1587565,2, +1709507,16,1587569,2,1,6,1,10,28,34,63,38,1,10,28,1709509, +14,1,1709641,16,3,3,1613419,12,8,1587567,2,1709641,16,1709633,14,97, +32,102,117,110,99,116,105,111,110,32,114,101,116,117,114,110, +105,110,103,32,46,117,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, +1709535,1591845,12,8,1604999,12,8,1,1709655,14,1,1310721,2,1,26,1310721, +4,18,1310721,2,175,28,1310721,4,1310721,2,1835009,40,1709703,16,1966081,1310721, +4,1579223,12,1310721,2,7,26,4,1310721,2,5,26,4,1310721,2,3, +26,4,1310721,2,4,1,1310721,2,11,26,4,1,1310721,2,13,26, +4,1,1310721,2,165,26,4,1587771,2,1310721,2,169,26,4,1587771,1, +10,3,6,10,4,8,1310721,2,3,26,2,1709825,16,3,1709851,14, +1587721,2,1,6,1,10,28,34,63,38,1,10,28,1709877,16,1310721, +2,165,26,3,10,3,6,10,4,8,1310721,2,9,26,1310721,2, +7,26,2,1593303,12,10,3,6,10,4,8,1310721,2,9,26,2, +1,40,1709935,16,3,1709973,14,1310721,2,9,26,2,1585221,2,40,1, +6,1,10,28,34,63,38,1,10,28,1709983,16,3,1710047,14,1417729, +1310721,2,9,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,1710057, +16,3,1710099,14,1442305,1310721,2,9,26,2,26,2,3,32,1,6, +1,10,28,34,63,38,1,10,28,1710169,16,1310721,2,9,26,1310721, +2,7,26,2,3,1,1592805,12,10,3,6,10,4,8,1442305,1310721, +2,9,26,2,26,1,10,3,6,10,4,8,1587599,2,1606959,12, +8,1587601,2,1606425,12,1,6,1,10,28,34,63,38,3,26,1711671, +16,3,1711671,16,1310721,2,15,26,1,10,3,6,10,4,8,1310721, +2,117,26,1310721,2,11,26,2,26,1587687,2,10,3,6,10,4, +8,1587637,2,1606425,12,1,6,1,10,28,34,63,38,3,26,1710647, +16,1585289,2,9,28,1,6,1,10,28,34,63,38,3,26,1710457, +16,1585291,2,1587623,2,28,1,6,1,10,28,34,63,38,3,26, +1710379,16,3,1710431,14,1585291,2,1587607,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,1710459,14,1,1710469,16,3, +1710621,14,1585289,2,5,28,1,6,1,10,28,34,63,38,3,26, +1710597,16,1585291,2,1587639,2,28,1,6,1,10,28,34,63,38,3, +26,1710541,16,3,1710571,14,1585291,2,1644211,12,1,6,1,10,28,34, +63,38,1,10,28,1,6,1,10,28,34,63,38,1,10,28, +1710599,14,1,1,6,1,10,28,34,63,38,1,10,28,1,6, +1,10,28,34,63,38,1,10,28,1710649,14,1,1710835,16,1310721,2, +117,26,1310721,2,11,26,2,26,1644591,12,10,3,6,10,4,8, +1310721,2,165,26,3,10,3,6,10,4,8,1310721,2,117,26,1310721, +2,11,26,2,26,2,1638921,12,1710835,16,1710827,14,115,116,114,117, +99,116,115,32,97,110,100,32,97,114,114,97,121,115,32,97, +114,101,32,112,97,115,115,101,100,32,98,121,32,112,111,105, +110,116,101,114,0,1710745,1591173,12,8,1587637,2,1606729,12,1711041,16,1585291, +2,1587653,2,28,1,6,1,10,28,34,63,38,3,26,1710907,16, +1310721,2,15,26,3,10,3,6,10,4,8,1711035,14,1585291,2,1587655, +2,28,1,6,1,10,28,34,63,38,3,26,1710967,16,1310721,2, +15,26,5,10,3,6,10,4,8,1711035,14,1711027,14,97,32,112, +97,114,97,109,101,116,101,114,32,116,97,103,32,105,115,32, +46,109,32,111,114,32,46,100,0,1710971,1591557,12,8,1604999,12,8, +1310721,2,21,26,1310721,2,11,26,2,26,1607249,12,10,3,6,10, +4,8,1310721,2,169,26,2,1711165,16,1310721,2,117,26,1310721,2,11, +26,2,26,2,1587687,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1711167,14,1,1711235, +16,1711227,14,111,51,32,112,97,114,97,109,101,116,101,114,115, +32,110,101,101,100,32,97,32,116,121,112,101,0,1711175,1591173,12, +8,1310721,2,11,26,2,25,40,3,36,1711293,16,1310721,2,15,26, +2,1,6,1,10,28,34,63,38,1,10,28,1711295,14,1,1711397, +16,1711389,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,1711303,1591557, +12,8,1310721,2,69,26,1310721,2,11,26,2,26,1310721,2,15,26, +2,10,3,6,10,4,8,1310721,2,11,26,2,25,40,1711523,16, +1310721,2,13,26,1310721,2,13,26,2,1310721,2,15,26,2,1310721,2, +11,26,2,1310721,2,11,26,2,26,48,26,10,3,6,10,4, +8,1310721,2,11,26,1,6,2,1,6,3,26,5,6,4,10, +8,8,1310721,2,11,26,2,49,40,3,36,1711631,16,1711623,14,116, +111,111,32,109,97,110,121,32,112,97,114,97,109,101,116,101, +114,115,0,1711583,1591557,12,8,1587611,2,1606729,12,1,6,1,10,28, +34,63,38,3,26,1711667,16,1711671,14,1710211,14,1587601,2,1606959,12,8, +1310721,2,17,26,1310721,2,5,26,2,1310721,2,11,26,2,26,1310721, +2,11,26,2,26,1310721,2,13,26,2,129,30,26,10,3,6, +10,4,8,1442305,1310721,2,9,26,2,26,2,5,32,1711841,16,1442305, +1310721,2,9,26,2,26,2,513,32,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1711843,14, +1,1712003,16,1434113,1310721,2,9,26,2,26,2,1310721,2,17,26,2, +28,1,6,1,10,28,34,63,38,1,10,28,1711999,16,1310721,2, +7,26,2,1711991,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,1711915,1591343,12,8,1712291, +14,1442305,1310721,2,9,26,2,26,2,9,32,1712105,16,1310721,2,13, +26,2,1712047,16,3,1712079,14,1310721,2,5,26,2,1,6,1,10, +28,34,63,38,1,10,28,1,6,1,10,28,34,63,38,1, +10,28,1712107,14,1,1712291,16,1310721,2,7,26,2,1712283,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,1712125,1591343,12, +8,1434113,1310721,2,9,26,2,26,1310721,2,17,26,2,10,3,6, +10,4,8,1442305,1310721,2,9,26,2,26,1442305,1310721,2,9,26,2, +26,2,5,34,1442305,1310721,2,9,26,2,26,2,513,32,28,10, +3,6,10,4,8,1587721,2,1712449,16,1442305,1310721,2,9,26,2,26, +1442305,1310721,2,9,26,2,26,2,257,34,10,3,6,10,4,8, +1310721,2,165,26,2,1712819,16,1310721,2,3,26,2,1,6,1,10, +28,34,63,38,3,26,1712521,16,1310721,2,3,26,1587687,2,10,3, +6,10,4,8,1310721,2,167,26,1310721,2,3,26,2,1310721,2,11, +26,2,1310721,2,117,26,1310721,2,17,26,2,1633771,12,10,3,6, +10,4,8,1559041,1310721,2,9,26,2,26,2,1712679,16,1559041,1310721,2, +9,26,2,26,2,1310721,2,167,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,1712681,14,1,1712783,16,1310721,2,7,26,2,1712775,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,1712699,1591343,12,8,1559041,1310721,2,9,26,2,26,1310721,2, +167,26,2,10,3,6,10,4,8,1587613,2,1606729,12,1712861,16,1587721, +1,10,3,6,10,4,8,1310721,2,9,26,2,1714221,14,1442305,1310721, +2,9,26,2,26,2,3,32,1712941,16,1310721,2,7,26,2,1712933, +14,105,115,32,100,101,102,105,110,101,100,32,116,119,105,99, +101,0,1712899,1591343,12,8,1425921,1310721,2,9,26,2,26,1587549,2,10, +3,6,10,4,8,1442305,1310721,2,9,26,2,26,1442305,1310721,2,9, +26,2,26,2,3,34,10,3,6,10,4,8,1450497,1310721,2,9, +26,2,26,2,1587549,2,1594231,12,8,1450497,1310721,2,9,26,2,26, +1,10,3,6,10,4,8,1310721,2,2,1310721,2,5,26,2,1708505, +12,8,1310721,2,165,26,2,1713131,16,1587597,1310721,2,3,26,2,10, +3,6,10,4,8,1589305,1,10,3,6,10,4,8,1310721,2,169, +26,2,1713229,16,1587769,3,10,3,6,10,4,8,1595939,12,8,1442305, +1310721,2,9,26,2,26,1442305,1310721,2,9,26,2,26,2,1025,34, +10,3,6,10,4,8,1708837,12,8,1310721,2,19,26,1,10,3, +6,10,4,8,1310721,2,19,26,2,1310721,2,11,26,2,40,1713757, +16,1310721,2,15,26,1310721,2,21,26,1310721,2,19,26,2,26,2, +1611819,12,10,3,6,10,4,8,1587563,1,6,2,1,6,3,26, +5,6,4,10,8,8,1556993,1310721,2,15,26,2,26,1310721,2,117, +26,1310721,2,19,26,2,26,2,10,3,6,10,4,8,1310721,2, +169,26,2,1713463,16,1558017,1310721,2,15,26,2,26,33,10,3,6, +10,4,8,1310721,2,15,26,2,1596201,12,8,1587565,2,1713543,16,1310721, +2,69,26,1310721,2,19,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,1713545,14,1,1713577,16,1469953,1310721,2,15,26,2,26,13,10,3, +6,10,4,8,1587565,2,1713657,16,1310721,2,69,26,1310721,2,19,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,1713659,14,1,1713719,16,1469953, +1310721,2,15,26,2,26,3,10,3,6,10,4,8,1474049,1310721,2, +15,26,2,26,3,10,3,6,10,4,8,1310721,2,19,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1713257,14,1310721,2, +19,26,1310721,2,11,26,2,10,3,6,10,4,8,1310721,2,19, +26,2,1713863,16,1310721,2,19,26,1,6,2,1,6,-1,26,5, +6,4,10,8,8,1310721,2,19,26,2,1595563,12,8,5,1594729,12, +8,1713787,14,1310721,2,169,26,2,1714083,16,1310721,2,171,26,1587549,2, +5,26,10,3,6,10,4,8,1310721,2,171,26,2,1594643,12,8, +15,1594729,12,8,1310721,2,19,26,1,10,3,6,10,4,8,1310721, +2,19,26,2,1310721,2,11,26,2,40,1714083,16,1310721,2,15,26, +1587559,2,1310721,2,19,26,2,26,10,3,6,10,4,8,1310721,2, +15,26,2,1596641,12,8,1310721,2,15,26,2,1597105,12,8,1310721,2, +19,26,1,6,2,1,6,3,26,5,6,4,10,8,8,1713951, +14,1709259,12,8,1310721,2,173,26,1587549,2,10,3,6,10,4,8, +1709075,12,8,1310721,2,169,26,2,1714183,16,1587769,1,10,3,6,10, +4,8,1310721,2,171,26,2,1310721,2,173,26,2,1587775,1587839,1587903,2, +1597353,12,8,1597859,12,8,1587721,1,10,3,6,10,4,8,1310721,2, +9,26,2,1714221,14,1,1310721,2,175,26,1310721,4,18,1310721,2,3, +28,1310721,4,1310721,2,1835009,40,1714269,16,1966081,1310721,4,1579223,12,1310721,2, +4,1604999,12,8,1,1,1607249,12,1714313,12,1714299,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,13,28,1310721,4,1310721,2,1835009,40,1714347,16, +1966081,1310721,4,1579223,12,1310721,2,5,26,4,1310721,2,3,26,4,1310721, +2,4,1310721,2,3,26,2,1714491,16,1714483,14,116,97,103,115,32, +103,111,32,111,110,32,108,111,99,97,108,115,32,97,110,100, +32,112,97,114,97,109,101,116,101,114,115,44,32,110,111,116, +32,103,108,111,98,97,108,115,0,1714391,1591173,12,8,1310721,2,2, +1587695,2,28,1,6,1,10,28,34,63,38,3,26,1714589,16,1714581, +14,97,32,118,97,114,105,97,98,108,101,32,99,97,110,39, +116,32,98,101,32,118,111,105,100,0,1714531,1591173,12,8,3,1715505, +16,1587607,2,1606729,12,1714881,16,1310721,2,9,26,1685483,12,10,3,6, +10,4,8,1587609,2,1606959,12,8,1310721,2,11,26,1310721,2,5,26, +2,7,1587549,2,1592805,12,10,3,6,10,4,8,1310721,2,2,1, +6,1,10,28,34,63,38,3,26,1714731,16,1310721,2,1587687,2,10, +3,6,10,4,8,1559041,1310721,2,11,26,2,26,1310721,2,2,1310721, +2,9,26,2,1633251,12,10,3,6,10,4,8,1310721,2,9,26, +1559041,1310721,2,11,26,2,26,2,1637519,12,10,3,6,10,4,8, +1310721,2,9,26,2,1714877,16,1,1594449,12,8,1310721,2,9,26,1, +6,2,1,6,-1,26,5,6,4,10,8,8,1714817,14,1715441,14, +1310721,2,2,1714927,16,1310721,2,2,1638921,12,1,6,1,10,28,34, +63,38,1,10,28,1714929,14,1,1715099,16,1310721,2,11,26,1310721,2, +5,26,2,7,1587549,2,1592805,12,10,3,6,10,4,8,1559041,1310721, +2,11,26,2,26,1310721,2,2,10,3,6,10,4,8,1310721,2, +9,26,1310721,2,2,1637519,12,10,3,6,10,4,8,1310721,2,9, +26,2,1715095,16,1,1594449,12,8,1310721,2,9,26,1,6,2,1, +6,-1,26,5,6,4,10,8,8,1715035,14,1715441,14,1310721,2,7, +26,1587549,2,10,3,6,10,4,8,1310721,2,11,26,1310721,2,5, +26,2,5,1310721,2,7,26,2,1592805,12,10,3,6,10,4,8, +1310721,2,2,1715211,16,1559041,1310721,2,11,26,2,26,1310721,2,2,10, +3,6,10,4,8,1,1594449,12,8,1587615,2,1606729,12,1715441,16,1585289, +2,7,28,1,6,1,10,28,34,63,38,3,26,1715409,16,1310721, +2,7,26,2,1587551,2,26,1587549,2,10,3,6,10,4,8,1310721, +2,9,26,1585291,2,10,3,6,10,4,8,1310721,2,9,26,2, +2,1715391,16,1310721,2,9,26,2,2,1594449,12,8,1310721,2,9,26, +1,6,2,1,6,3,26,5,6,4,10,8,8,1715319,14,1, +1594449,12,8,1604999,12,8,1715441,14,1310721,2,7,26,2,1587551,2,26, +1685483,12,10,3,6,10,4,8,1587611,2,1606729,12,1,6,1,10, +28,34,63,38,3,26,1715477,16,1715505,14,1310721,2,5,26,1607249,12, +10,3,6,10,4,8,1714589,14,1587613,2,1606959,12,8,1,1715523,14, +1,1310721,2,13,26,1310721,4,18,1310721,2,3,28,1310721,4,1310721,2, +1835009,40,1715571,16,1966081,1310721,4,1579223,12,1604999,12,8,3,1715671,16,1310721, +2,1607249,12,10,3,6,10,4,8,1587615,2,1606959,12,8,1310721,2, +2,9,1685483,12,1592805,12,8,1587611,2,1606729,12,1,6,1,10,28, +34,63,38,3,26,1715667,16,1715671,14,1715577,14,1587613,2,1606959,12,8, +1,1715689,14,1,1310721,2,3,26,1310721,4,18,1310721,2,43,28,1310721, +4,1310721,2,1835009,40,1715737,16,1966081,1310721,4,1579223,12,1,1310721,2,3, +26,4,3,1310721,2,5,26,4,1,1310721,2,13,26,4,1,1310721, +2,15,26,4,1604999,12,8,1585289,2,3,28,1,6,1,10,28, +34,63,38,3,26,1715993,16,1585291,2,1,40,1715841,16,3,1715873,14, +1585291,2,17,10,40,1,6,1,10,28,34,63,38,1,10,28, +1715963,16,1715955,14,97,110,32,101,110,104,97,110,99,101,109,101, +110,116,32,104,97,115,32,97,116,32,109,111,115,116,32,56, +32,111,117,116,112,117,116,115,0,1715881,1591173,12,8,1310721,2,5, +26,1585291,2,10,3,6,10,4,8,1604999,12,8,1310721,2,1607249,12, +10,3,6,10,4,8,1587599,2,1606959,12,8,1587601,2,1606425,12,1, +6,1,10,28,34,63,38,3,26,1716297,16,3,1716297,16,1310721,2, +3,26,2,17,28,1,6,1,10,28,34,63,38,3,26,1716187, +16,1716179,14,97,110,32,101,110,104,97,110,99,101,109,101,110, +116,32,116,97,107,101,115,32,97,116,32,109,111,115,116,32, +56,32,105,110,112,117,116,115,0,1716103,1591557,12,8,1310721,2,27, +26,1310721,2,3,26,2,26,1607249,12,10,3,6,10,4,8,1310721, +2,3,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1587611,2,1606729,12,1,6,1,10,28,34,63,38,3,26,1716293,16, +1716297,14,1716055,14,1587601,2,1606959,12,8,1310721,2,7,26,1587549,2,10, +3,6,10,4,8,1310721,2,17,26,1,10,3,6,10,4,8, +1310721,2,17,26,2,15,40,1716417,16,1,1594449,12,8,1310721,2,17, +26,1,6,2,1,6,3,26,5,6,4,10,8,8,1716353,14, +1310721,2,9,26,1587549,2,10,3,6,10,4,8,1310721,2,17,26, +1,10,3,6,10,4,8,1310721,2,17,26,2,1310721,2,3,26, +2,40,1716535,16,1,1594449,12,8,1310721,2,17,26,1,6,2,1, +6,3,26,5,6,4,10,8,8,1716463,14,1310721,2,17,26,1, +10,3,6,10,4,8,1310721,2,17,26,2,1310721,2,3,26,2, +40,1716787,16,1310721,2,9,26,2,1310721,2,17,26,2,26,1587551,2, +26,1587549,2,10,3,6,10,4,8,1310721,2,19,26,1310721,2,27, +26,1310721,2,17,26,2,26,2,10,3,6,10,4,8,1310721,2, +19,26,2,2,1716741,16,1310721,2,19,26,2,2,1594449,12,8,1310721, +2,19,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1716669,14,1,1594449,12,8,1310721,2,17,26,1,6,2,1,6,3, +26,5,6,4,10,8,8,1716557,14,1587679,2,1606729,12,1717083,16,1310721, +2,11,26,1587549,2,10,3,6,10,4,8,1585289,2,7,28,1, +6,1,10,28,34,63,38,1,10,28,1716933,16,1716925,14,101,120, +112,101,99,116,101,100,32,116,104,101,32,114,101,99,105,112, +101,32,97,115,32,97,32,115,116,114,105,110,103,0,1716861,1591557, +12,8,1585289,2,7,28,1,6,1,10,28,34,63,38,3,26, +1717071,16,1310721,2,19,26,1585291,2,10,3,6,10,4,8,1310721,2, +19,26,2,2,1717061,16,1310721,2,19,26,2,2,1594449,12,8,1310721, +2,19,26,1,6,2,1,6,3,26,5,6,4,10,8,8, +1716989,14,1604999,12,8,1716933,14,1,1594449,12,8,1717249,14,1587681,2,1606729, +12,1717195,16,1310721,2,11,26,1587549,2,10,3,6,10,4,8,1698013, +12,8,19,1594729,12,8,1310721,2,13,26,1587549,2,1310721,2,11,26, +2,28,10,3,6,10,4,8,1310721,2,15,26,3,10,3,6, +10,4,8,1717249,14,1717241,14,101,120,112,101,99,116,101,100,32, +109,105,99,114,111,32,111,114,32,118,109,0,1717199,1591557,12,8, +1310721,2,23,26,1585215,2,10,3,6,10,4,8,1310721,2,23,26, +2,1025,40,3,36,1717379,16,1717371,14,97,108,108,32,53,49,50, +32,101,110,104,97,110,99,101,109,101,110,116,32,115,108,111, +116,115,32,97,114,101,32,116,97,107,101,110,0,1717299,1591079,12, +8,1585215,1,6,2,1,6,3,26,5,6,4,10,8,8,1310721, +2,19,26,1310721,2,7,26,2,1587551,2,26,10,3,6,10,4, +8,1310721,2,19,26,2,1,26,1310721,2,23,26,2,10,3,6, +10,4,8,1310721,2,19,26,2,3,26,1310721,2,15,26,2,10, +3,6,10,4,8,1310721,2,19,26,2,5,26,1310721,2,3,26, +2,10,3,6,10,4,8,1310721,2,19,26,2,7,26,1310721,2, +5,26,2,10,3,6,10,4,8,1310721,2,19,26,2,9,26, +1310721,2,11,26,2,10,3,6,10,4,8,1310721,2,19,26,2, +11,26,1310721,2,13,26,2,10,3,6,10,4,8,1310721,2,19, +26,2,13,26,1310721,2,9,26,2,10,3,6,10,4,8,1310721, +2,21,26,1310721,2,2,13,1310721,2,23,26,2,1592805,12,10,3, +6,10,4,8,1434113,1310721,2,21,26,2,26,1310721,2,3,26,2, +1310721,2,5,26,2,33,30,26,1310721,2,7,26,2,513,30,26, +10,3,6,10,4,8,1587645,2,1606729,12,1717937,16,1310721,2,25,26, +1585291,2,1593303,12,10,3,6,10,4,8,1310721,2,25,26,2,1, +40,1717891,16,1310721,2,25,26,1585291,2,1595111,12,10,3,6,10,4, +8,1604999,12,8,1450497,1310721,2,21,26,2,26,1310721,2,25,26,2, +3,26,10,3,6,10,4,8,1587613,2,1606959,12,8,1587551,2,1, +6,1,10,28,34,63,38,3,26,1718257,16,1310721,2,25,26,1310721, +2,7,26,2,1572879,12,10,3,6,10,4,8,1310721,2,25,26, +2,1,40,1718257,16,1450497,1310721,2,21,26,2,26,2,1,6,1, +10,28,34,63,38,3,26,1718211,16,1310721,2,2,1718203,14,116,104, +101,32,101,110,104,97,110,99,101,109,101,110,116,32,100,105, +100,110,39,116,32,105,110,115,116,97,108,108,32,40,115,101, +101,32,105,110,115,116,97,108,108,39,115,32,99,111,100,101, +115,32,105,110,32,99,111,114,101,46,99,41,0,1718077,1591343,12, +8,1442305,1310721,2,21,26,2,26,1442305,1310721,2,21,26,2,26,2, +129,34,10,3,6,10,4,8,1,1718265,14,1,1310721,2,43,26, +1310721,4,18,1310721,2,3,28,1310721,4,1310721,2,1835009,40,1718313,16,1966081, +1310721,4,1579223,12,1,1310721,2,4,1585289,2,1,28,1,6,1,10, +28,34,63,38,1,10,28,1719203,16,1587603,2,1606425,12,1718401,16,1310721, +2,1,6,2,1,6,3,26,5,6,4,10,8,8,1719193,14, +1587605,2,1606425,12,1718479,16,1310721,2,1,6,2,1,6,-1,26,5, +6,4,10,8,8,1310721,2,2,1,40,1718475,16,1310721,2,1,10, +3,6,10,4,8,1719193,14,1310721,2,2,1,6,1,10,28,34, +63,38,3,26,1718563,16,1585289,2,5,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1718565, +14,1,1719183,16,1585291,2,1587639,2,28,1,6,1,10,28,34,63, +38,3,26,1718609,16,3,1718661,14,1585291,2,1587641,2,28,1,6,1, +10,28,34,63,38,3,26,1,6,1,10,28,34,63,38,1, +10,28,1718671,16,3,1718723,14,1585291,2,1587643,2,28,1,6,1,10, +28,34,63,38,3,26,1,6,1,10,28,34,63,38,1,10, +28,1718733,16,3,1718785,14,1585291,2,1587745,2,28,1,6,1,10,28, +34,63,38,3,26,1,6,1,10,28,34,63,38,1,10,28, +1718795,16,3,1718847,14,1585291,2,1587747,2,28,1,6,1,10,28,34, +63,38,3,26,1,6,1,10,28,34,63,38,1,10,28,1718857, +16,3,1718909,14,1585291,2,1587677,2,28,1,6,1,10,28,34,63, +38,3,26,1,6,1,10,28,34,63,38,1,10,28,1718919,16, +3,1718971,14,1585291,2,1587749,2,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1718981,16,3, +1719033,14,1585291,2,1587649,2,28,1,6,1,10,28,34,63,38,3, +26,1,6,1,10,28,34,63,38,1,10,28,1719043,16,3,1719095, +14,1585291,2,1587651,2,28,1,6,1,10,28,34,63,38,3,26, +1,6,1,10,28,34,63,38,1,10,28,1719105,16,3,1719157,14, +1585291,2,1587759,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,1719185,14,1,1719193,16,1719203,14,1604999,12,8,1718321, +14,1590585,1,10,3,6,10,4,8,1,1719227,14,1,1310721,2,3, +26,1310721,4,18,1310721,2,39,28,1310721,4,1310721,2,1835009,40,1719275,16, +1966081,1310721,4,1579223,12,1,1310721,2,5,26,4,1587729,2,1606425,12,1, +6,1,10,28,34,63,38,3,26,1719395,16,1587721,2,1719373,16,1587705, +1,26,2,1719365,14,105,115,110,39,116,32,97,32,116,121,112, +101,0,1719339,1591343,12,8,1587721,1,10,3,6,10,4,8,1,1720165, +14,1604999,12,8,3,1719601,16,1310721,2,5,26,2,17,40,3,36, +1719491,16,1719483,14,116,111,111,32,109,97,110,121,32,116,121,112, +101,32,112,97,114,97,109,101,116,101,114,115,0,1719433,1591079,12, +8,1310721,2,7,26,1310721,2,5,26,2,26,1607249,12,10,3,6, +10,4,8,1310721,2,5,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1587611,2,1606729,12,1,6,1,10,28,34,63,38, +3,26,1719597,16,1719601,14,1719401,14,1644489,12,8,1310721,2,23,26,1, +17,1574703,12,8,1310721,2,1,10,3,6,10,4,8,1310721,2,2, +1587721,2,40,1720033,16,1310721,2,3,26,1,10,3,6,10,4,8, +1310721,2,3,26,2,1310721,2,5,26,2,40,1719791,16,1310721,2,7, +26,1310721,2,3,26,2,26,2,1587705,1310721,2,2,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,1719793,14,1,1719835,16,1310721,2,3,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1719681,14,1310721,2,3, +26,2,1310721,2,5,26,2,28,1,6,1,10,28,34,63,38, +3,26,1719935,16,1587705,1310721,2,2,26,2,1719923,14,105,115,110,39, +116,32,97,32,116,121,112,101,0,1719897,1591343,12,8,1719999,14,1310721, +2,23,26,1310721,2,2,26,1310721,2,3,26,2,1310721,2,7,26, +1310721,2,3,26,2,26,2,1635193,12,10,3,6,10,4,8,1310721, +2,1,6,2,1,6,3,26,5,6,4,10,8,8,1719643,14, +1587721,2,1720071,16,1587725,2,1,6,1,10,28,34,63,38,1,10, +28,1720073,14,1,1720107,16,1587725,1587725,2,1310721,2,23,26,1637691,12,10, +3,6,10,4,8,1587705,1310721,2,7,26,1310721,2,5,26,2,1574491, +12,8,1587721,1310721,2,5,26,2,10,3,6,10,4,8,1,1720165, +14,1,1310721,2,39,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1720213,16,1966081,1310721,4,1579223,12,1587723,3,10,3,6,10, +4,8,1647783,12,8,1587723,1,10,3,6,10,4,8,1,1720259,14, +1,1310721,2,1,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721,2, +1835009,40,1720307,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2, +4,1587721,1,10,3,6,10,4,8,1310721,2,3,26,2,1720569,16, +1587551,2,1720479,16,1720471,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,1720365,1591173,12,8,1310721, +2,5,26,1409537,1310721,2,2,26,2,11,1425921,1310721,2,2,26,2, +1592805,12,10,3,6,10,4,8,1442305,1310721,2,5,26,2,26,3, +17,34,33,34,65,34,10,3,6,10,4,8,1,1720577,14,1, +1310721,2,7,26,1310721,4,18,1310721,2,11,28,1310721,4,1310721,2,1835009, +40,1720625,16,1966081,1310721,4,1579223,12,3,1310721,2,4,1,1310721,2,3, +26,4,1590585,2,1720661,16,1718279,12,1722455,14,1587649,2,1606577,12,1720731,16, +1604999,12,8,1587613,2,1606729,12,1720713,16,1585287,1,10,3,6,10,4, +8,1,1722455,14,1310721,2,1,10,3,6,10,4,8,1587651,2,1606577, +12,1720771,16,1604999,12,8,1310721,2,3,26,3,10,3,6,10,4, +8,1587771,1,10,3,6,10,4,8,1587759,2,1606577,12,1720821,16,1604999, +12,8,1587771,3,10,3,6,10,4,8,1587721,1,10,3,6,10, +4,8,1587639,2,1606577,12,1721063,16,1605859,12,8,1587511,2,9,28,1, +6,1,10,28,34,63,38,3,26,1720943,16,1587513,2,1587599,2,28, +1,6,1,10,28,34,63,38,3,26,1,6,1,10,28,34, +63,38,1,10,28,1720945,14,1,1,6,1,10,28,34,63,38, +3,26,1721063,16,1604999,12,8,1310721,2,9,26,1607249,12,10,3,6, +10,4,8,1587725,1,10,3,6,10,4,8,1719241,12,8,1310721,2, +2,1,1,1310721,2,9,26,2,1709669,12,1310721,2,3,26,2,1720273, +12,1722455,14,1310721,2,2,1,6,1,10,28,34,63,38,3,26, +1721099,16,3,1721131,14,1310721,2,3,26,2,1,6,1,10,28,34, +63,38,1,10,28,1721141,16,3,1721167,14,1587771,2,1,6,1,10, +28,34,63,38,1,10,28,1721501,16,1720179,12,8,1310721,2,9,26, +1607249,12,10,3,6,10,4,8,1719241,12,8,1587727,2,1721271,16,1587727, +2,5,28,1,6,1,10,28,34,63,38,1,10,28,1,6, +1,10,28,34,63,38,1,10,28,1721273,14,1,1721341,16,1721333,14, +116,104,101,32,111,110,108,121,32,114,101,116,117,114,110,32, +116,97,103,32,105,115,32,46,117,0,1721281,1591173,12,8,1587599,2, +1606425,12,1,6,1,10,28,34,63,38,3,26,1721431,16,1721417,14, +101,120,112,101,99,116,101,100,32,97,32,102,117,110,99,116, +105,111,110,0,1721377,1591557,12,8,1,1722455,14,1310721,2,2,1587725,2, +1587727,2,5,28,1,6,1,10,28,34,63,38,3,26,1310721,2, +9,26,2,1709669,12,1310721,2,3,26,2,1720273,12,1722455,14,1587641,2, +1606577,12,1721523,16,1,1714235,12,1722455,14,1587745,2,1606577,12,1721547,16,1648157, +12,8,1,1722455,14,1587747,2,1606577,12,1721567,16,1650063,12,1722455,14,1587749, +2,1606577,12,1721587,16,1650183,12,1722455,14,1587677,2,1606577,12,1721607,16,1715703, +12,1722455,14,1587643,2,1606577,12,1721627,16,1715537,12,1722455,14,1585289,2,5, +28,1,6,1,10,28,34,63,38,3,26,1721857,16,1310721,2,5, +26,1585291,2,1593303,12,10,3,6,10,4,8,1310721,2,5,26,2, +1,40,3,36,1721775,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,1721777,14,1,1721827,16,1442305,1310721,2,5,26,2, +26,2,65,32,1,6,1,10,28,34,63,38,1,10,28,1721829, +14,1,1721857,16,1310721,2,5,26,2,1,1663505,12,8,1,1722455,14, +1646981,12,1721871,16,3,1721901,14,1587623,2,1606425,12,1,6,1,10,28, +34,63,38,1,10,28,1721911,16,3,1722005,14,1585289,2,5,28,1, +6,1,10,28,34,63,38,3,26,1721981,16,1585291,2,1593303,12,1, +40,1,6,1,10,28,34,63,38,1,10,28,1721983,14,1,1, +6,1,10,28,34,63,38,1,10,28,1722389,16,1720179,12,8,1310721, +2,9,26,1607249,12,10,3,6,10,4,8,1587599,2,1606425,12,1722057, +16,3,1722087,14,1587729,2,1606425,12,1,6,1,10,28,34,63,38, +1,10,28,1722293,16,1719241,12,8,1587727,2,1722161,16,1587727,2,5,28, +1,6,1,10,28,34,63,38,1,10,28,1,6,1,10,28, +34,63,38,1,10,28,1722163,14,1,1722231,16,1722223,14,116,104,101, +32,111,110,108,121,32,114,101,116,117,114,110,32,116,97,103, +32,105,115,32,46,117,0,1722171,1591173,12,8,1310721,2,2,1587725,2, +1587727,2,5,28,1,6,1,10,28,34,63,38,3,26,1310721,2, +9,26,2,1709669,12,1,1720273,12,1722455,14,1587721,2,1722363,16,1587705,1, +26,2,1722339,14,105,115,110,39,116,32,97,32,116,121,112,101, +0,1722313,1591343,12,8,1587721,1,10,3,6,10,4,8,1587725,2,1587727, +2,1310721,2,9,26,2,1714313,12,1722455,14,1722439,14,101,120,112,101, +99,116,101,100,32,97,32,100,101,99,108,97,114,97,116,105, +111,110,0,1722393,1591557,12,8,1,1722455,14,1,1310721,2,11,26,1310721, +4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1722503,16,1966081,1310721, +4,1579223,12,1585289,2,1,28,1,6,1,10,28,34,63,38,1, +10,28,1722547,16,1720591,12,8,1722503,14,1,1722555,14,1,1310721,2,1, +26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1722603,16, +1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1310721,2,3,26,4, +1590585,1,10,3,6,10,4,8,1310721,2,3,26,2,1585219,2,40, +1722973,16,1417729,1310721,2,3,26,2,26,2,3,28,1,6,1,10, +28,34,63,38,3,26,1722771,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,1722773,14,1,1722819,16,1450497,1310721,2,3, +26,2,26,2,1,6,1,10,28,34,63,38,1,10,28,1722821, +14,1,1722935,16,1585295,1425921,1310721,2,3,26,2,26,2,10,3,6, +10,4,8,1409537,1310721,2,3,26,2,26,2,1722927,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,1722875,1591343,12,8,1310721,2,3,26,1, +6,2,1,6,3,26,5,6,4,10,8,8,1722641,14,1590583,2, +1722987,16,1590891,12,8,1,1722995,14,1,1310721,2,5,26,1310721,4,18, +1310721,2,11,28,1310721,4,1310721,2,1835009,40,1723043,16,1966081,1310721,4,1579223, +12,1310721,2,3,26,4,1310721,2,4,3,1,10,28,1310721,2,5, +26,4,1,1310721,2,7,26,4,1585219,2,1310721,2,9,26,4,1707025, +12,8,1587577,2,1723149,16,1310721,2,5,26,1595029,12,10,3,6,10, +4,8,15,1594729,12,8,1310721,2,3,26,2,1723177,16,3,1310721,2, +2,1705455,12,8,3,1310721,2,2,1,1,1598871,12,8,1604999,12,8, +1310721,2,3,26,2,1723225,16,1722469,12,8,1723379,14,1310721,2,7,26, +1587549,2,10,3,6,10,4,8,3,1,1708505,12,8,1708837,12,8, +1585289,2,1,28,1,6,1,10,28,34,63,38,1,10,28,1723309, +16,1686451,12,8,1723265,14,1587559,2,1614147,12,8,1587565,2,1723357,16,1587569, +2,1,6,1,10,28,34,63,38,1,10,28,1723359,14,1,1723373, +16,3,3,1613419,12,8,1709075,12,8,1600299,12,8,1310721,2,9,26, +2,1722569,12,8,1310721,2,5,26,2,1,40,3,36,1723443,16,1310721, +2,5,26,2,1587549,2,1594811,12,8,1587549,2,1587555,2,10,40,1723477, +16,1587555,1587549,2,10,3,6,10,4,8,1707801,12,8,1310721,2,7, +26,2,1723499,14,1,1310721,2,11,26,1310721,4,18,1310721,2,3,28, +1310721,4,1310721,2,1835009,40,1723547,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,1,1723009,12,1723571,14,1,1310721,2,3,26,1310721,4,18, +1310721,2,3,28,1310721,4,1310721,2,1835009,40,1723619,16,1966081,1310721,4,1579223, +12,1310721,2,4,1310721,2,2,3,1723009,12,8,1,1723647,14,1,1310721, +2,3,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40, +1723695,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2,1,1723009,12, +1310721,2,3,26,4,1310721,2,3,26,2,1,6,12,10,8,1723749, +14,1,1310721,2,5,26,1310721,4,18,1310721,2,7,28,1310721,4,1310721, +2,1835009,40,1723797,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2,2, +1702323,12,1310721,2,3,26,4,1310721,2,3,26,2,1723661,12,1310721,2, +5,26,4,1310721,2,3,26,2,1580973,12,8,1310721,2,5,26,2, +1723879,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28,1310721,4, +1310721,2,1835009,40,1723927,16,1966081,1310721,4,1579223,12,1310721,2,4,1310721,2, +2,1310721,2,3,26,4,1310721,2,3,26,2,1585219,2,40,1724347,16, +1417729,1310721,2,3,26,2,26,2,3,40,3,36,1724049,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,1724051,14,1,1724061,16,3,1724123,14,1417729,1310721, +2,3,26,2,26,2,13,28,1,6,1,10,28,34,63,38, +3,26,1,6,1,10,28,34,63,38,1,10,28,1724309,16,1417729, +1310721,2,3,26,2,26,2,1594449,12,8,1425921,1310721,2,3,26,2, +26,2,1594449,12,8,1434113,1310721,2,3,26,2,26,2,1594449,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,1724301,16,1310721,2,5,26,2,2, +1594449,12,8,1310721,2,5,26,1,6,2,1,6,3,26,5,6, +4,10,8,8,1724229,14,1,1594449,12,8,1310721,2,3,26,1,6, +2,1,6,3,26,5,6,4,10,8,8,1723949,14,1,1594449,12, +8,1,1724363,14,1,1310721,2,7,26,1310721,4,18,1310721,2,7,28, +1310721,4,1310721,2,1835009,40,1724411,16,1966081,1310721,4,1579223,12,1310721,2,4, +1310721,2,2,2,1724759,16,1310721,2,5,26,1310721,2,2,7,26,1592287, +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,1592805,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,2,1,26,2,13,28,1, +6,1,10,28,34,63,38,3,26,1724709,16,1310721,2,2,3,26, +2,1585215,2,40,3,36,1724687,16,1585215,1310721,2,2,3,26,2,3, +26,10,3,6,10,4,8,1310721,2,2,5,26,2,17,38,1572879, +12,8,1310721,2,1310721,2,2,7,26,1310721,2,2,7,26,1574039,12, +26,3,26,10,3,6,10,4,8,1724417,14,1,1724767,14,1,1310721, +2,7,26,1310721,4,18,1310721,2,21,28,1310721,4,1310721,2,1835009,40, +1724815,16,1966081,1310721,4,1579223,12,1310721,2,3,26,4,1310721,2,4,1587549, +2,1310721,2,5,26,4,1587551,2,1310721,2,7,26,4,1587553,2,1310721, +2,9,26,4,1585221,2,1310721,2,11,26,4,1585223,2,1310721,2,13, +26,4,1585219,2,1310721,2,15,26,4,1585215,2,1310721,2,17,26,4, +1585221,1585219,2,10,3,6,10,4,8,1585223,1585219,2,10,3,6,10, +4,8,1585215,1,10,3,6,10,4,8,1587549,1310721,2,2,10,3, +6,10,4,8,1587551,1310721,2,3,26,2,1310721,2,2,28,10,3, +6,10,4,8,1587553,1310721,2,2,393217,26,10,3,6,10,4,8, +1966081,1594643,12,8,1310721,1594643,12,8,5,1594729,12,8,1587667,2,1595111,12, +1595235,12,8,15,1594729,12,8,1,1594449,12,8,1,1594449,12,8,1706887, +12,8,1310721,2,3,26,2,11,26,1587549,2,10,3,6,10,4, +8,1585221,2,1723893,12,8,1310721,2,3,26,2,13,26,1587549,2,10, +3,6,10,4,8,1310721,2,19,26,1587549,2,1310721,2,2,28,10, +3,6,10,4,8,1310721,2,15,26,2,1593651,12,8,1585221,1310721,2, +11,26,2,10,3,6,10,4,8,1585223,1310721,2,13,26,2,10, +3,6,10,4,8,1587549,1310721,2,5,26,2,10,3,6,10,4, +8,1587551,1310721,2,7,26,2,10,3,6,10,4,8,1587553,1310721,2, +9,26,2,10,3,6,10,4,8,1585215,1310721,2,17,26,2,10, +3,6,10,4,8,1310721,2,19,26,2,1725403,14,1,1310721,2,21, +26,1310721,4,18,1310721,2,1,28,1310721,4,1310721,2,1835009,40,1725451,16, +1966081,1310721,4,1579223,12,1,1587555,2,1583851,12,8,1587551,2,1,6,1, +10,28,34,63,38,3,26,1725529,16,1587549,2,1587555,2,10,40,1, +6,1,10,28,34,63,38,1,10,28,1725531,14,1,1725549,16,1587555, +2,1587549,2,1583851,12,8,1572865,1572865,13,26,2,1583851,12,8,1540609,1540609, +2049,26,1583851,12,8,1310721,2,1966081,1583851,12,8,2064385,2097121,1583851,12,8, +1,1725609,14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721, +4,1310721,2,1835009,40,1725657,16,1966081,1310721,4,1579223,12,1585217,1327617,10,3, +6,10,4,8,1311233,1,16385,1574703,12,8,1585219,1,10,3,6,10, +4,8,1585225,1,10,3,6,10,4,8,1585227,1,10,3,6,10, +4,8,1585229,1,10,3,6,10,4,8,1585231,1,10,3,6,10, +4,8,1585233,1,10,3,6,10,4,8,1585235,1,10,3,6,10, +4,8,1585237,1,10,3,6,10,4,8,1587579,1,10,3,6,10, +4,8,1587583,1,10,3,6,10,4,8,1587585,1,10,3,6,10, +4,8,1587557,1,10,3,6,10,4,8,1587559,1,10,3,6,10, +4,8,1587599,1725903,14,40,0,1725899,1592287,12,10,3,6,10,4,8, +1587601,1725931,14,41,0,1725927,1592287,12,10,3,6,10,4,8,1587603,1725959, +14,123,0,1725955,1592287,12,10,3,6,10,4,8,1587605,1725987,14,125, +0,1725983,1592287,12,10,3,6,10,4,8,1587607,1726015,14,91,0,1726011, +1592287,12,10,3,6,10,4,8,1587609,1726043,14,93,0,1726039,1592287,12, +10,3,6,10,4,8,1587611,1726071,14,44,0,1726067,1592287,12,10,3, +6,10,4,8,1587613,1726099,14,59,0,1726095,1592287,12,10,3,6,10, +4,8,1587615,1726127,14,61,0,1726123,1592287,12,10,3,6,10,4,8, +1587617,1726157,14,45,62,0,1726151,1592287,12,10,3,6,10,4,8,1587619, +1726187,14,43,43,0,1726181,1592287,12,10,3,6,10,4,8,1587621,1726217, +14,45,45,0,1726211,1592287,12,10,3,6,10,4,8,1587623,1726245,14, +42,0,1726241,1592287,12,10,3,6,10,4,8,1587625,1726273,14,38,0, +1726269,1592287,12,10,3,6,10,4,8,1587627,1726301,14,58,0,1726297,1592287, +12,10,3,6,10,4,8,1587629,1726329,14,35,0,1726325,1592287,12,10, +3,6,10,4,8,1587631,1726357,14,45,0,1726353,1592287,12,10,3,6, +10,4,8,1587637,1726385,14,46,0,1726381,1592287,12,10,3,6,10,4, +8,1587659,1726413,14,63,0,1726409,1592287,12,10,3,6,10,4,8,1587661, +1726447,14,99,97,115,101,0,1726437,1592287,12,10,3,6,10,4,8, +1587663,1726487,14,100,101,102,97,117,108,116,0,1726471,1592287,12,10,3, +6,10,4,8,1587633,1726517,14,38,38,0,1726511,1592287,12,10,3,6, +10,4,8,1587635,1726547,14,124,124,0,1726541,1592287,12,10,3,6,10, +4,8,1587639,1726577,14,102,110,0,1726571,1592287,12,10,3,6,10,4, +8,1587641,1726609,14,108,101,116,0,1726601,1592287,12,10,3,6,10,4, +8,1587643,1726645,14,99,111,110,115,116,0,1726633,1592287,12,10,3,6, +10,4,8,1587645,1726679,14,101,108,115,101,0,1726669,1592287,12,10,3, +6,10,4,8,1587647,1726709,14,97,115,0,1726703,1592287,12,10,3,6, +10,4,8,1587649,1726753,14,117,110,99,104,101,99,107,101,100,0, +1726733,1592287,12,10,3,6,10,4,8,1587651,1726797,14,105,109,109,101, +100,105,97,116,101,0,1726777,1592287,12,10,3,6,10,4,8,1587653, +1726825,14,109,0,1726821,1592287,12,10,3,6,10,4,8,1587655,1726853,14, +100,0,1726849,1592287,12,10,3,6,10,4,8,1587657,1726881,14,117,0, +1726877,1592287,12,10,3,6,10,4,8,1587667,1726917,14,115,116,97,114, +116,0,1726905,1592287,12,10,3,6,10,4,8,1587669,1726951,14,109,97, +105,110,0,1726941,1592287,12,10,3,6,10,4,8,1587671,1726985,14,102, +114,101,101,0,1726975,1592287,12,10,3,6,10,4,8,1587673,1727017,14, +111,119,110,0,1727009,1592287,12,10,3,6,10,4,8,1587675,1727051,14, +113,110,101,119,0,1727041,1592287,12,10,3,6,10,4,8,1587665,1727105, +14,102,114,97,109,101,95,111,118,101,114,102,108,111,119,0, +1727075,1592287,12,10,3,6,10,4,8,1587677,1727145,14,101,110,104,97, +110,99,101,0,1727129,1592287,12,10,3,6,10,4,8,1587679,1727181,14, +109,105,99,114,111,0,1727169,1592287,12,10,3,6,10,4,8,1587681, +1727211,14,118,109,0,1727205,1592287,12,10,3,6,10,4,8,1,1727237, +14,1,1310721,2,1,26,1310721,4,18,1310721,2,1,28,1310721,4,1310721, +2,1835009,40,1727285,16,1966081,1310721,4,1579223,12,1727293,14,33,0,1727289,1727341, +14,48,32,36,32,48,32,126,32,45,32,124,32,51,49,32, +62,32,49,32,43,0,1727299,1611115,12,8,1727359,14,33,33,0,1727353, +1727411,14,48,32,36,32,48,32,126,32,45,32,124,32,51,49, +32,62,32,48,32,126,32,45,0,1727365,1611115,12,8,1727427,14,126, +0,1727423,1727443,14,45,49,32,94,0,1727433,1611115,12,8,1727459,14,45, +0,1727455,1727477,14,48,32,126,32,45,0,1727465,1611115,12,8,1727493,14, +42,0,1727489,21,1727505,14,42,0,1727501,1610075,12,8,1727521,14,47,0, +1727517,21,1727539,14,105,100,105,118,0,1727529,1610075,12,8,1727555,14,37, +0,1727551,21,1727573,14,105,109,111,100,0,1727563,1610075,12,8,1727589,14, +43,0,1727585,19,1727601,14,43,0,1727597,1610075,12,8,1727617,14,45,0, +1727613,19,1727629,14,45,0,1727625,1610075,12,8,1727647,14,60,60,0,1727641, +17,1727665,14,105,115,104,108,0,1727655,1610075,12,8,1727683,14,62,62, +0,1727677,17,1727695,14,62,0,1727691,1610075,12,8,1727711,14,60,0,1727707, +15,1727723,14,60,0,1727719,1610075,12,8,1727739,14,62,0,1727735,15,1727755, +14,126,32,60,0,1727747,1610075,12,8,1727773,14,60,61,0,1727767,15, +1727797,14,126,32,60,32,49,32,94,0,1727781,1610075,12,8,1727815,14, +62,61,0,1727809,15,1727835,14,60,32,49,32,94,0,1727823,1610075,12, +8,1727853,14,61,61,0,1727847,13,1727907,14,45,32,48,32,36,32, +48,32,126,32,45,32,124,32,51,49,32,62,32,49,32,43, +0,1727861,1610075,12,8,1727925,14,33,61,0,1727919,13,1727983,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,1727933,1610075,12,8,1727999,14,38,0,1727995, +11,1728011,14,38,0,1728007,1610075,12,8,1728027,14,94,0,1728023,9,1728039, +14,94,0,1728035,1610075,12,8,1728055,14,124,0,1728051,7,1728067,14,124, +0,1728063,1610075,12,8,1728085,14,38,38,0,1728079,3,1,10,28,1, +1610075,12,8,1728113,14,124,124,0,1728107,5,1,10,28,1,1610075,12, +8,1587615,2,1609247,12,8,1587617,2,1609247,12,8,1587619,2,1609247,12,8, +1587621,2,1609247,12,8,1728183,14,108,101,116,0,1728175,1688971,17,1611449,12, +8,1728205,14,105,102,0,1728199,1689043,17,1611449,12,8,1728233,14,119,104, +105,108,101,0,1728221,1691609,17,1611449,12,8,1728257,14,102,111,114,0, +1728249,1692221,17,1611449,12,8,1728287,14,115,119,105,116,99,104,0,1728273, +1694791,17,1611449,12,8,1728315,14,98,114,101,97,107,0,1728303,1693325,17, +1611449,12,8,1728349,14,99,111,110,116,105,110,117,101,0,1728331,1693751, +17,1611449,12,8,1728379,14,114,101,116,117,114,110,0,1728365,1696095,17, +1611449,12,8,1728415,14,117,110,99,104,101,99,107,101,100,0,1728395, +1697893,17,1611449,12,8,1728439,14,97,115,109,0,1728431,1700799,17,33,34, +1611449,12,8,1728471,14,113,117,111,116,101,0,1728459,1702049,33,1611449,12, +8,1728501,14,115,105,122,101,111,102,0,1728487,1653375,33,1611449,12,8, +1728531,14,116,121,112,101,111,102,0,1728517,1653491,33,1611449,12,8,1728553, +14,111,51,0,1728547,1696819,17,1611449,12,8,1728577,14,108,101,110,0, +1728569,1651499,33,1611449,12,8,1728601,14,99,97,112,0,1728593,1651989,33,1611449, +12,8,1728627,14,112,117,115,104,0,1728617,1652259,33,1611449,12,8,1728651, +14,112,111,112,0,1728643,1652983,33,1611449,12,8,1728681,14,114,101,115, +105,122,101,0,1728667,1653187,33,1611449,12,8,1,1728701,14,1,1310721,2, +1,26,1310721,4,18,1310721,2,5,28,1310721,4,1310721,2,1835009,40,1728749, +16,1966081,1310721,4,1579223,12,1577233,12,8,1725623,12,8,1572865,11,26,2, +1724377,12,8,1727251,12,8,1653603,12,8,1587549,1,10,3,6,10,4, +8,1587551,1,10,3,6,10,4,8,1587553,524289,10,3,6,10,4, +8,1587555,1,10,3,6,10,4,8,1585221,1585219,2,10,3,6,10, +4,8,1585223,1,10,3,6,10,4,8,1706887,12,8,1587549,2,1587555, +2,10,40,1728925,16,1587555,1587549,2,10,3,6,10,4,8,1310721,2, +1587669,2,1593303,12,10,3,6,10,4,8,1310721,2,2,1,40,3, +36,1729029,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, +1729031,14,1,1729077,16,1442305,1310721,2,2,26,2,3,32,1,6,1, +10,28,34,63,38,1,10,28,1729079,14,1,1729137,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,1573437,12,8,1,1729151,14,1,1310721, +2,5,26,1310721,4,18,1,864357,0,115,116,97,114,116,0,1, +786439,2,105,110,115,116,97,108,108,0,1,786627,2,112,117,116, +99,0,1,786662,0,103,101,116,99,0,1,786690,0,101,111,102, +0,1,786718,0,104,97,108,116,0,1,786747,2,112,117,116,115, +0,1,786828,2,112,117,116,110,0,1,787019,2,115,116,114,108, +101,110,0,1,787091,4,115,116,114,101,113,0,1,787245,6,119, +99,111,112,121,0,1,787351,6,119,102,105,108,108,0,1,787483, +4,122,117,100,105,118,0,1,787714,4,122,100,105,118,0,1, +787902,4,122,109,111,100,0,1,787997,4,122,115,104,108,0,1, +788082,2,116,111,112,115,105,122,101,0,1,788258,4,102,112,117, +115,104,0,1,788382,4,102,117,110,108,105,110,107,0,1,788495, +4,109,107,98,108,111,99,107,0,1,788616,0,104,101,97,112, +95,105,110,105,116,0,1,788847,2,98,97,108,108,111,99,0, +1,789084,2,98,102,114,101,101,0,1,789482,2,105,115,111,98, +106,0,1,789611,0,102,114,97,109,101,95,111,118,101,114,102, +108,111,119,0,1,789674,0,111,111,109,0,1,789735,3,110,101, +119,95,114,97,119,0,1,790016,5,110,101,119,95,116,0,1, +790109,3,110,101,119,0,1,790145,2,111,115,105,122,101,0,1, +790206,2,116,121,112,101,111,102,95,111,98,106,0,1,790292,2, +114,101,108,101,97,115,101,0,1,790486,130,102,114,101,101,0, +1,790530,4,111,119,110,0,1,790594,7,100,110,101,119,0,1, +790780,4,100,103,114,111,119,0,1,791136,4,111,111,98,0,1, +791244,4,100,97,116,0,1,791351,516,100,112,117,115,104,0,1, +791458,2,100,112,111,112,0,1,791547,4,100,114,101,115,105,122, +101,0,1,791703,2,100,108,101,110,0,1,791739,2,100,99,97, +112,0,1,791779,2,109,97,114,107,0,1,791925,4,109,97,114, +107,114,97,110,103,101,0,1,791996,0,100,114,97,105,110,0, +1,862708,0,103,99,95,114,111,111,116,115,0,1,792078,0,103, +99,0,1,792396,0,108,105,118,101,95,111,98,106,101,99,116, +115,0,1,792492,0,108,97,114,103,101,115,116,95,102,114,101, +101,0,1,795293,0,101,114,114,97,116,0,1,795365,0,101,114, +114,101,110,100,0,1,795445,0,103,105,118,101,117,112,0,1, +795539,2,102,97,116,97,108,0,1,795586,2,115,101,114,114,0, +1,795671,4,115,101,114,114,110,0,1,795778,2,100,105,101,0, +1,795845,4,100,105,101,110,0,1,795922,2,99,101,114,114,0, +1,795981,4,99,101,114,114,110,0,1,796053,2,104,97,115,104, +115,0,1,796143,2,105,110,116,101,114,110,0,1,796402,6,97, +100,100,115,121,109,0,1,796651,2,108,111,111,107,117,112,0, +1,796825,2,112,111,112,115,121,109,115,0,1,796902,2,108,111, +111,107,117,112,115,0,1,796939,4,102,105,120,110,101,119,0, +1,797115,4,102,105,120,97,108,108,0,1,797224,2,101,109,105, +116,0,1,797321,2,108,105,116,0,1,797364,2,111,112,0,1, +797405,4,115,101,116,108,105,116,0,1,797473,2,106,109,112,0, +1,797514,0,104,111,108,101,0,1,797555,2,102,119,100,102,110, +0,1,797617,2,102,110,114,101,102,0,1,797704,2,99,97,108, +108,110,97,109,101,0,1,797781,2,108,97,100,100,114,0,1, +797835,2,118,97,100,100,114,0,1,797969,0,111,51,114,101,115, +101,116,0,1,798021,0,111,51,116,97,107,101,0,1,798100,2, +111,51,112,114,111,109,111,116,101,0,1,798320,2,111,51,109, +107,99,97,99,104,101,0,1,798552,2,111,51,114,101,102,114, +101,115,104,0,1,798676,10,111,51,114,101,103,105,111,110,0, +1,798929,0,111,51,102,108,117,115,104,0,1,799052,2,115,116, +114,108,105,116,0,1,799158,0,110,101,120,116,99,104,0,1, +799435,8,115,114,99,95,112,117,115,104,0,1,800149,0,115,114, +99,95,112,111,112,0,1,800490,2,105,115,111,112,99,104,0, +1,800601,4,111,112,112,114,101,102,105,120,0,1,800844,2,105, +115,100,105,103,0,1,800905,2,105,115,97,108,0,1,801044,2, +104,101,120,118,0,1,801176,0,101,115,99,99,104,0,1,801350, +2,111,112,108,101,120,0,1,801495,0,108,101,120,0,1,802499, +0,110,101,120,116,0,1,802698,2,112,101,101,107,97,116,0, +1,802929,0,112,101,101,107,0,1,802959,0,110,101,120,116,48, +0,1,803212,2,105,115,95,111,112,0,1,803288,2,105,115,95, +105,100,0,1,803364,2,97,99,99,101,112,116,0,1,803479,2, +101,120,112,101,99,116,0,1,803624,0,110,97,109,101,0,1, +803701,2,115,101,113,97,115,109,0,1,804270,2,109,110,101,109, +105,100,120,0,1,804372,4,101,109,105,116,115,101,113,0,1, +804623,2,97,100,100,107,111,112,0,1,804743,2,98,105,110,102, +105,110,100,0,1,804841,2,117,110,102,105,110,100,0,1,804939, +2,97,115,103,102,105,110,100,0,1,805037,6,97,100,100,95, +98,105,110,111,112,0,1,805557,4,97,100,100,95,117,110,111, +112,0,1,805724,6,97,100,100,95,107,119,0,1,805807,2,102, +105,110,100,108,111,99,0,1,805909,2,110,101,119,108,111,99, +0,1,806154,2,108,114,111,111,116,0,1,806223,2,116,114,97, +99,107,101,100,0,1,806272,2,116,111,117,99,104,0,1,806516, +2,112,108,97,105,110,117,115,101,0,1,806656,2,102,114,101, +101,118,97,114,0,1,806709,4,101,120,105,116,95,118,97,114, +115,0,1,807073,2,117,110,117,115,101,100,95,99,104,101,99, +107,0,1,807222,2,98,108,111,99,107,95,99,108,111,115,101, +0,1,807508,0,115,110,97,112,95,112,117,115,104,0,1,807783, +2,115,110,97,112,95,112,111,112,0,1,807824,2,115,110,97, +112,95,114,101,115,116,111,114,101,0,1,808043,2,101,109,112, +116,121,0,1,808119,2,115,110,97,112,95,99,109,112,0,1, +808524,2,115,116,97,116,101,110,97,109,101,0,1,808742,6,109, +101,114,103,101,95,101,114,114,0,1,809008,4,106,115,116,0, +1,809083,4,106,111,119,0,1,809139,4,106,104,109,0,1,809195, +2,101,120,105,116,95,114,101,99,0,1,809491,2,106,97,100, +100,0,1,809595,6,106,115,97,109,101,0,1,809855,4,106,111, +105,110,0,1,810647,6,102,105,120,117,112,115,0,1,810894,2, +98,97,99,107,101,100,103,101,0,1,811685,12,106,111,105,110, +50,0,1,811972,4,114,101,99,97,115,116,0,1,812508,4,97, +114,103,99,104,101,99,107,0,1,813274,2,101,109,105,116,111, +119,110,0,1,813392,6,97,115,115,105,103,110,99,104,101,99, +107,0,1,815169,2,114,101,116,99,104,101,99,107,0,1,815676, +2,104,97,110,100,117,112,0,1,816034,2,100,105,115,99,97, +114,100,0,1,816157,2,116,97,108,108,111,99,0,1,816264,8, +116,110,101,119,0,1,816438,2,116,112,116,114,0,1,816625,4, +116,97,114,114,0,1,816885,8,116,102,110,0,1,817346,4,116, +100,121,110,0,1,817596,4,116,118,97,114,0,1,817792,6,116, +105,110,115,116,0,1,818223,2,116,114,101,115,111,108,118,101, +0,1,818759,2,116,115,122,0,1,818845,4,115,117,98,115,116, +0,1,819344,2,105,115,110,117,109,0,1,819460,2,105,115,97, +103,103,0,1,819542,2,105,115,112,116,114,0,1,819624,2,100, +101,99,97,121,0,1,819687,2,116,101,108,101,109,0,1,819781, +4,99,111,109,112,97,116,0,1,820439,6,117,110,105,102,121, +0,1,820984,2,116,112,114,105,110,116,0,1,821612,6,116,99, +101,114,114,0,1,821812,6,116,99,110,101,101,100,0,1,822007, +2,116,112,102,105,110,100,0,1,822105,2,105,115,116,121,112, +101,110,97,109,101,0,1,822244,0,99,108,111,115,101,97,110, +103,108,101,0,1,822295,0,112,116,121,112,101,0,1,822501,0, +112,116,121,112,101,48,0,1,823490,0,116,115,116,97,114,116, +0,1,823891,0,100,116,121,112,101,0,1,824078,0,107,119,95, +115,116,114,117,99,116,0,1,825031,0,107,119,95,116,121,112, +101,0,1,825091,0,107,119,95,116,121,112,101,99,104,101,99, +107,0,1,825198,4,116,102,105,110,100,102,105,101,108,100,0, +1,825322,0,116,121,112,101,97,114,103,0,1,825489,0,97,114, +114,97,114,103,0,1,825635,2,110,111,103,114,111,119,0,1, +825749,0,107,119,95,108,101,110,0,1,825994,0,107,119,95,99, +97,112,0,1,826129,0,107,119,95,112,117,115,104,0,1,826491, +0,107,119,95,112,111,112,0,1,826593,0,107,119,95,114,101, +115,105,122,101,0,1,826687,0,107,119,95,115,105,122,101,111, +102,0,1,826745,0,107,119,95,116,121,112,101,111,102,0,1, +826801,0,116,121,112,101,115,95,105,110,105,116,0,1,827665,2, +105,115,110,117,109,111,112,0,1,827758,6,98,105,110,116,121, +112,101,0,1,829151,2,116,107,105,110,100,0,1,829187,2,116, +115,105,122,101,0,1,829222,2,116,110,97,109,101,0,1,829258, +2,116,108,101,110,0,1,829294,2,116,110,102,105,101,108,100, +115,0,1,829336,2,104,97,115,112,116,114,0,1,829588,4,102, +97,116,116,101,110,0,1,829638,6,102,97,116,49,0,1,830312, +6,102,97,116,105,110,0,1,830751,4,116,102,110,97,109,101, +0,1,830807,4,116,102,116,121,112,101,0,1,830865,4,116,102, +111,102,102,0,1,830923,2,116,114,101,116,0,1,830959,2,116, +110,112,97,114,97,109,115,0,1,830995,4,116,112,97,114,97, +109,0,1,831042,4,116,112,97,114,97,109,116,97,103,0,1, +831099,2,116,114,101,116,117,0,1,831137,2,116,110,97,114,103, +115,0,1,831232,4,116,97,114,103,0,1,831282,2,115,105,103, +111,102,0,1,831593,2,115,105,103,111,102,115,0,1,831692,0, +114,118,97,108,0,1,831752,4,107,119,99,97,108,108,0,1, +831898,0,115,116,109,116,111,110,108,121,0,1,831976,8,97,114, +103,115,0,1,832321,0,110,101,119,116,121,112,101,100,0,1, +832798,2,99,97,108,108,0,1,833554,2,101,110,104,99,97,108, +108,0,1,833923,0,112,114,105,109,97,114,121,0,1,835388,4, +105,110,99,100,101,99,0,1,835812,2,102,105,101,108,100,0, +1,836488,0,112,111,115,116,102,105,120,0,1,838378,0,117,110, +97,114,121,0,1,839318,2,98,105,110,0,1,839831,0,115,116, +111,114,101,107,101,101,112,0,1,839879,2,116,101,114,110,97, +114,121,0,1,840529,0,101,120,112,114,0,1,841710,0,115,116, +109,116,115,116,97,114,116,0,1,841957,0,98,108,111,99,107, +101,120,112,114,0,1,842333,0,99,112,114,105,109,0,1,842741, +0,99,101,120,112,114,0,1,843098,0,114,101,115,121,110,99, +0,1,843225,0,115,116,109,116,0,1,843493,0,98,108,111,99, +107,0,1,843621,0,115,117,98,115,116,109,116,0,1,843701,2, +108,111,99,97,108,100,101,99,108,0,1,844485,0,107,119,95, +118,97,114,0,1,844521,0,107,119,95,105,102,0,1,845067,4, +108,111,111,112,95,112,117,115,104,0,1,845274,4,108,111,111, +112,95,101,110,100,0,1,845804,0,107,119,95,119,104,105,108, +101,0,1,846110,0,107,119,95,102,111,114,0,1,846662,0,107, +119,95,98,114,101,97,107,0,1,846875,0,107,119,95,99,111, +110,116,105,110,117,101,0,1,847162,4,99,97,115,101,98,111, +100,121,0,1,847395,0,107,119,95,115,119,105,116,99,104,0, +1,848047,0,107,119,95,114,101,116,117,114,110,0,1,848409,0, +107,119,95,111,51,0,1,848946,0,107,119,95,117,110,99,104, +101,99,107,101,100,0,1,849006,0,97,115,109,98,108,111,99, +107,0,1,850399,0,107,119,95,97,115,109,0,1,850441,1,103, +114,97,98,0,1,850781,3,113,110,101,119,0,1,850859,67,113, +100,117,112,0,1,850937,68,119,99,111,112,121,116,111,0,1, +851024,0,107,119,95,113,117,111,116,101,0,1,851161,3,116,111, +107,101,110,115,0,1,851401,130,102,101,101,100,0,1,851444,0, +114,101,97,100,115,114,99,0,1,851866,0,112,115,107,105,112, +97,110,103,108,101,0,1,851998,6,112,114,101,115,99,97,110, +95,102,110,0,1,852727,4,112,114,101,115,99,97,110,0,1, +853443,0,117,110,105,116,95,115,116,100,105,110,0,1,853512,0, +99,116,120,95,112,117,115,104,0,1,853900,0,99,116,120,95, +112,111,112,0,1,854252,4,102,110,95,98,101,103,105,110,0, +1,854418,0,112,114,111,108,111,103,117,101,0,1,854537,0,101, +112,105,108,111,103,117,101,0,1,854629,0,98,111,100,121,0, +1,854834,8,102,110,100,101,102,0,1,857117,2,103,100,101,99, +108,0,1,857156,6,103,100,101,99,108,50,0,1,857768,0,103, +99,111,110,115,116,0,1,857851,0,101,110,104,100,101,102,0, +1,859139,0,116,111,112,115,121,110,99,0,1,859620,0,103,101, +110,112,97,114,97,109,115,0,1,860089,0,114,101,116,116,121, +112,101,0,1,860136,4,102,110,100,111,110,101,0,1,860295,0, +116,111,112,105,116,101,109,0,1,861234,0,117,110,105,116,95, +116,111,112,0,1,861284,2,117,110,105,116,95,101,110,100,0, +1,861504,4,99,111,109,112,105,108,101,95,108,105,115,116,0, +1,861756,2,99,111,109,112,105,108,101,0,1,861792,2,108,111, +97,100,0,1,861830,2,101,118,97,108,0,1,861881,2,101,118, +97,108,115,0,1,861946,2,98,108,111,98,95,101,109,105,116, +0,1,862188,2,98,108,111,98,95,108,111,97,100,0,1,862390, +4,98,117,105,108,100,95,105,109,97,103,101,0,1,862811,0, +122,99,95,105,110,105,116,0,1,863625,0,122,99,95,116,97, +98,108,101,115,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,6,0,201337106,105,100,105,118,0,6,1,201343762,105,109,111, +100,0,6,2,201350418,105,115,104,108,0,6,3,201356817,108,102,97, +0,6,4,201366802,111,117,116,115,105,100,101,0,3,787450,0,112, +111,119,50,0,2,787482,0,122,114,101,109,0,4,6,0,72, +68,82,0,2,788046,0,104,98,117,109,112,0,3,788047,0,102, +114,101,101,108,0,2,788079,0,103,99,95,114,117,110,115,0, +2,788080,0,103,99,95,102,114,101,101,100,0,2,788081,0,103, +99,95,97,117,116,111,0,2,789083,0,102,101,110,100,0,2, +791775,0,109,115,95,116,111,112,0,2,791776,0,109,115,95,111, +118,101,114,0,2,791777,0,103,99,95,108,111,0,2,791778,0, +103,99,95,104,105,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,6,0, +75,95,69,78,72,0,4,7,0,75,95,84,89,80,69,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,64,0,70, +95,70,65,76,76,66,65,67,75,0,4,128,0,70,95,71, +69,78,0,4,256,0,70,95,80,82,69,0,4,512,0,70, +95,79,51,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,20,0,79,95,76, +84,0,4,22,0,88,79,80,48,0,4,-2,0,83,69,81, +82,69,70,0,2,792607,0,110,101,110,104,0,2,792608,0,112, +111,111,108,116,111,112,0,2,792609,0,110,115,121,109,0,2, +792610,0,117,98,97,115,101,0,2,792611,0,118,105,115,108,111, +0,2,792612,0,110,102,105,120,117,0,2,792613,0,102,105,120, +102,114,101,101,0,2,792614,0,110,98,105,110,0,2,792615,0, +110,117,110,0,2,792616,0,110,97,115,103,0,2,792617,0,110, +107,111,112,0,2,792618,0,115,101,113,116,111,112,0,2,792619, +0,109,110,101,109,0,2,792643,0,99,104,101,99,107,95,111, +110,0,2,792644,0,116,107,0,2,792645,0,116,118,0,2,792646, +0,116,103,108,117,101,0,2,792647,0,116,108,105,110,101,0, +2,792648,0,108,105,110,101,0,2,792649,0,99,104,0,2,792650, +0,99,104,107,105,110,100,0,2,792651,0,99,104,112,116,114, +0,2,792652,0,99,104,98,97,115,101,0,2,792653,0,113,100, +111,110,101,0,2,792654,0,105,115,112,0,3,792655,0,116,98, +117,102,0,2,793755,0,112,107,95,116,107,0,2,793756,0,112, +107,95,116,118,0,2,793757,0,112,113,95,110,0,3,793758,0, +112,113,95,116,107,0,3,793762,0,112,113,95,116,118,0,3, +793766,0,112,113,95,103,108,0,3,793770,0,112,113,95,108,110, +0,2,793774,0,104,101,114,101,0,2,793775,0,104,100,101,108, +116,97,0,2,793776,0,104,108,105,109,105,116,0,2,793777,0, +112,116,111,112,0,2,793778,0,110,108,111,99,0,2,793779,0, +108,98,97,115,101,0,2,793780,0,102,100,101,112,116,104,0, +2,793781,0,102,115,108,111,116,115,0,2,793782,0,102,99,104, +107,0,2,793783,0,102,114,101,116,0,2,793784,0,108,105,118, +101,0,2,793785,0,98,120,100,101,112,116,104,0,2,793786,0, +101,112,105,99,104,97,105,110,0,2,793787,0,102,102,114,97, +109,101,0,2,793788,0,105,110,102,110,0,2,793789,0,108,115, +112,0,2,793790,0,108,111,111,112,98,97,115,101,0,2,793791, +0,99,116,120,115,112,0,2,793792,0,115,110,97,112,116,111, +112,0,2,793793,0,108,118,0,2,793794,0,108,118,107,0,2, +793795,0,108,118,105,0,2,793796,0,107,119,95,101,120,112,114, +0,2,793797,0,120,99,108,115,0,2,793798,0,102,116,121,0, +2,793799,0,115,95,108,112,0,2,793800,0,115,95,114,112,0, +2,793801,0,115,95,108,98,0,2,793802,0,115,95,114,98,0, +2,793803,0,115,95,108,107,0,2,793804,0,115,95,114,107,0, +2,793805,0,115,95,99,111,109,109,97,0,2,793806,0,115,95, +115,101,109,105,0,2,793807,0,115,95,101,113,0,2,793808,0, +115,95,97,114,114,111,119,0,2,793809,0,115,95,105,110,99, +0,2,793810,0,115,95,100,101,99,0,2,793811,0,115,95,115, +116,97,114,0,2,793812,0,115,95,97,109,112,0,2,793813,0, +115,95,99,111,108,111,110,0,2,793814,0,115,95,104,97,115, +104,0,2,793815,0,115,95,109,105,110,117,115,0,2,793816,0, +115,95,97,110,100,97,110,100,0,2,793817,0,115,95,111,114, +111,114,0,2,793818,0,115,95,100,111,116,0,2,793819,0,115, +95,102,110,0,2,793820,0,115,95,118,97,114,0,2,793821,0, +115,95,99,111,110,115,116,0,2,793822,0,115,95,101,108,115, +101,0,2,793823,0,115,95,97,115,0,2,793824,0,115,95,117, +110,99,104,101,99,107,101,100,0,2,793825,0,115,95,105,109, +109,101,100,105,97,116,101,0,2,793826,0,115,95,109,0,2, +793827,0,115,95,100,0,2,793828,0,115,95,117,0,2,793829,0, +115,95,113,0,2,793830,0,115,95,99,97,115,101,0,2,793831, +0,115,95,100,101,102,97,117,108,116,0,2,793832,0,115,95, +102,111,118,102,0,2,793833,0,115,95,115,116,97,114,116,0, +2,793834,0,115,95,109,97,105,110,0,2,793835,0,115,95,102, +114,101,101,0,2,793836,0,115,95,111,119,110,0,2,793837,0, +115,95,113,110,101,119,0,2,793838,0,115,95,101,110,104,97, +110,99,101,0,2,793839,0,115,95,109,105,99,114,111,0,2, +793840,0,115,95,118,109,0,4,0,0,84,89,95,87,79,82, +68,0,4,1,0,84,89,95,73,78,84,0,4,2,0,84, +89,95,67,72,65,82,0,4,3,0,84,89,95,66,79,79, +76,0,4,4,0,84,89,95,86,79,73,68,0,4,5,0, +84,89,95,80,84,82,0,4,6,0,84,89,95,65,82,82, +0,4,7,0,84,89,95,70,78,0,4,8,0,84,89,95, +83,84,82,85,67,84,0,4,9,0,84,89,95,86,65,82, +0,4,10,0,84,89,95,71,69,78,0,4,11,0,84,89, +95,68,89,78,0,4,638976,0,82,95,84,89,0,4,655360,0, +82,95,84,89,69,78,68,0,4,1024,0,78,84,76,0,4, +778496,0,108,116,121,112,101,0,4,779008,0,108,116,97,103,0, +4,779520,0,115,116,121,112,101,0,2,793841,0,116,121,116,111, +112,0,2,793842,0,110,116,108,0,2,793843,0,116,119,111,114, +100,0,2,793844,0,116,105,110,116,0,2,793845,0,116,99,104, +97,114,0,2,793846,0,116,98,111,111,108,0,2,793847,0,116, +118,111,105,100,0,2,793848,0,116,99,95,111,110,0,2,793849, +0,120,116,121,0,2,793850,0,120,122,101,114,111,0,2,793851, +0,100,114,121,0,3,793852,0,116,112,110,0,2,793860,0,110, +116,112,0,2,793861,0,116,118,97,117,116,111,0,2,793862,0, +100,116,121,0,2,793863,0,100,116,97,103,0,2,793864,0,115, +95,108,116,0,2,793865,0,115,95,103,116,0,2,793866,0,115, +95,115,104,114,0,2,793867,0,115,95,108,101,0,2,793868,0, +115,95,103,101,0,2,793869,0,115,95,101,113,101,113,0,2, +793870,0,115,95,110,101,0,2,793871,0,115,95,112,108,117,115, +0,2,793872,0,115,95,115,116,114,117,99,116,0,2,793873,0, +115,95,116,121,112,101,0,2,793874,0,115,95,116,121,112,101, +99,104,101,99,107,0,2,793875,0,115,95,111,110,0,2,793876, +0,115,95,111,102,102,0,2,793877,0,115,95,110,101,119,0, +2,793878,0,115,95,110,101,119,95,116,0,2,793879,0,115,95, +111,51,0,2,793880,0,115,95,108,102,97,0,2,793881,0,115, +95,111,117,116,115,105,100,101,0,2,793882,0,115,95,110,101, +119,95,114,97,119,0,2,793883,0,115,95,111,111,98,0,2, +793884,0,111,51,111,110,0,2,793885,0,111,51,110,120,116,0, +2,793886,0,111,51,111,110,101,0,3,793887,0,111,51,115,108, +0,3,793919,0,111,51,114,103,0,2,793951,0,110,111,51,115, +108,0,3,793952,0,111,51,112,101,110,100,0,2,794652,0,110, +111,51,112,101,110,100,0,3,794653,0,111,51,100,115,99,0, +3,794733,0,111,51,102,114,101,101,0,2,794741,0,110,111,51, +102,114,101,101,0,2,794742,0,111,51,110,114,101,103,0,3, +794743,0,111,51,99,97,99,104,101,0,2,795255,0,97,114,103, +108,111,99,0,2,795256,0,115,95,104,105,116,101,109,115,0, +2,795257,0,115,95,104,108,101,110,0,2,795258,0,115,95,102, +97,116,116,101,110,0,3,795259,0,110,117,109,111,112,115,0, +2,795271,0,110,110,117,109,111,112,115,0,2,795272,0,115,95, +102,105,120,101,100,0,2,795273,0,115,95,100,108,101,110,0, +2,795274,0,115,95,100,99,97,112,0,2,795275,0,115,95,100, +110,101,119,0,2,795276,0,115,95,100,97,116,0,2,795277,0, +115,95,100,112,117,115,104,0,2,795278,0,115,95,100,112,111, +112,0,2,795279,0,115,95,100,114,101,115,105,122,101,0,2, +795280,0,120,99,111,110,115,116,0,2,795281,0,120,99,118,97, +108,0,3,795282,0,103,98,105,110,100,0,2,795290,0,110,103, +98,105,110,100,0,2,795291,0,110,101,114,114,0,2,795292,0, +112,97,110,105,99,0,4,783616,0,82,95,69,88,73,84,0, +4,786176,0,82,95,69,88,73,84,69,78,68,0,2,808942,0, +101,120,116,111,112,0,3,808943,0,106,112,115,0,2,809007,0, +110,106,112,115,0,0 +}; +#define GLEN 84118 diff --git a/docs/history/17-o3-boundaries/code/io_linux.c b/docs/history/17-o3-boundaries/code/io_linux.c new file mode 100644 index 0000000..7ea34e0 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/io_linux.c @@ -0,0 +1,6 @@ +#include +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/17-o3-boundaries/code/mkgenome.c b/docs/history/17-o3-boundaries/code/mkgenome.c new file mode 100644 index 0000000..8fb2cc5 --- /dev/null +++ b/docs/history/17-o3-boundaries/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 +#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/17-o3-boundaries/code/src/compiler.zc b/docs/history/17-o3-boundaries/code/src/compiler.zc new file mode 100644 index 0000000..1ac0c4b --- /dev/null +++ b/docs/history/17-o3-boundaries/code/src/compiler.zc @@ -0,0 +1,2980 @@ +// ============================================================================ +// 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, 32 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, 8 words per loop or switch +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, K_ENH = 6, K_TYPE = 7; +const F_DEF = 1, F_SIG = 2, F_UNTYPED = 4, F_STMT = 8, F_EXPR = 16, F_TOP = 32, F_FALLBACK = 64, F_GEN = 128, F_PRE = 256, F_O3 = 512; +// 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, O_LT = 20; +const XOP0 = 22; // first enhancement opcode +const SEQREF = -2; // in an operator sequence: the next word names a symbol + +// ---- state ---- +let nenh, pooltop, nsym, ubase, vislo, nfixu, fixfree; +let nbin, nun, nasg, nkop, seqtop; +let mnem = "q@!$_~cjzr,?.+-*&|^><%"; +let check_on = 1; // set to 0 to switch the analyzer off for what follows +let tk, tv, tglue, tline, line = 1, ch, chkind, chptr, chbase, qdone, isp = -1; +let tbuf[1100]; +let pk_tk, pk_tv, pq_n, pq_tk[4], pq_tv[4], pq_gl[4], pq_ln[4]; // up to 4 tokens of lookahead +let here, hdelta, hlimit, ptop; +let nloc, lbase, fdepth, fslots, fchk, fret, live, bxdepth, epichain, fframe, infn; +let lsp, loopbase, ctxsp, snaptop; +let lv, lvk, lvi, kw_expr, xcls, fty; +// interned spellings the parser compares against +let s_lp, s_rp, s_lb, s_rb, s_lk, s_rk, s_comma, s_semi, s_eq, s_arrow, s_inc, s_dec; +let s_star, s_amp, s_colon, s_hash, s_minus, s_andand, s_oror; +let s_dot, s_fn, s_var, s_const, s_else, s_as, s_unchecked, s_immediate, s_m, s_d, s_u; +let s_q, s_case, s_default, s_fovf, s_start, s_main, s_free, s_own, s_qnew, s_enhance, s_micro, s_vm; + +// ---- types: kinds, tables and parser state (see the types section) ---- +const TY_WORD = 0, TY_INT = 1, TY_CHAR = 2, TY_BOOL = 3, TY_VOID = 4, TY_PTR = 5, TY_ARR = 6; +const TY_FN = 7, TY_STRUCT = 8, TY_VAR = 9, TY_GEN = 10, TY_DYN = 11; // dyn: []T, a = element, n = 1 if fixed +const R_TY = 0x9C000, R_TYEND = 0xA0000, NTL = 1024; // the first NTL words list every record +const ltype = 0xBE100, ltag = 0xBE300, stype = 0xBE500; // type per local, declared tag per local, type per symbol +let tytop, ntl, tword, tint, tchar, tbool, tvoid; +let tc_on; // the optional typechecker, off unless a program says typecheck on; +let xty, xzero, dry; // type of the last expression, was it a literal 0, and dry runs (typeof) +let tpn[8], ntp; // type parameters in scope +let tvauto; // reading a return type: unknown names are type parameters declared after the function's name +let dty, dtag; // result of dtype() +let s_lt, s_gt, s_shr, s_le, s_ge, s_eqeq, s_ne, s_plus, s_struct, s_type, s_typecheck, s_on, s_off, s_new, s_new_t; +let s_o3, s_lfa, s_outside, s_new_raw, s_oob; +let o3on, o3nxt, o3one, o3sl[32], o3rg[32], no3sl, o3pend[700], no3pend, o3dsc[80]; +let o3free[8], no3free, o3nreg, o3cache[512], argloc, s_hitems, s_hlen, s_fatten; // registers freed by closed scopes; local -> its fixed array's cached items (len next to it) // o3: in an o3 region; the promoted slots; o3 blocks waiting for the function's end +let numops[12], nnumops, s_fixed, s_dlen, s_dcap, s_dnew, s_dat, s_dpush, s_dpop, s_dresize, xconst, xcval; +let gbind[8], ngbind; // explicit type arguments for the next call: f(...) + +// ---- errors ---- +// the compiler reports up to 20 errors before it stops. a syntax error +// (die) skips the token it happened on and sets panic, which skips ahead to +// the next ; or } (or the next top-level item) and keeps quiet until then. +// other errors (serr) just report: the parse is still in step. +let nerr, panic; +fn errat() { puts("zc: line "); putn(tline); puts(": "); nerr++; return 0; } +fn errend() { putc(10); if (nerr >= 20) { puts("zc: too many errors, stopping\n"); halt(); } return 0; } +fn giveup() { puts("zc: "); putn(nerr); if (nerr == 1) puts(" error\n"); else puts(" errors\n"); halt(); return 0; } +fn fatal(msg) { errat(); puts(msg); putc(10); halt(); return 0; } +fn serr(msg) { if (!panic && !dry) { errat(); puts(msg); errend(); } return 0; } +fn serrn(name, msg) { if (!panic && !dry) { errat(); puts(name); puts(": "); puts(msg); errend(); } return 0; } +fn die(msg) { serr(msg); panic = 1; if (tk == T_EOF) giveup(); next(); return 0; } +fn dien(name, msg) { serrn(name, msg); panic = 1; if (tk == T_EOF) giveup(); next(); return 0; } +// analyzer errors only count in checked, reachable code +fn cerr(msg) { if (fchk && live) serr(msg); return 0; } +fn cerrn(i, msg) { if (fchk && live) serrn(lname[i], msg); return 0; } + +// ---- interning ---- +fn hashs(s) { let h = 0; while (*s) { h = h * 31 + *s; s++; } return h & (IHN - 1); } +fn intern(s) +{ + let 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) fatal("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) +{ + let i = nsym; + if (nsym >= NS) fatal("symbol table full"); + nsym++; + sname[i] = name; skind[i] = kind; sval[i] = val; ssig[i] = 0; sflag[i] = F_DEF; sfix[i] = 0; stype[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) +{ + let i = name[-1] - 1; + while (i >= 0) { + if (i >= vislo || skind[i] == K_KW || skind[i] == K_TYPE) 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) +{ + let i = fixfree; + if (i) fixfree = fnext[i]; + else { nfixu++; i = nfixu; if (i >= NF) fatal("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) +{ + let 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 (dry) return 0; if (here >= hlimit) fatal("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) { if (dry) return 0; *(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() { let a = here; lit(MW - 1); return a; } +fn fwdfn(name) { let s = addsym(name, K_FN, tline); sflag[s] = 0; return s; } // the line of the first use, until it's defined +fn fnref(s) +{ + if (sflag[s] & F_DEF) { lit(sval[s]); return 0; } + if (dry) 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) { let 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; } +// an o3 variable's address: lfa(k) is fp + k as one enhancement, which the +// jit specializes on the literal k +fn vaddr(i) +{ + let s; + if (ltag[i] & 16) { s = lookup(s_lfa); if (s >= 0 && skind[s] == K_ENH) { lit(lslot[i]); op(XOP0 + sval[s]); return 0; } } + return laddr(lslot[i]); +} +// registers for an o3 region's variables: the cpu has 7. a variable takes the +// one its region freed last (when a scope closed), or the next unused one +fn o3reset() { no3free = 0; o3nreg = 1; no3sl = 0; return 0; } +fn o3take() { if (no3free) { no3free--; return o3free[no3free]; } if (o3nreg < 8) { o3nreg++; return o3nreg - 1; } return 0; } +fn o3promote(i) +{ + let r; + ltag[i] = ltag[i] - (ltag[i] & 1792); + if (!o3on || larr[i] || no3sl >= 32) return 0; + r = o3take(); + if (!r) return 0; + ltag[i] = ltag[i] + r * 256; + o3sl[no3sl] = lslot[i]; o3rg[no3sl] = r; no3sl++; + return 0; +} +// a fixed []T can't change its items or its length, so o3 code keeps both in +// two hidden variables, loaded when the array variable is set (or when the +// region starts), and indexes through them +fn o3mkcache(i) +{ + let k; + if (!o3on || ltype[i][0] != TY_DYN || !ltype[i][3]) return 0; + k = newloc(s_hitems); fslots++; ltag[k] = 16; o3promote(k); + newloc(s_hlen); fslots++; ltag[k + 1] = 16; o3promote(k + 1); + o3cache[i] = k; + return 0; +} +fn o3refresh(i) +{ + let k = o3cache[i]; + if (!k) return 0; + vaddr(i); op(O_LD); lit(2); op(O_ADD); op(O_LD); vaddr(k); op(O_ST); + vaddr(i); op(O_LD); op(O_LD); vaddr(k + 1); op(O_ST); + return 0; +} +// hands a region to the cpu: install kind 2 is [-, 2, lo, hi, n, slot, register, ...] +fn o3region(lo, hi, sl, rg, n) +{ + let i = 0; + if (hdelta || lo >= hi) return 0; + o3dsc[0] = 0; o3dsc[1] = 2; o3dsc[2] = lo; o3dsc[3] = hi; o3dsc[4] = n; + while (i < n) { o3dsc[5 + i + i] = sl[i]; o3dsc[6 + i + i] = rg[i]; i++; } + install(o3dsc); + return 0; +} +// o3 blocks go to the cpu once their function is done, so every jump in them is final +fn o3flush() +{ + let i = 0, p; + while (i < no3pend) { p = o3pend + i * 67; o3region(p[0], p[1], p + 3, p + 35, p[2]); i++; } + no3pend = 0; + return 0; +} +fn strlit(s) +{ + let 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 12 saved line +// 13 saved token line 14 saved lookahead count 15..30 saved lookahead 31 saved char buffer +fn nextch() +{ + if (chkind == 0) { + if (qdone || eof()) { ch = -1; return 0; } + ch = getc() & 255; + if (ch == 96) { qdone = 1; ch = -1; return 0; } // a backtick ends the source + } else if (chkind == 3) { + ch = (chbase[chptr >> 2] >> ((chptr & 3) * 8)) & 255; + if (ch) chptr++; else ch = -1; + } else { + ch = *chptr & 255; + if (ch) chptr++; else ch = -1; + } + if (ch == 10) line++; + return 0; +} +fn src_push(kind, obj, trans, owned) +{ + let f, i; + isp++; + if (isp >= 32) fatal("sources nested too deeply"); + f = R_SRC + isp * 32; + 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; + f[12] = line; f[13] = tline; f[14] = pq_n; f[31] = chbase; + i = 0; while (i < pq_n) { f[15 + i * 4] = pq_tk[i]; f[16 + i * 4] = pq_tv[i]; f[17 + i * 4] = pq_gl[i]; f[18 + i * 4] = pq_ln[i]; i++; } + pq_n = 0; + if (kind == 1) f[3] = obj[0]; + if (kind == 0) { chkind = 0; qdone = 0; line = 1; nextch(); } + if (kind == 2) { chkind = 2; chptr = obj; line = 1; nextch(); } + if (kind == 3) { chkind = 3; chbase = obj; chptr = 0; line = 1; nextch(); } + return 0; +} +fn src_pop() +{ + let f = R_SRC + isp * 32, i = 0; + tk = f[5]; tv = f[6]; tglue = f[7]; ch = f[8]; chkind = f[9]; chptr = f[10]; + line = f[12]; tline = f[13]; pq_n = f[14]; chbase = f[31]; + while (i < pq_n) { pq_tk[i] = f[15 + i * 4]; pq_tv[i] = f[16 + i * 4]; pq_gl[i] = f[17 + i * 4]; pq_ln[i] = f[18 + i * 4]; i++; } + isp--; + if (f[11]) free(f[1]); + return 0; +} +fn isopch(c) +{ + let 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) +{ + let 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() +{ + let 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() +{ + let n = 0, v, dg; + 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 ((dg = hexv(ch)) >= 0) { v = v * 16 + dg; 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; +} +// one token of lookahead: peek() fills pk_*, next() takes it first +fn next() +{ + let i = 1; + if (pq_n) { + tk = pq_tk[0]; tv = pq_tv[0]; tglue = pq_gl[0]; tline = pq_ln[0]; + while (i < pq_n) { pq_tk[i - 1] = pq_tk[i]; pq_tv[i - 1] = pq_tv[i]; pq_gl[i - 1] = pq_gl[i]; pq_ln[i - 1] = pq_ln[i]; i++; } + pq_n--; + return 0; + } + return next0(); +} +// the k-th token after the current one (k from 0 to 3), into pk_tk and pk_tv +fn peekat(k) +{ + let a, b, c, e; + while (pq_n <= k) { + a = tk; b = tv; c = tglue; e = tline; + next0(); + pq_tk[pq_n] = tk; pq_tv[pq_n] = tv; pq_gl[pq_n] = tglue; pq_ln[pq_n] = tline; pq_n++; + tk = a; tv = b; tglue = c; tline = e; + } + pk_tk = pq_tk[k]; pk_tv = pq_tv[k]; + return 0; +} +fn peek() { return peekat(0); } +fn next0() +{ + let f, q, i; + f = R_SRC + isp * 32; + if (f[0] != 1) { lex(); return 0; } + i = f[2]; + if (i < f[3]) { q = f[1]; tk = q[1 + i * 3]; tv = q[2 + i * 3]; tline = q[3 + i * 3]; 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)) { if (!panic && !dry) { errat(); puts("expected "); puts(s); errend(); } panic = 1; if (tk == T_EOF) giveup(); } return 0; } +fn name() +{ + let 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) +{ + let 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) { let i = 0; while (mnem[i]) { if (mnem[i] == c) return i; i++; } return -1; } +fn emitseq(a, n) +{ + let 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 if (skind[s] == K_ENH) op(XOP0 + sval[s]); else lit(sval[s]); + a = a + 2; + } else { emit(R_SEQ[a]); a++; } + } + return 0; +} +fn addkop(p) { let i = 0; while (i < nkop) { if (kops[i] == p) return 0; i++; } kops[nkop] = p; nkop++; return 0; } +fn binfind(p) { let i = nbin; while (i) { i--; if (bname[i] == p) return i; } return -1; } +fn unfind(p) { let i = nun; while (i) { i--; if (uname[i] == p) return i; } return -1; } +fn asgfind(p) { let 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) +{ + let 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) +{ + let 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) { let 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) { let i = nloc; while (i > lbase) { i--; if (lname[i] == n) return i; } return -1; } +fn newloc(n) +{ + let i = nloc; + if (nloc >= NL) fatal("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; ltype[i] = tword; ltag[i] = 0; o3cache[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) +{ + let 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) +{ + let 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]) serrn(lname[from], "m object is never used"); from++; } + return 0; +} +fn block_close(save) +{ + let i = save, k; + if (o3on) while (i < nloc) { k = (ltag[i] >> 8) & 7; if ((ltag[i] & 16) && k && no3free < 8) { o3free[no3free] = k; no3free++; } i++; } + 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() +{ + let 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) fatal("nesting too deep for the analyzer"); + return b; +} +fn snap_pop(b) { snaptop = b; return 0; } +fn snap_restore(b) +{ + let 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) +{ + let 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 || panic || dry) return 0; + errat(); puts(lname[i]); puts(": "); puts(what); + puts(" (one path leaves it "); puts(statename(sa)); puts(", another "); puts(statename(lstate[i])); puts(")"); + errend(); + return 0; +} +// after an if: the current state is the else path, sa is the then path + +// ---- joins ---- +// where control flow comes back together (after an if, a loop, a switch or +// ?:) every variable has to agree across the paths that reach the join. one +// exception: a variable that became d, or was given away, on some path is dead +// after the join, and the paths where it's still alive free it on the way in +// (fixups). u objects and borrows don't get this treatment: a u object still +// has to leave, and a borrow never changes. +const R_EXIT = 0xBF500, R_EXITEND = 0xBFF00; // exit records: the states at each break +let extop, jps[64], njps; // the paths being joined: [lbase, nloc, triples] +fn jst(p, i) { if (i >= p[1]) return S_PLAIN; return p[2 + 3 * (i - p[0])]; } +fn jow(p, i) { return p[3 + 3 * (i - p[0])]; } +fn jhm(p, i) { return p[4 + 3 * (i - p[0])]; } +// the states at a break, with the jump to patch: [site] then a snapshot +fn exit_rec(site) +{ + let p = R_EXIT + extop, i = lbase, q; + if (extop + 3 + 3 * (nloc - lbase) >= R_EXITEND - R_EXIT) fatal("too many breaks for the analyzer"); + p[0] = site; p[1] = lbase; p[2] = nloc; + q = p + 3; + while (i < nloc) { q[0] = lstate[i]; q[1] = lowner[i]; q[2] = lhome[i]; q = q + 3; i++; } + extop = q - R_EXIT; + return p; +} +fn jadd(p) { if (njps >= 64) fatal("too many paths for the analyzer"); jps[njps] = p; njps++; return 0; } +fn jsame(p, q, i) +{ + let s = jst(p, i), t = jst(q, i); + if (empty(s) && empty(t)) return 1; + return s == t && jhm(p, i) == jhm(q, i) && (s != S_CHILD || jow(p, i) == jow(q, i)); +} +// join the paths in jps over the locals [lbase, n0) into the current states +fn join(n0, what) +{ + let i = lbase, j, p, s, s0, dead, okdead, bad; + if (!njps) return 0; + while (i < n0) { + p = jps[0]; s0 = jst(p, i); + dead = 0; okdead = 1; bad = -1; + j = 0; + while (j < njps) { + s = jst(jps[j], i); + if (s == S_DEAD || s == S_D) dead = 1; + if (s == S_U || s == S_BORROW) okdead = 0; + if (!jsame(p, jps[j], i)) bad = j; + j++; + } + lstate[i] = s0; lowner[i] = jow(p, i); lhome[i] = jhm(p, i); + if (bad < 0) { + if (empty(s0)) { j = 0; while (j < njps) { if (jst(jps[j], i) == S_DEAD) lstate[i] = S_DEAD; j++; } } + } else if (dead && okdead) lstate[i] = S_DEAD; + else if (fchk && !panic && !dry) { + errat(); puts(lname[i]); puts(": "); puts(what); + puts(" (one path leaves it "); puts(statename(s0)); puts(", another "); puts(statename(jst(jps[bad], i))); puts(")"); + errend(); + } + i++; + } + return 0; +} +// on path p: count (and with doit, emit) the frees for what the join made dead but p still owns +fn fixups(p, n0, doit) +{ + let i = lbase, n = 0, s; + if (!fchk) return 0; + while (i < n0) { + s = jst(p, i); + if (lstate[i] == S_DEAD && (s == S_M || s == S_D)) { n++; if (doit) freevar(i); } + i++; + } + return n; +} +// a jump back to the top of a loop: whatever the loop owns has to be as it was +fn backedge(s0) +{ + let p = R_SNAP + s0, i = p[0], e = p[1], s; + if (!fchk || !live) return 0; + if (e > nloc) e = nloc; + while (i < e) { + s = lstate[i]; + if (empty(s) && empty(jst(p, i))) { if (jst(p, i) == S_DEAD) lstate[i] = S_DEAD; } + else if (s != jst(p, i) || lhome[i] != jhm(p, i) || (s == S_CHILD && lowner[i] != jow(p, i))) { + if (s == S_DEAD || s == S_D) cerrn(i, "is given away inside a loop that comes back around to it; give it away on a path that leaves the loop"); + else if (!panic && !dry) { + errat(); puts(lname[i]); puts(": changes state inside a loop; each pass has to leave it as it found it (it went from "); + puts(statename(jst(p, i))); puts(" to "); puts(statename(s)); puts(")"); errend(); + } + } + i++; + } + return 0; +} +// joins two paths that end at the same point, like the branches of if/else: +// path a jumped (through the hole at ja) and path b falls through to here +fn join2(sa, livea, ja, livebv, n0, what) +{ + let sb, nt, cj; + sb = snap_push(); + njps = 0; if (livea) jadd(R_SNAP + sa); if (livebv) jadd(R_SNAP + sb); + join(n0, what); + if (livebv) fixups(R_SNAP + sb, n0, 1); + nt = 0; if (livea) nt = fixups(R_SNAP + sa, n0, 0); + if (nt) { cj = hole(); op(O_JMP); setlit(ja, here); fixups(R_SNAP + sa, n0, 1); setlit(cj, here); } + else setlit(ja, here); + live = livea || livebv; + return 0; +} + +// ---- analyzer rules for the places values flow ---- +// recast: x as u / x as d / x as m +fn recast(c, t) +{ + let 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) +{ + let 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 <= 1) { // untagged parameters are m: a lend + 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 d*x to give it away"); + else if (st == S_U) cerrn(i, "is u; write d*x 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); + if (ltype[p][0] == TY_DYN) { lit(2); op(O_ADD); op(O_LD); } // a []T's elements live in its items object + callname(s_own); + if (o3on && hasptr(xty)) { lit(xty); callname(s_fatten); } + return 0; +} +// a store of class rc into an lvalue of kind k (local or container index i) +fn assigncheck(k, i, rc) +{ + let 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; if (ltag[i] & 15) lstate[i] = ltag[i] & 15; 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; if (ltag[i] & 15) lstate[i] = ltag[i] & 15; + 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_U) cerrn(j, "is u; it has to leave through the block above, not into a borrowed object"); + else { lstate[j] = S_DEAD; lused[j] = 1; emitown(i); } // storing it gives it away + } 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) +{ + let 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 u*x'"); + } + return 0; + } + if (c == C_FRESH) cerr("returns a new object; give the function a .u return type"); + else if (i >= 0) cerrn(i, "is owned and can't be returned from a function whose return type isn't .u"); + return 0; +} +// the last expression of a block expression +fn handup(c) +{ + let 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; +} + +// ---- types ---- +// types are a compiler primitive: records in the type area, hash-consed so +// the same type is always the same pointer and comparing types is comparing +// words. untyped code is typed word, which goes with anything. the records +// stay in memory after compiling, so programs can inspect them. +// t[0] kind t[1] size in words t[2] name t[3] n t[4] a t[5] b t[6] c t[7..] extra +// ptr: a = element arr: a = element, n = length +// fn: a = return type, n = parameter count, b = signature (u m d tags), extra = parameter types +// struct: n = field count (-1 until laid out), a = fields (name, type, offset), +// b = generic template, c = type arguments [n, t1, t2 ...] +// var: a type parameter, n = its index +// gen: a generic struct: n = parameter count, a = fields (name, type), b = field count, c = parameter names + + +fn talloc(n) { let p = tytop; if (tytop + n >= R_TYEND) fatal("the type area is full"); tytop = tytop + n; wfill(p, 0, n); return p; } +fn tnew(kind, size, nm, extra) +{ + let t = talloc(7 + extra); + t[0] = kind; t[1] = size; t[2] = nm; + if (ntl >= NTL) fatal("too many types"); + R_TY[ntl] = t; ntl++; + return t; +} +fn tptr(e) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_PTR && t[4] == e) return t; i++; } + t = tnew(TY_PTR, 1, 0, 0); t[4] = e; + return t; +} +fn tarr(e, n) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_ARR && t[4] == e && t[3] == n) return t; i++; } + t = tnew(TY_ARR, n * tsz(e), 0, 0); t[4] = e; t[3] = n; + return t; +} +fn tfn(ret, np, ps, sig) +{ + let i = 0, j, t; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_FN && t[4] == ret && t[3] == np && t[5] == sig) { + j = 0; while (j < np && t[7 + j] == ps[j]) j++; + if (j == np) return t; + } + i++; + } + t = tnew(TY_FN, 1, 0, np); t[4] = ret; t[3] = np; t[5] = sig; + wcopy(t + 7, ps, np); + return t; +} +// []T, or fixed []T +fn tdyn(e, f) +{ + let i = 0, t; + while (i < ntl) { t = R_TY[i]; if (t[0] == TY_DYN && t[4] == e && t[3] == f) return t; i++; } + t = tnew(TY_DYN, 1, 0, 0); t[4] = e; t[3] = f; + return t; +} +fn tvar(i, nm) +{ + let k = 0, t; + while (k < ntl) { t = R_TY[k]; if (t[0] == TY_VAR && t[3] == i) return t; k++; } + t = tnew(TY_VAR, 1, nm, 0); t[3] = i; + return t; +} +fn tinst(g, args, n) +{ + let i = 0, j, t, v; + while (i < ntl) { + t = R_TY[i]; + if (t[0] == TY_STRUCT && t[5] == g) { + v = t[6]; j = 0; while (j < n && v[1 + j] == args[j]) j++; + if (j == n) return t; + } + i++; + } + v = talloc(n + 1); v[0] = n; wcopy(v + 1, args, n); + t = tnew(TY_STRUCT, 0, g[2], 0); t[3] = -1; t[5] = g; t[6] = v; + return t; +} +// lay out a generic instance on first use +fn tresolve(t) +{ + let g, f, n, i, fs, off = 0, ft, bs[8]; + if (t[0] != TY_STRUCT || t[3] >= 0) return t; + if (t[3] == -2) { serr("a struct can't contain itself by value"); t[3] = 0; return t; } + t[3] = -2; + g = t[5]; n = g[5]; f = g[4]; + wfill(bs, 0, 8); wcopy(bs, t[6] + 1, t[6][0]); + fs = talloc(n * 3 + 1); + i = 0; + while (i < n) { + ft = subst(f[i + i + 1], bs); + fs[i * 3] = f[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = n; + return t; +} +fn tsz(t) { if (t[0] == TY_STRUCT && t[3] < 0) tresolve(t); return t[1]; } +// replace type parameters with what they were bound to (unbound ones become word) +fn subst(t, bs) +{ + let k = t[0], i, n, v[24], vec; + if (k == TY_VAR) { if (bs[t[3]]) return bs[t[3]]; return tword; } + if (k == TY_PTR) return tptr(subst(t[4], bs)); + if (k == TY_ARR) return tarr(subst(t[4], bs), t[3]); + if (k == TY_FN) { n = t[3]; i = 0; while (i < n) { v[i] = subst(t[7 + i], bs); i++; } return tfn(subst(t[4], bs), n, v, t[5]); } + if (k == TY_STRUCT && t[5]) { vec = t[6]; n = vec[0]; i = 0; while (i < n) { v[i] = subst(vec[1 + i], bs); i++; } return tinst(t[5], v, n); } + return t; +} +fn isnum(t) { return t[0] == TY_INT || t[0] == TY_CHAR || t[0] == TY_BOOL; } +fn isagg(t) { return t[0] == TY_ARR || t[0] == TY_STRUCT; } +fn isptr(t) { return t[0] == TY_PTR || t[0] == TY_ARR; } +fn decay(t) { if (t[0] == TY_ARR) return tptr(t[4]); return t; } +fn telem(t) { if (t[0] == TY_PTR || t[0] == TY_ARR) return t[4]; return tword; } +// can a value of type src go where dst is expected? +fn compat(dst, src) +{ + if (dst == src || dst == tword || src == tword) return 1; + if (isnum(dst) && isnum(src)) return 1; + src = decay(src); + if (dst[0] == TY_PTR && src[0] == TY_PTR) { + if (dst[4] == tword || src[4] == tword || dst[4] == tvoid || src[4] == tvoid) return 1; + return dst[4] == src[4]; + } + if ((dst[0] == TY_PTR || dst[0] == TY_FN || dst[0] == TY_DYN) && xzero) return 1; // a literal 0 is a null pointer + if (dst[0] == TY_DYN && src[0] == TY_DYN && dst[4] == src[4]) return dst[3] || !src[3]; // a growable array can't hold a fixed one + return dst == src; +} +fn unify(p, a, bs) +{ + let i, n, pv, av; + if (p[0] == TY_VAR) { i = p[3]; if (!bs[i]) { bs[i] = a; return 1; } return compat(bs[i], a); } + a = decay(a); + if (p[0] == TY_PTR && a[0] == TY_PTR) { if (a[4] == tword) return 1; return unify(p[4], a[4], bs); } + if (p[0] == TY_STRUCT && p[5] && a[0] == TY_STRUCT && a[5] == p[5]) { + pv = p[6]; av = a[6]; n = pv[0]; i = 0; + while (i < n) { if (!unify(pv[1 + i], av[1 + i], bs)) return 0; i++; } + return 1; + } + return compat(p, a); +} +fn tprint(t) +{ + let k = t[0], i, v; + if (k == TY_PTR) { putc('*'); return tprint(t[4]); } + if (k == TY_DYN) { if (t[3]) puts("fixed "); puts("[]"); return tprint(t[4]); } + if (k == TY_ARR) { putc('['); putn(t[3]); putc(']'); return tprint(t[4]); } + if (k == TY_FN) { + if (t[4] == tword) puts("fn"); else tprint(t[4]); + if (t[5] & 1) puts(".u"); + putc('('); + i = 0; + while (i < t[3]) { + if (i) puts(", "); + tprint(t[7 + i]); + if (i < 12 && tparamtag(t, i) == 1) puts(".m"); + if (i < 12 && tparamtag(t, i) == 2) puts(".d"); + i++; + } + putc(')'); + return 0; + } + if (t[2]) puts(t[2]); else puts("?"); + if (k == TY_STRUCT && t[5]) { + v = t[6]; putc('<'); + i = 0; while (i < v[0]) { if (i) puts(", "); tprint(v[1 + i]); i++; } + putc('>'); + } + return 0; +} +fn tcerr(what, want, got) +{ + if (!tc_on || !live || dry || panic) return 0; + errat(); puts("type error: "); puts(what); + puts(": expected "); tprint(want); puts(", got "); tprint(got); + errend(); + return 0; +} +fn tcneed(ok, what, got) +{ + if (ok || !tc_on || !live || dry || panic) return 0; + errat(); puts("type error: "); puts(what); puts(", got "); tprint(got); + errend(); + return 0; +} +fn tpfind(n) { let i = ntp; while (i) { i--; if (tpn[i] == n) return i; } return -1; } +fn istypename(n) +{ + let s; + if (n == s_fixed) return 1; + if (tpfind(n) >= 0) return 1; + if (findloc(n) >= 0) return 0; + s = lookup(n); + return s >= 0 && skind[s] == K_TYPE; +} +// the closing > of a type argument list; splits >> in two +fn closeangle() +{ + if (is_op(s_shr)) { tv = s_gt; return 0; } + expect(s_gt); + return 0; +} +// a type, then any number of (params) after it: int(int, int) is a function +// returning int, fn(int) one returning a plain word +fn ptype() +{ + let t = ptype0(), np, ps[24]; + while (is_op(s_lp)) { + next(); np = 0; + if (!is_op(s_rp)) { while (1) { if (np >= 24) fatal("too many parameters"); ps[np] = ptype(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + t = tfn(t, np, ps, np + np); + } + return t; +} +fn ptype0() +{ + let n, s, t, args[8], na = 0, i; + if (accept(s_star)) return tptr(ptype0()); + if (accept(s_lk)) { + if (accept(s_rk)) return tdyn(ptype0(), 0); // []T: grows + n = cexpr(); expect(s_rk); t = ptype0(); if (n < 0) serr("a negative array length"); return tarr(t, n); + } + if (is_id(s_fixed)) { // fixed []T can't grow; fixed [n]T says what [n]T already means + next(); t = ptype0(); + if (t[0] == TY_DYN) return tdyn(t[4], 1); + if (t[0] != TY_ARR) serr("only arrays can be fixed"); + return t; + } + if (is_id(s_fn)) { next(); if (!is_op(s_lp)) die("fn as a type needs its parameters: fn(int)"); return tword; } + if (tk != T_ID) { die("expected a type"); return tword; } + n = tv; + i = tpfind(n); + if (i >= 0) { next(); return tvar(i, n); } + s = lookup(n); + if (tvauto && (s < 0 || skind[s] != K_TYPE) && ntp < 8) { tpn[ntp] = n; ntp++; next(); return tvar(ntp - 1, n); } // T in T first(...) + if (s < 0 || skind[s] != K_TYPE) { dien(n, "isn't a type"); return tword; } + next(); + t = sval[s]; + if (t[0] != TY_GEN) return t; + expect(s_lt); + while (1) { + if (na >= 8) die("too many type arguments"); + args[na] = ptype(); + if (tsz(args[na]) != 1) serr("type arguments have to be one word (a pointer, a number, or a parameter)"); + na++; + if (!accept(s_comma)) break; + } + closeangle(); + if (na != t[3]) serrn(n, "wrong number of type arguments"); + return tinst(t, args, na); +} +// does a declaration start here? (a type, or a bare .tag) +fn tstart() +{ + let k; + if (tk == T_OP) { + if (tv == s_lk || tv == s_dot) return 1; + if (tv == s_star) { // *T name, **T name ...: look past the stars + k = 0; + while (k < 3) { peekat(k); if (!(pk_tk == T_OP && pk_tv == s_star)) break; k++; } + peekat(k); + return (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) || (pk_tk == T_OP && pk_tv == s_lk); + } + return 0; + } + if (tk != T_ID) return 0; + return tv == s_fn || istypename(tv); +} +// [type] [.tag] +fn dtype() +{ + dty = 0; dtag = 0; + if (!is_op(s_dot)) dty = ptype(); + if (accept(s_dot)) { + if (tv == s_m) dtag = S_M; else if (tv == s_u) dtag = S_U; else if (tv == s_d) dtag = S_D; else die("a tag is .u, .m or .d"); + next(); + } + return 0; +} +// struct name { type field, ... } or struct name { ... } +fn kw_struct() +{ + let n, t, s, nf = 0, buf = R_QBUF, i, fs, off = 0, gen = 0, ft; + next(); + n = name(); + if (is_op(s_lt)) { // generic + next(); ntp = 0; + while (1) { if (ntp >= 8) die("too many type parameters"); tpn[ntp] = name(); ntp++; if (!accept(s_comma)) break; } + closeangle(); + gen = 1; + t = tnew(TY_GEN, 0, n, 0); t[3] = ntp; + fs = talloc(ntp); wcopy(fs, tpn, ntp); t[6] = fs; + } else { t = tnew(TY_STRUCT, 0, n, 0); t[3] = -2; } // -2 while its fields are read + s = addsym(n, K_TYPE, t); + expect(s_lb); + while (!is_op(s_rb)) { + ft = ptype(); + while (1) { + if (nf >= 1000) fatal("too many fields"); + buf[nf + nf] = name(); buf[nf + nf + 1] = ft; nf++; + if (!accept(s_comma)) break; + } + expect(s_semi); + } + next(); + if (gen) { + fs = talloc(nf + nf); wcopy(fs, buf, nf + nf); + t[4] = fs; t[5] = nf; + ntp = 0; + } else { + fs = talloc(nf * 3 + 1); + i = 0; + while (i < nf) { + ft = buf[i + i + 1]; + if (ft == t) { serr("a struct can't contain itself by value; use a pointer"); ft = tword; } + fs[i * 3] = buf[i + i]; fs[i * 3 + 1] = ft; fs[i * 3 + 2] = off; + off = off + tsz(ft); + i++; + } + t[4] = fs; t[1] = off; t[3] = nf; + } + accept(s_semi); + return s; +} +// type name = T; +fn kw_type() { let n; next(); n = name(); expect(s_eq); addsym(n, K_TYPE, ptype()); expect(s_semi); return 0; } +// typecheck on; / typecheck off; +fn kw_typecheck() +{ + next(); + if (is_id(s_on)) tc_on = 1; else if (is_id(s_off)) tc_on = 0; else die("typecheck on or typecheck off"); + next(); expect(s_semi); + return 0; +} +// the field of a struct type, or -1 +fn tfindfield(t, n) { let i = 0; tresolve(t); while (i < t[3]) { if (t[4][i * 3] == n) return i; i++; } return -1; } +// sizeof(T or expr), typeof(T or expr): the expression form is compiled dry, so it never runs +fn typearg() +{ + let t, sb, c; + expect(s_lp); + if (tstart() && !is_op(s_dot)) t = ptype(); + else { + sb = snap_push(); dry++; + c = expr(); rval(); + t = xty; + dry--; snap_restore(sb); snap_pop(sb); + } + expect(s_rp); + return t; +} +// len(a), cap(a), push(a, x), pop(a), resize(a, n): growable arrays. +// len of a [n]T is just n. +fn arrarg() +{ + let c; + expect(s_lp); c = expr(); + argloc = -1; + if (o3on && lv && lvk == LV_LOCAL && o3cache[lvi]) argloc = lvi; + rval(); plainuse(c); + return xty; +} +fn nogrow(t) { if (t[0] == TY_DYN && t[3]) serr("a fixed array can't grow or shrink"); return 0; } +fn kw_len() +{ + let t; + next(); t = arrarg(); expect(s_rp); + if (t[0] == TY_ARR) { op(O_DROP); lit(t[3]); } + else { tcneed(t[0] == TY_DYN || t == tword, "len needs an array", t); if (argloc >= 0) { op(O_DROP); vaddr(o3cache[argloc] + 1); op(O_LD); } else if (o3on && t[0] == TY_DYN) op(O_LD); else callname(s_dlen); } + xty = tint; + return 0; +} +fn kw_cap() { let t; next(); t = arrarg(); expect(s_rp); tcneed(t[0] == TY_DYN || t == tword, "cap needs a []T", t); callname(s_dcap); xty = tint; return 0; } +fn kw_push() +{ + let t, c; + next(); t = arrarg(); nogrow(t); + if (t[0] == TY_DYN && tsz(t[4]) != 1) serr("push takes one-word elements; use resize for structs"); + expect(s_comma); c = expr(); rval(); argcheck(c, 2); + if (t[0] == TY_DYN && !compat(t[4], xty)) tcerr("push", t[4], xty); + if (o3on && t[0] == TY_DYN && hasptr(t[4])) { lit(t[4]); callname(s_fatten); } + expect(s_rp); + callname(s_dpush); xty = tint; + return 0; +} +fn kw_pop() { let t; next(); t = arrarg(); nogrow(t); expect(s_rp); callname(s_dpop); xty = telem(t); if (t[0] == TY_DYN) xty = t[4]; return 0; } +fn kw_resize() { let t, c; next(); t = arrarg(); nogrow(t); expect(s_comma); c = expr(); rval(); plainuse(c); expect(s_rp); callname(s_dresize); xty = tint; return 0; } +fn kw_sizeof() { let t; next(); t = typearg(); lit(tsz(t)); xty = tint; return 0; } +fn kw_typeof() { let t; next(); t = typearg(); lit(t); xty = tword; return 0; } +fn types_init() +{ + tytop = R_TY + NTL; ntl = 0; + tword = tnew(TY_WORD, 1, intern("word"), 0); + tint = tnew(TY_INT, 1, intern("int"), 0); + tchar = tnew(TY_CHAR, 1, intern("char"), 0); + tbool = tnew(TY_BOOL, 1, intern("bool"), 0); + tvoid = tnew(TY_VOID, 0, intern("void"), 0); + addsym(tword[2], K_TYPE, tword); addsym(tint[2], K_TYPE, tint); addsym(tchar[2], K_TYPE, tchar); + addsym(tbool[2], K_TYPE, tbool); addsym(tvoid[2], K_TYPE, tvoid); + s_lt = intern("<"); s_gt = intern(">"); s_shr = intern(">>"); s_le = intern("<="); s_ge = intern(">="); + s_eqeq = intern("=="); s_ne = intern("!="); s_plus = intern("+"); + s_struct = intern("struct"); s_type = intern("type"); s_typecheck = intern("typecheck"); + s_on = intern("on"); s_off = intern("off"); s_new = intern("new"); s_new_t = intern("new_t"); + s_hitems = intern("#items"); s_hlen = intern("#len"); s_fatten = intern("fatten"); + s_o3 = intern("o3"); s_lfa = intern("lfa"); s_outside = intern("outside"); s_new_raw = intern("new_raw"); s_oob = intern("oob"); + s_fixed = intern("fixed"); s_dlen = intern("dlen"); s_dcap = intern("dcap"); s_dnew = intern("dnew"); s_dat = intern("dat"); + s_dpush = intern("dpush"); s_dpop = intern("dpop"); s_dresize = intern("dresize"); + numops[0] = intern("*"); numops[1] = intern("/"); numops[2] = intern("%"); numops[3] = intern("&"); + numops[4] = intern("|"); numops[5] = intern("^"); numops[6] = intern("<<"); numops[7] = s_shr; nnumops = 8; + return 0; +} +fn isnumop(o) { let i = 0; while (i < nnumops) { if (numops[i] == o) return 1; i++; } return 0; } +// the type of a binary operation, checking it when the typechecker is on +fn bintype(b, lt, rt) +{ + let o = bname[b]; + lt = decay(lt); rt = decay(rt); + if (blen[b] < 0) { tcneed(!isagg(lt) && !isagg(rt), "&& and || need scalars", lt); return tbool; } + if (o == s_eqeq || o == s_ne) { if (!compat(lt, rt) && !compat(rt, lt)) tcerr("comparison", lt, rt); return tbool; } + if (o == s_lt || o == s_gt || o == s_le || o == s_ge) { + if (!(lt == tword || rt == tword || (isnum(lt) && isnum(rt)) || (lt[0] == TY_PTR && rt[0] == TY_PTR))) tcerr("comparison", lt, rt); + return tbool; + } + if (o == s_plus) { + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (rt[0] == TY_PTR && isnum(lt)) return rt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("+", lt, rt); return tword; + } + if (o == s_minus) { + if (lt[0] == TY_PTR && rt[0] == TY_PTR) return tint; + if (lt[0] == TY_PTR && (isnum(rt) || rt == tword)) return lt; + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + tcerr("-", lt, rt); return tword; + } + if (isnumop(o)) { + if (lt == tword || rt == tword) return tword; + if (isnum(lt) && isnum(rt)) return tint; + if (isnum(lt)) lt = rt; + tcneed(0, "arithmetic needs numbers", lt); return tword; + } + return tword; // operators a program added +} + +// ---- reflection ---- +// for programs (and parse words) looking at types at runtime +fn tkind(t) { return t[0]; } +fn tsize(t) { return tsz(t); } +fn tname(t) { return t[2]; } +fn tlen(t) { return t[3]; } +fn tnfields(t) { tresolve(t); return t[3]; } +// ---- fattening ---- +// o3's new_raw stamps no type: the header's type word holds -(n + 1), n the +// words asked for. where o3 data reaches normal code (a store outside o3 +// variables, an argument to a normal function, a return, the end of an o3 +// block) the compiler knows its static type t and calls fatten(p, t), which +// stamps the type, zeroes the slack, and does the same for every object p +// reaches through typed pointers. it returns p. +fn hasptr(t) +{ + let k = t[0], i, n; + if (k == TY_PTR || k == TY_DYN) return 1; + if (k == TY_ARR) return hasptr(t[4]); + if (k == TY_STRUCT && !t[5]) { n = tnfields(t); i = 0; while (i < n) { if (hasptr(tftype(t, i))) return 1; i++; } } + return 0; +} +fn fatten(p, t) { fat1(p, t, 32); return p; } +fn fat1(p, t, dl) +{ + let e, n, k, i, es; + if (dl <= 0 || !t || !isobj(p)) return 0; + if (t[0] == TY_DYN) { // a handle is always fat; what it holds may not be + if (hasptr(t[4])) { es = tsz(t[4]); n = p[0]; i = 0; while (i < n) { fatin(p[2] + i * es, t[4], dl - 1); i++; } } + return 0; + } + if (t[0] != TY_PTR || p[-1] >= 0) return 0; + e = t[4]; n = 0 - p[-1] - 1; es = tsz(e); + if (es < 1) es = 1; + if (e == tword || e[0] == TY_VAR) p[-1] = 0; + else if (n > es) p[-1] = tarr(e, 0); + else p[-1] = e; + if (osize(p) > n) wfill(p + n, 0, osize(p) - n); + if (hasptr(e)) { k = n / es; i = 0; while (i < k) { fatin(p + i * es, e, dl - 1); i++; } } + return 0; +} +fn fatin(a, t, dl) +{ + let k = t[0], i, n, o, ft, es; + if (k == TY_PTR || k == TY_DYN) return fat1(a[0], t, dl); + if (k == TY_ARR) { n = t[3]; es = tsz(t[4]); i = 0; while (i < n) { fatin(a + i * es, t[4], dl); i++; } return 0; } + if (k == TY_STRUCT && !t[5]) { n = tnfields(t); i = 0; while (i < n) { o = tfoff(t, i); ft = tftype(t, i); fatin(a + o, ft, dl); i++; } } + return 0; +} +fn tfname(t, i) { tresolve(t); return t[4][i * 3]; } +fn tftype(t, i) { tresolve(t); return t[4][i * 3 + 1]; } +fn tfoff(t, i) { tresolve(t); return t[4][i * 3 + 2]; } +fn tret(t) { return t[4]; } +fn tnparams(t) { return t[3]; } +fn tparam(t, i) { return t[7 + i]; } +fn tparamtag(t, i) { return ((t[5] >> 6) >> (i + i)) & 3; } // 0 untagged (m), 1 .m, 2 .d +fn tretu(t) { return t[5] & 1; } +fn tnargs(t) { if (t[0] != TY_STRUCT || !t[5]) return 0; return t[6][0]; } +fn targ(t, i) { return t[6][1 + i]; } +// the type of a function, by address. untyped functions get one made from their signature +fn sigof(f) +{ + let i = nsym, s = -1, ws[24], n, k; + while (i) { i--; if (skind[i] == K_FN && sval[i] == f && (sflag[i] & F_DEF)) { s = i; break; } } + if (s < 0) return 0; + if (stype[s]) return stype[s]; + n = (ssig[s] >> 1) & 31; k = 0; + while (k < n) { ws[k] = tword; k++; } + return tfn(tword, n, ws, ssig[s]); +} +fn sigofs(nm) { let s = lookups(nm); if (s < 0 || skind[s] != K_FN) return 0; return sigof(sval[s]); } + +// ---- expressions ---- +// every expression leaves its value on the stack, returns its analyzer class, +// and sets xty to its type. lv means the stack holds an address that hasn't +// been loaded yet; structs and arrays are never loaded, their address is +// their value. +fn rval() { if (lv) { if (!isagg(xty)) op(O_LD); lv = 0; } return 0; } +fn kwcall(s, e) +{ + let f = sval[s], old = kw_expr, c; + kw_expr = e; xcls = C_PLAIN; xty = tword; xzero = 0; + f(); + kw_expr = old; + c = xcls; + lv = 0; lvk = LV_NONE; + return c; +} +fn stmtonly() { if (kw_expr) serr("this can't be used inside an expression"); return 0; } +// the arguments of a call. ft is the callee's type (or 0), bs the generic bindings +fn args(tags, ft, bs, fat) +{ + let np = 0, c, pt, t; + expect(s_lp); + if (!is_op(s_rp)) { + while (1) { + c = expr(); rval(); t = xty; + argcheck(c, (tags >> (np + np)) & 3); + if (fat && hasptr(t)) { lit(t); callname(s_fatten); xty = t; } // o3 data handed to normal code + if (ft && np < ft[3]) { pt = ft[7 + np]; if (!unify(pt, xty, bs)) tcerr("argument", subst(pt, bs), xty); } + np++; + if (!accept(s_comma)) break; + } + } + expect(s_rp); + return np; +} +// new(T) and new(T, count): a typed object, its type stamped into the header +fn newtyped() +{ + let t, c; + t = ptype(); + if (t[0] == TY_DYN) { // a growable array: element size, length, type + lit(tsz(t[4])); + if (accept(s_comma)) { c = expr(); rval(); plainuse(c); } + else { lit(0); if (t[3]) serr("a fixed array needs its length: new(fixed []T, n)"); } + lit(t); + expect(s_rp); + callname(s_dnew); + lv = 0; lvk = LV_NONE; xty = t; xzero = 0; + return C_FRESH; + } + if (o3on) { // o3: new_raw(words), no stamp, no zeroing + if (accept(s_comma)) { c = expr(); rval(); plainuse(c); if (tsz(t) != 1) { lit(tsz(t)); op(15); } } + else lit(tsz(t)); + expect(s_rp); + callname(s_new_raw); + lv = 0; lvk = LV_NONE; xty = tptr(t); xzero = 0; + return C_FRESH; + } + if (accept(s_comma)) { + c = expr(); rval(); plainuse(c); + if (tsz(t) != 1) { lit(tsz(t)); op(15); } + lit(tarr(t, 0)); + } else { lit(tsz(t)); lit(t); } + expect(s_rp); + callname(s_new_t); + lv = 0; lvk = LV_NONE; xty = tptr(t); xzero = 0; + return C_FRESH; +} +fn call(s) +{ + let np, tags = 0, ret = 0, ft = stype[s], bs[8]; + if (sname[s] == s_new && skind[s] == K_FN) { + peek(); + if (pk_tk == T_OP && (pk_tv == s_star || pk_tv == s_lk)) { next(); return newtyped(); } + if (pk_tk == T_ID && (istypename(pk_tv) || pk_tv == s_fn)) { next(); return newtyped(); } + } + if (o3on && sname[s] == s_new) { tags = lookup(s_new_raw); if (tags >= 0) s = tags; tags = 0; } + if (sflag[s] & F_SIG) { tags = ssig[s] >> 6; ret = ssig[s] & 1; } + else sflag[s] = sflag[s] | F_UNTYPED; + wfill(bs, 0, 8); + if (ngbind) { wcopy(bs, gbind, ngbind); ngbind = 0; } + np = 0; + if (o3on && !(sflag[s] & F_O3) && sname[s] != s_free) np = 1; // o3 calling normal code: fatten the arguments + np = args(tags, ft, bs, np); + if ((sflag[s] & F_SIG) && np != ((ssig[s] >> 1) & 31)) serrn(sname[s], "wrong number of arguments"); + fnref(s); op(O_CALL); + lv = 0; lvk = LV_NONE; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + if (ret) return C_FRESH; + return C_PLAIN; +} +// an enhancement used like a function: the arguments, then its one opcode +fn enhcall(s) +{ + let nin = ssig[s] & 15, nout = (ssig[s] >> 4) & 15, n = 0, c; + expect(s_lp); + if (!is_op(s_rp)) { while (1) { c = expr(); rval(); plainuse(c); n++; if (!accept(s_comma)) break; } } + expect(s_rp); + if (n != nin) serrn(sname[s], "wrong number of inputs"); + lv = 0; lvk = LV_NONE; xty = tword; xzero = 0; + if (sflag[s] & F_FALLBACK) { fnref(sfix[s] - 1); op(O_CALL); return C_PLAIN; } + op(XOP0 + sval[s]); + if (nout == 0) lit(0); + if (nout > 1) serrn(sname[s], "leaves several values; use it from asm"); + return C_PLAIN; +} +fn primary() +{ + let n, i, s, c; + lv = 0; lvk = LV_NONE; xzero = 0; + xconst = 0; + if (tk == T_NUM) { lit(tv); xzero = tv == 0; xconst = 1; xcval = tv; xty = tint; next(); return C_PLAIN; } + if (tk == T_STR) { strlit(tv); next(); xty = tptr(tchar); 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"); lit(0); xty = tword; return C_PLAIN; + } + if (tk != T_ID) { die("expected an expression"); lit(0); xty = tword; return C_PLAIN; } + n = tv; + i = findloc(n); + if (i >= 0) { + next(); + if (!fchk && tracked(i)) serrn(n, "is tracked by the analyzer and can't be used in unchecked code"); + vaddr(i); + xty = ltype[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); + } + if (s >= 0 && skind[s] == K_TYPE) { dien(n, "is a type, not a value"); lit(0); xty = tword; return C_PLAIN; } + next(); + xty = tword; + if (s >= 0 && skind[s] == K_CONST) { lit(sval[s]); xty = tint; xzero = sval[s] == 0; xconst = 1; xcval = sval[s]; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GVAR) { lit(sval[s]); if (stype[s]) xty = stype[s]; lv = 1; lvk = LV_GLOBAL; return C_PLAIN; } + if (s >= 0 && skind[s] == K_GARR) { lit(sval[s]); if (stype[s]) xty = stype[s]; return C_PLAIN; } + if (s >= 0 && skind[s] == K_ENH) return enhcall(s); + if (s < 0) s = fwdfn(n); + if (is_op(s_lt) && (sflag[s] & F_GEN)) { // f(...) + next(); ngbind = 0; + while (1) { if (ngbind >= 8) die("too many type arguments"); gbind[ngbind] = ptype(); ngbind++; if (!accept(s_comma)) break; } + closeangle(); + if (!is_op(s_lp)) die("expected ( after the type arguments"); + } + if (is_op(s_lp)) return call(s); + fnref(s); + if (stype[s]) xty = stype[s]; + return C_PLAIN; +} +// ++ and -- on the address at the top of the stack +fn incdec(post, dlt) +{ + 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"); + tcneed(isnum(xty) || xty[0] == TY_PTR || xty == tword, "++ and -- need a number or a pointer", xty); + lv = 0; lvk = LV_NONE; xzero = 0; + lit(0); op(O_PICK); op(O_LD); + if (post) { lit(0); op(O_PICK); lit(dlt); op(O_ADD); lit(2); op(O_PICK); op(O_ST); } + else { lit(dlt); 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; +} +// p.x and p->x: a field of a struct, or of the struct a pointer points at +fn field(c) +{ + let n, st, i, b = -1; + next(); + n = name(); + rval(); + if (c == C_FRESH) cerr("use a field of a new object only after binding it to a name"); + else if (c >= C_VAR) { touch(c - C_VAR); b = c - C_VAR; } + st = xty; + if (st[0] == TY_PTR) st = st[4]; + if (st[0] != TY_STRUCT) { + if (!panic && !dry) { errat(); putc('.'); puts(n); puts(": that's a "); tprint(xty); puts(", not a struct or a pointer to one"); errend(); } + xty = tword; lv = 1; lvk = LV_OTHER; return C_PLAIN; + } + i = tfindfield(st, n); + if (i < 0) { + if (!panic && !dry) { errat(); tprint(st); puts(" has no field "); puts(n); errend(); } + xty = tword; lv = 1; lvk = LV_OTHER; return C_PLAIN; + } + if (st[4][i * 3 + 2]) { lit(st[4][i * 3 + 2]); op(O_ADD); } + xty = st[4][i * 3 + 1]; + lv = 1; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + return C_PLAIN; +} +fn postfix() +{ + let c = primary(), b, n, t, et, ft, bs[8], k, ci; + while (1) { + if (tk == T_ID && tv == s_as) { // e as T: same bits, another type + next(); t = ptype(); rval(); xty = t; lvk = LV_NONE; + continue; + } + if (tk != T_OP) return c; + if (tv == s_lk) { + ci = 0; + if (o3on && lv && lvk == LV_LOCAL && o3cache[lvi]) ci = o3cache[lvi]; + 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; } + if (xty[0] == TY_DYN) { // a growable array: bounds-checked, through the runtime + et = xty[4]; + if (ci && lookup(s_outside) >= 0) op(O_DROP); + c = expr(); rval(); plainuse(c); + tcneed(isnum(xty) || xty == tword, "an index has to be a number", xty); + expect(s_rk); + k = lookup(s_outside); + if (ci && k >= 0 && skind[k] == K_ENH) { // a fixed array in o3: through its cached length and items + lit(0); op(O_PICK); vaddr(ci + 1); op(O_LD); op(XOP0 + sval[k]); + k = hole(); op(O_JZ); + vaddr(ci + 1); op(O_LD); callname(s_oob); + setlit(k, here); + vaddr(ci); op(O_LD); op(O_SWAP); + if (tsz(et) != 1) { lit(tsz(et)); op(15); } + op(O_ADD); + } else if (o3on && k >= 0 && skind[k] == K_ENH) { // h i: check i against h[0], then h[2] + i * size + lit(0); op(O_PICK); lit(2); op(O_PICK); op(O_LD); op(XOP0 + sval[k]); + k = hole(); op(O_JZ); + lit(1); op(O_PICK); op(O_LD); callname(s_oob); + setlit(k, here); + op(O_SWAP); lit(2); op(O_ADD); op(O_LD); op(O_SWAP); + if (tsz(et) != 1) { lit(tsz(et)); op(15); } + op(O_ADD); + } else callname(s_dat); + } else { + tcneed(isptr(xty) || xty == tword, "only pointers and arrays can be indexed", xty); + et = telem(xty); + n = 0 - 1; if (xty[0] == TY_ARR && xty[3] > 0) n = xty[3]; + xconst = 0; + c = expr(); rval(); plainuse(c); + if (n >= 0 && xconst && (xcval < 0 || xcval >= n)) serr("the index is out of range for this array"); + tcneed(isnum(xty) || xty == tword, "an index has to be a number", xty); + expect(s_rk); + if (tsz(et) != 1) { lit(tsz(et)); op(15); } + op(O_ADD); + } + lv = 1; xty = et; xzero = 0; + if (b >= 0) { lvk = LV_ELEM; lvi = b; } else lvk = LV_OTHER; + c = C_PLAIN; + continue; + } + if (tv == s_dot || tv == s_arrow) { c = field(c); continue; } + if (tv == s_lp) { // call through a value + rval(); plainuse(c); + ft = 0; + if (xty[0] == TY_FN) ft = xty; + else tcneed(xty == tword, "only functions can be called", xty); + wfill(bs, 0, 8); + n = args(0, ft, bs, o3on); + lit(n); op(O_PICK); op(O_CALL); op(O_SWAP); op(O_DROP); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; + xty = tword; + if (ft) xty = subst(ft[4], bs); + 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() +{ + let c, un, t; + if (tk == T_ID && (tv == s_u || tv == s_m || tv == s_d)) { // u*x, d*x, m*x: recast + t = S_M; if (tv == s_u) t = S_U; if (tv == s_d) t = S_D; + next(); expect(s_star); + c = unary(); rval(); + lvk = LV_NONE; + return recast(c, t); + } + if (tk == T_OP) { + if (tv == s_star) { + next(); c = unary(); rval(); plainuse(c); + tcneed(xty[0] == TY_PTR || xty == tword, "only pointers can be dereferenced", xty); + xty = telem(xty); + lv = 1; lvk = LV_OTHER; xzero = 0; + return C_PLAIN; + } + if (tv == s_amp) { + next(); c = unary(); + if (!lv && !isagg(xty)) die("& needs something addressable"); + if (lv && lvk == LV_LOCAL && (ltag[lvi] & 16)) serr("an o3 variable has no address"); + if (c >= C_VAR) touch(c - C_VAR); + lv = 0; lvk = LV_NONE; xzero = 0; + xty = tptr(xty); + return C_PLAIN; + } + if (tv == s_inc) { next(); unary(); return incdec(0, 1); } + if (tv == s_dec) { next(); unary(); return incdec(0, -1); } + un = unfind(tv); + if (un >= 0) { + next(); c = unary(); rval(); plainuse(c); + emitseq(useq[un], ulen[un]); + xconst = 0; + if (un <= 1) xty = tbool; + else if (xty != tword) { tcneed(isnum(xty), "this operator needs a number", xty); xty = tint; } + lv = 0; lvk = LV_NONE; xzero = 0; + return C_PLAIN; + } + } + return postfix(); +} +fn bin(minp) +{ + let c = unary(), b, p, a, j, lt; + while (tk == T_OP) { + b = binfind(tv); + if (b < 0) return c; + p = bprec[b]; + if (p < minp) return c; + next(); rval(); plainuse(c); + lt = xty; + 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]); + } + xty = bintype(b, lt, xty); + lv = 0; lvk = LV_NONE; c = C_PLAIN; xzero = 0; xconst = 0; + } + 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; } +// c ? a : b +fn ternary(c) +{ + let a, b, s0, sa, livea, live0 = live, n0 = nloc, ca, cb, ta; + rval(); plainuse(c); + next(); + a = hole(); op(O_JZ); + s0 = snap_push(); + ca = expr(); rval(); ta = xty; + if (ca != C_FRESH) plainuse(ca); + livea = live; sa = snap_push(); + b = hole(); op(O_JMP); + expect(s_colon); + setlit(a, here); + snap_restore(s0); live = live0; + cb = expr(); rval(); + if (cb != C_FRESH) plainuse(cb); + join2(sa, livea, b, live, n0, "ends the two sides of ?: in different states"); + snap_pop(s0); + if (!compat(ta, xty) && !compat(xty, ta)) tcerr("the two sides of ?:", ta, xty); + if (ta != tword) xty = ta; + lv = 0; lvk = LV_NONE; xzero = 0; + if (ca == C_FRESH && cb == C_FRESH) return C_FRESH; + if (ca == C_FRESH || cb == C_FRESH) cerr("both sides of ?: have to be new objects, or neither"); + return C_PLAIN; +} +fn expr() +{ + let c = bin(1), k, i, a, rc, lt; + if (tk != T_OP) return c; + if (tv == s_q) return ternary(c); + if (tv == s_eq) { + if (!lv) die("this can't be assigned to"); + k = lvk; i = lvi; lt = xty; + if (isagg(lt)) serr("a whole struct or array can't be assigned; assign its fields"); + next(); + a = o3on && k == LV_LOCAL && (ltag[i] & 16) && !larr[i]; + if (a) op(O_DROP); // an o3 variable: its address comes after the value, so it never waits on the stack across a branch + rc = expr(); rval(); + if (!compat(lt, xty)) tcerr("assignment", lt, xty); + if (a) { lit(0); op(O_PICK); vaddr(i); op(O_ST); o3refresh(i); } + else { + if (o3on && k != LV_ELEM && hasptr(lt)) { lit(lt); callname(s_fatten); } // o3 data going somewhere normal code can see + storekeep(); + } + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + 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"); + lt = xty; + next(); + i = o3on && lvk == LV_LOCAL && (ltag[lvi] & 16) && !larr[lvi]; + if (i) { i = lvi; op(O_DROP); vaddr(i); op(O_LD); i = i + 1; } + else { lit(0); op(O_PICK); op(O_LD); } + lv = 0; + rc = expr(); rval(); plainuse(rc); + emitseq(bseq[abin[a]], blen[abin[a]]); + k = bintype(abin[a], lt, xty); + if (!compat(lt, k)) tcerr("compound assignment", lt, k); + if (i) { lit(0); op(O_PICK); vaddr(i - 1); op(O_ST); } else storekeep(); + lv = 0; lvk = LV_NONE; xty = lt; xzero = 0; + return C_PLAIN; + } + return c; +} +// does the current token start a statement rather than an expression? +fn stmtstart() +{ + let s; + if (tk == T_OP) return tv == s_semi || tv == s_lb || tstart(); + if (tk != T_ID || findloc(tv) >= 0) return 0; + if (tstart()) return 1; + 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() +{ + let save = nloc, c = C_PLAIN, tail = 0, t = tint; + 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; t = xty; + } + next(); + if (tail) c = handup(c); else lit(0); + block_close(save); + fdepth--; bxdepth--; + lv = 0; lvk = LV_NONE; xty = t; xzero = 0; + return c; +} + +// ---- constant expressions ---- +fn cprim() +{ + let 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() +{ + let 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 ---- +// after a syntax error: skip to the end of the statement +fn resync() +{ + while (tk != T_EOF && !is_op(s_semi) && !is_op(s_rb)) next(); + if (is_op(s_semi)) next(); + panic = 0; + return 0; +} +fn stmt() +{ + let s, c; + if (panic) return resync(); + 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 (tstart()) { localdecl(1); 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() +{ + let save = nloc; + expect(s_lb); + fdepth++; + while (!is_op(s_rb)) { if (tk == T_EOF) die("missing }"); stmt(); } + block_close(save); // before the }, so its line is the one reported + next(); + fdepth--; + return 0; +} +// the body of if/while/for: its own block, even without braces +fn substmt() +{ + let save = nloc; + if (is_op(s_lb)) return block(); + fdepth++; + stmt(); + block_close(save); + fdepth--; + return 0; +} +// let a = e, b[10]; or, typed: int a = 1, b; *node.m p = new(node); .u r; +// let infers pointer, struct and function types from the initializer and +// keeps numbers as plain words. +fn localdecl(typed) +{ + let n, i, c, k, t = 0, tg = 0; + if (typed) { dtype(); t = dty; tg = dtag; if (t == tvoid) serr("a variable can't be void"); } + if ((o3on || o3one) && !typed) serr("o3 variables need a type"); + while (1) { + n = name(); + i = newloc(n); + ltag[i] = tg; + if (o3on || o3one) ltag[i] = tg | 16; + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + if (!t) t = tword; + larr[i] = 1; ltype[i] = tarr(t, k); fslots = fslots + tsz(ltype[i]); + } else if (t && isagg(t)) { larr[i] = 1; ltype[i] = t; fslots = fslots + tsz(t); } + else { fslots++; if (t) ltype[i] = t; if (o3on) { o3promote(i); o3mkcache(i); } } + if (accept(s_eq)) { + if (larr[i]) serr("an array or a struct can't be initialized with ="); + c = expr(); rval(); vaddr(i); op(O_ST); o3refresh(i); + if (t) { if (!compat(t, xty)) tcerr("initializer", t, xty); } + else if (!isnum(xty)) ltype[i] = xty; + assigncheck(LV_LOCAL, i, c); + } + if (!accept(s_comma)) break; + } + expect(s_semi); + return 0; +} +fn kw_var() { stmtonly(); next(); return localdecl(0); } +fn kw_if() +{ + let a, b, c, s0, sa, live0, livea, n0 = nloc, nt, cj; + 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(); + join2(sa, livea, b, live, n0, "ends the branches of an if in different states"); + } else { + // the path that skips the then branch still has the states from before it + njps = 0; if (livea) jadd(R_SNAP + sa); if (live0) jadd(R_SNAP + s0); + join(n0, "ends the branches of an if in different states"); + if (livea) fixups(R_SNAP + sa, n0, 1); + nt = 0; if (live0) nt = fixups(R_SNAP + s0, n0, 0); + if (nt) { cj = hole(); op(O_JMP); setlit(a, here); fixups(R_SNAP + s0, n0, 1); setlit(cj, here); } + else setlit(a, here); + live = livea || live0; + } + snap_pop(s0); + return 0; +} +// loop frame: 0 continue target 1 break chain 2 depth 3 snapshot 4 block-expression depth +// loop frame: 0 continue target (-1 for a switch) 2 depth 3 snapshot at the top +// 4 block-expression depth 5 locals at the start 6 its first exit record +fn loop_push(cont, s0) +{ + let f = R_LOOP + lsp * 8; + if (lsp >= 60) fatal("loops nested too deeply"); + f[0] = cont; f[1] = 0; f[2] = fdepth; f[3] = s0; f[4] = bxdepth; f[5] = nloc; f[6] = extop; + lsp++; + return 0; +} +// the end of a loop or switch: join its exits (the fall-out path sc through +// the jump at a, if there is one, and every break) and lay out each path's +// fixups on its way to the end +fn loop_end(a, sc) +{ + let f, p, e, n0, outs = 0; + lsp--; + f = R_LOOP + lsp * 8; + n0 = f[5]; + njps = 0; + if (sc >= 0) jadd(R_SNAP + sc); + p = R_EXIT + f[6]; e = R_EXIT + extop; + while (p < e) { jadd(p + 1); p = p + 3 + 3 * (p[2] - p[1]); } + join(n0, "leaves the loop in different states on different paths"); + live = njps > 0; + p = R_EXIT + f[6]; + while (p < e) { + if (fixups(p + 1, n0, 0)) { setlit(p[0], here); fixups(p + 1, n0, 1); outs = fixnew(hole(), outs); op(O_JMP); } + else outs = fixnew(p[0], outs); + p = p + 3 + 3 * (p[2] - p[1]); + } + if (a >= 0) setlit(a, here); + if (sc >= 0) fixups(R_SNAP + sc, n0, 1); + fixall(outs, here); + extop = f[6]; + return 0; +} +fn kw_while() +{ + let c0 = here, a, s0, sc = -1, c, inf = 0; + stmtonly(); + next(); + s0 = snap_push(); + expect(s_lp); + if (tk == T_NUM && tv) { peek(); if (pk_tk == T_OP && pk_tv == s_rp) inf = 1; } // while (1): no way out but break + c = expr(); rval(); plainuse(c); expect(s_rp); + a = hole(); op(O_JZ); + if (!inf && live) sc = snap_push(); + loop_push(c0, s0); + substmt(); + backedge(s0); + jmp(c0); + loop_end(a, sc); + snap_pop(s0); + return 0; +} +fn kw_for() +{ + let save = nloc, s0, sc = -1, c0, a, b, st, c, inf = 0; + stmtonly(); + next(); + expect(s_lp); + fdepth++; + if (is_id(s_var)) kw_var(); + else if (tstart()) localdecl(1); + 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)) { + if (tk == T_NUM && tv) { peek(); if (pk_tk == T_OP && pk_tv == s_semi) inf = 1; } + c = expr(); rval(); plainuse(c); + } else { lit(1); inf = 1; } + expect(s_semi); + a = hole(); op(O_JZ); + if (!inf && live) sc = snap_push(); + b = hole(); op(O_JMP); + st = here; + if (!is_op(s_rp)) { c = expr(); rval(); op(O_DROP); discard(c); } + expect(s_rp); + jmp(c0); + setlit(b, here); + loop_push(st, s0); + substmt(); + backedge(s0); + jmp(st); + loop_end(a, sc); + snap_pop(s0); + block_close(save); + fdepth--; + return 0; +} +fn kw_break() +{ + let f; + stmtonly(); + next(); expect(s_semi); + if (lsp <= loopbase) { serr("break outside a loop or a switch"); return 0; } + f = R_LOOP + (lsp - 1) * 8; + if (f[4] != bxdepth) { serr("break can't leave a block expression"); return 0; } + exit_vars(f[2] + 1, 0); + if (live) exit_rec(hole()); else hole(); + op(O_JMP); + live = 0; + return 0; +} +fn kw_continue() +{ + let j = lsp - 1, f; + stmtonly(); + next(); expect(s_semi); + while (j >= loopbase && R_LOOP[j * 8] == -1) j--; // past any switch + if (j < loopbase) { serr("continue outside a loop"); return 0; } + f = R_LOOP + j * 8; + if (f[4] != bxdepth) { serr("continue can't leave a block expression"); return 0; } + backedge(f[3]); + exit_vars(f[2] + 1, 0); + jmp(f[0]); + live = 0; + return 0; +} +// switch (e) { case 1, 2: ... case 'x': ... default: ... } +// cases don't fall through: each one ends where the next begins, and break +// leaves the switch early. case labels are constants. +fn casebody(s0, live0) +{ + let save = nloc; + snap_restore(s0); live = live0; + fdepth++; + while (!is_op(s_rb) && !is_id(s_case) && !is_id(s_default)) { if (tk == T_EOF) { die("missing }"); break; } stmt(); } + block_close(save); + fdepth--; + if (live) { exit_rec(hole()); op(O_JMP); } // the end of a case leaves the switch + live = 0; + return 0; +} +fn kw_switch() +{ + let save = nloc, tmp, c, s0, live0, defent = -1, skip, nxt, bj, v, a = -1; + stmtonly(); + next(); + expect(s_lp); c = expr(); rval(); plainuse(c); expect(s_rp); + fdepth++; + tmp = newloc(0); fslots++; // a hidden local holds the value + laddr(lslot[tmp]); op(O_ST); + live0 = live; + s0 = snap_push(); + loop_push(-1, s0); + expect(s_lb); + while (!is_op(s_rb)) { + if (tk == T_EOF) { die("missing }"); break; } + if (is_id(s_case)) { + next(); + bj = 0; + while (1) { + v = cexpr(); + laddr(lslot[tmp]); op(O_LD); lit(v); op(O_SUB); + bj = fixnew(hole(), bj); op(O_JZ); + if (!accept(s_comma)) break; + } + expect(s_colon); + nxt = hole(); op(O_JMP); + fixall(bj, here); + casebody(s0, live0); + setlit(nxt, here); + } else if (is_id(s_default)) { + next(); expect(s_colon); + if (defent >= 0) serr("a switch has one default"); + skip = hole(); op(O_JMP); // only reached when nothing matched + defent = here; + casebody(s0, live0); + setlit(skip, here); + } else die("expected case or default"); + } + next(); + snap_restore(s0); live = live0; + if (defent >= 0) { jmp(defent); loop_end(-1, -1); } + else { a = hole(); op(O_JMP); loop_end(a, s0); } // nothing matched: out with the states from the top + snap_pop(s0); + block_close(save); + fdepth--; + return 0; +} +fn kw_return() +{ + let c; + stmtonly(); + next(); + if (!infn) serr("return outside a function"); + if (bxdepth) serr("return can't leave a block expression"); + if (is_op(s_semi)) { lit(0); c = C_PLAIN; } + else { + c = expr(); rval(); + if (fty == tvoid) tcerr("return value", tvoid, xty); + else if (fty && !compat(fty, xty)) tcerr("return value", fty, xty); + if (o3on && fty && hasptr(fty)) { lit(fty); callname(s_fatten); } + } + expect(s_semi); + retcheck(c); + exit_vars(1, 0); + epichain = fixnew(here, epichain); + lit(MW - 1); op(O_JMP); + live = 0; + return 0; +} +// o3 { ... }: an optimized region. o3 T x = e;: one o3 variable +fn kw_o3() +{ + let lo, i, p, save, outer; + stmtonly(); + next(); + if (!is_op(s_lb)) { o3one = 1; localdecl(1); o3one = 0; return 0; } + if (o3on || !infn) return block(); + lo = here + 2; lit(lo); op(O_JMP); + o3on = 1; o3reset(); + save = nloc; outer = nloc; + i = lbase; + while (i < outer) { if (ltag[i] & 16) { o3promote(i); o3mkcache(i); o3refresh(i); } i++; } // o3 variables declared outside + block(); + o3on = 0; + if (no3pend < 10) { + p = o3pend + no3pend * 67; p[0] = lo; p[1] = here; p[2] = no3sl; + wcopy(p + 3, o3sl, no3sl); wcopy(p + 35, o3rg, no3sl); no3pend++; + } + nloc = save; // the hidden cache variables + i = lbase; + while (i < outer) { + ltag[i] = ltag[i] - (ltag[i] & 1792); o3cache[i] = 0; + if ((ltag[i] & 16) && hasptr(ltype[i])) { vaddr(i); op(O_LD); lit(ltype[i]); callname(s_fatten); op(O_DROP); } // leaving o3: fatten what they hold + i++; + } + return 0; +} +fn kw_unchecked() +{ + let 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() +{ + let 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) fatal("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 && (ltag[i] & 16) && !larr[i]) serr("asm can't reach an o3 variable"); + 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_ENH) { op(XOP0 + sval[s]); next(); continue; } + 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) fatal("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) serrn(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, line for each token. names, +// strings and operators are interned pointers. +.u grab() +{ + let 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 >= 2700) fatal("quote too long"); + R_QBUF[n * 3] = tk; R_QBUF[n * 3 + 1] = tv; R_QBUF[n * 3 + 2] = tline; n++; + next(); + } + next(); + q = new(n * 3 + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n * 3); + return u*q; +} +unchecked .u qnew(src) { let n = src[0] * 3 + 1, q = new(n); wcopy(q, src, n); return q; } +.u qdup(.m q) { let n = q[0] * 3 + 1, r = new(n); wcopy(r, q, n); return u*r; } +fn wcopyto(.m q, n) { let i = 0; while (i < n) { emit(q[i]); i++; } return 0; } +fn kw_quote() +{ + let q, j, a, n; + next(); + q = grab(); + j = hole(); op(O_JMP); + a = here; + n = q[0] * 3 + 1; + wcopyto(q, n); + free(d*q); + setlit(j, here); + lit(a); + callname(s_qnew); + xcls = C_FRESH; + return 0; +} +// tokens of a string, as a token list +.u tokens(s) +{ + let n = 0, q; + src_push(2, s, 0, 0); + next(); + while (tk != T_EOF) { + if (n >= 2700) fatal("too many tokens"); + R_QBUF[n * 3] = tk; R_QBUF[n * 3 + 1] = tv; R_QBUF[n * 3 + 2] = tline; n++; + next(); + } + src_pop(); + q = new(n * 3 + 1); + q[0] = n; + wcopy(q + 1, R_QBUF, n * 3); + return u*q; +} +// 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; } + +// ---- reading a unit and scanning it for signatures ---- +// a unit from stdin is read whole first (4 chars to a word), then scanned +// once for function signatures, so a function's tags are known before its first +// call even when it's defined further down. +unchecked fn readsrc() +{ + let cap = 4090, b = new(4090), n = 0, c, nb, w; + while (!eof()) { + c = getc() & 255; + if (c == 96) break; + if ((n >> 2) + 2 >= cap) { nb = new(cap + cap + 6); wcopy(nb, b, cap); free(b); b = nb; cap = cap + cap + 6; } + w = n >> 2; + if (!(n & 3)) b[w] = 0; + b[w] = b[w] | (c << ((n & 3) * 8)); + n++; + } + b[n >> 2] = b[n >> 2] & (pow2[(n & 3) * 8] - 1); // the 0 at the end + if ((n & 3) == 0) b[n >> 2] = 0; + b[(n >> 2) + 1] = 0; + return b; +} +// skip a <...> group (type parameters) +fn pskipangle() +{ + let dp = 0; + while (tk != T_EOF) { + if (is_op(s_lt)) dp++; + else if (is_op(s_gt)) dp--; + else if (is_op(s_shr)) dp = dp - 2; + next(); + if (dp <= 0) return 0; + } + return 0; +} +// at the name after fn: read the signature's tags and record them +fn prescan_fn(ret, n, o3) +{ + let np = 0, tags = 0, t = 0, dp, s; + next(); // the ( + if (!is_op(s_rp)) { + np = 1; dp = 1; + while (tk != T_EOF) { + if (is_op(s_lp)) dp++; + else if (is_op(s_rp)) { dp--; if (!dp) break; } + else if (dp == 1 && is_op(s_comma)) { if (np <= 12) tags = tags + (t << (np + np - 2)); np++; t = 0; } + else if (dp == 1 && is_op(s_dot)) { next(); if (is_id(s_m)) t = 1; else if (is_id(s_d)) t = 2; continue; } + next(); + } + if (np <= 12) tags = tags + (t << (np + np - 2)); + } + next(); + if (!is_op(s_lb) && !is_op(s_semi)) return 0; // not a function: an enhancement, a call in a parse word... + s = lookup(n); + if (s < 0 || s < ubase || skind[s] != K_FN || (sflag[s] & F_DEF)) s = fwdfn(n); + if (!(sflag[s] & F_SIG)) { ssig[s] = ret + np + np + tags * 64; sflag[s] = sflag[s] | F_SIG | F_PRE; } + if (o3) sflag[s] = sflag[s] | F_O3; + return 0; +} +fn prescan(kind, obj) +{ + let depth = 0, sp = panic, sn = nerr, pend = 0, po3 = 0, n, dep; + dry++; + src_push(kind, obj, 0, 0); + next(); + while (tk != T_EOF) { + if (is_op(s_lb)) depth++; + else if (is_op(s_rb)) { depth--; pend = 0; po3 = 0; } + else if (depth <= 0) { + if (is_op(s_semi)) { pend = 0; po3 = 0; } + else if (is_op(s_dot)) { peek(); if (pk_tk == T_ID && pk_tv == s_u) pend = 1; } + else if (is_id(s_o3)) po3 = 1; + else if (tk == T_ID) { + peek(); + if (pk_tk == T_OP && pk_tv == s_lp) { n = tv; next(); prescan_fn(pend, n, po3); pend = 0; po3 = 0; continue; } + if (pk_tk == T_OP && pk_tv == s_lt) { // list in a type, or first( a generic function + n = tv; next(); dep = 0; + while (tk != T_EOF) { + if (is_op(s_lt)) dep++; else if (is_op(s_gt)) dep--; else if (is_op(s_shr)) dep = dep - 2; + next(); + if (dep <= 0) break; + } + if (is_op(s_lp)) { prescan_fn(pend, n, po3); pend = 0; po3 = 0; } + continue; + } + } + } + next(); + } + src_pop(); + dry--; panic = sp; nerr = sn; + return 0; +} +// compile a whole unit from stdin +fn unit_stdin() +{ + let src = readsrc(); + prescan(3, src); + src_push(3, src, 0, 0); + next(); + unit_top(); + unit_end(ubase); + src_pop(); + free(src); + 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() +{ + let f = R_CTX + ctxsp * 24; + if (ctxsp >= 30) fatal("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; + f[19] = fty; f[20] = ntp; f[21] = xty; wcopy(f + 22, tpn, 2); + return 0; +} +fn ctx_pop() +{ + let 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]; + fty = f[19]; ntp = f[20]; xty = f[21]; wcopy(tpn, f + 22, 2); + return 0; +} + +// ---- functions and the top level ---- +fn fn_begin(chk, ret) +{ + lbase = nloc; fdepth = 1; fslots = 0; fchk = chk && check_on; fret = ret; fty = 0; + live = 1; bxdepth = 0; epichain = 0; infn = 1; loopbase = lsp; lv = 0; lvk = LV_NONE; + return 0; +} +// fp -= frame size, then check the frame stack: past FBOT, reset fp and stop +fn prologue() +{ + let k; + lit(ZFP); op(O_LD); fframe = hole(); op(O_SUB); lit(ZFP); op(O_ST); + if (o3on) return 0; // o3 gave up the frame check + lit(ZFP); op(O_LD); lit(FBOT); op(O_LT); k = hole(); op(O_JZ); + lit(FTOP); lit(ZFP); op(O_ST); callname(s_fovf); + setlit(k, here); + 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(); } + unused_check(lbase); + if (fchk && live) { exit_vars(1, 1); if (fret) cerr("a function returning .u has to end with a return"); } + next(); + return 0; +} +// the rest of a function, after its return type and name: +// int f(int a, *node.m n, .d x, b) { ... } *list.u mk(int n) { ... } +// rty is 0 for fn (a plain word), ret is 1 for a .u return +fn fndef(chk, rty, ret, n) +{ + let s, np = 0, tags = 0, t, sig, i, pn[24], pt[24], pty[24], typed = 0, ft, o3f = o3nxt, lo, hi; + o3nxt = 0; + if (rty || ntp) typed = 1; + 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; + pty[np] = tword; + if (!is_op(s_dot) && ((tk == T_OP && (tv == s_star || tv == s_lk)) || (tk == T_ID && (tv == s_fn || istypename(tv))))) { + pty[np] = ptype(); typed = 1; + if (isagg(pty[np])) serr("structs and arrays are passed by pointer"); + } + if (accept(s_dot)) { // .m lends, .d takes over + if (tv == s_m) t = 1; else if (tv == s_d) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + pn[np] = name(); + if (o3f && pty[np] == tword) serr("o3 parameters need a type"); + 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); + sig = ret + np + np + tags * 64; + if ((sflag[s] & F_SIG) && !(sflag[s] & F_PRE)) { if (ssig[s] != sig) serrn(n, "doesn't match its earlier declaration"); } + else if ((sflag[s] & F_UNTYPED) && (tags || ret)) serrn(n, "was called before its tags were declared; put a prototype above the first call"); + ssig[s] = sig; + sflag[s] = (sflag[s] | F_SIG) - (sflag[s] & F_PRE); + if (ntp) sflag[s] = sflag[s] | F_GEN; + if (typed) { + if (!rty) rty = tword; + ft = tfn(rty, np, pty, sig); + if (stype[s] && stype[s] != ft) serrn(n, "doesn't match its earlier declaration"); + stype[s] = ft; + } + if (accept(s_semi)) { ntp = 0; return s; } + if (sflag[s] & F_DEF) serrn(n, "is defined twice"); + sval[s] = here; + sflag[s] = sflag[s] | F_DEF; + fixall(sfix[s], here); sfix[s] = 0; + fn_begin(chk, ret); + if (typed) fty = rty; + no3pend = 0; + if (o3f) { o3on = 1; o3reset(); sflag[s] = sflag[s] | F_O3; } + prologue(); + i = 0; + while (i < np) { + t = newloc(pn[i]); fslots++; + ltype[t] = pty[i]; + if (o3f) { ltag[t] = 16; o3promote(t); } + 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); } + if (o3f) { // the region starts here: a jump, so the cpu enters it + lo = here + 2; lit(lo); op(O_JMP); + i = 0; while (i < np) { t = lbase + i; o3mkcache(t); o3refresh(t); i++; } + } + body(); + hi = here; + epilogue(); + if (o3f) { o3on = 0; o3region(lo, hi, o3sl, o3rg, no3sl); } + o3flush(); + ntp = 0; + return s; +} +// let g = 1, buf[10]; int g = 3; [10]int buf; point origin; +fn gdecl(typed) { next(); return gdecl2(0, 0, name()); } +fn gdecl2(t, tg, n) +{ + let a, k, s; + if (tg) serr("tags go on locals and parameters, not globals"); + if (t == tvoid) serr("a variable can't be void"); + while (1) { + if (accept(s_lk)) { + k = cexpr(); expect(s_rk); + s = addsym(n, K_GARR, here); + if (!t) t = tword; + stype[s] = tarr(t, k); + k = tsz(stype[s]); + while (k) { emit(0); k--; } + } else if (t && isagg(t)) { + s = addsym(n, K_GARR, here); stype[s] = t; + k = tsz(t); + while (k) { emit(0); k--; } + } else { + a = here; + s = addsym(n, K_GVAR, a); + if (t) stype[s] = t; + 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; + n = name(); + } + expect(s_semi); + return 0; +} +fn gconst() +{ + let n; + next(); + while (1) { n = name(); expect(s_eq); addsym(n, K_CONST, cexpr()); if (!accept(s_comma)) break; } + expect(s_semi); + return 0; +} +// enhance [n] name(a, b) micro "recipe" [else fn]; n outputs, 1 if left out +// enhance [n] name(a, b) vm { asm } [else fn]; +// lays out the descriptor the install opcode reads, and wires it in right +// away (an image wires its own in when it boots). +fn enhdef() +{ + let n, np = 0, nout = 1, dsc, na, pay, len = 0, kind = 0, i, p, s, slot, r, pn[8]; + next(); + if (tk == T_NUM) { if (tv < 0 || tv > 8) serr("an enhancement has at most 8 outputs"); nout = tv; next(); } // enhance 2 divmod(a, b) + n = name(); + expect(s_lp); + if (!is_op(s_rp)) { while (1) { if (np == 8) die("an enhancement takes at most 8 inputs"); pn[np] = name(); np++; if (!accept(s_comma)) break; } } + expect(s_rp); + dsc = here; i = 0; while (i < 7) { emit(0); i++; } + na = here; i = 0; while (i < np) { emit(0); i++; } + i = 0; + while (i < np) { *(na + i + hdelta) = here; p = pn[i]; while (*p) { emit(*p); p++; } emit(0); i++; } + if (accept(s_micro)) { + pay = here; + if (tk != T_STR) die("expected the recipe as a string"); + while (tk == T_STR) { p = tv; while (*p) { emit(*p); p++; } next(); } + emit(0); + } else if (accept(s_vm)) { pay = here; asmblock(); op(O_RET); len = here - pay; kind = 1; } + else die("expected micro or vm"); + slot = nenh; + if (slot >= 512) fatal("all 512 enhancement slots are taken"); + nenh++; + p = dsc + hdelta; + p[0] = slot; p[1] = kind; p[2] = np; p[3] = nout; p[4] = pay; p[5] = len; p[6] = na; + s = addsym(n, K_ENH, slot); + ssig[s] = np + nout * 16 + dsc * 256; + if (accept(s_else)) { r = lookup(tv); if (r < 0) r = fwdfn(tv); next(); sfix[s] = r + 1; } + expect(s_semi); + if (!hdelta) { + r = install(dsc); + if (r < 0) { + if (!sfix[s]) serrn(n, "the enhancement didn't install (see install's codes in core.c)"); + sflag[s] = sflag[s] | F_FALLBACK; + } + } + return 0; +} +// after a syntax error at the top level: skip to something that starts a declaration +fn topsync() +{ + let depth = 0; + while (tk != T_EOF) { + if (is_op(s_lb)) depth++; + else if (is_op(s_rb)) { depth--; if (depth < 0) depth = 0; } + else if (!depth && tk == T_ID && (tv == s_fn || tv == s_var || tv == s_const || tv == s_struct || tv == s_type + || tv == s_enhance || tv == s_typecheck || tv == s_unchecked || tv == s_immediate || tv == s_o3)) break; + next(); + } + panic = 0; + return 0; +} +// after a function's name: declares its type parameters. any the return +// type used were taken on trust; now they get their real numbers +fn genparams() +{ + let i, j, n = 0, ps[8], bs[8]; + if (!is_op(s_lt)) { if (ntp) serrn(tpn[0], "isn't a type"); ntp = 0; return 0; } + next(); + while (1) { if (n >= 8) fatal("too many type parameters"); ps[n] = name(); n++; if (!accept(s_comma)) break; } + closeangle(); + wfill(bs, 0, 8); + i = 0; + while (i < ntp) { + j = 0; + while (j < n && ps[j] != tpn[i]) j++; + if (j == n) serrn(tpn[i], "isn't a type"); else bs[i] = tvar(j, ps[j]); + i++; + } + if (ntp && dty) dty = subst(dty, bs); + wcopy(tpn, ps, n); ntp = n; + return 0; +} +// the return type of a function or the type of a global, with unknown names allowed for now +fn rettype() { tvauto = 1; dtype(); tvauto = 0; return 0; } +fn fndone(s, imm) +{ + let k; + ntp = 0; + if (imm) { + if (hdelta) serr("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; +} +fn topitem() +{ + let chk = 1, imm = 0, s, k, n; + if (panic) return topsync(); + 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; } + o3nxt = 0; + if (is_id(s_o3)) { next(); o3nxt = 1; } + ntp = 0; + if (is_id(s_fn)) { peek(); if (!(pk_tk == T_OP && pk_tv == s_lp)) { next(); n = name(); dty = 0; genparams(); return fndone(fndef(chk, 0, 0, n), imm); } } + if (!chk || imm || o3nxt) { // has to be a function, with a return type + rettype(); n = name(); genparams(); + if (dtag && dtag != S_U) serr("the only return tag is .u"); + if (!is_op(s_lp)) { die("expected a function"); return 0; } + return fndone(fndef(chk, dty, dtag == S_U, n), imm); + } + if (is_id(s_var)) return gdecl(0); + if (is_id(s_struct)) { kw_struct(); return 0; } + if (is_id(s_type)) return kw_type(); + if (is_id(s_typecheck)) return kw_typecheck(); + if (is_id(s_enhance)) return enhdef(); + 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; } + } + if (tstart() || is_op(s_star) || (tk == T_ID && lookup(tv) < 0)) { // int f(...) { }, T first(...) { }, int g = 1; + rettype(); n = name(); + if (is_op(s_lp) || is_op(s_lt)) { + genparams(); + if (dtag && dtag != S_U) serr("the only return tag is .u"); + return fndone(fndef(chk, dty, dtag == S_U, n), 0); + } + if (ntp) { serrn(tpn[0], "isn't a type"); ntp = 0; } + return gdecl2(dty, dtag, n); + } + die("expected a declaration"); + return 0; +} +fn unit_top() { while (tk != T_EOF) topitem(); return 0; } +fn unit_end(from) +{ + let i = from; + panic = 0; + while (i < nsym) { + if (skind[i] == K_FN && !(sflag[i] & F_DEF) && sfix[i]) { tline = sval[i]; serrn(sname[i], "is used but never defined"); } + i++; + } + if (nerr) giveup(); + 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(q, top) +{ + let hop = -1, entry = 0, from = nsym; + ctx_push(); + if (infn) { hop = hole(); op(O_JMP); } + if (top) prescan(1, q); + 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(q) { return compile_list(q, 0); } +fn load(q) { compile_list(q, 1); return 0; } +fn eval(q) { let f = compile_list(q, 0); return f(); } +fn evals(s) { let q = tokens(s), r = eval(q); free(d*q); 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) +{ + let i = from, p; + while (i < nsym) { + if ((skind[i] >= K_FN && skind[i] <= K_CONST) || skind[i] == K_ENH) { + 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) +{ + let 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; + if (p[0] == K_ENH) { if (p[1] >= nenh) nenh = p[1] + 1; install(p[2] >> 8); } + 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) +{ + let sh = here, sd = hdelta, sl = hlimit, sub = ubase, svl = vislo, sns = nsym, sen = nenh, n; + ubase = nsym; vislo = nsym; nenh = 0; + 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); + unit_stdin(); + *(dst + 5) = here; + blob_emit(ubase); + *(dst + 6) = here; + n = here - org; + popsyms(sns); + ubase = sub; vislo = svl; here = sh; hdelta = sd; hlimit = sl; nenh = sen; + 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 + 1024); + 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_dot = intern("."); s_q = intern("?"); s_case = intern("case"); s_default = intern("default"); s_andand = intern("&&"); s_oror = intern("||"); + s_fn = intern("fn"); s_var = intern("let"); 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"); s_fovf = intern("frame_overflow"); + s_enhance = intern("enhance"); s_micro = intern("micro"); s_vm = intern("vm"); + 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, "idiv"); // native divide, wired in by rt.zc + add_binop("%", 10, "imod"); + add_binop("+", 9, "+"); // 3 + add_binop("-", 9, "-"); // 4 + add_binop("<<", 8, "ishl"); // 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("let", 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("switch", kw_switch, 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); + add_kw("sizeof", kw_sizeof, F_EXPR); + add_kw("typeof", kw_typeof, F_EXPR); + add_kw("o3", kw_o3, F_STMT); + add_kw("len", kw_len, F_EXPR); + add_kw("cap", kw_cap, F_EXPR); + add_kw("push", kw_push, F_EXPR); + add_kw("pop", kw_pop, F_EXPR); + add_kw("resize", kw_resize, F_EXPR); + return 0; +} +fn start() +{ + let s, f; + heap_init(); + zc_init(); + blob_load(GORG[5]); + zc_tables(); + types_init(); + here = 0; hdelta = 0; hlimit = HEAP_LO; ptop = 0; + ubase = nsym; vislo = 0; + unit_stdin(); + 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/17-o3-boundaries/code/src/rt.zc b/docs/history/17-o3-boundaries/code/src/rt.zc new file mode 100644 index 0000000..63409b3 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/src/rt.zc @@ -0,0 +1,291 @@ +// ============================================================================ +// 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; + +// ---- virtual enhancements ---- +// install(desc) wires a custom opcode into the cpu (the % opcode). these three +// give the language native division and left shift (zdiv, zmod and zshl +// below are the same thing done in software). they come first, since the +// compiler resolves / % and << to them by name. +fn install(desc) { return asm { desc @ % }; } +enhance idiv(a, b) micro "a = sdiv a b"; +enhance imod(a, b) micro "a = srem a b"; +enhance ishl(a, b) micro "a = shl a b"; +// for o3: an o3 variable's address (fp + k), and a bounds check (1 if i isn't in 0..n-1) +enhance lfa(k) micro "r1 = ld 655360; k = add r1 k"; +enhance outside(i, n) micro "i = ltu i n; i = xor i 1"; + +// ---- 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(s) { let i = 0; while (s[i]) { putc(s[i]); i++; } return 0; } +fn putn(n) +{ + let 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(s) { let n = 0; while (s[n]) n++; return n; } +fn streq(a, b) { let i = 0; while (a[i] && a[i] == b[i]) i++; return a[i] == b[i]; } +fn wcopy(dst, src, n) { let i = 0; while (i < n) { dst[i] = src[i]; i++; } return 0; } +fn wfill(dst, v, n) { let i = 0; while (i < n) { dst[i] = v; i++; } return 0; } + +// ---- arithmetic the hardware doesn't have ---- +let pow2[32]; +let zrem; +fn zudiv(n, dv) +{ + let q = 0, r = 0, i = 30; + if (n < dv) { zrem = n; return 0; } + while (i >= 0) { + r = r + r + ((n >> i) & 1); + q = q + q; + if (r >= dv) { r = r - dv; q++; } + i--; + } + zrem = r; + return q; +} +fn zdiv(a, b) +{ + let 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) { let neg = a < 0; if (b == 0) return a; zdiv(a, b); if (neg) return 0 - zrem; return zrem; } +fn zshl(a, b) { return a * pow2[b & 31]; } + +// ---- heap ---- +// a buddy allocator. the heap is cut into aligned power-of-two chunks, every +// block is a power of two words, and a freed block merges with its buddy +// (the other half of the block they were split from) whenever that one is +// free too, so freed space can be reused at any size. every block has a 6 +// word header before the pointer the program sees: +// p[-6] block size p[-5] size class p[-4] flags (0 free, 1 live, 3 marked) +// p[-3] p ^ MAGIC p[-2] owner (the container that owns it, or 0) +// p[-1] its type (a type record from new(T), 0 from new(n), -(n + 1) from o3's new_raw) +// free blocks sit on a doubly linked list per class, linked through p[0], p[1]. +const HDR = 6; +let hbump, freel[32], gc_runs, gc_freed, gc_auto = 1; + +// the size of the top-level chunk holding heap offset off +fn topsize(off) +{ + let h = HEAP_HI - HEAP_LO, base = 0, sz; + while (h) { + sz = 1; + while (sz + sz <= h) sz = sz + sz; + if (off < base + sz) return sz; + base = base + sz; h = h - sz; + } + return 0; +} +fn fpush(b, k) { b[2] = 0; b[6] = freel[k]; b[7] = 0; if (freel[k]) freel[k][7] = b; freel[k] = b; return 0; } +fn funlink(b, k) +{ + if (b[7]) b[7][6] = b[6]; else freel[k] = b[6]; + if (b[6]) b[6][7] = b[7]; + return 0; +} +fn mkblock(b, k) { b[0] = pow2[k]; b[1] = k; b[2] = 0; b[3] = 0; b[4] = 0; b[5] = 0; return b; } +fn heap_init() +{ + let i = 1, b = HEAP_LO, sz, k; + pow2[0] = 1; + while (i < 32) { pow2[i] = pow2[i - 1] + pow2[i - 1]; i++; } + hbump = HEAP_HI; + wfill(freel, 0, 32); + while (b < HEAP_HI) { + sz = topsize(b - HEAP_LO); k = 0; + while (pow2[k] < sz) k++; + fpush(mkblock(b, k), k); + b = b + sz; + } + return 0; +} +// a free block of class k, split down from a bigger one if needed; 0 if none +fn balloc(k) +{ + let j = k, b, h; + while (j < 32 && !freel[j]) j++; + if (j >= 32) return 0; + b = freel[j]; + funlink(b, j); + while (j > k) { j--; h = b + pow2[j]; fpush(mkblock(h, j), j); } + mkblock(b, k); + return b; +} +let fend; // end of the block bfree last made, for the sweep +// put block b back, merging it with its buddy as long as it can +fn bfree(b) +{ + let k = b[1], sz = pow2[k], off, bud; + while (1) { + off = b - HEAP_LO; + if (sz >= topsize(off)) break; + bud = HEAP_LO + (off ^ sz); + if (bud[2] != 0 || bud[1] != k || bud[0] != sz) break; + funlink(bud, k); + if (bud < b) { b[0] = 0; b[3] = 0; b = bud; } // the upper header is inside the merged block now + else { bud[0] = 0; bud[3] = 0; } + k++; sz = sz + sz; + mkblock(b, k); + } + fpush(mkblock(b, k), k); + fend = b + sz; + return 0; +} +fn isobj(x) { return x >= HEAP_LO + HDR && x < hbump && x[-3] == (x ^ MAGIC) && (x[-4] & 1); } + +// every prologue checks the frame stack; on overflow it resets the frame +// pointer (so this can run at all) and stops +fn frame_overflow() { puts("zy: frame stack overflow\n"); halt(); return 0; } +fn oom() { puts("zc: out of heap memory\n"); halt(); return 0; } +// n words, untyped and not zeroed: what new gives o3 code. the type word +// keeps -(n + 1), so fatten (in the compiler) can type it later +unchecked .u new_raw(n) +{ + let need = n + HDR, k = 3, b, p; + if (n < 0) need = HDR; + while (pow2[k] < need) k++; + b = balloc(k); + if (!b && gc_auto) { gc(); b = balloc(k); } + if (!b) oom(); + p = b + HDR; + b[2] = 1; b[3] = p ^ MAGIC; b[4] = 0; b[5] = 0 - n - 1; + return p; +} +// n words typed t, zeroed +unchecked .u new_t(n, t) +{ + let p = new_raw(n); + p[-1] = t; + wfill(p, 0, p[-6] - HDR); + return p; +} +unchecked .u new(n) { return new_t(n, 0); } +fn osize(p) { if (!isobj(p)) return 0; return p[-6] - HDR; } +fn typeof_obj(p) { if (!isobj(p) || p[-1] < 0) return 0; return p[-1]; } + +// frees p and, recursively, every object p owns +fn release(p) +{ + let b = p - HDR, n = b[0] - HDR, i = 0, w; + b[2] = 2; // going: not live, and not free yet either, so a child's buddy check can't merge into it + while (i < n) { w = p[i]; if (isobj(w) && w[-2] == p) release(w); i++; } + bfree(b); + return 0; +} +unchecked fn free(.d p) { if (isobj(p)) release(p); return 0; } +fn own(c, p) { if (isobj(c)) c[-2] = p; return c; } + +// ---- growable arrays ---- +// a []T is a handle: [len, cap, items, element size]. items is an object the +// handle owns; growing swaps it for a bigger one and moves its children over. +unchecked .u dnew(es, n, t) +{ + let h = new_t(4, t), c = n, it; + if (c < 4) c = 4; + it = new(c * es); + h[0] = n; h[1] = c; h[2] = own(it, h); h[3] = es; + return h; +} +unchecked fn dgrow(h, need) +{ + let c = h[1], it, old = h[2], i = 0, w, n; + if (need <= c) return 0; + while (c < need) c = c + c; + it = new(c * h[3]); + n = h[0] * h[3]; + wcopy(it, old, n); + while (i < n) { w = it[i]; if (isobj(w) && w[-2] == old) w[-2] = it; i++; } // the children move with the elements + h[2] = own(it, h); h[1] = c; + free(old); + return 0; +} +fn oob(i, n) { puts("zy: index "); putn(i); puts(" out of range (length "); putn(n); puts(")\n"); halt(); return 0; } +unchecked fn dat(h, i) { if (i < 0 || i >= h[0]) oob(i, h[0]); return h[2] + i * h[3]; } +unchecked fn dpush(h, .d x) { dgrow(h, h[0] + 1); h[2][h[0]] = x; own(x, h[2]); h[0] = h[0] + 1; return 0; } +unchecked fn dpop(h) { if (!h[0]) oob(-1, 0); h[0] = h[0] - 1; return h[2][h[0]]; } +unchecked fn dresize(h, n) +{ + let old = h[0] * h[3]; + if (n < 0) n = 0; + dgrow(h, n); + if (n * h[3] > old) wfill(h[2] + old, 0, n * h[3] - old); + h[0] = n; + return 0; +} +fn dlen(h) { return h[0]; } +fn dcap(h) { return h[1]; } + +// ---- 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. +let ms_top, ms_over, gc_lo, gc_hi; +fn mark(w) +{ + if (!isobj(w) || (w[-4] & 2)) return 0; + w[-4] = w[-4] | 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() +{ + let p; + while (ms_top) { ms_top--; p = MARK0[ms_top]; markrange(p, p + p[-6] - HDR); } + return 0; +} +fn gc_roots(); +unchecked fn gc() +{ + let 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 < HEAP_HI) { if (b[2] == 3) markrange(b + HDR, b + b[0]); b = b + b[0]; drain(); } + } + b = HEAP_LO; + while (b < HEAP_HI) { + sz = b[0]; + if (b[2] == 1) { bfree(b); n++; b = fend; } // merging may swallow what follows + 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() { let b = HEAP_LO, n = 0; while (b < HEAP_HI) { if (b[2] & 1) n++; b = b + b[0]; } return n; } +// the biggest block that's free right now, in words +fn largest_free() { let k = 31; while (k > 0 && !freel[k]) k--; if (!freel[k]) return 0; return pow2[k]; } diff --git a/docs/history/17-o3-boundaries/code/test.sh b/docs/history/17-o3-boundaries/code/test.sh new file mode 100755 index 0000000..533042d --- /dev/null +++ b/docs/history/17-o3-boundaries/code/test.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# full check: bootstraps the compiler from zc0, verifies the fixpoint, then runs +# the examples and tests on the portable interpreter (host), the arm64 jit under +# qemu, and the llvm backend. needs gcc; the jit half needs aarch64-linux-gnu-gcc +# and qemu-aarch64, the llvm half needs llvm-config and libLLVM (each is skipped +# if 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 < examples/typed.zc | tr '\n' '/')" "last: 4/point is 2 words: x int, y int/vec<*point> is 3 words: len int, cap int, items **point/push is bool(*vec, T.d)/the heap says v is a vec, and v.items[0] is a point/" "$l typed example" + chk "$($vm < examples/wiring.zc)" "16 1234 25 4/9" "$l enhancement example" + 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" + chk "$($vm < tests/types.zc | tr '\n' '/')" "12 5 2 15 56 42 7 14 3/rect *rect *list *list.u(int) T(*list) fn(word.d)/a:point@0 b:point@2 tag:int@4 /point 1 1/" "$l types, generics, reflection" + chk "$($vm < tests/typeok.zc)" "14" "$l a program the typechecker accepts" + chk "$($vm < tests/typeoff.zc)" "6" "$l the typechecker is off by default" + chk "$($vm < tests/enhance.zc)" "100 0 343 3,2 5 -2 0" "$l virtual enhancements" + chk "$($vm < tests/joins.zc)" "0 0 5 80 8 3 9 0" "$l joins free what one path gave away; switch, ?:, no prototypes" + chk "$($vm < tests/buddy.zc)" "131072 262144 1 0" "$l buddy allocator merges freed blocks" + chk "$($vm < tests/borrowmove.zc)" "6" "$l storing into a borrowed object moves it" + chk "$($vm < tests/manyerrors.zc | tr '\n' '/')" "zc: line 3: expected an expression/zc: line 4: x: m object is never used/zc: line 5: type error: initializer: expected *char, got int/zc: line 6: expected ;/zc: 4 errors/" "$l several errors in one run" + chk "$($vm < tests/overflow_return.zc 2>&1)" "zy: return stack overflow" "$l return stack overflow is caught" + chk "$($vm < tests/overflow_data.zc 2>&1)" "zy: data stack overflow" "$l data stack overflow is caught" + chk "$($vm < tests/overflow_frame.zc 2>&1)" "zy: frame stack overflow" "$l frame stack overflow is caught" + chk "$($vm < examples/mandel.zc 2>&1 | md5sum | cut -c1-32)" "f41aecbf2c844168050413cfa832db0e" "$l example: mandelbrot with a fixed-point enhancement" + chk "$($vm < examples/bf.zc 2>&1 | md5sum | cut -c1-32)" "223570983752b17f7ece32e93d5e19e4" "$l example: brainfuck compiled at runtime" + chk "$($vm < examples/dump.zc 2>&1 | md5sum | cut -c1-32)" "757774b00f6b3cd0bfbcba66448a8619" "$l example: struct printer through reflection" + chk "$($vm < examples/tree.zc 2>&1 | md5sum | cut -c1-32)" "b86a2e4e9e31acc294a4ddf86be863f2" "$l example: owning tree frees itself" + chk "$($vm < examples/lang.zc 2>&1 | md5sum | cut -c1-32)" "aa1a18c78b5200129c7c2b315f163d28" "$l example: pipe operator, unless, assert, times" + chk "$($vm < examples/staged.zc 2>&1 | md5sum | cut -c1-32)" "6f790a125c48b0cc7a897cee73ee5627" "$l example: staged code compiled while running" + chk "$($vm < examples/quine.zc 2>&1 | md5sum | cut -c1-32)" "c868ecb9dd7b05224a1bd8a4c32ae788" "$l example: quine" + chk "$($vm < examples/primes.zc 2>&1 | md5sum | cut -c1-32)" "814faffc70dad0ae520c0671c33e73d4" "$l example: o3 prime sieve" + chk "$($vm < examples/life.zc 2>&1 | md5sum | cut -c1-32)" "aefb036b6f9ad1dadfc3e6bb47a6885d" "$l example: game of life" + chk "$($vm < tests/arrays.zc | tr '\n' '/')" "100 128 9801 9801 99 3 4 12 19 8 19 28/0/" "$l growable and fixed arrays" + chk "$($vm < tests/o3.zc)" "3142 42 43 9 57 98781 520625 10192 -18782 1152" "$l o3 regions: loops, calls, recursion, switch, arrays, more vars than registers" + chk "$($vm < tests/o3scopes.zc)" "116" "$l o3 registers shared by scopes, cached fixed arrays" + chk "$($vm < tests/o3fat.zc)" "node node 3 box node [0]int" "$l o3 data gets fattened on the way out" + chk "$($vm < tests/o3_bounds.zc 2>&1)" "zy: index 7 out of range (length 5)" "$l o3 bounds check" + local r; r=$(tests/runerr.sh "$vm" tests/errors | tail -1) + chk "$r" "rejected: $(ls tests/errors/*.zc | wc -l) passed, 0 failed" "$l analyzer rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/typeerrors | tail -1) + chk "$r" "rejected: $(ls tests/typeerrors/*.zc | wc -l) passed, 0 failed" "$l typechecker rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/langerrors | tail -1) + chk "$r" "rejected: $(ls tests/langerrors/*.zc | wc -l) passed, 0 failed" "$l o3 and array misuse is rejected" +} +gcc -O2 -w -DJTYPE=int core.c io_linux.c -o $T/zy +run $T/zy "interp" +chk "$(ZYTRACE=1 $T/zy < tests/o3.zc 2>&1 | grep -c 'micro-ops$')" "8" "every o3 region lifts" +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" + chk "$(ZYTRACE=1 $T/jit < tests/o3.zc 2>&1 | grep -c 'bytes of arm64')" "8" "jit compiles every o3 region to arm64" + 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 +if command -v llvm-config >/dev/null; then + gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c -o $T/zyl $(llvm-config --ldflags --libs) || exit 1 + run $T/zyl "llvm" + chk "$(ZYTRACE=1 $T/zyl < tests/o3.zc 2>&1 | grep -c 'compiled by llvm')" "8" "llvm compiles every o3 region" + printf '#!/bin/sh\nZYHOT=1 exec %s "$@"\n' $T/zyl > $T/llall; chmod +x $T/llall + chk "$($T/llall < tests/types.zc | md5sum)" "$($T/zy < tests/types.zc | md5sum)" "llvm compiling every block agrees" + selfc $T/zyl $T/gl.bin; cmp -s $T/g1.bin $T/gl.bin && chk 1 1 "llvm self-compile matches" || chk 0 1 "llvm self-compile matches" +else echo "skip llvm (no llvm-config)"; fi +echo "$ok passed, $bad failed"; [ $bad = 0 ] diff --git a/docs/history/17-o3-boundaries/code/tests/arrays.zc b/docs/history/17-o3-boundaries/code/tests/arrays.zc new file mode 100644 index 0000000..f8d46d8 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/arrays.zc @@ -0,0 +1,24 @@ +// growable arrays and fixed ones +struct point { int x, y; }; +fn main() +{ + let before = live_objects(); + { + []int a = new([]int); + for (int i = 0; i < 100; i++) push(a, i * i); + putn(len(a)); putc(' '); putn(cap(a)); putc(' '); putn(a[99]); putc(' '); + putn(pop(a)); putc(' '); putn(len(a)); putc(' '); + resize(a, 3); putn(len(a)); putc(' '); putn(a[2]); putc(' '); + fixed []int f = new(fixed []int, 5); + f[4] = 7; putn(f[4] + len(f)); putc(' '); + []point ps = new([]point, 2); + ps[1].y = 9; resize(ps, 10); putn(ps[1].y + len(ps)); putc(' '); + [8]int st; putn(len(st)); putc(' '); + []*point owned = new([]*point); + for (int i = 0; i < 20; i++) { *point p = new(point); p.x = i; push(owned, d*p); } + putn(owned[19].x); putc(' '); + putn(live_objects() - before); putc(10); + } + putn(live_objects() - before); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/basics.zc b/docs/history/17-o3-boundaries/code/tests/basics.zc new file mode 100644 index 0000000..c1f1faf --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/basics.zc @@ -0,0 +1,22 @@ +let table[10]; +let 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() +{ + let i, s = 0, a[5]; + for (i = 0; i < N; i++) table[i] = i * i; + for (let 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); + let b = { let 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); + let x = asm { 2 3 + }; + putn(x); putc(10); + asm { 'o' . 'k' . 10 . } + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/bench.zc b/docs/history/17-o3-boundaries/code/tests/bench.zc new file mode 100644 index 0000000..a7e53f5 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/bench.zc @@ -0,0 +1,30 @@ +// four kernels with and without o3; bench.sh runs each one on each backend +int csum(int lim) { int s = 0; for (int n = 1; n < lim; n++) { int x = n; while (x != 1) { if (x & 1) x = 3 * x + 1; else x = x / 2; s++; } } return s; } +o3 int csum3(int lim) { int s = 0; for (int n = 1; n < lim; n++) { int x = n; while (x != 1) { if (x & 1) x = 3 * x + 1; else x = x / 2; s++; } } return s; } +int sieve(fixed []int f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; } +o3 int sieve3(fixed []int f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; } +int digits(int n) { int s = 0; for (int i = 0; i < n; i++) { int x = i; while (x) { s = s + x % 10; x = x / 10; } } return s; } +o3 int digits3(int n) { int s = 0; for (int i = 0; i < n; i++) { int x = i; while (x) { s = s + x % 10; x = x / 10; } } return s; } +int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } +o3 int fib3(int n) { if (n < 2) return n; return fib3(n - 1) + fib3(n - 2); } +// input: a letter (the kernel; z runs none) and how many times to run it +fn main() +{ + fixed []int f = new(fixed []int, 50000); + let which = getc(), reps = 0, ch = getc(), r = 0; + while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = getc(); } + while (reps > 0) { + if (which == 'a') r = csum(30000); + if (which == 'b') r = csum3(30000); + if (which == 'c') r = sieve(f); + if (which == 'd') r = sieve3(f); + if (which == 'e') r = digits(300000); + if (which == 'f') r = digits3(300000); + if (which == 'g') r = fib(22); + if (which == 'h') r = fib3(22); + reps--; + } + putn(r); putc(10); + free(d*f); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/borrowmove.zc b/docs/history/17-o3-boundaries/code/tests/borrowmove.zc new file mode 100644 index 0000000..43f27b2 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/borrowmove.zc @@ -0,0 +1,2 @@ +fn put(.m box, int v) { *int c = new(int); *c = v; box[0] = c; return 0; } +fn main() { let b = new(1); put(b, 6); putn(*(b[0] as *int)); putc(10); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/buddy.zc b/docs/history/17-o3-boundaries/code/tests/buddy.zc new file mode 100644 index 0000000..2000598 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/buddy.zc @@ -0,0 +1,15 @@ +// the buddy allocator: 20000 small blocks, freed, merge back into one big one +let keep[20000]; +fn main() +{ + let i = 0, p; + while (i < 20000) { keep[i] = new(2); i++; } // 20000 8-word blocks + putn(largest_free()); putc(' '); + i = 0; while (i < 20000) { free(keep[i]); i++; } + putn(largest_free()); putc(' '); + p = new(200000); // only possible if the small blocks merged back + putn(osize(p) >= 200000); putc(' '); + free(d*p); + putn(live_objects()); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/enhance.zc b/docs/history/17-o3-boundaries/code/tests/enhance.zc new file mode 100644 index 0000000..33eb85b --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/enhance.zc @@ -0,0 +1,29 @@ +// custom opcodes: recipes, lifted vm code, several outputs, and a fallback +enhance clampadd(a, b) micro "a = add a b; a = min a 100; a = max a 0"; +enhance cube(x) vm { 0 $ 0 $ * * }; +enhance 2 divmod(a, b) micro "r2 = sdiv a b" "\n r1 = srem a b\n r0 = r2"; +enhance div7(a) micro "a = sdiv a 7"; +enhance urem10(a) micro "a = urem a 10"; +enhance hi(a, b) micro "a = mulhu a b"; +enhance noisy(x) vm { 0 $ . } else soft_noisy; // i/o can't be lifted, so calls use the fallback +fn soft_noisy(x) { return x + 1; } +let qq, rr, seed = 7; +fn rnd() { seed = seed * 1103515245 + 12345; return seed ^ (seed >> 11); } +fn main() +{ + let i = 0, a, bad = 0; + putn(clampadd(70, 50)); putc(' '); putn(clampadd(-50, 2)); putc(' '); putn(cube(7)); putc(' '); + asm { 17 5 divmod rr ! qq ! } + putn(qq); putc(','); putn(rr); putc(' '); + putn(noisy(4)); putc(' '); + putn(hi(-1, -1)); putc(' '); + while (i < 5000) { + a = rnd(); + if (div7(a) != zdiv(a, 7)) bad++; + if (urem10(a) < 0 || urem10(a) > 9) bad++; + if (a / (i + 1) != zdiv(a, i + 1)) bad++; + i++; + } + putn(bad); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/errors/back_to_m.zc b/docs/history/17-o3-boundaries/code/tests/errors/back_to_m.zc new file mode 100644 index 0000000..b8c160f --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/back_to_m.zc @@ -0,0 +1,2 @@ +// expect: x: can't be recast back to m +fn main() { let x = new(3); d*x; m*x; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/borrow_escape.zc b/docs/history/17-o3-boundaries/code/tests/errors/borrow_escape.zc new file mode 100644 index 0000000..ce24480 --- /dev/null +++ b/docs/history/17-o3-boundaries/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() { let x = new(1); f(x); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/branch_mismatch.zc b/docs/history/17-o3-boundaries/code/tests/errors/branch_mismatch.zc new file mode 100644 index 0000000..bd19968 --- /dev/null +++ b/docs/history/17-o3-boundaries/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() { let x = new(1); if (x[0]) take(d*x); else u*x; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/child_dies.zc b/docs/history/17-o3-boundaries/code/tests/errors/child_dies.zc new file mode 100644 index 0000000..67caca9 --- /dev/null +++ b/docs/history/17-o3-boundaries/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() { let p = new(2), c = new(1); p[0] = c; take(d*p); return c[0]; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/child_recast.zc b/docs/history/17-o3-boundaries/code/tests/errors/child_recast.zc new file mode 100644 index 0000000..c9ccd62 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/child_recast.zc @@ -0,0 +1,2 @@ +// expect: c: belongs to a container; recast the container instead +fn main() { let p = new(2), c = new(1); p[0] = c; d*c; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/copy_owned.zc b/docs/history/17-o3-boundaries/code/tests/errors/copy_owned.zc new file mode 100644 index 0000000..862c7ef --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/copy_owned.zc @@ -0,0 +1,2 @@ +// expect: x: is an owned object and can't be copied +fn main() { let x = new(1); let y = x; return y[0]; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/d_into_block.zc b/docs/history/17-o3-boundaries/code/tests/errors/d_into_block.zc new file mode 100644 index 0000000..2d7f526 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/d_into_block.zc @@ -0,0 +1,2 @@ +// expect: x: used after it was given away +fn main() { let x = new(1); d*x; { x[0] = 5; } return x[0]; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/d_kept.zc b/docs/history/17-o3-boundaries/code/tests/errors/d_kept.zc new file mode 100644 index 0000000..dcbfb86 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/d_kept.zc @@ -0,0 +1,2 @@ +// expect: x: d object was never given away +fn main() { let x = new(3); d*x; x[0] = 1; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/discard_u.zc b/docs/history/17-o3-boundaries/code/tests/errors/discard_u.zc new file mode 100644 index 0000000..9293378 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/discard_u.zc @@ -0,0 +1,3 @@ +// expect: can't be thrown away +.u mk() { let p = new(1); return u*p; } +fn main() { mk(); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/give_m.zc b/docs/history/17-o3-boundaries/code/tests/errors/give_m.zc new file mode 100644 index 0000000..cd67896 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/give_m.zc @@ -0,0 +1,3 @@ +// expect: x: is m; write d*x +fn take(.d p) { return p[0]; } +fn main() { let x = new(3); take(x); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/global_store.zc b/docs/history/17-o3-boundaries/code/tests/errors/global_store.zc new file mode 100644 index 0000000..dc0e546 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/global_store.zc @@ -0,0 +1,3 @@ +// expect: x: must be d to be stored in a global +let g; +fn main() { let x = new(1); g = x; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/leak_overwrite.zc b/docs/history/17-o3-boundaries/code/tests/errors/leak_overwrite.zc new file mode 100644 index 0000000..d19b5fd --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/leak_overwrite.zc @@ -0,0 +1,2 @@ +// expect: x: still owns an object +fn main() { let x = new(1); x = new(2); return x[0]; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/lend_d.zc b/docs/history/17-o3-boundaries/code/tests/errors/lend_d.zc new file mode 100644 index 0000000..55ac7e0 --- /dev/null +++ b/docs/history/17-o3-boundaries/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() { let x = new(3); d*x; look(x); take(x); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/loop_move.zc b/docs/history/17-o3-boundaries/code/tests/errors/loop_move.zc new file mode 100644 index 0000000..df3c94a --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/loop_move.zc @@ -0,0 +1,3 @@ +// expect: x: is given away inside a loop that comes back around to it +fn take(.d p) { return p[0]; } +fn main() { let x = new(1); let i = 0; d*x; while (i < 3) { take(x); i++; } return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/plain_return.zc b/docs/history/17-o3-boundaries/code/tests/errors/plain_return.zc new file mode 100644 index 0000000..45fb545 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/plain_return.zc @@ -0,0 +1,3 @@ +// expect: returns a new object; give the function a .u return type +fn mk() { return new(1); } +fn main() { return mk(); } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/return_m.zc b/docs/history/17-o3-boundaries/code/tests/errors/return_m.zc new file mode 100644 index 0000000..b5ef519 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/return_m.zc @@ -0,0 +1,3 @@ +// expect: x: has to be u to be returned +.u mk() { let x = new(1); return x; } +fn main() { let y = mk(); return y[0]; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/tag_mismatch.zc b/docs/history/17-o3-boundaries/code/tests/errors/tag_mismatch.zc new file mode 100644 index 0000000..079f249 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/tag_mismatch.zc @@ -0,0 +1,2 @@ +// expect: c: its tag doesn't match its container's +fn main() { let p = new(2), c = new(1); u*p; p[0] = c; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/u_dropped.zc b/docs/history/17-o3-boundaries/code/tests/errors/u_dropped.zc new file mode 100644 index 0000000..e1ca68a --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/u_dropped.zc @@ -0,0 +1,2 @@ +// expect: x: u object must leave this block +fn main() { let x = new(3); u*x; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/u_skip_level.zc b/docs/history/17-o3-boundaries/code/tests/errors/u_skip_level.zc new file mode 100644 index 0000000..6caeeb3 --- /dev/null +++ b/docs/history/17-o3-boundaries/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() { let r; { { let t = new(1); u*t; r = t; } } return r[0]; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/unchecked_touch.zc b/docs/history/17-o3-boundaries/code/tests/errors/unchecked_touch.zc new file mode 100644 index 0000000..141639d --- /dev/null +++ b/docs/history/17-o3-boundaries/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() { let x = new(1); unchecked { x[0] = 1; } return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/unused.zc b/docs/history/17-o3-boundaries/code/tests/errors/unused.zc new file mode 100644 index 0000000..64aff1f --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/errors/unused.zc @@ -0,0 +1,2 @@ +// expect: x: m object is never used +fn main() { let x = new(3); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/errors/use_after_give.zc b/docs/history/17-o3-boundaries/code/tests/errors/use_after_give.zc new file mode 100644 index 0000000..8a10922 --- /dev/null +++ b/docs/history/17-o3-boundaries/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() { let x = new(3); take(d*x); return x[0]; } diff --git a/docs/history/17-o3-boundaries/code/tests/gc.zc b/docs/history/17-o3-boundaries/code/tests/gc.zc new file mode 100644 index 0000000..41f14a0 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/gc.zc @@ -0,0 +1,20 @@ +let keep; +unchecked fn churn(n) +{ + let i = 0, p; + while (i < n) { p = new(10); p[0] = i; if (i % 100 == 0) keep = p; i++; } + return 0; +} +fn main() +{ + let 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/17-o3-boundaries/code/tests/joins.zc b/docs/history/17-o3-boundaries/code/tests/joins.zc new file mode 100644 index 0000000..913929b --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/joins.zc @@ -0,0 +1,32 @@ +// joins: something given away on one path is dead afterwards, and the paths +// that still own it free it on the way in. nothing here leaks. +fn take(.d p) { return p[0]; } +fn later(.d p); // not needed any more, but still allowed +*int.u mk(int v) { *int p = new(int); *p = v; return u*p; } +fn count(int n) { let s = 0; switch (n % 4) { case 0: s = 10; case 1, 2: s = 20; break; default: s = 30; } return s; } +fn main() +{ + let base = live_objects(), i = 0, hits = 0, k; + while (i < 50) { + let x = mk(i); + if (i % 3 == 0) take(d*x); // else: freed here by the fixup + i++; + } + putn(live_objects() - base); putc(' '); + // give away and break: fine now; the normal exit frees it + i = 0; + let y = mk(7); + while (i < 10) { if (i == 4) { take(d*y); break; } i++; } + putn(live_objects() - base); putc(' '); + let z = mk(5); + while (1) { if (z[0] == 5) { hits = take(d*z); break; } } + putn(hits); putc(' '); + putn(count(0) + count(1) + count(2) + count(3)); putc(' '); + k = i > 3 ? i * 2 : 0 - 1; + putn(k); putc(' '); + putn(forward(new(int))); putc(' '); // tagged and defined below: the prescan knows .d + **int pp; *int q = new(int); *q = 9; pp = &q; putn(**pp); free(d*q); putc(' '); + putn(live_objects() - base); putc(10); + return 0; +} +fn forward(*int.d p) { return 3 + *p; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/const_index.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/const_index.zc new file mode 100644 index 0000000..03e927b --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/const_index.zc @@ -0,0 +1,2 @@ +// expect: the index is out of range for this array +fn main() { [4]int a; a[4] = 1; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_nolen.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_nolen.zc new file mode 100644 index 0000000..b79c31e --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_nolen.zc @@ -0,0 +1,2 @@ +// expect: a fixed array needs its length +fn main() { fixed []int f = new(fixed []int); free(d*f); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_push.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_push.zc new file mode 100644 index 0000000..a19bcb4 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_push.zc @@ -0,0 +1,2 @@ +// expect: a fixed array can't grow or shrink +fn main() { fixed []int f = new(fixed []int, 3); push(f, 1); free(d*f); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_to_dyn.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_to_dyn.zc new file mode 100644 index 0000000..483f62f --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/fixed_to_dyn.zc @@ -0,0 +1,4 @@ +// expect: type error: argument: expected []int, got fixed []int +typecheck on; +int take([]int.m g) { return len(g); } +fn main() { fixed []int f = new(fixed []int, 3); take(f); free(d*f); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/gen_undeclared.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/gen_undeclared.zc new file mode 100644 index 0000000..919fb51 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/gen_undeclared.zc @@ -0,0 +1,3 @@ +// expect: T: isn't a type +T first(*int l) { return l[0]; } +fn main() { return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/o3_addr.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_addr.zc new file mode 100644 index 0000000..815253d --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_addr.zc @@ -0,0 +1,2 @@ +// expect: an o3 variable has no address +fn main() { o3 int z = 2; *int q = &z; return *q; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/o3_asm.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_asm.zc new file mode 100644 index 0000000..c8afb44 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_asm.zc @@ -0,0 +1,2 @@ +// expect: asm can't reach an o3 variable +fn main() { o3 int zz = 2; asm { zz @ _ } return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/o3_let.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_let.zc new file mode 100644 index 0000000..d2aff9a --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_let.zc @@ -0,0 +1,2 @@ +// expect: o3 variables need a type +fn main() { o3 { let x = 1; x++; } return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/langerrors/o3_param.zc b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_param.zc new file mode 100644 index 0000000..5694720 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/langerrors/o3_param.zc @@ -0,0 +1,3 @@ +// expect: o3 parameters need a type +o3 int f(x) { return x; } +fn main() { return f(1); } diff --git a/docs/history/17-o3-boundaries/code/tests/manyerrors.zc b/docs/history/17-o3-boundaries/code/tests/manyerrors.zc new file mode 100644 index 0000000..f4c0c68 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/manyerrors.zc @@ -0,0 +1,6 @@ +// several errors in one run: a syntax error, an analyzer error, a type error +typecheck on; +fn f() { let a = ; return 0; } +fn g() { let x = new(3); return 0; } +int h() { *char s = 5; return 1; } +fn main() { return 0 } diff --git a/docs/history/17-o3-boundaries/code/tests/meta.zc b/docs/history/17-o3-boundaries/code/tests/meta.zc new file mode 100644 index 0000000..bc89454 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/meta.zc @@ -0,0 +1,46 @@ +fn ipow(a, b) { let 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() +{ + let 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() +{ + let n, body, i = 0; + next(); n = tv; next(); + body = grab(); + while (i < n) { feed(qdup(body)); i++; } + free(d*body); + 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); + let q = quote { putn(40 + 2); putc(10); return 7; }; + putn(q[0]); putc(' '); + putn(eval(q)); putc(10); + let f = compile(q); + putn(f()); putc(10); + free(d*q); + let defs = quote { fn sq(x) { return x * x; } }; + load(defs); + free(d*defs); + putn(evals("return sq(12);")); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/misc.zc b/docs/history/17-o3-boundaries/code/tests/misc.zc new file mode 100644 index 0000000..25fc53b --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/misc.zc @@ -0,0 +1,30 @@ +// ct { ... } runs a block while compiling and leaves its result as a constant +immediate fn ct() +{ + let q, v; + next(); + q = grab(); + v = eval(q); + free(d*q); + 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 { let 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() { let p = new(3); p[0] = 'o'; p[1] = 'k'; return p; } diff --git a/docs/history/17-o3-boundaries/code/tests/o3.zc b/docs/history/17-o3-boundaries/code/tests/o3.zc new file mode 100644 index 0000000..296d1d5 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/o3.zc @@ -0,0 +1,83 @@ +// o3 regions: every kind of control flow, against the same code without o3 +struct pt { int x; int y; }; +int g = 3; +int sq(int x) { return x * x; } +o3 int collatz(int n) +{ + int steps = 0; + while (n != 1) { if (n % 2 == 0) n = n / 2; else n = 3 * n + 1; steps++; } + return steps; +} +o3 int ack(int am, int n) +{ + if (am == 0) return n + 1; + if (n == 0) return ack(am - 1, 1); + return ack(am - 1, ack(am, n - 1)); +} +o3 int many(int a, int b, int c) +{ + int dd = a + b, e = b + c, f = c + a, h = dd * e, i2 = e * f, j = f * dd, k = h + i2 + j, l = k / 7; + for (int t = 0; t < 5; t++) { dd += t; e -= t; f = f ^ t; l = l + dd * e - f; } + return dd + e + f + h + i2 + j + k + l; +} +o3 int mix(int n) +{ + int acc = 0; + for (int i = 0; i < n; i++) { + if (i % 3 == 0 && i % 5 == 0) acc += 15; + else if (i % 3 == 0 || i > 90) acc += 3; + else acc = acc + (i & 1 ? sq(i) : g); + switch (i % 4) { case 0: acc += 1; case 1: acc -= 2; default: acc = acc ^ 1; } + if (acc > 100000) break; + if (i == 7) continue; + acc = acc + i / 10 - i % 7 + (i << 2) - (i >> 1); + } + return acc; +} +o3 int dyn(int n) +{ + []int a = new([]int, n); + fixed []int f = new(fixed []int, n); + int s = 0; + for (int i = 0; i < len(a); i++) { a[i] = i * i; f[i] = n - i; } + for (int i = 0; i < n; i++) s = s + a[i] * f[i]; + free(d*a); free(d*f); + return s; +} +o3 int pts(int n) +{ + *pt p = new(pt); + int s = 0; + p->x = 1; p->y = 2; + for (int i = 0; i < n; i++) { p->x = p->x + p->y; p->y = p->x - p->y; s = s + p->x % 1000; } + free(d*p); + return s; +} +o3 int divs(int x) +{ + int s = 0; + for (int i = -50; i < 50; i++) s = s + (x + i) / 7 + (x + i) % 7 + (x - i) / -3 + i / 16 + i % 16; + return s; +} +fn main() +{ + o3 int lone = 2; + let r = 0; + lone = lone * 21; + o3 { + int i = 0, s = 0; + while (i < 100) { s = s + collatz(i + 1); i++; } + putn(s); putc(' '); + putn(lone); putc(' '); + lone++; + } + putn(lone); putc(' '); + putn(ack(2, 3)); putc(' '); + putn(many(1, 2, 3)); putc(' '); + putn(mix(100)); putc(' '); + putn(dyn(50)); putc(' '); + putn(pts(30)); putc(' '); + putn(divs(1000)); putc(' '); + putn(divs(-77)); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/o3_bounds.zc b/docs/history/17-o3-boundaries/code/tests/o3_bounds.zc new file mode 100644 index 0000000..fb347c0 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/o3_bounds.zc @@ -0,0 +1,2 @@ +// an index outside a []T inside o3 code: caught by the inline check +fn main() { []int a = new([]int, 5); o3 { int i = 7; a[i] = 1; } free(d*a); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/o3fat.zc b/docs/history/17-o3-boundaries/code/tests/o3fat.zc new file mode 100644 index 0000000..313c87c --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/o3fat.zc @@ -0,0 +1,22 @@ +// o3 objects reaching normal code get their types: through a return (all the way down the list), an assignment, a store into a field +struct node { int v; *node next; }; +struct box { [3]*node slots; int n; }; +unchecked o3 *node build(int n) +{ + *node head = 0; + for (int i = 0; i < n; i++) { *node k = new(node); k.v = i; k.next = head; head = k; } + return head; +} +unchecked fn main() +{ + *node l = build(5); + tprint(typeof_obj(l)); putc(' '); tprint(typeof_obj(l.next.next.next)); putc(' '); + putn(l.next.v); putc(' '); + *box b = 0; + o3 { b = new(box); b.slots[1] = new(node); b.n = 2; } + tprint(typeof_obj(b)); putc(' '); tprint(typeof_obj(b.slots[1])); putc(' '); + *int raw = 0; + o3 { raw = new(int, 6); } + tprint(typeof_obj(raw)); putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/o3scopes.zc b/docs/history/17-o3-boundaries/code/tests/o3scopes.zc new file mode 100644 index 0000000..9457c77 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/o3scopes.zc @@ -0,0 +1,19 @@ +// registers reused by scopes that never overlap, and a fixed array read through its cached items and length +o3 int scopes(fixed []int f) +{ + int total = 0; + for (int a = 0; a < 3; a++) { int x = a * 2; total += x; } + for (int b = 0; b < 3; b++) { int y = b * 3; total += y; } + for (int c = 0; c < 3; c++) { int z = c * 5; total += z; } + for (int e = 0; e < len(f); e++) { int w = f[e]; total += w; } + for (int g = 0; g < 4; g++) { int h = g + 1, q = h * h, r = q - 1; total += r; } + return total; +} +fn main() +{ + fixed []int f = new(fixed []int, 4); + for (int i = 0; i < 4; i++) f[i] = 10 * i; + putn(scopes(f)); putc(10); + free(d*f); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/overflow_data.zc b/docs/history/17-o3-boundaries/code/tests/overflow_data.zc new file mode 100644 index 0000000..3042f0a --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/overflow_data.zc @@ -0,0 +1 @@ +fn main() { while (1) asm { 1 } return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/overflow_frame.zc b/docs/history/17-o3-boundaries/code/tests/overflow_frame.zc new file mode 100644 index 0000000..3897bf4 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/overflow_frame.zc @@ -0,0 +1,2 @@ +fn big(n) { let a[500]; a[0] = n; return big(n + 1) + a[0]; } +fn main() { return big(0); } diff --git a/docs/history/17-o3-boundaries/code/tests/overflow_return.zc b/docs/history/17-o3-boundaries/code/tests/overflow_return.zc new file mode 100644 index 0000000..9d5c622 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/overflow_return.zc @@ -0,0 +1,2 @@ +fn deep(n) { return deep(n + 1) + 1; } +fn main() { return deep(0); } diff --git a/docs/history/17-o3-boundaries/code/tests/runerr.sh b/docs/history/17-o3-boundaries/code/tests/runerr.sh new file mode 100755 index 0000000..23ea054 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/runerr.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# runs every .zc in a folder (tests/errors by default) and checks the compiler +# rejects it with the message on its first line: // expect: ... +vm=${1:-zy}; dir=${2:-$(dirname "$0")/errors}; pass=0; fail=0 +for f in "$dir"/*.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 "rejected: $pass passed, $fail failed" diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/arg.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/arg.zc new file mode 100644 index 0000000..909672a --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/arg.zc @@ -0,0 +1,5 @@ +// expect: type error: argument: expected *point, got *int +typecheck on; +struct point { int x, y; }; +int f(*point p) { return p.x; } +fn main() { *int q = new(int); f(q); free(d*q); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/arith.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/arith.zc new file mode 100644 index 0000000..76e3111 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/arith.zc @@ -0,0 +1,3 @@ +// expect: type error: arithmetic needs numbers, got *int +typecheck on; +fn main() { *int p = 0; int x = p * 2; return x; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/assign.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/assign.zc new file mode 100644 index 0000000..8b8a888 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/assign.zc @@ -0,0 +1,3 @@ +// expect: type error: initializer: expected *char, got int +typecheck on; +fn main() { *char s = 5; return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/call.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/call.zc new file mode 100644 index 0000000..7b03dbf --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/call.zc @@ -0,0 +1,3 @@ +// expect: type error: only functions can be called, got int +typecheck on; +fn main() { int k = 3; return k(1); } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/deref.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/deref.zc new file mode 100644 index 0000000..ed030f5 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/deref.zc @@ -0,0 +1,3 @@ +// expect: type error: only pointers can be dereferenced, got int +typecheck on; +fn main() { int x = 3; return *x; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/field.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/field.zc new file mode 100644 index 0000000..ba03697 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/field.zc @@ -0,0 +1,3 @@ +// expect: point has no field z +struct point { int x, y; }; +fn main() { point p; return p.z; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/generic.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/generic.zc new file mode 100644 index 0000000..49f2c10 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/generic.zc @@ -0,0 +1,4 @@ +// expect: type error: argument: expected int, got *char +typecheck on; +T same(T a, T b) { return a; } +fn main() { return same(1, "x"); } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/notstruct.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/notstruct.zc new file mode 100644 index 0000000..0dff6bd --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/notstruct.zc @@ -0,0 +1,2 @@ +// expect: .x: that's a int, not a struct or a pointer to one +fn main() { int n = 1; return n.x; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/ret.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/ret.zc new file mode 100644 index 0000000..be951d5 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/ret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected bool, got *char +typecheck on; +bool f() { return "no"; } +fn main() { return f(); } diff --git a/docs/history/17-o3-boundaries/code/tests/typeerrors/voidret.zc b/docs/history/17-o3-boundaries/code/tests/typeerrors/voidret.zc new file mode 100644 index 0000000..86c9c17 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeerrors/voidret.zc @@ -0,0 +1,4 @@ +// expect: type error: return value: expected void, got int +typecheck on; +void f() { return 3; } +fn main() { f(); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeoff.zc b/docs/history/17-o3-boundaries/code/tests/typeoff.zc new file mode 100644 index 0000000..e44e450 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeoff.zc @@ -0,0 +1,2 @@ +// the typechecker is off unless asked for: this mismatch compiles and runs +fn main() { *char s = 5; putn(s as int + 1); putc(10); return 0; } diff --git a/docs/history/17-o3-boundaries/code/tests/typeok.zc b/docs/history/17-o3-boundaries/code/tests/typeok.zc new file mode 100644 index 0000000..93462bd --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/typeok.zc @@ -0,0 +1,21 @@ +// passes the typechecker: words mix with everything, literal 0 is null, +// arrays decay to pointers, generic calls bind their parameters +typecheck on; +struct pair { A a; B b; }; +*pair.u mk(A x, B y) { *pair p = new(pair); p.a = x; p.b = y; return u*p; } +A left(*pair p) { return p.a; } +int strlen2(*char s) { int n = 0; while (s[n]) n++; return n; } +int main() { + *pair p = mk(3, "four"); + int a = left(p); + *char s = p.b; + [8]char buf; + *char q = buf; + *int nothing = 0; + let w = 5; + int mixed = w + 1; + q[0] = 'h'; q[1] = 0; + putn(a + strlen2(s) + strlen2(buf) + mixed); putc(10); + free(d*p); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/types.zc b/docs/history/17-o3-boundaries/code/tests/types.zc new file mode 100644 index 0000000..c988499 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/types.zc @@ -0,0 +1,56 @@ +struct point { int x, y; }; +struct rect { point a, b; int tag; }; +struct list { int len; *T items; }; +struct node { int v; *node next; }; +type num = int; + +int counter = 5; +[4]int squares; +point origin; + +int area(*rect r) { return (r.b.x - r.a.x) * (r.b.y - r.a.y); } +*list.u mklist(int cap) { + *list l = new(list); + l.len = 0; + l.items = new(T, cap) as *T; + return u*l; +} +T first(*list l) { return l.items[0]; } +int sum(*node n) { int s = 0; while (n) { s += n.v; n = n.next; } return s; } + +fn main() +{ + rect r; + r.a.x = 1; r.a.y = 2; r.b.x = 4; r.b.y = 6; + putn(area(&r)); putc(' '); + putn(sizeof(rect)); putc(' '); putn(sizeof(point)); putc(' '); putn(sizeof([3]rect)); putc(' '); + let p = new(point); // let infers *point + p.x = 7; p->y = 8; + putn(p.x * p.y); putc(' '); + free(d*p); + *list l = mklist(4); + l.items[0] = 42; l.len = 1; + putn(first(l)); putc(' '); + free(d*l); + *node a = new(node), b = new(node); + a.v = 3; b.v = 4; a.next = b; + putn(sum(a)); putc(' '); + free(d*a); // b went with it: a.next = b made a its owner + [3]point pts; + pts[2].y = 9; + putn(pts[2].y + counter); putc(' '); + num k = 3; + putn(k); putc(10); + + // reflection + tprint(typeof(r)); putc(' '); tprint(typeof(&r)); putc(' '); tprint(typeof(l)); putc(' '); + tprint(sigof(mklist)); putc(' '); tprint(sigof(first)); putc(' '); tprint(sigofs("free")); putc(10); + let t = typeof(r), i = 0; + while (i < tnfields(t)) { puts(tfname(t, i)); putc(':'); tprint(tftype(t, i)); putc('@'); putn(tfoff(t, i)); putc(' '); i++; } + putc(10); + *point q = new(point); + tprint(typeof_obj(q)); putc(' '); putn(typeof_obj(q) == typeof(point)); putc(' '); putn(tkind(typeof_obj(q)) == TY_STRUCT); + free(d*q); + putc(10); + return 0; +} diff --git a/docs/history/17-o3-boundaries/code/tests/umd.zc b/docs/history/17-o3-boundaries/code/tests/umd.zc new file mode 100644 index 0000000..497c9fc --- /dev/null +++ b/docs/history/17-o3-boundaries/code/tests/umd.zc @@ -0,0 +1,51 @@ +// lists as [len, items...], items owned by the list +.u mklist(n) { + let l = new(n + 1); + l[0] = 0; + return u*l; +} +fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; } +fn sum(.m l) { let s = 0, i = 1; while (i <= l[0]) { s += l[i][0]; i++; } return s; } +.u box(v) { let b = new(1); b[0] = v; return u*b; } +fn consume(.d b) { return b[0]; } + +fn main() +{ + let base = live_objects(); + { + let l = mklist(8); // u from mklist arrives m*here + let i = 0; + while (i < 5) { + let b = box(i * 10); // m in the loop body + d*b; // 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 + let outer; + { + let t = box(7); + u*t; + outer = t; + } + let v = { let w = box(8); u*w }; + putn(outer[0] + v[0]); putc(' '); + + // d given away to a callee + let g = box(99); + putn(consume(d*g)); putc(' '); + + // containers: child takes its parent's tag + let 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/17-o3-boundaries/code/tools/build.zc b/docs/history/17-o3-boundaries/code/tools/build.zc new file mode 100644 index 0000000..a38e97f --- /dev/null +++ b/docs/history/17-o3-boundaries/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() +{ + let 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/17-o3-boundaries/code/zc0.c b/docs/history/17-o3-boundaries/code/zc0.c new file mode 100644 index 0000000..7615cd7 --- /dev/null +++ b/docs/history/17-o3-boundaries/code/zc0.c @@ -0,0 +1,461 @@ +/* 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 +#include +#include +#include + +#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, K_KW, K_ENH }; +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, ""); 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 if (tk == T_ID && (!strcmp(ts, "u") || !strcmp(ts, "m") || !strcmp(ts, "d"))) { next(); expect("*"); unary(); } /* u*x: a recast, no code */ + 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("let") || 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("let") || 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(int ret) +{ + char *n = ident(); Sym *s; int np = 0, tags = 0, t, 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 (accept(".")) { /* .m name, .d name */ + if (is("m")) t = 1; else if (is("d")) t = 2; else die("a parameter tag is .m or .d"); + next(); + } + if (np < 12) tags += t << (2 * np); + strcpy(pn[np++], ident()); + } while (accept(",")); + expect(")"); + } + 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; +} +/* enhance name(params) [-> n] micro "recipe"; or ... vm { asm }; + emits the install descriptor; the booted genome installs it */ +static int nenh; +static void enhdef(void) +{ + char *n, pn[8][64]; int np = 0, nout = 1, d, na, pay, len = 0, i, j; Sym *s; + if (tk == T_NUM) { nout = tv; next(); } /* enhance 2 name(...) */ + n = ident(); + expect("("); + if (!accept(")")) { do { if (np == 8) die("at most 8 inputs"); strcpy(pn[np++], ident()); } while (accept(",")); expect(")"); } + d = here; for (i = 0; i < 7; i++) emit(0); + na = here; for (i = 0; i < np; i++) emit(0); + for (i = 0; i < np; i++) { img[na + i - GORG] = here; for (j = 0; pn[i][j]; j++) emit((unsigned char)pn[i][j]); emit(0); } + if (accept("micro")) { pay = here; while (tk == T_STR) { for (j = 0; ts[j]; j++) emit((unsigned char)ts[j]); next(); } emit(0); } + else if (accept("vm")) { pay = here; asmblock(); op(O_RET); len = here - pay; img[d + 1 - GORG] = 1; } + else die("expected micro or vm"); + img[d - GORG] = nenh; img[d + 2 - GORG] = np; img[d + 3 - GORG] = nout; + img[d + 4 - GORG] = pay; img[d + 5 - GORG] = len; img[d + 6 - GORG] = na; + s = add(n, K_ENH, nenh++); s->sig = np + nout * 16 + d * 256; + expect(";"); +} +static void top(void) +{ + while (tk != T_EOF) { + if (accept("unchecked")) continue; + if (accept("fn")) { fndef(0); continue; } + if (accept(".")) { if (strcmp(ident(), "u")) die("the only return tag is .u"); fndef(1); continue; } /* .u name(...) */ + if (accept("const")) { do { char *n = ident(); expect("="); add(n, K_CONST, cexpr()); } while (accept(",")); expect(";"); continue; } + if (accept("enhance")) { enhdef(); continue; } + if (accept("let") || 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; +} diff --git a/docs/history/17-o3-boundaries/notes.md b/docs/history/17-o3-boundaries/notes.md new file mode 100644 index 0000000..d2f27b4 --- /dev/null +++ b/docs/history/17-o3-boundaries/notes.md @@ -0,0 +1,48 @@ +# generics after the name, leaving o3, registers by scope, cached fixed arrays + +code/ next to this file is the tree at the end of this stage. + +## message 17 + +> generics should go after fn name and before parens +> we also need some machinery for converting values to/from o3. to is pretty easy, we just hand over the data, and o3 ignores the fat metadata. from is a bit harder, there needs to be a system to get type hints and fatten the metadata for the packed data +> variables just get the latest free register, it's fine for now +> add the fixed array once per region thing +> +> also if you have any tips on how to make the memory system better (aka avoiding gc and leaks/uaf as much as possible) do tell + +## working notes + +**generics after the name.** the reason they had moved in front last stage was that `T first(...)` uses T before declaring it. the fix: while a top-level return type is read, an unknown name becomes a provisional type parameter (numbered by first use), and the `<...>` after the name renumbers them with subst. a provisional one that the list doesn't confirm, or a global whose type used one, is "T: isn't a type". the prescan learned that `NAME<...>(` is a function too: at depth 0 it skips a balanced `<...>` and checks for `(`, which also steps over `list` in return types harmlessly. + +**registers by scope.** the compiler keeps a free list of the 7 registers per region. a declaration takes the one freed last, or the next unused one; block_close gives back the registers of its scope's o3 locals. so the descriptor became (slot, register) pairs, several slots can share a register, and the core spills a register to every slot it stands for (harmless, the dead ones are never read again) and loads it from the first. the bits live in ltag (8..10), next to the o3 flag (16) and the tag (low 4). + +**cached fixed arrays.** two hidden o3 locals per `fixed []T` variable (`#items`, `#len`, names a program can't write), created when the variable is declared in o3 code, or at the start of the region for parameters and for o3 variables from outside an o3 block. refreshed after every assignment to the array variable in o3 code and at region start. indexing compares against the len variable and adds to the items variable. careful with o3 function parameters: their caches can't be created in the parameter loop, since the prologue stores parameter i to slot i and a hidden local there would shift them; they're made after the `jmp lo`, inside the region. + +**fattening.** "packed data" here is o3's new_raw object: header, no type, no zeroing. the hint that survives is the size asked for, kept as -(n + 1) in the type word (typeof_obj reads that as 0). everything else comes from the compiler's static types at the boundary. the boundaries picked: stores of pointer-typed values anywhere but an o3 local, arguments to functions not known to be o3 (F_O3, also set by the prescan when `o3` comes before a function), returns from o3 code, push, container stores (after own), and the end of an o3 block for outer o3 variables. fatten is in compiler.zc, not rt.zc, because it walks type records with tnfields/tftype/tfoff. it stops at fat objects, so walks are cheap after the first, and dyn handles (always fat) are walked with a depth limit. + +zc0 bug found on the way: `fatin(a + tfoff(t, i), tftype(t, i), dl)` (calls nested in an argument list next to arithmetic) made zc0 report "undefined function dl". rewritten with temporaries rather than fixing zc0. also `d` is reserved in zc0 too (`d*x`), so a local named d is a parse error there. + +**numbers** after this stage (ms per run, start-up removed): + +``` +backend kernel plain ms o3 ms speedup +interp collatz 324.90 240.61 1.4x +interp sieve 47.08 21.71 2.2x +interp digits 160.89 100.82 1.6x +interp fib 3.48 4.09 0.8x +llvm collatz 47.03 3.34 14.1x +llvm sieve 10.77 0.28 38.9x +llvm digits 18.93 1.45 13.1x +llvm fib 0.87 1.01 0.9x +arm64 (qemu) collatz 323.89 13.04 24.8x +arm64 (qemu) sieve 56.84 1.74 32.6x +arm64 (qemu) digits 147.06 4.17 35.3x +arm64 (qemu) fib 5.19 5.71 0.9x +``` + +the sieve got about 2x on arm64 from the cache (3.85 -> 1.74 ms). fib is flat: each call exits and re-enters the region, and that costs what the body saves. the earlier "3.9x" for fib was noise; bench.sh now grows the run count until a timing difference is over a second. + +## memory tips (answered in chat, not built) + +arenas per block for m objects that provably don't escape; borrowed-from marks on derived pointers so aliases are checked; a quarantine for freed blocks plus a debug mode that checks the header on every deref; allocation sites in a debug header so leaks report where they came from; explicit shared ownership (a counted tag) instead of the collector for the cases that really need sharing; and making unchecked code the only way into the collector. diff --git a/docs/history/18-aliases/notes.md b/docs/history/18-aliases/notes.md new file mode 100644 index 0000000..eb0afc0 --- /dev/null +++ b/docs/history/18-aliases/notes.md @@ -0,0 +1,13 @@ +# tracked aliases + +the open end was untracked aliases: `let q = p + 0` or `let c = list[1]` became a plain word, and it dangled once the owner was freed. + +## what landed + +the analyzer reuses the child link. a pointer-typed value computed from a tracked variable is stored as `S_CHILD` with no `lown` bit: `p + k` and `p - k` (not a pointer difference), `p.field` when the field is a pointer, and `p[i]` when the element is a pointer. untyped `p + k` on an owned object counts too, since that variable is a pointer even when its type is still `word`. using the alias after the owner dies is the same error a child already gets, "used after it was given away". an alias is not an owner, so it can be copied, incremented and passed on, and the scope-end free doesn't free it. an alias that outlives the block its owner was declared in is marked dead when that block closes. + +`free` no longer returns the block to the buddy lists. it leaves the header marked free and the check word in place, so `isobj` fails and a second free is a no-op, but the bytes stay. the mark treats a word with that check word and a free flag as a quarantined object and traces it. the sweep merges a quarantined block back only when nothing pointed at it. a reachable one stays quarantined, still intact. the compiler zeros a local after the free it inserts, and `start` scrubs the data stack and collects once compilation is done, so the compiler's own garbage doesn't sit on the heap forever. + +## tests + +`tests/alias.zc` uses an alias while the owner is alive (arithmetic, a pointer field, an index). `tests/errors/alias_plus.zc`, `alias_index.zc`, `alias_field.zc` and `alias_scope.zc` are the uses after the owner dies. `tests/quarantine.zc` is unchecked: after `free`, churn that would have reused the block, the old words are still there, `free` through the alias doesn't smash them, and a collection while an exact pointer is still live keeps the block. an interior pointer (`p + k` with `k` not zero) does not match the check word, so a later collection reclaims that block; exact pointers (`p + 0`, a pointer field, a pointer element) keep it. an untyped index stays a plain word, since the element might be an integer, and quarantine is what covers that case. diff --git a/docs/history/19-tools/notes.md b/docs/history/19-tools/notes.md new file mode 100644 index 0000000..6989b80 --- /dev/null +++ b/docs/history/19-tools/notes.md @@ -0,0 +1,25 @@ +# memory debug, a bit more c, and a small host surface + +stage 18 tracks an alias that is still a name in the analyzer, and quarantines a block so a stale exact pointer reads intact bytes. this stage is the next layer: diagnostics you turn on, syntax people reach for, and enough of a host to write a small tool. + +## memory debug + +`memdebug on` (or `mem_set(1|4)`) records the source line of each `new` in a 64-slot table. the slot stores `p ^ MAGIC`, so the collector does not treat the table as a root. `memreport` prints `leak: line N W words` for slots whose block is still live and returns the count. W is the buddy payload, header included in the block but not in the count. + +checks walk at most 64 words back from a heap address to a header whose payload covers it. a dead header is `zy: use after free from line N` and the program stops. `free` of a block that is already quarantined prints `zy: double free from line N` and returns. the site stays until the storage is reused, which is why the second free still knows the line. + +bit 2 fills the payload with 57005 after children are released. bit 4 teaches the mark to accept an interior pointer the same way, so `p + k` keeps the block. it is off by default: a stale integer in that window would pin a block and the self-compile doesn't want that. programs that never say `memdebug` compile and run as before. + +`gc` zeros its own locals before scanning frames. an uninitialized slot was a root, and a leftover pointer from `free` was enough to keep a buddy chunk from merging. + +## syntax + +`do`/`while`, `enum` constants (the name is an int type), and `(T)e` for a simple type. `include "path"` reads a file with `readfile` and compiles it on the source stack the compiler already had, signatures first. `u`, `m` and `d` stay reserved. + +## host + +a store of an op to word `0xA0002` is a syscall: open, close, read, write, getenv, time. arguments are the next three words. `lib/std.zc` is not in the genome. it has atoi, itoa, strcat, starts, env, now and writefile. `examples/cli.zc` prints the length and first character of `$ZC_FILE`. + +## left alone + +the collector still scans the whole data stack, because the vm can't read its stack pointer. an alias that leaves a function, or an untyped index, is still not a compile-time borrow. interior pinning is opt-in and only 64 words deep. `include` is a path the host can open, not a search path. o3 stores don't hit the syscall gate. casts the parser can't see in a few tokens stay on `as`. diff --git a/docs/history/20-words/notes.md b/docs/history/20-words/notes.md new file mode 100644 index 0000000..ae63b79 --- /dev/null +++ b/docs/history/20-words/notes.md @@ -0,0 +1,22 @@ +# 20 — 64-bit words + +the vm word went from 32 bits to 64. memory is still word-addressed, and the map (heap, frames, stacks, `GORG`, the syscall gate) is the same word indices. each cell is 8 bytes on the host. there is no dual-width flag. + +## what changed + +- the image is little-endian 64-bit words: `zc0`, `mkgenome` and `tools/build.zc` read and write 8 bytes per word. `genome.h` is `int64_t`. +- a literal is still an odd word. `w >> 1` is a 63-bit signed immediate. the resident `lit` (`v + v + 1`) did not need a new formula. zero tests (`!`, `!!`, `==`, `!=`) shift by 63, in `zc0` and in the operator recipes. +- the interpreter, the enhancement evaluator and the o3 region interpreter use 64-bit cells. shifts mask with 63. `mulhs` / `mulhu` are the high half of a 128-bit product. `clz` of 0 is 64. signed and unsigned division by a constant use the 64-bit magic-number sequence, and `INT64_MIN / -1` stays defined. +- the arm64 jit loads and stores 8-byte cells, does alu in the x registers, and builds 64-bit immediates with up to four `movk` halfwords. the stack index is a byte offset shifted by 3. the llvm path uses i64 for vm values and i128 for the multiply-high. neither backend was executed here (no `aarch64` toolchain, no `llvm-config`); both were typechecked as far as this host allows, and the jit path compiles. +- `zshl` and the software divider cover 64 bits. `putn` and `itoa` print the full magnitude, including the minimum word. the mandelbrot fixed-point multiply is a multiply and an arithmetic shift, which matches the old 16.16 picture. the popcount recipe uses 64-bit masks; `popcount(0xff00ff)` is still 16. +- calling convention is unchanged: arguments are words, frame slots are word indices, and the signature packs the same small fields (`(ssig >> 1) & 31` is still the arity, not a shift width). the 6-word object header, buddy classes and the heap word counts are unchanged. `tests/buddy.zc` still expects `131072 262144 1 0`. + +## abi + +images, `genome.h` and any saved binary are not compatible with the 32-bit machine. source that fits in a 63-bit signed literal recompiles. the minimum word is not itself a literal. + +this is still not a C abi. a character is still one word, not one byte. the compiler's own source buffer still packs four characters into a word. calls do not match a host calling convention. + +## check + +`test.sh` on the interpreter: fixpoint at 91158 words, `genome.h` matches, 57 checks, 0 failed. that includes aliases, quarantine, memdebug, syscalls, `lib/std.zc`, o3, and `tests/wide.zc` (`1 << 40` and equality of that value). diff --git a/docs/history/21-micro/notes.md b/docs/history/21-micro/notes.md new file mode 100644 index 0000000..77c8d8b --- /dev/null +++ b/docs/history/21-micro/notes.md @@ -0,0 +1,23 @@ +# 21 — microcore + +a second interpreter, small enough to carry the genome to a new target. `core.c` is unchanged and still the jit, the llvm backend, o3 and the enhancement optimizer. + +## what it is + +`micro.c` (467 lines) is the base machine: 1m words, the two stacks, opcodes 0..21, call and return, and a copy of `genome.h` at `GORG`. it includes `stdint.h` and `genome.h` and nothing else. compiled with `-ffreestanding`, the only undefined symbols are the five hooks in `micro_port.h`: read a byte, write a byte, end of input, the syscall gate, and a diagnostic line. bss must be cleared before `micro_run`. the image is still 8 mb. on a cpu without a 64-bit divider the compiler's division helpers get linked as well; the object built here does not reference them. + +`port_linux.c` is the hosted port the suite runs (stdin, stdout, the six syscalls, stderr for the overflow lines). `port_stub.c` is the bare-metal sketch: a uart transmit register, input already finished, and every syscall returning -1. + +## enhancements + +`/` `%` `<<` are not base opcodes. the genome installs `idiv`, `imod`, `ishl`, `lfa` and `outside` through opcode 21 at boot, and user programs install more. a built-in for only the first three would miss `lfa` and `outside`, which o3 code emits as ordinary opcodes, and would miss `enhance` in the tests. pointing the operators at `zdiv` in `rt.zc` would make a different genome from the one `core.c` runs. so the microcore lowers a recipe, or a straight-line `vm` body, to a flat micro-op list and runs it. no constant folding, no multiply-high division. `x / 7` is a divide; the quotient matches. a `vm` body with i/o or a branch fails install with -4, so an `else` fallback still runs. install kind 2 (an o3 region) returns 0 and is ignored. the bytecode of that region still runs, which is why the o3 tests print the same numbers. + +the caps: 128 ops and 256 values in one enhancement, 4096 ops in the pool. reinstalling the most recent slot reuses its pool space; other reinstalls leak until the pool is full, and then install returns -5. an enhancement's stores do not enter the syscall gate, same as `core.c`. + +## left out + +no jit, no llvm, no o3 register interpreter, no coverage map, no threads. speed is the plain interpreter, slower still where `core.c` rewrote a constant divide. still not a C ABI. a character is still one word. the compiler's source buffer still packs four characters into a word. + +## check + +`test.sh` runs the interpreter suite and then the same examples and feature tests on `micro.c` linked with `port_linux.c`. output matches, including the self-compile against the interpreter's image. `micro.c` and `port_stub.c` compile with `-ffreestanding`. diff --git a/docs/history/22-size/notes.md b/docs/history/22-size/notes.md new file mode 100644 index 0000000..b282189 --- /dev/null +++ b/docs/history/22-size/notes.md @@ -0,0 +1,82 @@ +# 22 — memory size + +the machine was a fixed 1,048,576 words, 8 mb, and the map was copied as hex into `core.c`, `micro.c`, `zc0.c`, `mkgenome.c`, `src/rt.zc`, `src/compiler.zc` and `tools/build.zc`. a board with a couple of megabytes of ram cannot boot that. + +## the choice + +addresses in the genome are literals. a `const` is folded into the symbol table and into every instruction that uses it. the boot stub is `lit FTOP; lit ZFP; store; jump start`, and `lfa` is the recipe string `ld 655360`. three ways to support another size: + +1. one map the genome reads at boot, and every address computed from it. that is a different instruction stream. the 1m image would not stay byte-identical, and the whole compiler would be adding bases it currently treats as constants. +2. one set of formulas of `MW` (`HEAP_LO = MW>>2`, `GORG = MW-(MW>>2)`, …) shared by every size. those formulas reproduce the 1m map, and `const SYSGATE = ZFP + 2` was compiled both ways and the self-hosted images matched. they do not leave room below 1m words. the compiler's tables are about 0x24000 words and the image is about 91000. scaling the 1m gaps shrinks the tables with the machine, and at 262144 words the gap from the frame pointer to the genome is 32768 words, which cannot hold them. +3. one genome per size, from one layout. the default sources keep the historical numbers. a smaller build is a copy of those sources with a different const block, compiled by `zc0` against the same `memmap.h` the c cores use. + +(3) is what landed. it is the smallest change that keeps the 1m image byte-identical. the cost is that a size is a rebuild, not a boot flag: the 1m `genome.h` does not run in the small core, and the small image does not run in the 1m core. `tools/genmap.c` writes the directory (`memmap.h`, `rt.zc`, and for the compiler profile `compiler.zc`). `lfa`'s immediate is rewritten there and nowhere else; the checked-in recipe stays `ld 655360`. + +`SYSGATE`, the type area, the local-type tables and the exit records are formulas in the shared sources (`ZFP + 2`, `ZFP - 16384`, `R_ASM + 1024`, `stype + NS`). they fold to the old numbers, so the default image does not change. `genmap` rewrites `ZFP - 16384` to `ZFP - 8192` in the small copy only, and lowers the snapshot cap from 8000 to 1000 and the quote cap from 2700 to 300 there too. those three literals stay in `src/compiler.zc`. + +the 1m cores read `memmap.h`. `MW` has to be a multiple of 4096 so the arm64 `cmp xn, #MW` still fits in a shifted imm12. at 1<<20 that instruction is still `0xf144001f`. + +## what was measured + +on the 1m compiler, after compiling one program (the peaks, not the totals at `main`, except where the counter does not shrink): + +| | symbols | pool words | snapshot | quote tokens | code words | +|---|---|---|---|---|---| +| hello | 689 | 5695 | | | 171 | +| types | 701 | 5823 | | | 1016 | +| o3 | 700 | 5827 | 99 | | 1649 | +| meta | 697 | 5811 | 22 | 14 | 685 | +| life | 696 | 5781 | 182 | | 852 | +| joins | 695 | 5773 | 68 | | 736 | + +an empty `main` is already ~688 symbols and ~5700 pool words: that is the compiler itself. the data stack high water on the 1m machine was 1028 words for every program tried, including a self-compile. frame depth peaked at 451 during that self-compile and under 350 compiling tests. return depth peaked at 80. the interpreter's data-stack check sits 1100 words above `DSLO`, so the data region has to be at least about 2200 words or a shallow program looks like an overflow. + +`tests/gc.zc` keeps 1000 live 16-word blocks (16000 words) through its first loop, then allocates far past the heap so the collector runs. the live-object count only matches the 1m output if that first loop does not collect. + +## the floors + +**full compiler: 172032 words, 1376256 bytes.** `genmap small`. stage 27 raised the genome reservation from 90000 to 92000 words, and that machine is now 176128 words. + +``` +0 .. 8192 program +8192 .. 28672 heap (20480) +28672 .. 36864 types (8192), not overlapping the heap +36864 ZFP, syscall gate at 36866 +37120 .. 75264 compiler tables +75520 genome, 87661 words (zc0), ends at 163181 +165520 .. 167568 frame +167568 .. 168080 return +168080 .. 168592 mark (512) +168592 .. 172016 data +``` + +verified on the microcore and on `core.c`, output matched the 1m interpreter: hello, fact, lists, typed, wiring, life, basics, wide, gc, types, alias, meta, arrays, joins, enhance, o3, csyn, umd, quarantine, and all three stack overflows. both microcores (this one and the run-only one) compile with `-ffreestanding`. + +**run-only: 32768 words, 262144 bytes.** `genmap run`, then `rt.zc` + `src/run.zc` + one program, compiled by `zc0`. no resident compiler and none of its tables. `src/run.zc` supplies `start` and `gc_roots`. + +``` +0 .. 512 unused (code is in the genome) +512 .. 16896 heap (16384) +16928 ZFP, syscall gate at 16930 +17152 genome +27392 .. 28416 frame +28416 .. 28672 return +28672 .. 28928 mark (256) +28928 .. 32752 data +``` + +hello is 9458 words, fact 9558, wide 9523, selfpatch 9578, echo 9458, gc 9666. gc's image ends at 26818, 574 words below the frame stack. output matched, including echo reading `abc` from stdin (there is no backtick, the program is already compiled). + +256 kb cannot hold the compiler. 87661 words of image is about 700 kb before a heap, tables or a stack. + +## limits + +- `examples/primes.zc` wants a 60000-word array, a 65536-word buddy block. the small heap is 20480 words and the program stops with `zc: out of heap memory`. the compiler is not the problem; grow the heap in `place_small` and MW follows. +- the small machine does not self-host. `tools/build.zc` writes at word `0x10000`, and `build_image` allows `org + 0x30000` words. low memory here is 8192 words. producing the small image is `zc0`'s job, which is also why the small image is 87661 words and the self-hosted 1m image is 91158: those two compilers do not emit identical bytes, only the self-hosted fixpoint does. +- `tests/buddy.zc` expects `131072 262144`, the 1m heap's top-level chunks. left out of the subset. +- run-only source has to be the `zc0` subset. `tests/basics.zc` uses a block expression and `zc0` rejects it. types, `o3` and `quote` are out too. +- the small compiler will die, rather than smash a neighbour, past 1000 snapshot words, 300 quote tokens, 1024 symbols or an 8192-word string pool. the peaks above are well under those. a program that is a lot bigger than `life.zc` or `o3.zc` may need a knob turned up in `genmap`. +- the 1m type area still overlaps the top of the heap. that is historical and the image depends on it. the small map does not overlap. +- still not a C ABI. a character is still one word. the microcore still has no o3 fast path. + +stage 25 folded `place_small` and `place_run` into one layout. the sizes above are now `genmap --preset small` and `genmap --preset run`, and a different heap is `--preset small --heap N`. see `history/25-genmap`. diff --git a/docs/history/23-baremetal/notes.md b/docs/history/23-baremetal/notes.md new file mode 100644 index 0000000..eed69fe --- /dev/null +++ b/docs/history/23-baremetal/notes.md @@ -0,0 +1,85 @@ +# 23 — bare metal + +the microcore already compiled with `-ffreestanding` and `port_stub.c`, and it already fit in 256KB when the program was baked in. nothing had executed that image. the stub's `uart_putc` was empty. this stage boots it on QEMU's `virt` board, with no OS, and the program's own output on the emulated UART. + +## which machines + +the host is x86_64. what was installable: + +- `gcc-riscv64-linux-gnu` and `gcc-aarch64-linux-gnu` (gcc 13) +- `qemu-system-misc` (8.2.2), which provides `qemu-system-riscv64` +- `qemu-system-arm` (8.2.2), which provides `qemu-system-aarch64` + +`qemu-aarch64`, the linux-user emulator the jit section of `test.sh` looks for, is still not installed. a system emulator does not satisfy that check, and the jit stayed skipped. + +two boards booted. + +**RISC-V `virt`.** `qemu-system-riscv64 -machine virt -bios none -cpu rv64 -m 64 -nographic -monitor none -serial stdio -kernel bare.elf`. `-bios none` means no OpenSBI, so the core comes up in machine mode at the ELF entry. RAM is at `0x80000000`. the linker script claims 48MB of it. the UART is a 16550 at `0x10000000` (byte registers: holding/receive at 0, interrupt enable at 1, FIFO control at 2, line control at 3, line status at 5; receive-ready is bit 0, transmit-empty is bit 5). power-off is the SiFive test device at `0x100000`. writing `0x5555` makes QEMU exit 0. writing `0x13333` is `FINISHER_FAIL` with status 1. + +**AArch64 `virt`.** `qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 64 -nographic -monitor none -serial stdio -kernel bare.elf`. RAM is at `0x40000000`, same 48MB in the linker, 64MB given to QEMU. the UART is a PL011 at `0x09000000`, 32-bit registers, the flag register at offset `0x18` (receive FIFO empty is bit 4, transmit FIFO full is bit 5). power-off is PSCI `SYSTEM_OFF`: `hvc #0` with `x0 = 0x84000008`. that call does not take a status, so a guest that returns an error from `micro_run` still looks like a clean exit. the UART transcript is the result that matters. + +this QEMU starts that ELF at EL1. the startup still checks `CurrentEL` and, at EL2, sets `HCR_EL2.RW`, `SPSR_EL2 = 0x3c5`, and `eret`s to EL1h. that path was not taken on the boots below. `-bios none` is not on the command line. on this 8.2 build it is a filename, and QEMU exits with `Could not find ROM image 'none'`. `-kernel` of an ELF is loaded and entered directly. + +**Cortex-M was not tried.** the word is `int64_t` and the run-only bss is about 400KB before the genome in rodata. `qemu-system-arm`'s small boards (Stellaris `lm3s6965`, 64KB of SRAM) cannot hold it, and a 32-bit core would do every cell in software. `virt` has the RAM and a 64-bit CPU, so that is the port. + +## the image + +`baremetal/start_*.S` sets a 64KB stack, zeroes bss eight bytes at a time, and calls `bare_main`. `baremetal/port.c` is the five `micro_port.h` hooks. syscalls return -1. `baremetal/run.sh` is the build and the QEMU command, with `timeout` so a hang does not stick (120 seconds for `run`, 90 for `compile`). + +two modes. + +`run` asks `genmap` for the 32768-word map, compiles `rt.zc` plus `src/run.zc` plus the program with `zc0`, and links that `genome.h` into the ELF with `-DBARE_INPUT=0`. `micro_eof` is true and `micro_getc` returns -1. the program is already in the image. + +`compile` copies the default `genome.h` and `memmap.h` (1,048,576 words, the self-hosted compiler) and links with `-DBARE_INPUT=1`. the script pipes the source and a trailing backtick into the UART. `virt` has 64MB, so the 8MB machine fits and there was no reason to boot the 172032-word compiler instead. the copies sit next to `micro.c` because `#include "genome.h"` searches the including file's directory first. + +the cross compile is `-ffreestanding -fno-pic -nostdlib -static -O2`. RISC-V adds `-march=rv64gc -mabi=lp64d -mcmodel=medany -mno-relax`. AArch64 adds `-march=armv8-a`. `--build-id=none` keeps the linker from warning about a discarded note. + +## what the first boots did + +RISC-V hello printed `hello, world!` on the first try and QEMU exited 0. the 16550 needed no setup for that, and it must stay that way. an early port wrote the line-control and FIFO-enable registers. QEMU has already delivered the first source bytes by then, and enabling the FIFO dropped the `f` of `fn`. the compiler then said `zc: line 1: n: isn't a type`. `uart_init` on RISC-V is empty. + +AArch64 hello produced nothing and sat until `timeout`. the instruction trace showed `_start`, the bss clear, `bare_main`, then `micro_run`, then a jump to guest address `0x200`, which is the synchronous-exception vector when `VBAR_EL1` is 0. the faulting instruction was `ldr q0`, the `-O2` copy of the genome. `CPACR_EL1.FPEN` is 0 out of reset, so SIMD traps. startup now sets `FPEN` to 3 (and clears `CPTR_EL2.TFP` on the EL2 path) and issues an `isb`. RISC-V sets `mstatus.FS` for the same reason; that core had not emitted a float op yet, but the abi is `lp64d`. + +after those two fixes, both boards printed the same bytes as the hosted interpreter. + +run-only, no input: + +``` +hello, world! +1101110101111100000000 +3628800 +1099511627776 1 1 1 -1 +1000 1 900 1 199900 +``` + +those are `examples/hello.zc`, `examples/fact.zc`, `tests/wide.zc` and `tests/gc.zc`. `gc` took 28 seconds on RISC-V and 32 on AArch64. the second `churn(200000)` is a lot of interpreted allocation, and a 20 second timeout cut it off after `1000 1 900`. + +the resident compiler, source plus a backtick on the UART, for hello, fact and wide, printed the same three results (fact's two lines, wide's one). the compiler image itself does not depend on which file is piped in. + +## sizes + +`size` on the ELF, text and data added together. bss is the word array, the enhancement tables and the 64KB stack. + +| image | ELF bytes | text+data | bss | +|---|---|---|---| +| RISC-V run, hello | 87704 | 81741 | 410664 | +| RISC-V run, fact | 88504 | 82541 | 410664 | +| AArch64 run, hello | 149704 | 82248 | 410656 | +| RISC-V compiler | 741624 | 735565 | 8537128 | +| AArch64 compiler | 803616 | 736040 | 8537136 | + +the AArch64 file is larger than its text and data because the load segment's alignment is 64KB. the compiler's text is mostly the default genome, 91158 words, 729264 bytes. run-only bss is the 256KB machine. compiler bss is the 8MB one. + +## input, and what was left out + +`micro_eof` is not allowed to block. the compiler calls it after every `getc`, including the backtick that ends the unit. if eof waited for another byte, a source that ends in a backtick would hang. an empty FIFO therefore means "a byte may still arrive", not "the file is over". the one real end-of-file byte is `0x04`, and only when it is already sitting in the FIFO: it is consumed and not returned to the program. a program that loops on `eof()`, the way `examples/echo.zc` does, needs that byte queued behind the payload. the 16550 FIFO holds 16 bytes, so a longer stream can make the peek see `0x04` too early or not at all. echo-until-eof is not in the bare-metal checks. the backtick protocol does not need it. + +other limits, unchanged from the hosted microcore except where the board forces them: + +- every syscall returns -1 +- install kind 2 (an o3 region) succeeds and is ignored; the bytecode runs +- diagnostics share the UART with program output +- a run-only program has to be the `zc0` subset +- 256KB still cannot hold the compiler +- not a C ABI, and a character is still one word +- AArch64 power-off cannot report a guest failure status diff --git a/docs/history/24-backends/notes.md b/docs/history/24-backends/notes.md new file mode 100644 index 0000000..2512369 --- /dev/null +++ b/docs/history/24-backends/notes.md @@ -0,0 +1,49 @@ +# 24 — the arm64 jit and the llvm backend, actually run + +both backends were updated when the word went to 64 bits, and neither had been executed since. the jit section of `test.sh` wants `aarch64-linux-gnu-gcc` and `qemu-aarch64` (linux-user). `qemu-system-aarch64` does not satisfy that check. the llvm section wants `llvm-config`. this host had the cross gcc and the system emulators from the bare-metal stage, and not the other two. they were installed here: `qemu-user` 8.2.2 (provides `/usr/bin/qemu-aarch64`), `qemu-user-binfmt`, `libc6-dev-arm64-cross` (the sysroot a static aarch64 link needs), and `llvm-dev` (LLVM 18.1.3, `llvm-config` works). clang 18.1.3 was already present. the suite links the llvm binary with gcc, not clang. + +## how each one was built and run + +the hosted interpreter, for the comparison, is the usual host binary: `gcc -O2 -w -DJTYPE=int core.c io_linux.c`. host gcc is 13.3.0, the machine is x86_64. + +the jit: + +``` +aarch64-linux-gnu-gcc -O2 -w -DJTYPE=int -static core.c io_linux.c -o zyj +qemu-aarch64 zyj < program.zc +``` + +`aarch64-linux-gnu-gcc` is 13.3.0. `-static` is what `test.sh` passes, so the binary does not need the aarch64 dynamic loader at run time. the smoke binary was 1,428,296 bytes. `ZYTRACE=1` counts lines containing `bytes of arm64`. + +the llvm backend: + +``` +gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c \ + -o zyl $(llvm-config --ldflags --libs) +``` + +`llvm-config` is 18.1.3. `ZYTRACE=1` counts lines containing `compiled by llvm`. `ZYHOT=1` compiles every block, not only the hot ones, and `test.sh` checks that `tests/types.zc` then matches the interpreter's stdout by md5. + +## what matched + +a short smoke, before the full script: `examples/hello.zc`, `examples/fact.zc`, `tests/wide.zc` and `tests/o3.zc` on both backends printed the same stdout as the interpreter. `tests/o3.zc` lifted 8 regions on each (`bytes of arm64`, `compiled by llvm`). + +then `bash test.sh`, which is the existing list, not a new one. the fixpoint stayed 91158 words and `genome.h` matched. the interpreter, the microcore, the 172032-word compiler, the 32768-word run-only image, and both virt boards (7 boots each) passed as before. the jit ran that same `run` list under qemu-user, plus the 8-region count and a self-compile compared with `g1.bin`. the llvm binary ran the same list, plus the 8-region count, the `ZYHOT=1` md5, and its own self-compile. the second full run, after the fix below, was 292 passed, 0 failed. + +## the one failure + +the first full run was 291 passed, 1 failed: `jit virtual enhancements`, stdout `100 0 343 3,2 ` instead of `100 0 343 3,2 5 -2 0`. exit status 0. the interpreter and the llvm backend both printed the full line. + +`tests/enhance.zc` installs `noisy` as vm code whose body does a `putc`. `lift_vm` refuses i/o and `install` returns `-4`. the compiler, when that return is negative, sets the fallback bit and emits a call to `soft_noisy` instead of the opcode. the prints that did come out are `clampadd`, `cube` and `divmod`, which install cleanly. the halt is the next call, `noisy(4)`. + +opcode 21 in the jit is a `blr` to `inst_hook`, which returns `int`, then a 64-bit store of `x0` onto the data stack. on aarch64 a write to `w0` zeroes bits 63:32. `-4` in `w0` is `0x00000000fffffffc` in `x0`, which as a cell is 4294967292, and `r < 0` in the compiler is false. the fallback bit stays clear, the compiler emits the opcode, the slot was never installed, and the translator's unwired path is `movn x0, #0` and a branch to the exit stub. that is a clean halt, which is why the status was 0 and the line simply stopped. + +the llvm path does not have this hole. its install helper is `static Cell linstall(Cell d) { return install((int)d); }`, and the C conversion sign-extends. the interpreter assigns `install`'s `int` straight into a `Cell`. + +the fix is one instruction after that `blr`: `sxtw x0, w0` (`0x93407c00`), then the store. `tests/enhance.zc` under `qemu-aarch64` then printed `100 0 343 3,2 5 -2 0`, and `examples/wiring.zc` still printed `16 1234 25 4/9`. the genome did not change. the instruction is in the translator, so a Darwin build of the same core gets it too, but that build was not run. + +## what was not run + +- the Darwin jit. `core.c` takes a different path there (`MAP_JIT`, `pthread_jit_write_protect_np`, `sys_icache_invalidate`). this machine is x86_64 Linux. qemu-user executes the linux aarch64 ELF; it does not execute that path. +- real aarch64 hardware. every jit instruction ran inside qemu-user 8.2.2. +- the jit and llvm backends on the small and run-only maps, and on the bare-metal boards. `test.sh` runs those maps on the interpreter and the microcore. the two native backends stay on the default 1,048,576-word genome. diff --git a/docs/history/25-genmap/notes.md b/docs/history/25-genmap/notes.md new file mode 100644 index 0000000..65e322e --- /dev/null +++ b/docs/history/25-genmap/notes.md @@ -0,0 +1,28 @@ +# 25 — one memory-size layout + +the sizes lived in four places that had to be kept in step by hand: the numbers in `memmap.h`, the `// @map-rt` block in `src/rt.zc`, the `// @map-cc` block in `src/compiler.zc`, and two functions in `tools/genmap.c` (`place_small`, `place_run`). there were no extra checked-in copies of the runtime. the history snapshots stay as they were. `src/run.zc` is the run-only boot stub, not a second map, and it stayed. + +`tools/genmap.c` is now one packer. a `Spec` says whether this is a compiler or a run-only image, and the sizes that actually differ: heap low and heap length, a type region, a pad before the frame-pointer word, the genome reservation, and the frame, return, mark and data stacks. compiler tables (hash, pool, symbols, locals, forward refs, snapshots, quotes, source stack, operator sequences, contexts, loop stack) have a tight default and a historical one. `layout` places the regions from the bottom. `--words` pins MW and gives whatever is left to the data stack. without it, MW is the packed size rounded up to a multiple of 4096, which is what the arm64 `cmp xn, #MW` encoding needs. + +## presets + +`--preset small` and `--preset run` are the two maps from stage 22. `--preset default` is the historical 1,048,576-word machine. that one is not the tight compiler stretched to 1m words. the type area still overlaps the top of the heap (`ZFP == HEAP_HI`, and `R_TY = ZFP - 16384` stays in the source), the tables stay large (string pool 40704 words, 4096 symbols, snapshot and quote buffers 8192), and the gaps between the genome and the frame stack stay where they were. packing those sizes reproduces the old addresses: heap `0x40000..0xA0000`, tables `0xA0100..0xBFF00`, `GORG 0xC0000`, frame `0xE0000..0xF0000`, data `0xFC000..0xFFFF0`. + +the checked-in sources are still that default, so `cat src/rt.zc src/compiler.zc | zc0` is the same compile as before. `genmap --preset default --check` reads `memmap.h` and the two const blocks and exits non-zero if a number disagrees. the small copy still rewrites, in the copy only, `ZFP - 16384` to `ZFP - 8192`, the snapshot cap 8000 to 1000, and both quote caps 2700 to 300. `lfa` is still the string `ld 655360` in `src/rt.zc`. the copy gets `ld` of that build's `ZFP`. + +## the same bytes another way + +the flag form of the two old profiles was diffed against `--preset`. same `memmap.h`, `rt.zc`, `compiler.zc` and `map.txt`: + +``` +genmap --mode compiler --name small --heap-lo 8192 --heap 20480 --types 8192 \ + --genome 90000 --frame 2048 --return 512 --mark 512 --data 3072 \ + --snap-cap 1000 --quote-cap 300 -o build/small +genmap --mode run --words 32768 -o build/run +``` + +`genmap small DIR` and `genmap run DIR` still work. `test.sh` and `baremetal/run.sh` call the new flags. a bigger heap for `primes.zc` is `genmap --preset small --heap 65536`, and MW follows. + +what did not change: the 1m genome, the 172032-word compiler, the 32768-word run-only image. a `--mode compiler --words 1048576` without the default preset is a different machine (tight tables, type region of its own, packed from the bottom). it is not a substitute for `--preset default`. + +`test.sh` after this stage: 295 passed, 0 failed. the three new checks are the default `--check` and the two flag-form diffs. the fixpoint stayed 91158 words. diff --git a/docs/history/26-bareapi/notes.md b/docs/history/26-bareapi/notes.md new file mode 100644 index 0000000..c7294f4 --- /dev/null +++ b/docs/history/26-bareapi/notes.md @@ -0,0 +1,25 @@ +# 26 — bare-metal syscalls + +the virt port's `micro_syscall` returned -1 for every op. the gate itself was already there (`SYSGATE`, the same numbers the hosted core uses), and `port_stub.c` still returns -1, so a board with no devices keeps building. `port_linux.c` and `core.c`'s `hostcall` grew the three new numbers too: 7 exits the process, 8 is a counter, 9 reports `MW` and the heap. the genome did not change. the test programs pass the numbers as literals, so `src/rt.zc` stays as it was. + +## console, and eof that waits + +`examples/echo.zc` is `while (!eof()) putc(getc())`. on the host, `micro_eof` blocks in `getchar` until the next byte or a real end. the old UART port returned immediately, and an empty FIFO counted as "not the end", so a `0x04` that had not arrived yet was read by `getc` as a failure and then printed. it also could not see an end that was sitting behind more than 16 bytes, which is the 16550's FIFO. + +`BARE_INPUT=1` now waits in both `micro_getc` and `micro_eof` until a byte is in the register. `0x04` is the end and is not returned. a pause with an empty FIFO is just a wait, so the length of the stream does not matter. `run` mode is still `BARE_INPUT=0`: eof is true, getc is -1, and a program that never reads does not sit on the UART. + +the compiler's backtick is unchanged. the opcode that reads a byte then probes eof, and that probe used to deadlock if it waited, because the probe runs before the compiler has noticed the backtick. `compile` therefore writes the source, a backtick, and a `0x04`. the probe after the backtick finds the `0x04` and returns. hello, fact and wide compiled over the UART still print what they printed before. + +`io` mode is a run-only image with the UART open. the script appends `0x04` to stdin. both boards, fed `abcdefghijklmnopqrstuvwxyz0123456789` (36 bytes, past the FIFO), printed that string and exited 0. the hosted interpreter, given the same letters after the backtick, printed the same string. + +## the rest of the gate + +time is the hardware counter. RISC-V is `rdtime` (the virt machine's `mtime`). AArch64 is `cntvct_el0`. neither is unix seconds, so `tests/sys.zc` is still a hosted test. `tests/bareio.zc` reads it, spins, reads it again, and prints `tick` when the second value is at least the first and neither is negative. both boards did. + +exit is a status, not only success or failure. RISC-V writes the SiFive test device at `0x100000`: `0x5555` exits 0, and `(status << 16) | 0x3333` exits with that status. the high half is 16 bits. AArch64 is semihosting `SYS_EXIT`: `hlt #0xf000` with `x0 = 0x18` and `x1` pointing at `{0x20026, status}` (`ADP_Stopped_ApplicationExit`). the first try hung because the stack pointer was unset in a throwaway ELF, and because PSCI `SYSTEM_OFF` cannot carry a status. the boot path already has a stack. QEMU is started with `-semihosting-config enable=on,target=native`. `tests/bareexit.zc` prints `bye` and calls exit 3. both boards exited 3 and did not print `still`. a guest that returns from `micro_run` with an error now exits 1 on AArch64 too. + +open, close, read and write are four RAM files, 128 bytes each, names up to 31 characters. they are not the host filesystem. `tests/bareio.zc` writes `zy` to `note` and reads it back: `2 zy`. getenv answers `BOARD` with `riscv` or `aarch64` and -1 for anything else. random is an xorshift seeded from the counter, and it is never -1. memory op 0 is `MW`, which on the run-only image is 32768. the line from both boards was `tick 2 zy rand board 32768`. + +`port_stub.c` and a freestanding compile of it are unchanged in behaviour. the linux port still serves real files for ops 1 to 4. + +`test.sh` runs the echo, the bareio line, the exit text and the exit code on each board that is present. with both virt boards, that is eight checks on top of the 295 from stage 25. the full script passed 303, and failed 0. the fixpoint is still 91158 words. diff --git a/docs/history/27-float/notes.md b/docs/history/27-float/notes.md new file mode 100644 index 0000000..4420a32 --- /dev/null +++ b/docs/history/27-float/notes.md @@ -0,0 +1,19 @@ +# 27 — floating point + +a float is an IEEE-754 binary64 in one 64-bit word. an odd literal only has 63 bits, and bit 0 of a double is part of the number, so a float literal is not an odd word. opcode 600 (`flit`, the even word 1200) is followed by the raw bits, and every decoder consumes that word inside the instruction so a payload with bit 0 set is not executed. 601..611 are add, sub, mul, div, eq, lt, le, int-to-float, float-to-int (trunc toward zero), print and parse. they sit above 533, so the enhancement slots do not move and an old image still means what it meant. + +every target here has an FPU: x86_64 SSE2, AArch64, and RV64 with the D extension. the interpreter, the microcore and both bare-metal images use the host `double` (gcc emits the hardware op). the arm64 jit emits `fadd`/`fsub`/`fmul`/`fdiv`, `fcmp` plus `cset` (`mi` and `ls`, not `lt` and `le`, because an unordered compare must not count as less), `scvtf` and `fcvtzs`. the llvm backend uses `fadd` and the rest on a double, bitcast to and from i64. print and parse are `fops.h`, not libc, so a board with no C library writes the same text. the form is an optional minus, the integer digits, a dot, and six fractional digits. a tie in the seventh digit rounds away from zero. the non-finite texts are `nan`, `inf` and `-inf`. a parsed significand keeps at most 15 digits. magnitudes past about 1e32 print as `inf` because the scaled integer no longer fits in 128 bits. + +the resident lexer stays inside the zc0 subset: it copies the spelling into `tbuf` and runs opcode 611 (`asm { tbuf #1222 }`), which is the same parser zc0 calls in C. neither compiler source contains a float literal. codegen emits `flit` plus the bits. a local that is assigned a float gets bit 5 of its tag, and a later load is still a float. one integer operand of `+ - * /` or a comparison is converted. the result of a comparison is an int. a call's result is not known to be a float, `++` and `--` stay integer adds and clear the flag, and o3 does not lift these opcodes (the region runs as bytecode). `0.0` is false where a word is tested, because its bits are zero. `-0.0` is true, because the sign bit is set. `f2i` of a value outside int64 saturates in the interpreter, the microcore and the arm64 jit; the llvm conversion is only promised for values that fit, which is all the tests use. + +`tests/float.zc` is in the zc0 subset, so the same source runs on the resident compiler, the microcore, the arm64 jit, the llvm backend, the small compiler, the run-only image, and both virt boards (run-only and, on the boards, compiled by the resident compiler). the line is + +``` +4.000000 4.500000 3.000000 2.500000 2.500000 0.001500 0.100000 -0.125000 inf -inf nan 1 1 1 0 0 3 -3 3.000000 -2.000000 2 +``` + +`1 + 1.5` is the second `2.500000`. `10 / 4` at the end is still integer division. + +the image grew from 91158 words to 93712. the fixpoint holds. the small compiler's hole was 90000 words and the new image is 90138, so the reservation is 92000 and that machine is 176128 words instead of 172032. the heap, the tables and the run-only map are the same. + +`test.sh` after this stage: 315 passed, 0 failed. the twelve new checks are the float line on the interpreter, the microcore, the arm64 jit and the llvm backend, the small microcore and `core.c` at that size, the run-only image, both virt boards running the program and compiling it, and one llvm run with `ZYHOT=1` so every float block is compiled. the line matched on all of them. diff --git a/docs/history/28-bytes/notes.md b/docs/history/28-bytes/notes.md new file mode 100644 index 0000000..24a67fa --- /dev/null +++ b/docs/history/28-bytes/notes.md @@ -0,0 +1,21 @@ +# 28 — byte addressing + +memory stays an array of 64-bit words. a byte address is a second numbering of that same image: word `w` occupies bytes `w << 3` through `(w << 3) + 7`, and byte 0 of a word is its low 8 bits. `baddr` and `waddr` convert. the odd/even tag is only for code words (a literal is an odd word, an opcode is even), so a byte address is a plain integer and can be odd. `u`, `m` and `d` stay on the word pointer of a heap object. a byte address into a payload is not itself a tracked owner. + +the opcodes sit above the floats, so the enhancement slots do not move: + +``` +612 ld8 613 st8 614 ld16 615 st16 616 ld32 617 st32 +``` + +16- and 32-bit accesses are little-endian and may cross a word boundary. an access that does not lie entirely inside memory loads 0 and stores nothing. the runtime names are `ld8`, `st8`, `ld16`, `st16`, `ld32`, `st32`. `bops.h` is the one implementation. the interpreter, the microcore and the llvm backend call it. the arm64 jit calls the same functions, so a spanning store is one path on every target. a byte store of a word some translation covers goes through the same hook as opcode 2, and the block is dropped. it does not run a syscall. the gate is still a word store at `SYSGATE`. + +`tests/bytes.zc` checks a spanning 16-bit store, a 32-bit store, the two words those stores build, an address off the end of memory, a 1000-byte checksum (30768), and a rewrite of the literal in `f` from `A` to `B` to `C` by storing one byte of that code word. on the jit that store drops the translation twice. the line is the same on the interpreter, the microcore, the arm64 jit, llvm with `ZYHOT=1`, the small compiler, the run-only image, and both virt boards. + +`tests/bench_bytes.zc` is a run-only image, so the timing does not include the resident compiler. it walks 4000 bytes of a 512-byte buffer, repeated, and the slope between one repetition and many is the loop. the checksum of one repetition is 123504. + +the run-only hole was 10240 words. the byte runtime plus `tests/bytes.zc` is 10365, so the reservation is 11264 and that machine is still 32768 words. the frame, return and mark stacks moved up by 1024 and the data stack gave up those words. hello on that map is 9742 words. the fixpoint image grew from 93712 words to 94083. + +`test.sh` after this stage: 327 passed, 0 failed. the twelve new checks are the byte line on the interpreter, the microcore, the arm64 jit and the llvm backend, the small microcore and `core.c` at that size, the run-only image, both virt boards running the program and compiling it, and one llvm run with `ZYHOT=1`. + +`bench_bytes.sh` times a run-only image, 4000 byte loads per repetition, slope of 1 repetition against 40. checksum 123504. on this host: interpreter 1.24 ms, microcore 1.20 ms, arm64 jit under qemu-user 0.53 ms, llvm 0.50 ms. the llvm slope includes compiling the loop once, because one repetition stays under the default hot threshold and forty do not. diff --git a/docs/history/29-strings/notes.md b/docs/history/29-strings/notes.md new file mode 100644 index 0000000..9d96087 --- /dev/null +++ b/docs/history/29-strings/notes.md @@ -0,0 +1,21 @@ +# 29 — byte strings + +word strings stay one character per word, 0 terminated. `"hi"` did not change, and neither did ops 1 to 5. a new literal, `b"..."`, is a packed string on the byte addressing from stage 28. the `b` has to sit against the quote; `b "hi"` is still a name plus a word string. + +the layout is the same for a literal in the code and an object on the heap. word 0 is the length, not counting the trailing 0. the bytes start at the next word, eight per word, little-endian, and a 0 byte follows the last character. when the length is a multiple of 8, including 0, that 0 occupies a word of its own. a literal is a jump over the data, the length as a raw word, the packed words, then a literal of the length word's address. `snew(n)` is `new(1 + ((n + 8) >> 3))`, which is one length word plus enough words for the bytes and the trailing 0. + +the runtime names are `slen`, `sbyte`, `snew`, `scat`, `sslice`, `scmp`, `seqs`, `slt`, `sle`, `bputs`, `ston` and `ntos`. `sbyte` returns 0 outside the length. `sslice` takes an exclusive end and clamps. `scmp` returns -1, 0 or 1 over unsigned bytes. `ntos` of the minimum word copies the word-string `"-9223372036854775808"` into a byte string. heap results are fresh owned objects, so the analyzer requires a `let`. they are not shared yet. + +the resident compiler and `zc0` both track which value is a byte string. on the resident compiler that is bit 6 of the local's tag. `len` of one calls `slen`. `s[i]` calls `sbyte` and is not a place to store. `s[i:j]` calls `sslice`. `+` and the six comparisons require a byte string on both sides; one side is an error. `puts` of one byte string calls `bputs`. `++` and `+=` clear the bit. + +ops 10 to 13 are the packed versions of open, read, write and getenv. the pointer they take is `baddr(s + 1)`, the payload, not the object. the hosted core, the linux microcore port and the virt-board port implement them. the stub port still returns -1. the RAM file store on the boards is unchanged, so `tests/bstr_io.zc` stays hosted. `lib/std.zc` keeps `atoi`, `itoa`, `strcat`, `starts`, `env` and `writefile`, and adds `batoi`, `bitoa`, `bstarts`, `benv` and `bwritefile`. + +the 1m map stores type records in the last 16384 words of the heap, and the type list is the first words of that range. holding those words as a buddy block does not survive `types_init`, which writes the list over the header, and the next large `new` was then handed the type records. the self-host died at `let pow2[64]` with `program too big` because `tword`'s size word had become the source text `= 0;`. the compiler now cuts the allocator off at `R_TY` after `heap_init` and leaves it cut. the sweep stops at the same line, so it does not walk a header that is really the type list. `tests/buddy.zc` still prints `131072 262144 1 0`: the bottom chunk is untouched, and the 20000 small blocks fragment it the same way. the small map keeps its type area above the heap, so the cut does not apply there. + +`tests/strings.zc` prints `hi! 3 3 104 i! 1 1 1 -42 42 -42 11 1 -9223372036854775808 0 1 3 10 1 1 1 W ab`. `examples/strings.zc` prints `hello, zc` and `9 42`. the fixpoint image is 100011 words, 800088 bytes. the stage-0 image of the same sources is 96068 words. the run-only reservation is 14336 words in a 36864-word machine; `tests/bytes.zc` is the largest of those images at 13191 words, and hello is 12568. the small compiler's stage-0 image is 96067 words against a reservation of 97280, in a 180224-word machine. + +`tests/bench_strings.zc` is a run-only image. one repetition scans the 36-character literal 200 times, concatenates a `!`, and slices `[1:8]`. the checksum is 674542. `bench_strings.sh` times that without the resident compiler. on this host: interpreter 5.499 ms, microcore 5.22 ms, arm64 jit under qemu-user 3.171 ms, llvm 0.235 ms. the llvm slope is the compiled loop; the first repetition pays to compile it. + +`test.sh` after this stage: 350 passed, 0 failed. the twenty-three new checks are the string line, `examples/strings.zc`, and `tests/bstr_io.zc` on the interpreter, the microcore, the arm64 jit and the llvm backend; the string line and the example on the small microcore and on `core.c` at that size; the run-only image of both; both virt boards running `tests/strings.zc` and compiling it; and one llvm run with `ZYHOT=1`. `tests/bstr_io.zc` is hosted only. the fixpoint is the same 100011 words on the interpreter, the microcore, the jit and llvm. + +what is still open: heap strings are uniquely owned, not shared, so a structure cannot point at one substring from two places without copying. there is no mutation through `s[i]`. `ston` stops at the first non-digit and does not say so. comparison is unsigned bytes, not a character set. part 3 is the collector that can share these objects. diff --git a/docs/history/30-sharing/notes.md b/docs/history/30-sharing/notes.md new file mode 100644 index 0000000..ff1671f --- /dev/null +++ b/docs/history/30-sharing/notes.md @@ -0,0 +1,17 @@ +# 30 — shared structure + +the heap already mark-sweeps. this stage adds objects many pointers can hold, collected by that sweep when none of them remain. there is no second heap and no reference count. a cycle is just a mark that sees the same cell twice. + +bit 8 of the header flags (`F_SHARE`, value 8) means shared. bits 0..2 stay what they were: live, releasing or marked, and the pin bit on a quarantined block something still points at. `share(p)` sets bit 8, clears the owner, and leaves the object live. `free` of a shared object returns without quarantining and without poisoning. `own` will not record an owner for one, and `release` will not follow one, so a unique container can point at a shared child without freeing it. the sweep masks the low three bits: an unmarked live cell is freed whether or not bit 8 is set, and a marked cell is restored to live with bit 8 kept. unique `free` still quarantines, and the sweep still returns a quarantined block only when nothing points at it. memdebug's allocation note is the one `new` already writes. `car`, `cdr` and `tget` call `checkptr` when bit 1 of the memdebug flags is on, so a shared cell is checked the same way as any other heap pointer. + +`cons(a, b)` and `triple(a, b, c)` allocate, publish any child that is a heap object, and publish the cell. publishing a child means a later `free` from its old owner does not clear a cell that still points at it. `snew`, `scat`, `sslice` and `ntos` return shared strings, so a byte string is a value you can copy. code literals `b"..."` are not heap objects; they live in the image. `is_shared` reads the bit. + +`tests/share.zc` builds two cells on one pair, a string held by two cells, a cycle, and a triple, then drops every root, scrubs the data stack and collects. the line is `1 2 1 4 1 1 1 1 42 1 1 1 6 0`. the last 0 is `live_objects` back to the baseline, on the resident compiler and on a run-only image. `tests/share_dbg.zc` turns memdebug on, frees a shared cell, and reads it back: `7 1`. + +the fixpoint image is 100757 words. the run-only reservation stays 14336 in the 36864-word machine; `tests/bytes.zc` is the largest of those images at 13871 words. the small compiler's stage-0 image is 96736 words against 97280, in the 180224-word machine. neither hole moved. the type-area cut from stage 29 stays: the 1m compiler still does not hand 0x9C000..0x9FFFF back to the allocator. + +`tests/bench_share.zc` is a run-only image. it builds one 40-cell spine, hangs two parents off it, and walks the spine 200 times. the checksum of one repetition is 156003. `bench_share.sh` times that without the resident compiler. on this host: interpreter 2.939 ms, microcore 2.679 ms, arm64 jit under qemu-user 1.733 ms, llvm 0.434 ms. + +`test.sh` after this stage: 368 passed, 0 failed. the eighteen new checks are the sharing line and the memdebug line on the interpreter, the microcore, the arm64 jit and the llvm backend; both of those on the small microcore and on `core.c` at that size; the run-only sharing line; both virt boards running `tests/share.zc` and compiling it; and one llvm run with `ZYHOT=1`. the fixpoint is the same 100757 words on the interpreter, the microcore, the jit and llvm. + +what is still open: a store through a shared pointer is not trapped, so immutability is the discipline of `car`, `cdr` and `tget` rather than a hardware check. the cycle test uses that store on purpose. the collector is still conservative, so a stale stack word can keep a cell alive until `scrub`. a shared object is not quarantined, so after the sweep reclaims it a leftover pointer is dangling; `checkptr` reports that on the next `car`. there is no write barrier and no compaction. diff --git a/docs/history/31-fpu/notes.md b/docs/history/31-fpu/notes.md new file mode 100644 index 0000000..5fe01d7 --- /dev/null +++ b/docs/history/31-fpu/notes.md @@ -0,0 +1,23 @@ +# 31 — hardware float, and a soft fallback + +float arithmetic was already a host `double` on the interpreter and the microcore, and the arm64 jit and llvm already lowered 601..609 themselves. this stage makes that split explicit and adds the path for a machine with no FPU. + +the arm64 jit emits the FPU directly: `fadd`, `fsub`, `fmul`, `fdiv`, `fcmp` plus `cset` (`mi` and `ls`, so unordered is not less), `scvtf` and `fcvtzs`. print and parse stay calls, because they are formatting. llvm builds `fadd`/`fsub`/`fmul`/`fdiv`, `fcmp` (`oeq`/`olt`/`ole`), `sitofp` and `fptosi` on a double bitcast to i64. neither backend calls a C helper for those opcodes. + +the interpreter and the microcore go through `fops.h`. by default that is a `volatile double`, so the C compiler emits the FPU rather than folding the operation: x86_64 `addsd`/`mulsd`/`ucomisd`/`cvtsi2sd`/`cvttsd2si`, AArch64 `fadd`/`fmul`/`fcmp`/`scvtf`/`fcvtzs`, RV64 `fadd.d`/`fmul.d`/`flt.d`/`fcvt.d.l`/`fcvt.l.d` with `-mabi=lp64d`. the virt boards already set the FPU live before any C runs. RISC-V writes `mstatus.FS` to Dirty (`0x6000`). AArch64 clears the FP trap at EL2 and sets `CPACR_EL1.FPEN`. both images are built hard-float (`-march=rv64gc -mabi=lp64d`, `-march=armv8-a`). + +`-DZY_SOFTFLOAT` replaces those entry points with an integer IEEE binary64. round ties to even. a NaN becomes a canonical quiet NaN; every other finite result matches the host FPU, including signed zero, subnormals and overflow to infinity. the parser scales with the same add/mul/div, so a soft build and a hard build read a literal the same way. there is still no libc. an AArch64 compile of that path with `-mgeneral-regs-only` is free of `fadd` and of `bl` into a helper. + +which path a build takes: + +- hosted interpreter, x86_64: hardware, SSE2, via `fops.h` +- hosted microcore, x86_64: the same +- arm64 jit under qemu-user: native FPU instructions in the translator +- llvm backend: native `double` ops +- RISC-V virt: FPU enabled in the boot stub, `fadd.d` in the microcore +- AArch64 virt: FPU enabled in the boot stub, `fadd` in the microcore +- `-DZY_SOFTFLOAT`: integer fallback, selected at build time. the float test line is the same + +`test.sh` compiles one interpreter that way and checks `tests/float.zc`. the line is unchanged, so the fixpoint is still 100757 words. the suite after this stage was 369 passed, 0 failed. the one new check is that soft-float interpreter. + +what is still open: a call result, a global, a field, a parameter and a return are not yet known to be floats. `-0.0` is still true in `if`, because the sign bit is set. `o3` still does not lift 600..611. magnitudes past about 1e32 still print as `inf`, and a parsed significand is still at most 15 digits. diff --git a/docs/history/32-ftype/notes.md b/docs/history/32-ftype/notes.md new file mode 100644 index 0000000..bc119f6 --- /dev/null +++ b/docs/history/32-ftype/notes.md @@ -0,0 +1,17 @@ +# 32 — float is a type + +a float used to be a bit on a local. a call, a global, a field, a parameter and a return forgot it, so the next `+` was an integer add unless the programmer wrote the literal again. `-0.0` was true in `if`, because the test was the integer one and the sign bit is set. `1.field` was a float, because a dot after digits was always a fraction. + +`float` is type kind 12. a literal, a local declared `float`, a global, a field, an index, a dereference, a parameter and a call result are floats. assigning an int into a float converts with opcode 608, and assigning a float into an int converts with 609. a `word` keeps the bits. `+ - * /` and the six comparisons promote whichever side is not already a float. `++` stays an integer add. + +the vm's `jz` is still an integer test. where a float is used as a condition (`if`, `while`, `for`, `do`, `?:`, `&&`, `||`, `!`) the compiler emits a compare with `+0` and inverts it, so both zeros are false and every other value, including a NaN, is true. `zc0` emits the same test, so a run-only image does too. the spelling `-0.0` is unary minus of `0.0`, and `0 - 0` is `+0`; a product such as `0.0 * -1.0` is a real negative zero, and that is the value the test covers. + +`1.field` is an integer and a field. the dot is a fraction only when a digit or an exponent follows it (`1.5`, `1.`, `1.e2`, `1.+2`). a letter is a field name. an integer or a word used as the base resolves a field name that belongs to exactly one struct in that program, and the address is the base plus the field's offset. `tests/ftype.zc` prints `&(1.field)` as 2, because `field` is the second word of `cell`, and it reads and writes that field through a word that holds an object's address. + +`tests/ftruth.zc` is in the zc0 subset. the line is `00111000110107`. `tests/ftype.zc` needs the resident compiler. the line is `3.500000 10.500000 3.500000 4.250000 5.250000 4.250000 6.500000 2 4 4.250000 8.500000 1 4`. + +the fixpoint image is 103348 words, 826784 bytes. the stage-0 image is 99284 words. the small compiler's stage-0 image is 99283 words, so its reservation moved from 97280 to 100352 and that machine is now 184320 words. the run-only reservation stays 14336 in the 36864-word machine. `tests/ftruth.zc` there is 13693 words. + +`test.sh` after this stage is 391 passed, 0 failed. the new checks are the negative-zero line and the float-type line on the interpreter, the microcore, the arm64 jit and the llvm backend; both lines on the small microcore and on `core.c` at that size; the run-only image of the negative-zero program; both virt boards running that program and compiling it and the float-type program; a soft-float interpreter on the negative-zero line; and `ZYHOT=1` on both. + +what is still open: `o3` does not lift 600..609, and a region that contains a float literal can be misread because the lifter does not skip the payload word. magnitudes past about 1e32 still print as `inf`, and a parsed significand is still at most 15 digits. diff --git a/docs/history/33-fo3/notes.md b/docs/history/33-fo3/notes.md new file mode 100644 index 0000000..60d515d --- /dev/null +++ b/docs/history/33-fo3/notes.md @@ -0,0 +1,24 @@ +# 33 — o3 lifts floats + +`o3` used to leave 600..609 in the bytecode, and a float literal could split a region: the word after opcode 600 is raw bits, and a payload of zero is the halt opcode if the lifter reads it as an instruction. discovery and the block lifter now consume that word themselves. print and parse (610 and 611) still leave the region. + +the lifted ops are `fadd`, `fsub`, `fmul`, `fdiv`, `feq`, `flt`, `fle`, `i2f` and `f2i`. two constant operands fold by running that same operation, so the fold is the IEEE result, including a NaN and a signed zero. nothing rewrites `x - x` to zero, `x + 0` to `x`, or `x * 1` to `x`. + +a float variable's install word is negative. that home is a `d` register on arm64 and a `double` alloca on llvm, so a loop that only adds and multiplies does not move the value through an integer register. an integer variable still lives in an `x` register. a freed register keeps its class, because one var index cannot be both. the interpreter runs the same micro-ops through `fops.h`, which is the host FPU unless the build selected `-DZY_SOFTFLOAT`. + +`tests/fo3.zc` prints `5997 5997 4.000000 nan 0 3.250000 1 0 0`. the two 5997s are `(int)` of the same polynomial, plain and `o3`, at 2000 steps. `1.5 + 2.5` folds to 4. `nan - nan` stays `nan`. a negative zero is false in `if` and `while` inside the region. `1.0 < 2.0` is 1, and a NaN is not less than 1. `tests/o3.zc` still lifts 8 regions. + +the fixpoint image is 103655 words, 829240 bytes. the stage-0 image is 99591 words. the small compiler's stage-0 image is 99590 words, inside the 100352 reservation (762 words of room). the run-only map did not move. + +`tests/fbench.zc` times `poly(20000)` without bootstrapping: the slope between 1 repetition and N drops startup and compile time. `(int)` of one call is 59997. before the lift, an o3 copy of that loop did not finish, because the payload of `0.0` was read as halt, so the before number is the plain bytecode. milliseconds per call: + +- interpreter, before 5.318, after (o3) 0.869, about 6.1 times +- llvm, before 0.167, after 0.037, about 4.5 times +- arm64 jit under qemu-user, before 1.620, after 0.292, about 5.5 times +- microcore, before 5.194, after 5.054. it does not lift o3, so both are the bytecode + +the plain loop after the change is the same speed as before (interpreter 5.268, llvm 0.163, arm64 1.625, microcore 5.179). + +`test.sh` after this stage is 401 passed, 0 failed. + +what was still open here, and closed in stage 34: magnitudes past about 1e32 printed as `inf`, and a parsed significand stopped at 15 digits. diff --git a/docs/history/34-ftext/notes.md b/docs/history/34-ftext/notes.md new file mode 100644 index 0000000..6f0c7ae --- /dev/null +++ b/docs/history/34-ftext/notes.md @@ -0,0 +1,11 @@ +# 34 — float text + +opcode 610 still prints six digits after the dot, and a tie in the next digit still rounds away from zero, so the existing float line does not move. it no longer gives up past about 1e32: the scaled magnitude is a base-2^32 integer, so a finite value prints its digits. `-0` stays `-0.000000`, and a nan is `nan` whatever its sign bit. + +opcode 618 (the word 1236) pops `(bits prec mode)`. mode 0 is the shortest spelling that parses back to the same bits: a plain decimal when the exponent is between -4 and 15, otherwise scientific (`1e+308`, `1e-10`, `-0`). mode 1 is fixed, `prec` digits after the dot. mode 2 is scientific, `prec` significant digits. `prec` is capped at 17. print and parse stay out of an o3 region, the same way 610 and 611 do. + +the parser keeps the digits of the word it is given (eighty, past that a sticky bit) and converts `significand * 10^exp` with the same integer arithmetic. ties round to even, which is why `9007199254740993` and `9007199254740992` are one double and the next integer is not. `inf`, `-inf`, `nan` and `-nan` are accepted, and an exponent past the double range is an infinity or a zero. nothing here calls libc, so the text does not depend on the host printf. the arm64 jit and llvm call the same C function the interpreter does; the arithmetic opcodes are still native. + +`tests/ftext.zc` prints `1e+308 1e-10 -0 inf -inf nan 0.1 1.50 1.250e+0 100000000000000000000.000000 1e+40 1111111111`. the ten ones are bit checks: `1.5` against `3/2`, `0.1` against `1/10`, the infinities, negative zero, the 17-digit tie, a subnormal, an underflow to zero, and a signed nan. the compiler and the runtime were not rebuilt for this; `fops.h` is the whole conversion. + +`test.sh` after this stage is 414 passed, 0 failed. diff --git a/docs/history/35-bench/notes.md b/docs/history/35-bench/notes.md new file mode 100644 index 0000000..914bbba --- /dev/null +++ b/docs/history/35-bench/notes.md @@ -0,0 +1,82 @@ +# 35 — zc against C + +two programs, each written in zc and in C, timed without bootstrapping the compiler. the sieve is the integer loop, where o3 and the llvm backend should look good. the tree is the allocator and the call, where they should not. + +`bench/sieve.zc` and `bench/sieve.c` count primes below 100000. one word per flag, marks start at `i * i`, checksum 9592. zc has three kernels: a plain `fixed []int` (bounds-checked), the same function marked `o3`, and an `o3` loop through a raw `*int` with no per-index check. C has the same word loop, plus a byte-flag loop that is a different representation. `bench/trees.zc` and `bench/trees.c` build a full binary tree of depth 12 and walk it. checksum 8191, the node count. zc `new(node)` / `free`, the same marked `o3`, and one array used as an arena of pairs. C uses `malloc` / `free`, and the same arena shape. a node in zc is two pointers plus the 6-word buddy header, which rounds to 8 words (64 bytes). the C node is two pointers (16 bytes). + +the number is the slope between 1 repetition and N, so process startup falls out, and so does the time zc spends compiling the benchmark. five slopes, median, min and max. pinned to one cpu with `taskset`. the vms are built at `-O3`. C is `gcc` and `clang` at `-O3 -march=native`, then again with `-flto`, and gcc again with `-fprofile-generate` / `-fprofile-use`. LTO and PGO stayed inside the spread on both programs, so the tables below use the plain `-O3 -march=native` line for C and mention the others only where they differ. `ZYHOT=1` on the llvm vm, so every block is compiled, and each o3 region is compiled with llvm's O3 pipeline at install time. the arm64 jit is `qemu-aarch64` 8.2.2 running an aarch64 binary on this x86 host. that is emulation, not arm64 hardware. the microcore is not in the table: it does not lift o3. + +the machine: Linux 6.12.94+ x86_64, KVM, 4 vCPUs. `/proc/cpuinfo` says Intel Xeon, family 6 model 207; the hypervisor leaves the model name as "Intel(R) Xeon(R) Processor". gcc 13.3.0, clang 18.1.3, llvm 18.1.3. + +the llvm tree rows were retimed with about 3 seconds of kernel work (n = 220, 155 and 38419). the first calibration aimed at 0.8 seconds and undershot, because compiling the benchmark under `ZYHOT=1` takes about 9 seconds and a short slope drowns in that jitter. `bench/run.py` now grows N until the measured gap actually reaches the target. the other rows already had a tight spread at 0.8 seconds, except the llvm raw sieve, whose five samples still all sit between 1.4x and 1.7x the gcc sieve. + +## sieve + +milliseconds per count of the primes below 100000. + +| path | median | min | max | +| --- | ---: | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.149 | 0.149 | 0.150 | +| clang -O3 -march=native, word flags | 0.157 | 0.157 | 0.173 | +| gcc -O3 -march=native -flto, byte flags | 0.081 | 0.080 | 0.081 | +| zc interpreter, plain, bounds-checked | 214.3 | 212.8 | 215.7 | +| zc interpreter, o3, bounds-checked | 22.92 | 22.91 | 22.93 | +| zc interpreter, o3, raw pointer | 14.36 | 14.26 | 15.84 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.219 | 0.209 | 0.256 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.640 | 0.633 | 0.667 | +| zc arm64 jit, qemu-user, o3 raw pointer | 2.094 | 2.075 | 2.102 | + +gcc with `-flto` was 0.149, gcc with PGO was 0.149, clang with `-flto` was 0.158. + +on the same word algorithm, the llvm backend is about 1.5x the best C. that is the strength. the interpreter running the lifted blocks is about 65x slower than that llvm region (14.4 ms against 0.22 ms), and the plain bytecode is about 9x slower again than the lifted blocks (214 ms against 23 ms). the bounds check costs 1.6x on the interpreter and 2.9x once llvm has made the arithmetic cheap (0.64 ms against 0.22 ms). + +the arm64 column is qemu-user. 2.09 ms is 14x the native gcc number and only 6.9x faster than the native interpreter running the same lifted blocks. both of those comparisons are skewed: qemu is translating aarch64, and the interpreter is x86 host code. the ratio that is safe to read is jit against itself. it is not a measurement of arm64 hardware. + +the byte sieve is the same algorithm in 1 byte per flag. gcc runs it in 0.081 ms, 1.8x faster than the word sieve. zc cannot take that path on the fast tier: byte loads and stores are opcodes 612..617, and `lift_block` leaves the region on anything it does not recognize. + +## trees + +milliseconds per tree of depth 12, built and walked, then released. + +| path | median | min | max | +| --- | ---: | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.092 | 0.091 | 0.092 | +| clang -O3 -march=native, malloc | 0.110 | 0.110 | 0.111 | +| gcc -O3 -march=native -flto, arena | 0.0144 | 0.0143 | 0.0144 | +| clang -O3 -march=native -flto, arena | 0.0308 | 0.0304 | 0.0311 | +| zc interpreter, plain new/free | 178.1 | 177.6 | 179.4 | +| zc interpreter, o3 new/free | 269.4 | 269.2 | 273.9 | +| zc interpreter, o3 arena | 2.108 | 2.102 | 2.164 | +| zc llvm, ZYHOT=1, plain new/free | 13.69 | 13.14 | 14.60 | +| zc llvm, ZYHOT=1, o3 new/free | 23.70 | 21.67 | 28.14 | +| zc llvm, ZYHOT=1, o3 arena | 0.282 | 0.269 | 0.291 | +| zc arm64 jit, qemu-user, plain new/free | 80.83 | 80.64 | 83.65 | +| zc arm64 jit, qemu-user, o3 arena | 1.667 | 1.624 | 1.691 | + +gcc malloc with `-flto` was 0.093, with PGO 0.092. clang malloc with `-flto` was 0.110. + +`new` / `free` on the llvm backend is about 150x gcc `malloc` (13.7 ms against 0.092 ms). the same backend walking an arena, with no allocator in the loop, is 0.28 ms, about 20x gcc's arena (0.014 ms) and about 50x faster than zc's own `new`. so most of the tree gap is the allocator, and what is left after the allocator is gone is the call. marking the tree `o3` makes it slower: 269 ms against 178 ms on the interpreter, 24 ms against 14 ms on llvm. `new` in o3 code is `new_raw`, and every return and every store of a child calls `fatten` and `own`, which are ordinary calls out of the region. + +`free` only quarantines. the timed loop does not call `gc` itself; the next `new` sweeps when an 8-word block will not fit. an earlier single slope that called `gc` on every tree was about twice as slow. forty iterations completed without `scrub`. the sweep still scans the whole data-stack area (`gc_roots` marks `DSLO`..`DSHI`), so a shape that leaves a pointer in an unused slot would pin the quarantined nodes. `scrub` only overwrites 1024 words below the stack pointer. + +under qemu the arena jit (1.67 ms) is barely faster than the interpreter's arena (2.11 ms). the body between calls is a handful of micro-ops, and every call returns to the driver. the sieve, whose inner loop never calls, is where the jit pays off. + +## what is missing, by impact + +1. the buddy allocator. `new_raw` in `src/rt.zc` adds a 6-word header and rounds up to a power of two, so a two-pointer node is 64 bytes. `free` quarantines instead of pushing the block back on its size-class list; the next failed allocation runs `gc`, which walks the whole heap. on llvm that is the difference between 13.7 ms and 0.28 ms, and against gcc `malloc` it is about 150x. fix: a bump allocator the program can opt into (the arena kernel is that, written by hand), and a free path that returns a block the program has already dropped to the free list without a full sweep. stamp the type in `new` so the header does not have to be repaired later. + +2. the call ABI. `lift_block` ends the block at a call (opcode 6, `T_CALL`). `run` spills the region, returns to the C driver, dispatches the callee, and re-enters at the return point. a depth-12 tree is 8191 calls to build and 8191 calls to walk, and the llvm arena is still 20x gcc's arena (0.28 ms against 0.014 ms). the same exit is why `o3` cannot speed the tree up. fix: when the callee is an o3 region, compile a native call to its entry with the arguments in registers, and only spill to the vm stack when the callee is ordinary bytecode. + +3. bounds checks on `fixed []T`. the o3 index path in `src/compiler.zc` compares the index with `outside` and, on the failure path, calls `oob`. in the lifted sieve that compare spills the index to the data stack and reloads it on the way back, on every in-bounds store. llvm pays 2.9x for it (0.64 ms against 0.22 ms). fix: keep the index in a register across the check, and drop the check when the loop bound was already compared against the length. a raw `*int` is the escape hatch that already exists; the checked form should not be this far from it. + +4. the lifted blocks are too small, and nothing vectorizes. the raw sieve's inner step is a compare block, an empty block, a store block and an add block, four dispatches per flag. that is the interpreter's 14 ms. llvm's O3 pipeline closes most of it (down to 0.22 ms) but does not match gcc, which fills and counts with `ymm` stores and `vpaddd` (0.15 ms, 1.5x faster). fix: merge an empty block into its successor and rotate the loop before codegen, so both `rexec` and llvm see one block per iteration. gcc's leftover advantage is the vectorizer; a region whose loops are single blocks gives llvm's vectorizer a chance at the fill and the count. + +5. `fatten` and `own` on the way out of o3. storing a fresh child emits a call to `own`, and because the value has pointer fields the compiler also calls `fatten` (`emitown`, and again on an o3 return). `fatten` stamps the type `new_raw` left blank and walks children that are already stamped. the o3 tree is about 1.5x slower than the plain one on the interpreter, and about 1.7x slower on llvm, for that. fix: pass the type into the allocation so the header is born stamped, and inline `p[-2] = owner` as a store in the region when memdebug is off. do not fatten a pointer that was allocated as that type a few instructions earlier. + +6. byte addressing is not on the fast path. opcodes 612..617 fall into the `leave_at` default in `lift_block`, so a byte sieve would run as bytecode even inside `o3`. the C byte sieve shows the prize is about 1.8x on this size, less than the gaps above, and it grows for a bigger limit where the word sieve stops fitting in cache. fix: lift `ld8` / `st8` / `ld16` / `st16` / `ld32` / `st32` the same way the word load and store are lifted, in the interpreter, the arm64 jit and the llvm region. + +7. the collector's roots, and quarantine. `gc_roots` marks every word from `DSLO` to `DSHI`, not just the live stack, so a pointer left above the stack pointer keeps a freed block quarantined forever. `scrub` clears 1024 words and is easy to forget; this tree happened to overwrite those slots before the sweep. fix: mark from the stack pointer to the top, and treat a block the program freed, whose pointer it has cleared, as immediately reusable. + +8. library and language gaps the two programs ran into. there is no arena and no packed array in `lib/std.zc`, so the fast tree is an index bump written out by hand and the fast sieve is a word per flag. a small arena and a packed byte buffer in the library would make those the ordinary spelling. `u`, `m` and `d` are still reserved as bare words, so the first draft of the tree would not compile with a parameter named `d` (`if (d > 0)` is read as a tag). fix: only treat those letters as tags after a dot. `new` inside `o3` does not zero its memory (`new_raw`); the leaves had to store null children or the walk would read garbage. fix: have the compiler emit those zero stores in the region, or zero pointer fields in `new_raw` when the type is known. + +the register file is part of the same ceiling. a region has seven variable registers (`RMAXV`). the bounds-checked sieve already uses all seven. a loop with one more live value stays in memory, and the arm64 jit gives up on a block that needs more temporary registers than it has. raising that, or spilling inside the region instead of abandoning it, matters once the calls and the checks above are cheap enough for register pressure to show. diff --git a/docs/history/36-alloc/notes.md b/docs/history/36-alloc/notes.md new file mode 100644 index 0000000..aff6965 --- /dev/null +++ b/docs/history/36-alloc/notes.md @@ -0,0 +1,47 @@ +# 36 — allocator + +the tree was paying for a quarantine and a sweep on every `new`. `free` left the block intact until `gc` walked the heap. a uniquely owned pointer does not need that. `free(d*x)`, and the free the analyzer emits when an owned local dies, now call `recycle`. children go first, then the block is pushed onto its size-class list. there is no buddy walk and no heap scan. a plain `free`, the one an alias might still see, still quarantines. `tests/quarantine.zc` is that contract, and it still prints `0 1234`. + +the header lost the class word. size is `p[-5]`, and the class sits in the high bits of the flags word, so `p[-4]` through `p[-1]` are still flags, check word, owner and type. a two-word node is still 8 words: five header words plus two payload words is 7, and the smallest block is 8. a three-word node fits in 8 instead of 16. `new(int)` therefore reports a payload of 3 in `memreport`, and `tests/memleak.zc` expects that. the slack past the size `new` was asked for is zeroed, so a later walk does not follow an uninitialized word. the words that were asked for stay uninitialized in `new_raw`. + +`arena_new(n)`, `arena_alloc` and `arena_reset` are a bump allocator over one owned block. the pointers it hands out are interior. resetting the bump reuses them. `tests/arena.zc` and `tests/recycle.zc` cover both. + +`<<` is an enhancement, and `heap_init` runs before the image installs enhancements, so the class is packed with a multiply by `pow2[16]` rather than a shift. + +the stage-0 image is 100933 words and the fixpoint is 105074. the small compiler's stage-0 image is 100932, so its reservation moved from 100352 to 102400. that machine is still 184320 words; the extra reservation came out of the data-stack slack. the run-only image of `tests/bytes.zc` is 15030 words, so that reservation moved from 14336 to 15600. the machine is still 36864 words. + +the suite is 422 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +## sieve + +the sieve does not allocate in the loop. it stayed inside the previous spread. milliseconds per count, median of five slopes. the before column is `history/35-bench`. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.149 | 0.149 | +| gcc -O3 -march=native -flto, byte flags | 0.081 | 0.081 | +| zc interpreter, plain, bounds-checked | 214.3 | 214.2 | +| zc interpreter, o3, bounds-checked | 22.92 | 22.89 | +| zc interpreter, o3, raw pointer | 14.36 | 14.63 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.219 | 0.233 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.640 | 0.626 | +| zc arm64 jit, qemu-user, o3 raw pointer | 2.094 | 2.066 | + +## trees + +milliseconds per tree of depth 12. same kernels as stage 35. gcc on this run was 0.091 for malloc and 0.0143 for the arena. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.092 | 0.091 | +| gcc -O3 -march=native -flto, arena | 0.0144 | 0.0143 | +| zc interpreter, plain new/free | 178.1 | 76.37 | +| zc interpreter, o3 new/free | 269.4 | 175.3 | +| zc interpreter, o3 arena | 2.108 | 2.111 | +| zc llvm, ZYHOT=1, plain new/free | 13.69 | 6.91 | +| zc llvm, ZYHOT=1, o3 new/free | 23.70 | 15.73 | +| zc llvm, ZYHOT=1, o3 arena | 0.282 | 0.270 | +| zc arm64 jit, qemu-user, plain new/free | 80.83 | 44.85 | +| zc arm64 jit, qemu-user, o3 arena | 1.667 | 1.554 | + +plain `new` / `free` is about 2.3x faster on the interpreter (76 ms against 178) and about 2.0x on llvm (6.9 ms against 13.7). the arm64 jit under qemu dropped from 81 ms to 45 ms. llvm against gcc `malloc` is about 76x, down from about 150x. the arena rows did not move: that kernel never calls the allocator. the o3 tree is still slower than the plain one (175 ms against 76, and 15.7 ms against 6.9), because `fatten` and `own` are still calls on every child. diff --git a/docs/history/37-call/notes.md b/docs/history/37-call/notes.md new file mode 100644 index 0000000..e135411 --- /dev/null +++ b/docs/history/37-call/notes.md @@ -0,0 +1,43 @@ +# 37 — calls + +an o3 function calling another o3 function was leaving the region, running the prologue, and coming back through the epilogue. the return also called `fatten` whenever the type had a pointer. both are boundary work. a call that stays inside o3 is not a boundary. + +the region descriptor now carries the frame size, the arity, and the prologue address. a bare o3 block stores -1 for that address, so a real function whose prologue is at word 0 still gets registered. the caller builds the frame, copies the arguments, and enters the callee's region at its first block. the callee's prologue and epilogue do not run. a return to the caller puts the frame pointer back. `fatten` runs only when the value actually crosses into code that is not o3: the call site in ordinary code, an argument passed to an ordinary function (`free` and `recycle` still excepted), a store out of an o3 variable, and the end of an o3 block. `tests/o3call.zc` checks the split. `inner` returns a raw header (`p[-1] < 0`), and the same function called from `main` comes back fat. + +on the interpreter and on llvm, that entry is a direct call into the region. a callee that is ordinary bytecode is pushed on the vm return stack and run by the same driver that runs everything else, so a hot `new` stays compiled. on the arm64 jit the o3 callee is a `blr` to its entry stub. the return address lives in a small link stack, not in a trip out to c and back through `x_enter`. + +the fixpoint is 105293 words. the stage-0 image is 101152, still inside the 102400-word small reservation. the run-only image did not change. the suite is 426 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +## sieve + +the inner loops do not call. milliseconds per count, median of five slopes. the before column is `history/36-alloc`. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.149 | 0.148 | +| gcc -O3 -march=native -flto, byte flags | 0.081 | 0.081 | +| zc interpreter, plain, bounds-checked | 214.2 | 202.3 | +| zc interpreter, o3, bounds-checked | 22.89 | 21.66 | +| zc interpreter, o3, raw pointer | 14.63 | 14.35 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.233 | 0.249 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.626 | 0.745 | +| zc arm64 jit, qemu-user, o3 raw pointer | 2.066 | 2.103 | + +## trees + +milliseconds per tree of depth 12. same kernels as stage 36. gcc on this run was 0.091 for malloc and 0.0143 for the arena. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.091 | 0.091 | +| gcc -O3 -march=native -flto, arena | 0.0143 | 0.0143 | +| zc interpreter, plain new/free | 76.37 | 72.59 | +| zc interpreter, o3 new/free | 175.3 | 162.1 | +| zc interpreter, o3 arena | 2.111 | 1.426 | +| zc llvm, ZYHOT=1, plain new/free | 6.91 | 7.78 | +| zc llvm, ZYHOT=1, o3 new/free | 15.73 | 16.43 | +| zc llvm, ZYHOT=1, o3 arena | 0.270 | 0.195 | +| zc arm64 jit, qemu-user, plain new/free | 44.85 | 43.58 | +| zc arm64 jit, qemu-user, o3 arena | 1.554 | 0.624 | + +the arena kernel is the one this change is aimed at: recursive o3 calls and no allocator. it dropped from 2.111 ms to 1.426 on the interpreter, from 0.270 ms to 0.195 on llvm, and from 1.554 ms to 0.624 on the arm64 jit under qemu. the o3 `new` / `free` tree is still slower than the plain one (162 ms against 73, and 16.4 ms against 7.8). `fatten` and `own` are still calls on every child store. diff --git a/docs/history/38-bounds/notes.md b/docs/history/38-bounds/notes.md new file mode 100644 index 0000000..698d15b --- /dev/null +++ b/docs/history/38-bounds/notes.md @@ -0,0 +1,43 @@ +# 38 — bounds + +the o3 index of a `fixed []T` compared the index with `outside` and left that index on the data stack across the branch. the lifter reloaded it from a stack slot on the way back, on every in-bounds store. when the index is a local, both sides of the branch now load it from the variable. the failure path is the only spill, and it only exists to hand `oob` its two arguments. + +a `for` whose test is `i < b`, whose step is `i++` or `i += 1`, and whose `b` holds `len` of that fixed array, drops the check. `i` has to be known non-negative, and the body must not have stored `i`, `b`, or the array yet. `i * i < n` is not that test, and `j += i` is not a step of one: a product can wrap negative, so the inner sieve loop keeps the check. `i = -1` keeps it. `f[i + 1]` keeps it, because that index is not the induction variable. the same proof applies to plain bytecode, which then computes the address without calling `dat`. `tests/bounds.zc` is the sum and a small sieve. `tests/bounds_lo.zc` and `tests/bounds_hi.zc` are the two checks that have to stay. + +the fixpoint is 109545 words. the stage-0 image is 105232, and the small machine's copy is 105231, so that reservation moved from 102400 to 110592. the small machine is now 192512 words. the run-only image did not change. the suite is 438 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +## sieve + +milliseconds per count, median of five slopes. the before column is `history/37-call`. the raw pointer does not check, so it is the control. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.148 | 0.148 | +| gcc -O3 -march=native -flto, byte flags | 0.081 | 0.080 | +| zc interpreter, plain, bounds-checked | 202.3 | 144.2 | +| zc interpreter, o3, bounds-checked | 21.66 | 18.42 | +| zc interpreter, o3, raw pointer | 14.35 | 14.22 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.249 | 0.254 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.745 | 0.430 | +| zc arm64 jit, qemu-user, o3 raw pointer | 2.103 | 2.080 | + +the fill and the count are `i = 2; i < n; i++` with `n = len(f)`, so those checks are gone. the inner `j = i * i; j < n; j += i` still checks, and the index stays in its variable across that check. on llvm the checked sieve went from 0.745 ms to 0.430 ms. the raw pointer is 0.254 ms. the gap that is left is the check itself, and the empty blocks the loop still splits into. + +## trees + +milliseconds per tree of depth 12. gcc on this run was 0.091 for malloc and 0.0143 for the arena. these kernels do not index a `fixed []T` in a proved loop. a dump of their four o3 regions is the same blocks, at the same addresses, as the previous compiler. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.091 | 0.091 | +| gcc -O3 -march=native -flto, arena | 0.0143 | 0.0143 | +| zc interpreter, plain new/free | 72.59 | 72.73 | +| zc interpreter, o3 new/free | 162.1 | 162.0 | +| zc interpreter, o3 arena | 1.426 | 1.429 | +| zc llvm, ZYHOT=1, plain new/free | 7.78 | 7.32 | +| zc llvm, ZYHOT=1, o3 new/free | 16.43 | 18.31 | +| zc llvm, ZYHOT=1, o3 arena | 0.195 | 0.184 | +| zc arm64 jit, qemu-user, plain new/free | 43.58 | 44.21 | +| zc arm64 jit, qemu-user, o3 arena | 0.624 | 0.838 | + +the interpreter arena stayed at 1.43 ms. the arm64 arena moved under qemu, from 0.624 ms to 0.838 ms, on code this pass did not change. diff --git a/docs/history/39-blocks/notes.md b/docs/history/39-blocks/notes.md new file mode 100644 index 0000000..5133381 --- /dev/null +++ b/docs/history/39-blocks/notes.md @@ -0,0 +1,43 @@ +# 39 — blocks + +a `for` left the lifter as a test, an empty jump, a body and a step. the raw sieve's inner loop was four dispatches per flag. after the blocks exist and before any backend runs, three cleanups share one cfg. + +an empty jump (no ops, no stack, no variable write) is retargeted at its successor, including an entry that landed on it. a jump to a block that has no other predecessor, and that is not itself an entry, is pasted onto that predecessor: the two stacks are empty, and a read of a variable the first half already wrote uses that value. a header whose test is a branch, and whose one edge is a straight run of those jumps back to the header, is rotated. the run plus a copy of the test becomes one block. the zero edge of that test still leaves, and the other edge branches to the block itself. the header's first test stays in front of it, so a loop that runs zero times never enters. a body that contains another branch is left alone, which is the inner sieve's bounds check and the `if (f[i])` around it. a block nothing can reach becomes a jump to itself, so it is not a second predecessor of the live loop. + +the raw sieve's fill, its inner `j += i` store, and its count are each one block per iteration. the checked sieve's fill and count are too. its inner loop is the test, the bounds branch, and one block that stores and steps. the same blocks are what the interpreter, the arm64 jit and llvm compile. the fixpoint is still 109545 words. this pass is in the core, and the genome did not change. the suite is 438 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +## sieve + +milliseconds per count, median of five slopes. the before column is `history/38-bounds`. plain bytecode is the control: this pass only reshapes o3 regions. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.148 | 0.167 | +| gcc -O3 -march=native -flto, byte flags | 0.080 | 0.080 | +| zc interpreter, plain, bounds-checked | 144.2 | 144.1 | +| zc interpreter, o3, bounds-checked | 18.42 | 12.46 | +| zc interpreter, o3, raw pointer | 14.22 | 7.97 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.254 | 0.227 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.430 | 0.414 | +| zc arm64 jit, qemu-user, o3 raw pointer | 2.080 | 1.931 | + +the interpreter's raw pointer went from 14.22 ms to 7.97 ms, and the checked o3 sieve from 18.42 ms to 12.46 ms. the arm64 jit went from 2.080 ms to 1.931 ms. gcc's word flags came out at 0.167 ms on this run, against 0.148 ms last time, and the byte flags stayed at 0.080 ms. the plain zc sieve, which is still bytecode, stayed at 144 ms. + +`bench/run.sh` timed the llvm raw pointer at 315 repetitions. one of the five trials came out negative, and the median of that set is 0.399 ms (spread -0.72 to 0.88). a slope from 4000 repetitions to 16000 on the same binary is 0.227 ms (0.224 to 0.238), and that is the after column. the checked sieve's long slope is 0.439 ms (0.430 to 0.483), next to the run's 0.414 ms. the inner checked loop still branches on the bounds test, so llvm did not get a single block there, and the raw pointer stayed near a quarter of a millisecond rather than the byte-flag 0.080 ms. + +## trees + +milliseconds per tree of depth 12. gcc on this run was 0.091 for malloc and 0.0144 for the arena. these kernels are calls and recursion. a straight counted loop is not where they spend the time. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.091 | 0.091 | +| gcc -O3 -march=native -flto, arena | 0.0143 | 0.0144 | +| zc interpreter, plain new/free | 72.73 | 75.69 | +| zc interpreter, o3 new/free | 162.0 | 158.6 | +| zc interpreter, o3 arena | 1.429 | 1.413 | +| zc llvm, ZYHOT=1, plain new/free | 7.32 | 7.58 | +| zc llvm, ZYHOT=1, o3 new/free | 18.31 | 17.68 | +| zc llvm, ZYHOT=1, o3 arena | 0.184 | 0.159 | +| zc arm64 jit, qemu-user, plain new/free | 44.21 | 44.87 | +| zc arm64 jit, qemu-user, o3 arena | 0.838 | 0.836 | diff --git a/docs/history/40-fatten/notes.md b/docs/history/40-fatten/notes.md new file mode 100644 index 0000000..c7ff0fd --- /dev/null +++ b/docs/history/40-fatten/notes.md @@ -0,0 +1,41 @@ +# 40 — fatten + +typed `new(T)` now stamps the header and zeroes the payload inside an o3 region, the same path `new(T)` takes outside one. a child store writes `p[-2] = owner` in the region when memdebug is off. a shared child keeps the owner it already has, and a store through null does not land. the store skips `fatten` when that value was just allocated, or came back from an o3 function whose type has a pointer. `fatten` still runs where o3 data reaches code that is not o3: a store into a normal local or a global, an argument to a function that is not o3, the call site where ordinary code calls an o3 function, `push` into a growable array, and the end of an o3 block. a call or a return from o3 to o3 does none of that. an untyped `new(n)` in o3 is still `new_raw`, with `-(n + 1)` in the type word and the requested words left uninitialized. + +`tests/o3call.zc` now prints `0 0 4 23 55 node`: both the o3 caller and the ordinary caller see a stamped header. the fixpoint is 109799 words. the suite is 438 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +## sieve + +milliseconds per count, median of five slopes. the before column is `history/39-blocks`. this change does not touch the sieve's loops. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.167 | 0.151 | +| gcc -O3 -march=native -flto, byte flags | 0.080 | 0.084 | +| zc interpreter, plain, bounds-checked | 144.1 | 146.8 | +| zc interpreter, o3, bounds-checked | 12.46 | 12.75 | +| zc interpreter, o3, raw pointer | 7.97 | 8.09 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.227 | 0.233 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.414 | 0.444 | +| zc arm64 jit, qemu-user, o3 raw pointer | 1.931 | 1.936 | + +`bench/run.sh` timed the llvm raw pointer at 216 repetitions. one trial came out negative, and the median of that set is 0.172 ms (spread -0.12 to 1.14). the checked sieve's run was 45 repetitions and the median was -1.23 ms (spread -5.09 to 7.41). a slope from 4000 repetitions to 16000 on the same binary is 0.233 ms for the raw pointer (0.230 to 0.241) and 0.444 ms for the checked sieve (0.434 to 0.462). those two are the after column. they sit next to the previous long slopes, 0.227 ms and 0.439 ms. + +## trees + +milliseconds per tree of depth 12. the o3 `new` / `free` tree is the one this change is for. gcc on this run was 0.091 for malloc and 0.0144 for the arena. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.091 | 0.091 | +| gcc -O3 -march=native -flto, arena | 0.0144 | 0.0144 | +| zc interpreter, plain new/free | 75.69 | 72.97 | +| zc interpreter, o3 new/free | 158.6 | 64.89 | +| zc interpreter, o3 arena | 1.413 | 1.411 | +| zc llvm, ZYHOT=1, plain new/free | 7.58 | 7.42 | +| zc llvm, ZYHOT=1, o3 new/free | 17.68 | 6.49 | +| zc llvm, ZYHOT=1, o3 arena | 0.159 | 0.175 | +| zc arm64 jit, qemu-user, plain new/free | 44.87 | 44.12 | +| zc arm64 jit, qemu-user, o3 arena | 0.836 | 0.780 | + +on the interpreter the o3 tree went from 158.6 ms to 64.89 ms, and the plain tree on the same run was 72.97 ms. on llvm the o3 tree went from 17.68 ms to 6.49 ms, and the plain tree was 7.42 ms. each node is one call to `new_t`, an owner store in the region, and the two recursive calls. the arena rows are the same shape as last time. diff --git a/docs/history/41-obytes/notes.md b/docs/history/41-obytes/notes.md new file mode 100644 index 0000000..cf3280d --- /dev/null +++ b/docs/history/41-obytes/notes.md @@ -0,0 +1,39 @@ +# 41 — byte ops in o3 + +opcodes 612..617 (`ld8`, `st8`, and the 16- and 32-bit pair) lift. a call to one of those six from o3 code emits the opcode instead of leaving the region. the interpreter, the arm64 jit and llvm each run it: an out-of-range load is 0, an out-of-range store does nothing, and a store into a word a translation covers goes through the same hook as a word store, so a patch of the program's own code still drops that translation. the byte cases sit on the default path of the region interpreter, so the switch that runs the word sieve stays the size it was. + +`tests/o3bytes.zc` writes twenty bytes, reads them back at 8, 16 and 32 bits, rejects an address off either end of memory, and patches a `putc` literal from inside a region. it prints `190 4660 7 2055 16909060 0 0` and then `ABC`. the fixpoint is 110426 words. the suite is 442 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +## sieve + +milliseconds per count, median of five slopes. the before column is `history/40-fatten`. the kernels are still one word per flag. this pass does not change them. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.151 | 0.150 | +| gcc -O3 -march=native -flto, byte flags | 0.084 | 0.081 | +| zc interpreter, plain, bounds-checked | 146.8 | 145.6 | +| zc interpreter, o3, bounds-checked | 12.75 | 13.22 | +| zc interpreter, o3, raw pointer | 8.09 | 7.87 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.233 | 0.233 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.444 | 0.438 | +| zc arm64 jit, qemu-user, o3 raw pointer | 1.936 | 1.963 | + +`bench/run.sh` timed the llvm raw pointer at 3684 repetitions, median 0.250 ms (0.176 to 0.286), and the checked sieve at 1460 repetitions, median 0.423 ms (0.230 to 0.558). a slope from 4000 repetitions to 16000 on the same binary is 0.233 ms for the raw pointer (0.208 to 0.237) and 0.438 ms for the checked sieve (0.432 to 0.477). those two are the after column. the interpreter's raw pointer went from 8.09 ms to 7.87 ms. the checked o3 sieve went from 12.75 ms to 13.22 ms. gcc's byte flags were 0.081 ms. + +## trees + +milliseconds per tree of depth 12. these kernels do not touch a byte. gcc on this run was 0.094 for malloc and 0.0144 for the arena. the o3 tree stays ahead of the plain one. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.091 | 0.094 | +| gcc -O3 -march=native -flto, arena | 0.0144 | 0.0144 | +| zc interpreter, plain new/free | 72.97 | 72.86 | +| zc interpreter, o3 new/free | 64.89 | 65.55 | +| zc interpreter, o3 arena | 1.411 | 1.378 | +| zc llvm, ZYHOT=1, plain new/free | 7.42 | 8.08 | +| zc llvm, ZYHOT=1, o3 new/free | 6.49 | 6.95 | +| zc llvm, ZYHOT=1, o3 arena | 0.175 | 0.163 | +| zc arm64 jit, qemu-user, plain new/free | 44.12 | 44.15 | +| zc arm64 jit, qemu-user, o3 arena | 0.780 | 0.704 | diff --git a/docs/history/42-roots/notes.md b/docs/history/42-roots/notes.md new file mode 100644 index 0000000..628b3db --- /dev/null +++ b/docs/history/42-roots/notes.md @@ -0,0 +1,41 @@ +# 42 — roots + +opcode 619 pushes the data-stack index, the first live word. `gc_roots` marks from that index to the top, in the compiler and in the run-only image. a pointer sitting in a word the program has already dropped is not a root, so the next collection reclaims the block. `scrub` zeroes the unused region from `DSLO` up to the live top. the last 16 words are the ones the loop itself is using, and those are pushed as zeros. `free` still quarantines. a block something live still points at stays readable. + +`tests/roots.zc` plants a pointer at the bottom of the data stack, drops the local, collects, and prints `1 0`: the object is gone, and scrub cleared the planted word. the fixpoint is 110446 words. the suite is 448 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +## sieve + +milliseconds per count, median of five slopes. the before column is `history/41-obytes`. the sieve does not collect. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.150 | 0.149 | +| gcc -O3 -march=native -flto, byte flags | 0.081 | 0.080 | +| zc interpreter, plain, bounds-checked | 145.6 | 144.2 | +| zc interpreter, o3, bounds-checked | 13.22 | 11.11 | +| zc interpreter, o3, raw pointer | 7.87 | 6.87 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.233 | 0.252 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.438 | 0.439 | +| zc arm64 jit, qemu-user, o3 raw pointer | 1.963 | 1.920 | + +the interpreter's raw pointer went from 7.87 ms to 6.87 ms, and the checked o3 sieve from 13.22 ms to 11.11 ms. `bench/run.sh` timed the llvm raw pointer at 0.225 ms (0.177 to 0.244, 3517 repetitions) and the checked sieve at 0.396 ms (0.364 to 0.634, 1905 repetitions). a slope from 4000 repetitions to 16000 on the same binary is 0.252 ms for the raw pointer (0.230 to 0.287) and 0.439 ms for the checked sieve (0.427 to 0.441). those two are the after column. gcc's byte flags were 0.080 ms. + +## trees + +milliseconds per tree of depth 12. gcc on this run was 0.091 for malloc and 0.0143 for the arena. the o3 tree stays ahead of the plain one. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.094 | 0.091 | +| gcc -O3 -march=native -flto, arena | 0.0144 | 0.0143 | +| zc interpreter, plain new/free | 72.86 | 72.52 | +| zc interpreter, o3 new/free | 65.55 | 64.46 | +| zc interpreter, o3 arena | 1.378 | 1.353 | +| zc llvm, ZYHOT=1, plain new/free | 8.08 | 7.43 | +| zc llvm, ZYHOT=1, o3 new/free | 6.95 | 6.83 | +| zc llvm, ZYHOT=1, o3 arena | 0.163 | 0.183 | +| zc arm64 jit, qemu-user, plain new/free | 44.15 | 43.82 | +| zc arm64 jit, qemu-user, o3 arena | 0.704 | 0.702 | + +`bench/run.sh` timed the llvm plain tree at 211 repetitions, median 7.21 ms (4.32 to 7.62), and the o3 tree at 111 repetitions, median 8.30 ms (5.74 to 11.94). a slope from 400 repetitions to 1600 on the same binary is 7.43 ms for the plain tree (7.20 to 7.60) and 6.83 ms for the o3 tree (6.75 to 7.13). those two are the after column. on the interpreter the o3 tree is 64.46 ms and the plain tree is 72.52 ms. diff --git a/docs/history/43-stdlib/notes.md b/docs/history/43-stdlib/notes.md new file mode 100644 index 0000000..65fbebc --- /dev/null +++ b/docs/history/43-stdlib/notes.md @@ -0,0 +1,47 @@ +# 43 — names, an arena, a byte buffer + +`u`, `m` and `d` are ordinary names in the resident compiler. a tag is still `.u`, `.m` or `.d`. `u*x` with no space before the star is still a recast; a space is multiplication. `zc0.c` keeps the old rule, so the runtime and the compiler still do not use those letters as names. `tests/names.zc` prints `12 1 8`. `tests/umd.zc` is unchanged. + +untyped `new(n)` inside o3 calls `new_oz`. that zeroes the words that were asked for and leaves the type word at `-(n + 1)`, so a later `fatten` can still stamp it. `new_raw` itself does not zero those words, so typed `new` does not zero them twice. `tests/o3zero.zc` reads the header inside the region and prints `1`. + +`lib/std.zc` adds `arena`, `aalloc` and `areset` over the bump allocator, and `bnew`, `blen`, `bcap`, `bget` and `bset` for a packed byte buffer. `tests/stdbuf.zc` prints `4 1 266 8`. + +the fixpoint is 110623 words. the stage-0 image is 106266, still inside the 110592-word small reservation. the suite is 460 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm. + +the kernels below are the same programs as `history/42-roots`. zeroing an untyped `new` does not sit on the typed-new tree, and the sieve does not allocate. + +## sieve + +milliseconds per count, median of five slopes. the before column is `history/42-roots`. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, word flags | 0.149 | 0.148 | +| gcc -O3 -march=native -flto, byte flags | 0.080 | 0.080 | +| zc interpreter, plain, bounds-checked | 144.2 | 144.9 | +| zc interpreter, o3, bounds-checked | 11.11 | 11.08 | +| zc interpreter, o3, raw pointer | 6.87 | 6.86 | +| zc llvm, ZYHOT=1, o3 raw pointer | 0.252 | 0.235 | +| zc llvm, ZYHOT=1, o3 bounds-checked | 0.439 | 0.435 | +| zc arm64 jit, qemu-user, o3 raw pointer | 1.920 | 1.936 | + +`bench/run.sh` timed the llvm raw pointer at 0.219 ms (0.083 to 0.286, 3135 repetitions) and the checked sieve at 0.400 ms (0.168 to 0.480, 1923 repetitions). a slope from 4000 repetitions to 16000 on the same binary is 0.235 ms for the raw pointer (0.227 to 0.246) and 0.435 ms for the checked sieve (0.429 to 0.440). those two are the after column. gcc's byte flags were 0.080 ms. + +## trees + +milliseconds per tree of depth 12. gcc on this run was 0.091 for malloc and 0.0144 for the arena. the o3 tree stays ahead of the plain one. + +| path | before | after | +| --- | ---: | ---: | +| gcc -O3 -march=native, malloc | 0.091 | 0.091 | +| gcc -O3 -march=native -flto, arena | 0.0143 | 0.0144 | +| zc interpreter, plain new/free | 72.52 | 73.02 | +| zc interpreter, o3 new/free | 64.46 | 64.62 | +| zc interpreter, o3 arena | 1.353 | 1.305 | +| zc llvm, ZYHOT=1, plain new/free | 7.43 | 7.50 | +| zc llvm, ZYHOT=1, o3 new/free | 6.83 | 6.99 | +| zc llvm, ZYHOT=1, o3 arena | 0.183 | 0.172 | +| zc arm64 jit, qemu-user, plain new/free | 43.82 | 43.88 | +| zc arm64 jit, qemu-user, o3 arena | 0.702 | 0.724 | + +`bench/run.sh` timed the llvm plain tree at 47 repetitions, median 6.89 ms (1.66 to 7.67), and the o3 tree at 115 repetitions, median 7.14 ms (6.82 to 7.61). a slope from 400 repetitions to 1600 on the same binary is 7.50 ms for the plain tree (7.46 to 7.63) and 6.99 ms for the o3 tree (6.94 to 7.06). those two are the after column. on the interpreter the o3 tree is 64.62 ms and the plain tree is 73.02 ms. diff --git a/docs/history/44-check-mode/notes.md b/docs/history/44-check-mode/notes.md new file mode 100644 index 0000000..2cb0493 --- /dev/null +++ b/docs/history/44-check-mode/notes.md @@ -0,0 +1,33 @@ +# 44 — check mode, methods, closures, postfix pointers, wasm + +the language server stopped being its own program. `src/compiler.zc` grew a check mode, `lsp/server.zc` wraps it, and everything the editor shows comes from the compiler's own run over the document. + +## check mode + +`cmode` turns errors into records (`[severity, line, offset, length, text]`) instead of printing, and the compiler keeps going. `chkabort` makes `next` return end of file so the loops unwind after a fatal error, and a fuel counter halts a run that never unwinds. `expect` puts "expected x" at the end of the previous token. tokens carry their place (`toff`, `toklen`), packed with the line into one word that the quote lists and the lookahead queue carry along, so a hint can point at a token that was read earlier. check mode re-initialises the heap, symbols and tables for every document, so one check can't leak into the next. + +four sets of names (locals, parameters, type parameters, fields) are recorded as the compiler sees them declared, which is how the highlighter tells a field from a variable without a second parser. + +## hints + +a variable never read, a `let` that could be a `const`, multiplying by a power of two, a number with no name, `new` inside a loop, a small `new` that never leaves its function, an object given away once right after it was made, an owned object that outlives its last use by four lines. they are reported only in check mode and don't change the code that comes out. + +## methods and closures + +`fn name(params) { body }` inside a struct is a function called `Struct.name` with a hidden `Struct* this` first. `p.name(args)` calls it. `fn(a, b) { ... }` in an expression captures the variables it uses by value into a block whose first three words are a trampoline, so the block's address is a callable value. + +## postfix pointers + +`ptype0` reads a type and then any stars after it, so `int*`, `vec*` and `point**` work, and the prefix star still does. `tprint` writes the new form. + +## same-line braces + +every `.zc` under src, lib, lsp, tools, bench, examples and tests (apart from the tests whose expected output names a line) moved to `fn name() {`. the history folders are untouched. + +## web + +`web/build.sh` builds the microcore to webassembly with clang's wasm32 target. `web/zc.js` and `web/index.html` run a program in the browser. the port is one small file, plus a 64 by 64 to 128 bit multiply the core uses. + +## numbers + +the fixpoint is 123810 words (the slot is 131072). the stage-0 image is 119013, so the small map's genome reservation went from 110592 to 126976 words. the suite is 426 passed, 0 failed on this machine: interpreter, microcore, soft-float, small and run-only maps, arm64 jit under qemu, llvm, the javascript vm, webassembly and the language server. the baremetal boards were skipped (no cross compilers here). the windows scripts were edited but not run. diff --git a/docs/history/45-fast-alloc/notes.md b/docs/history/45-fast-alloc/notes.md new file mode 100644 index 0000000..4ef5182 --- /dev/null +++ b/docs/history/45-fast-alloc/notes.md @@ -0,0 +1,13 @@ +# 45 — no prefix pointers, a fast path for constant-size allocation, maps that fit, a makefile + +**prefix pointer types are gone.** `*int` as a type is an error now; `int*` is the only form, and a star in front of an expression is only a dereference. the parser lost its prefix branch in `ptype1`, `tstart`, `caststart`, `new(...)` and the parameter detection, casts learned `(int*)x` and `(node**)x`, and every source (src, lib, lsp, tools, bench, examples, tests) was converted by a script and checked by the suite. a pointer to an array or a function type is spelled through a `type` alias. + +**allocator primitives.** a `new` with a constant size computes its size class at compile time and calls `new_k`. a typed `new` of a pointer-free struct is freed with `recycle_leaf`, which re-checks type and class at run time. the hold test in `new_k` is "does this block overlap the held range" rather than "is there a held range", because the default map always has one (the compiler's type area) and the blanket test sent every call down the slow path. `tests/allocfast.zc` covers zeroing, the owner case and the live count. + +**maps that fit.** `genmap --grow` and `tools/automap.sh` size a map to the program. the run-only images stopped fitting the fixed 36864-word map once the runtime grew; now each is laid out for its own length. `baremetal/run.sh` had stale paths from before the reorganisation and was fixed on the way. + +**makefile, and no binaries in the tree.** `make` builds into `bin/`; `bin/`, `build/` and `web/zc.wasm` are ignored. the task list file was removed once everything on it was done. + +**formatted and commented.** `src/rt.zc`, `src/compiler.zc` and `lsp/server.zc` were rewritten to one layout (one statement per line, a body of more than one simple statement opened out, short single-statement ifs kept on one line), checked by confirming the genome came out byte for byte the same. then the two core files got a pass of explanation: an overview at the top of each saying how the pieces fit, a note before every function that was not self-evident, and the analyzer's model of a local (what each state means) written down once where the locals are declared. the whole pass was comment-only, so the genome is still identical. one thing to know when writing comments in zc: a backtick ends the source even inside a comment, so none can appear in these files. + +fixpoint 125702 words. suite 440 passed, 0 failed here. diff --git a/docs/history/46-c-abi/notes.md b/docs/history/46-c-abi/notes.md new file mode 100644 index 0000000..cc53f28 --- /dev/null +++ b/docs/history/46-c-abi/notes.md @@ -0,0 +1,17 @@ +# 46 — a backtick that means it, native calls, and a bigger default map + +**the backtick.** a backtick ends the source only outside a comment, a string and a character literal. `srcend` keeps a small state (normal, line comment, block comment, string, char) across `nextch`, so a backtick inside a comment no longer cuts the program off. three comments in the compiler that had one were the failure that showed it (the fixpoint broke), and they were reworded anyway. + +**a parse word has to read.** a handler run by `kwcall` that never took a token would be called again on the same token forever. `next` counts tokens, and `kwcall` compares the count before and after: no progress is an error ("a parse word has to read its own name with next()"). a fuzz run found it. `tests/langerrors/parseword_noread.zc` keeps it. + +**lexer.** `isopch` is a 31-bit mask test and `isidc` a range test, `intern` checks the first character before hashing, `readsrc` has a fast path for stdin. the compiler compiles itself about 12% faster. the 64-bit literal that first stood in for the mask lost its top bit (`lit(v)` is `2v+1`), which is why the mask is 31 bits wide. + +**llvm gets the target.** the module carries the host's triple and data layout, functions carry attributes, and element addresses are `inbounds` GEPs. `noalias` is not valid on vm memory because host helpers read and write it. on the bench kernels the code was already near native, so nothing moved. + +**native calls.** `extern double pow(double, double);` defines a zc function that calls the c function. the compiler reads a c prototype (`ckind` maps c spellings to kinds), writes the symbol name, a signature word and room for the arguments into the code stream, compiles a small stub from text (the same way `include` compiles a file) that stores its arguments and does `syscall(14, block)`. the host looks the symbol up with `dlsym` (the math library is opened if the first lookup misses) and calls it through a prototype of six longs and eight doubles ending in `...`, so integer and float registers fill independently and a variadic callee sees its register count. kinds: long, double, byte pointer, int, float, word pointer, unsigned int, short, unsigned short, char, unsigned char, and `str` for a zc byte string. a pointer into vm memory is `(char *)m + byte address`, which works because vm memory is one flat array; anything outside the array passes through, so a `malloc` result is an opaque number. `as` now sets the float flag for a cast to `float`, which the stub's result needs. + +**callbacks.** `cfunc(f)` asks gate op 16 for a native pointer. there are 16 prebuilt c functions per result class (long, double, float), each taking six longs and eight doubles; calling one packs the arguments by the signature, pushes them on the vm data stack under the stacks as they were at the gate store, pushes a sentinel return address and runs `vm_until`, the same nested run an o3 call uses. the signature comes from the function's declared types, so a typed `o3` function is entered at its compiled region. the stack pointers are published by the gate store: a global in the interpreter, a store from the alloca in an llvm block, and in the jit the same two words (`S[1]`, `S[2]`) the exit stub writes. it passes under the interpreter, llvm with every block compiled (`ZYHOT=1`) and the arm64 jit under qemu (a dynamic binary: a static one has no `dlsym`). + +**not done.** a call from o3 code to an extern leaves the region like any call to ordinary code. lowering it to a direct call inside a region, so llvm could see the callee and its argument types, would need a variadic micro-op in the lifter, the optimizer, the rexec loop, the arm64 emitter and the llvm lowering, which today all assume at most two inputs. structs by value, more than 6 integer or 8 float arguments, and a callback that outlives its native call are not supported. + +**the default map is 1081344 words.** the genome (`rt.zc` plus `compiler.zc`) came to 134045 words, past the 131072 that the default map reserved. the default preset of `genmap` now reserves 0x28000 words for it and everything above moves up by 0x8000, with `memmap.h`, the const block in `rt.zc` and the javascript vm's constants following. the small maps are separate presets and did not change. diff --git a/docs/history/47-limits/notes.md b/docs/history/47-limits/notes.md new file mode 100644 index 0000000..6fa29ba --- /dev/null +++ b/docs/history/47-limits/notes.md @@ -0,0 +1,15 @@ +# 47 — the limits come off: a heap that grows, native calls the optimizer sees, sized types, more micro-ops + +**a heap that grows.** the machine now has two sizes. PW is the end of the fixed part (code, compiler tables, genome, stacks) and MW is the host's total memory, 0x8000000 words by default. the heap starts at PW with 0x60000 words and grows at run time: when `new_raw` finds no block big enough it calls `heap_grow`, which appends an aligned piece (a few times the request, at least 0x40000 words, never past MW) through the same free code the buddy merge uses. the host's array is static and untouched until the heap reaches into it, so a small program costs what it did before. `heap_reset` (the compiler cutting the allocator off below its type area) holds growth off for that process, and the language server's fixed map has growth switched off. `tools/genmap` emits PW, CODE_END and HEAP_GROW; a build can choose its total with `-DMW=`. memory facts come from `syscall(9, k)`. + +**host-assisted bulk work.** filling, copying and scanning a block were loops in zc. ops 18 (fill), 19 (copy) and 20 (does the block hold a heap pointer, for `release`) do each in one call on hosts that know them, and answer -1 elsewhere, in which case the zc loop runs. freeing a large block stopped being the slow part of the grow test. + +**native calls.** up to 15 arguments (registers first, then the c stack), opcode 620 lets the lifter see a native call whose callee and signature are constants, so an o3 region keeps the call in the generated code: a call instruction on arm64, a direct call to the symbol's address on llvm, which means llvm can inline across it and turns the common libm functions on doubles into its own intrinsics. the dispatcher round trip is gone for those. + +**sized integers.** `i8 u8 i16 u16 i32 u32`. a scalar is a word that is cut to size at every store; arrays and pointers of them are packed (8, 4 or 2 to a word, little endian) with the byte ops, indexing yields a "packed twin" whose lvalue is a byte address. pointer arithmetic stays in words and `sizeof` counts words. no new vm opcodes: the byte ops from stage 28 already lift in o3, so packed access gets the optimizer and both jits for free. not done: packed struct fields, growable `[]u8`, taking the address of one element. + +**f32.** the same machinery with a float: a variable holds a value rounded to single precision, an array or pointer of f32 is packed two to a word. the rounding is two new micro-ops. + +**micro-ops.** `ctz popcnt bswap rotl rotr` and `f2s s2f` join the set. the interpreter, the microcore and the javascript vm (integers only) evaluate them; arm64 uses rbit+clz, the vector popcount, rev, rorv and fcvt; llvm uses `cttz ctpop bswap fshl fshr` and fptrunc/fpext. `rt.zc` wraps them as enhancements (`ctz(x)`, `popcnt(x)`, ...). a bug worth remembering: the interpreter's enhancement runner treated every op number at or above `U_LD8` as a byte op, so a new op past the end of the list ran as nothing. it is bounded now. + +**what this stage did not do.** the invalidation of translated code is still coarse (a store to a covered word rescans every block and an install flushes all), o3 calls still leave a region through the dispatcher, there is no automatic tiering, and the windows scripts and the bare metal runs were not re-run after the map change. they are listed under "open ends" in the readme. diff --git a/docs/history/48-landing/notes.md b/docs/history/48-landing/notes.md new file mode 100644 index 0000000..f4465e3 --- /dev/null +++ b/docs/history/48-landing/notes.md @@ -0,0 +1,7 @@ +# stage 48: landing the leftovers + +done: packed struct fields, growable arrays of sized integers and f32, f32 in extern and cfunc signatures, page-indexed invalidation with counted coverage, per-slot install invalidation, per-block llvm resource trackers freed when no compiled code is running, a direct-mapped function cache and a short call path for llvm o3 calls (fib bench 0.69 s to 0.53 s), and a faster self-modification path (bench/selfmod.zc about 7x on the jit). + +not done: structs by value in native calls, an inline llvm-to-llvm call, loop-invariant motion and cross-block cse in the core's optimizer, automatic tiering. the address of a packed element is declined on purpose. + +the stale test langerrors/pk_dyn.zc (which expected growable []sized to be rejected) was removed. diff --git a/docs/history/49-generics/notes.md b/docs/history/49-generics/notes.md new file mode 100644 index 0000000..311d82d --- /dev/null +++ b/docs/history/49-generics/notes.md @@ -0,0 +1,5 @@ +# 49 generics + +what landed: generics are monomorphized instead of erased. templates keep their tokens, each set of type arguments gets its own compiled copy named name, with any size of type and any number of parameters (record), plus methods in generic structs. llvm gets an inline call path. the core gets a global constant lattice pass with branch folding. o3 push and pop are inline. the default memory map is bigger (pw 0x1c5000, heap up to 0x225000) and the small preset was resized (genome 163840, ns 1280). + +what did not: register-passing direct llvm calls, loop-invariant motion and cross-block cse in the core, automatic tiering, structs by value in native calls, and a table that grows at run time (addresses are literals in the genome, so each size is its own image). a template must be written before the first call with type arguments. the js vm and windows scripts were not touched beyond the map constants. diff --git a/docs/history/50-adt/notes.md b/docs/history/50-adt/notes.md new file mode 100644 index 0000000..a9e04da --- /dev/null +++ b/docs/history/50-adt/notes.md @@ -0,0 +1,9 @@ +# 50 adt + +what was asked: tagged enums and pattern matching (task 34). the four design questions were answered: payload syntax `circle { int r; }`, match form `case circle(r):`, a missing member in a switch is a warning, and the tag is the word at offset 0. see design/adt.md. + +what landed: an enum can give its members fields. the enum becomes one struct: a tag word, then every member's fields, each named `member_field`, so every value is as big as the largest member. `shape.circle(3)` is a generated static constructor that returns an owned `shape*`. a switch over a `shape*` matches with `case circle(r):`, binds the fields in that arm only, and reads them through the same field access as any struct. a switch that leaves out a member, with no `default`, prints a warning on the line of the switch. the coverage check keeps a bit set of the tags a switch covers. two enums may use the same member name, since each keeps its own fields. + +checks: tests/tagenum.zc, tests/tagenum_warn.zc, tests/tagenum_two.zc (including a case inside an o3 loop), and three langerrors (explicit values on a member, a wrong number of bindings, a wrong number of constructor arguments). the fast suite passed 126 of 126, the lsp protocol checks 41 of 41 and the wasm checks 10 of 10. the enum output matched on the interpreter, the llvm backend and the arm64 jit under qemu. + +what did not: members with explicit values are rejected, not supported. a member with fields can't be matched without its binding list (the arm must bind every field). the constructor's owned result can't be passed straight to a borrowing parameter (the existing rule for `new`), so it has to go through a name first. the warning only fires with no `default`. the llvm and jit runs were done by hand, not from the test script. diff --git a/docs/history/51-llvm-inline-stdlib/notes.md b/docs/history/51-llvm-inline-stdlib/notes.md new file mode 100644 index 0000000..c061f7b --- /dev/null +++ b/docs/history/51-llvm-inline-stdlib/notes.md @@ -0,0 +1,19 @@ +# 51 llvm inline, stdlib, host syscalls + +what was asked: finish the open tasks in any order (task 19 llvm inlining of o3 calls, task 38 stdlib expansion with a host syscall notation), then fuzz every part of the toolchain. + +what landed: +- llvm inlining of o3-to-o3 calls (task 19). a callee is inlined into the caller's native code behind a check that its region still holds, so a self-modifying callee falls back to the native entry. checked against the interpreter on every example and test with ZYHOT=1 (117 files, 0 diffs). a call-heavy helper benchmark took 2.46 s with ZYNOINLINE=1 and 2.29 s with inlining (about 7 percent). +- stdlib (task 38): Text gains len, eq, copy, find, lower, upper and trim; a new Num group gains abs, min, max, clamp, gcd, pow, isqrt and sign. tests/stdmore.zc. +- host syscall notation (task 38): SYS_RAW (op 40) runs any linux syscall on the host. the block holds the number and six arguments, and the result is the kernel's or -errno. Host.raw(nr, a, b, c, d, e, f) in lib/std.zc builds the block. it is host-only and bypasses the vm's checks, so it is a deliberate escape hatch. tests/rawsys.zc, and tests/rawpid.zc on x86-64 only (syscall numbers differ on arm64). +- the full make test passed: 571 passed, 0 failed. + +also landed: cross-block copy propagation in the global pass (task 20). a copy fact (C_COPY) says a variable holds what another holds at block entry, a read of the copy becomes a read of the source, and a block that writes the source drops the fact. tests/o3copy.zc; the full suite and an llvm ZYHOT=1 comparison over 120 files agree. + +automatic tiering was dropped by decision (tasks 25 and 35). it needed a calling-convention change for unannotated functions; design/tiering.md has the analysis. task 17 is closed with the perf work that landed. + +fuzzing (scratchpad campaign, every target): +- sanitizer builds rebuilt from the current tree (zc0, zy, zym, zyl, lsp, mkgenome, genmap). +- found: under ASan only, an unbounded o3 recursion grows host memory until the OOM killer stops it. the plain, -O0, -O1, -O2 and UBSan builds stop with "frame stack overflow". the ASan build's o3 path does not hit the frame check. the reproducer is `o3 int f(int n) { return f(n + 1) + 1; }`. +- found: a zy vs zym difference on an unchecked program that exhausts the heap. the microcore has a fixed map and reports out of heap memory where the hosted heap grows. the diff harness now skips runs that hit a resource limit. +- the harness now has an RSS watchdog (2.5 GB) so a runaway child is killed instead of taking the host down. diff --git a/docs/history/52-closures/notes.md b/docs/history/52-closures/notes.md new file mode 100644 index 0000000..335923e --- /dev/null +++ b/docs/history/52-closures/notes.md @@ -0,0 +1,14 @@ +# 52 closures + +closures compiled and built their value, but calling one halted the program silently with exit 0. + +cause: the vm only runs code inside the code area (the interpreter loop runs while `pc < PW`). a closure's body was copied into a heap block, so a call into it left the loop without an error. + +fix (`src/compiler.zc`): +- the closure block is a heap value whose word 0 is the body's entry. captured variables start at word 3, and the env the body receives is block + 3, so the body reads capture `i` at env + `i` as before. +- a call through a value compares the callee with `HEAP_LO`. below it, the call goes straight to the function as before. at or above it, the call pushes block + 3 as the env, loads the entry from word 0, and calls that. both paths meet at the same result handling. +- a capture of a variable from further out is chained through each closure in between (`clocap_at`). `clo_via` records the slot in the enclosing closure's environment that the new closure copies from. + +checks: `tests/closure.zc` (interpreter, in `tests/test.sh`), `examples/learn/25-closures.zc` (the guide), and the full suite (604 checks, 0 failed), with the fixpoint at 230551 words. + +what closures still don't do: captures are by value, a closure can't be handed to a c function as a callback, and a closure passed directly to a parameter that isn't `.d` is rejected by the analyzer as an owned object, the same as any new object. diff --git a/docs/history/53-typed-source/notes.md b/docs/history/53-typed-source/notes.md new file mode 100644 index 0000000..1e5134d --- /dev/null +++ b/docs/history/53-typed-source/notes.md @@ -0,0 +1,16 @@ +# 53 typed source and the diagnostics cache + +asked: type everything. the compiler, the runtime and the language server had untyped `fn` and `let` in most places, and the stdlib had one untyped method. + +built: +- src/rt.zc, src/compiler.zc, lsp/server.zc: every function header and every local and global `let` now has a type. parameters and returns that hold an address are `word`, the rest are `int`, and the `.u` return tag stays as it was (`word .u new(int n)`). `.m` and `.d` parameter tags are kept too. +- lib/std.zc: `fn end()` in struct `capture` is `word end()`. +- the proof that nothing changed: zc0's image of the typed sources is byte-identical to the untyped one (`cat src/rt.zc src/compiler.zc | bin/zc0` against the original). the full genome fixpoint is 232070 words (it was 230551 before the typing: zy generates different code for typed declarations). +- editors/vscode: diagnostics are cached under a sha256 key per document (client/diagcache.js). the key covers the server build, the path and text, and every file the document includes, transitively. a cached key is answered without asking the server, which hears the text only when hover or highlighting needs it. an included file saved or changed on disk checks its dependents again. the cache is saved in the extension's storage. tests/diagcache_test.js checks the rules, tests/ext_cache_test.js runs the client end to end on the built-in server. +- tests/lsp_test.js: tests/undefined_call.zc is an intentional error, like manyerrors.zc, so the clean check skips it. + +what went wrong on the way, kept for the next person: +- the first typer dropped `.d` and `.m` parameter tags when it rewrote headers. zc0 writes those tags into the symbol table's signature word, so `free(.d p)` changed from 130 to 2. the typer now keeps the tags, and word-typed parameters and returns turned out to be harmless. +- the typer grouped `let` items by type, which moved some arrays ahead of scalars. zc0 numbers locals by declaration order, so the frame slots of those variables moved (a 5 became a 21 in the image). the typer now keeps source order, and the image matches again. +- a bare `.u name(...)` header is not a type word, so the first typer missed it. `unchecked .u readfile(path)` and the others were typed in a second pass. +- the built-in wasm server cannot read include files (every include is "can't read that include"). the native server reads them. this is an existing limit, and the cache keys do not depend on it. diff --git a/docs/history/README.md b/docs/history/README.md new file mode 100644 index 0000000..b38f981 --- /dev/null +++ b/docs/history/README.md @@ -0,0 +1,50 @@ +# history + +the scrapbook. one folder per stage, each with notes.md: what was asked, what got built, and the working notes from the time, kept as written and only added to. stages that still have their code keep a frozen copy in code/: + +- 01-golf, 02-hardware, 04-darwin-compiler, 05-hybrid, 06-choosing: notes only, their code wasn't kept +- 07-zygote: notes and code (the asm genome and the arm64-only core, as packed in stages 8 and 9) +- 08-packaging: notes only +- 10-zc: notes and code (zc, u m d, the collector, the self-hosting compiler) +- 11-types-enhancements: notes and code (types, generics, reflection, the typechecker, virtual enhancements, the llvm backend) +- 13-gap-fixes: notes and code (joins with fixup frees, the buddy heap, stack checks, error recovery, the prescan, ?: and switch) +- 15-o3: notes and code (the examples, c-style return types, growable and fixed arrays, the o3 optimizing tier, literal-specialized enhancements, the release fix) +- 17-o3-boundaries: notes and code (generics after the name, fattening o3 data on the way out, registers by scope, cached fixed arrays) +- 18-aliases: notes only (borrowed-from marks on derived pointers, quarantine on free) +- 19-tools: notes only (memory debug, do/while, enum, casts, include, syscalls, lib/std.zc) +- 20-words: notes only (the vm word widened from 32 bits to 64) +- 21-micro: notes only (a portable microcore for the same genome) +- 22-size: notes only (a build-time memory map, a 1.31 mb compiler, a 256 kb run-only image) +- 23-baremetal: notes only (the microcore booting on qemu-system, riscv and aarch64 virt, UART in and out) +- 24-backends: notes only (the arm64 jit under qemu-user, and the llvm backend, run against the interpreter) +- 25-genmap: notes only (one layout for every memory size) +- 26-bareapi: notes only (syscall gate on the virt boards: console, clock, exit, files) +- 27-float: notes only (IEEE binary64 on the interpreter, both jits, the microcore and both virt boards) +- 28-bytes: notes only (byte addresses beside word addresses, opcodes 612..617) +- 29-strings: notes only (packed byte strings, `b"..."`, length, slice, concat, and byte syscalls) +- 30-sharing: notes only (shared cons cells and strings, collected by the existing sweep) +- 31-fpu: notes only (hardware float ops where an FPU exists, and a soft-float fallback) +- 32-ftype: notes only (float is a type: calls, globals, fields, parameters, returns; -0.0 is false; 1.field is a field) +- 33-fo3: notes only (o3 lifts float ops: IEEE-safe folds, FP registers, no x-x rewrite) +- 34-ftext: notes only (libc-free print and parse of the full double range) +- 35-bench: notes only (a word sieve and a binary tree, timed against C) +- 36-alloc: notes only (recycle onto the size-class list, a 5-word header, a bump arena) +- 37-call: notes only (o3 calls o3 by entering the region, and fatten only at a real boundary) +- 38-bounds: notes only (a proved index stays in a register, and a +1 loop drops the check) +- 39-blocks: notes only (empty jumps folded, a straight loop rotated to one block) +- 40-fatten: notes only (typed new stamps the header, and a child store writes the owner in the region) +- 41-obytes: notes only (ld8 through st32 lift inside an o3 region) +- 42-roots: notes only (the collector marks from the live stack index, and scrub clears the rest) +- 43-stdlib: notes only (u, m and d are names, an arena and a packed byte buffer, and untyped new inside o3 is zeroed) +- 44-check-mode: notes only (the language server is the compiler in check mode, struct methods and closures, postfix pointer types, same-line braces, a webassembly build) +- 45-fast-alloc: notes only (no prefix pointers, constant-size allocation fast path, maps sized to their program, a makefile, the core sources formatted and explained) +- 46-c-abi: notes only (the backtick is lexical, a parse word must read, lexer speed-ups, llvm target info, extern and cfunc native calls, a default map with a bigger genome slot) +- 47-limits: notes only (a heap that grows to the host's memory, host fill/copy/scan, native calls the optimizer sees, sized integers and f32 with packed arrays, ctz popcnt bswap rotl rotr f2s s2f) + +the code folders are snapshots. they're not built or tested from here, the top level is the live tree. +- 48 landing: packed fields, []sized, f32 extern, page-indexed invalidation, llvm trackers, faster o3 calls +- 49 generics: monomorphized multi-parameter generics and generic methods, llvm inline calls, global const-prop in o3, bigger default map +- 50 adt: tagged enums with fields, constructors, `case member(a, b):` matching, and a coverage warning +- 51 llvm-inline-stdlib: llvm inlining of o3 calls, stdlib text and num helpers, host syscalls through SYS_RAW, and the fuzz campaign's findings +- 52 closures: closure calls work (the block is never run; a call into a heap closure goes through its entry word), captures chain through enclosing closures, and the closure test joins the suite +- 53 typed source: every function, local and global in the compiler, the runtime and the language server is typed (zc0's image does not change), and the extension caches diagnostics by a sha256 of the tree they cover diff --git a/docs/history/baremetal-measurements.md b/docs/history/baremetal-measurements.md new file mode 100644 index 0000000..ef1ecd8 --- /dev/null +++ b/docs/history/baremetal-measurements.md @@ -0,0 +1,55 @@ +# earlier bare-metal measurements + +these measurements describe the builds recorded at the time; they are not current size guarantees. + +## bare metal + +`baremetal/run.sh` builds a freestanding image and boots it on QEMU's `virt` board, headless, with the UART on stdio. there is no kernel and no libc. startup sets the stack, zeroes bss, and calls `bare_main`, which calls `micro_run`. two targets, picked because a cross gcc and a system emulator both install from the distro packages: + +``` +baremetal/run.sh ready riscv # exits 0 when the tools exist +baremetal/run.sh riscv run examples/hello.zc +baremetal/run.sh riscv io examples/echo.zc # stdin, then 0x04 +baremetal/run.sh riscv compile examples/fact.zc +baremetal/run.sh aarch64 run tests/gc.zc +baremetal/run.sh aarch64 compile tests/wide.zc +``` + +`run` is the 36864-word image from `genmap --preset run`: `rt.zc`, `src/run.zc` and the program, compiled by `zc0` into the ELF. nothing is read. `io` is that same image with the UART open: the script's stdin is the program's input and a `0x04` is appended, which `eof()` reports and `getc()` does not return. `compile` is the default 1,048,576-word genome. the script writes the source, a backtick, and a `0x04`. the backtick ends the unit, the same rule as the hosted compiler, and the `0x04` is what the probe after that backtick is waiting on. `test.sh` runs these, on each target whose tools are present, and skips the one that isn't. a missing `timeout(1)`, cross gcc or `qemu-system-*` is a skip, not a failure. + +the guest is the same two word maps as the hosted builds. what changes per target is where RAM, the UART and the power-off device sit. + +RISC-V, `qemu-system-riscv64 -machine virt -bios none -cpu rv64 -m 64`. machine mode, no OpenSBI. RAM starts at `0x80000000`; the linker uses 48MB of it. the UART is a 16550 at `0x10000000`, polled through the line-status register. exit is the SiFive test device at `0x100000`: `0x5555` makes QEMU exit 0, and `(status << 16) | 0x3333` exits with that status (`0x13333` is status 1, `0x33333` is status 3). the clock is `rdtime`. `mstatus.FS` is set so a compiler that emits a float op does not trap. + +AArch64, `qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 64`. RAM starts at `0x40000000`, again 48MB in the linker and 64MB given to QEMU. the UART is a PL011 at `0x09000000` (flag register at `0x18`). this QEMU 8.2 starts the ELF at EL1, and `-bios none` is not passed: that build looks for a file named `none` and refuses. `-kernel` of the ELF is enough, and the CPU begins at the entry point. if it had come up at EL2 the startup drops to EL1h before touching the stack. SIMD is turned on in `CPACR_EL1`, because `-O2` copies the genome with `q` registers and a disabled FPU takes an exception at the vector base plus `0x200` (that is what the first boot did, before there was any UART output). exit is semihosting `SYS_EXIT` (`hlt #0xf000`, `x0 = 0x18`, `x1` pointing at `{0x20026, status}`), and the command line passes `-semihosting-config enable=on,target=native`. PSCI `SYSTEM_OFF` cannot carry a status, which is why it is not the exit path. the clock is `cntvct_el0`. the UART line is the thing to read. + +both images are linked with `-ffreestanding -nostdlib -static`. the cross compilers are `riscv64-linux-gnu-gcc` (`-march=rv64gc -mabi=lp64d -mcmodel=medany -mno-relax`) and `aarch64-linux-gnu-gcc` (`-march=armv8-a`). QEMU is `-nographic -monitor none -serial stdio`, so the bytes on stdout are the bytes the guest wrote. `run` is killed after 120 seconds, `compile` after 90. `tests/gc.zc` on the run-only image needs about 30 seconds; the others finish in about a second. + +image sizes, from `size` and the ELF file length. bss is the machine plus the enhancement tables and a 64KB stack. the AArch64 file is bigger than its text and data because the load segment is aligned to 64KB. + +| | ELF file | text+data | bss | +|---|---|---|---| +| RISC-V, run, hello | 87704 | 81741 | 410664 | +| RISC-V, run, fact | 88504 | 82541 | 410664 | +| AArch64, run, hello | 149704 | 82248 | 410656 | +| RISC-V, resident compiler | 741624 | 735565 | 8537128 | +| AArch64, resident compiler | 803616 | 736040 | 8537136 | + +the compiler file does not change with the program fed over the UART. most of its text is the default genome, 103655 words, 829240 bytes. the run-only bss is the 294912-byte machine; the compiler bss is the 8MB one. both fit in the 64MB QEMU gives `virt`. + +what booted, and matched the hosted interpreter on the same source: `hello`, `fact`, `wide` and `gc` as run-only images, and `hello`, `fact` and `wide` compiled by the resident compiler over the UART, on both boards. `gc` printed `1000 1 900 1 199900`. + +a Cortex-M was not ported. the word is 64 bits and the run-only bss is already about 400KB, before the genome in rodata. the boards `qemu-system-arm` actually models at that size (the Stellaris `lm3s6965` has 64KB) cannot hold it, and a 32-bit core would be emulating every cell in software. + +limits, on top of the ones in the smaller-machines section: + +- the syscall gate is the same one as the hosted core. on these boards, open/close/read/write are a RAM file store (4 files, 128 bytes, 31-character names), `getenv("BOARD")` is `riscv` or `aarch64`, time is the hardware counter rather than unix seconds, exit takes a status, random is a counter seeded from that clock, and memory info returns `MW`, the heap bounds and the byte size. the stub port still returns -1 for every op. a file is not the host's filesystem, and the counter is not wall time, so `tests/sys.zc` stays a hosted test. +- the microcore still has no o3 fast path. the bytecode runs. +- diagnostics (`zy: data stack overflow` and the rest) go out the same UART as program output. +- the 16550 is left at QEMU's reset settings. writing the line-control or FIFO register after the source has started arriving drops the first byte, and `fn` becomes `n`, which the compiler reports as `n: isn't a type`. +- end of input is `0x04`. `micro_eof` and `micro_getc` wait until a byte is actually in the UART, so an empty FIFO is a pause and not the end, and a stream longer than the 16-byte 16550 FIFO still reaches its `0x04`. that byte is not delivered. the compiler still ends a unit on a backtick; `compile` sends `0x04` after it so the probe that follows the backtick returns. `examples/echo.zc` fed 36 letters under `io` prints those letters on both boards. +- the 192512-word compiler is not what these boards boot. `virt` has room for the default genome, and that is the one the `compile` mode uses. 294912 bytes still cannot hold a compiler. +- no native calls (the c abi needs `dlsym`), and a character is still one word. + +the notes in `history/23-baremetal` have the boot log and the places the first images hung. + diff --git a/docs/history/maintenance-notes.md b/docs/history/maintenance-notes.md new file mode 100644 index 0000000..2a2bed4 --- /dev/null +++ b/docs/history/maintenance-notes.md @@ -0,0 +1,30 @@ +# historical test results and maintenance notes + +this material records earlier builds. current work and verification are tracked in TODO.md. + +## test results + +the whole of `test.sh` is 614 checks on a machine with gcc, qemu-user, llvm, node and clang's wasm32 target (572 passed, 0 failed; the baremetal boards need cross compilers and are skipped without them). on the interpreter alone it starts with the fixpoint (236652 words), an up-to-date `genome.h`, and then every example and feature test, including a shift past bit 31 and equality of a value above 2^31. it also covers joins and fixup frees (with a leak count), `switch` and `?:`, the buddy allocator, aliases used while their owner is alive, quarantine (a freed block stays intact for a stale alias, a second free does nothing, and a collection keeps a block a word still points at), `do`/`while` with `enum` and a cast, `include` and the string helpers, syscalls, memdebug leaks, use-after-free (including through an interior pointer), double free, payload poison and interior pinning, several errors in one run, all three stack overflows, growable and fixed arrays, and `tests/o3.zc` (loops, recursion, calls inside loops, `switch`, `&& ||`, structs through pointers, arrays, division by constants, and a function with more variables than registers). it checks that every o3 region in that test lifts, that the o3 bounds check fires, and that all 26 programs in `tests/errors/` (including derived aliases used after their owner dies), all 10 in `tests/typeerrors/` and all 9 in `tests/langerrors/` get rejected with the expected message. the same script then runs that list on the microcore, checks that the microcore's self-compile matches the interpreter's image, and checks that `micro.c` and `port_stub.c` compile with `-ffreestanding`. that is 113 checks with the jit and llvm skipped. it then builds the 339968-word compiler and runs 22 programs on the small microcore and again on `core.c` at that size, builds the 32768-word run-only image for six programs, and checks that both reduced microcores compile freestanding. that is 165 checks with the jit, llvm and bare-metal boots skipped. when the cross gcc and `qemu-system-*` for a target exist, `test.sh` adds 7 boots on that target (run-only hello, fact, wide and gc, then the resident compiler fed hello, fact and wide). both virt boards were present here, which is 14 more. the jit needs `qemu-aarch64`, the linux-user emulator, which `qemu-system-aarch64` is not. the llvm backend needs `llvm-config`. those two were not executed in the environment that cut the word to 64 bits. they were executed later (stage 24), on this host, and the full script then passed 292 checks. stage 25 added three more (the default map matches the checked-in sources, and the flag form of `genmap` reproduces the small and run maps), 295 passed, 0 failed. stage 26 added eight more (echo until eof, the clock and RAM-file line, the exit text and the exit code, on each virt board), 303 passed, 0 failed. stage 27 added twelve more: the float line on the interpreter, the microcore, the arm64 jit and the llvm backend, the same line on the small microcore and on `core.c` at that size, the run-only image, both virt boards running the program and compiling it, and one llvm run with `ZYHOT=1` so every float block is compiled. 315 passed, 0 failed. stage 28 added twelve more, the same shape of check for byte loads and stores, including a one-byte patch of a live literal. 327 passed, 0 failed. stage 29 added twenty-three more for packed byte strings: the string line, the example, and the hosted byte-file check on the interpreter, the microcore, the arm64 jit and the llvm backend; the string line and the example on the small microcore and on `core.c` at that size; the run-only image of both; both virt boards running the program and compiling it; and one llvm run with `ZYHOT=1`. 350 passed, 0 failed. stage 30 added eighteen more for shared cells: the sharing line and the memdebug line on the interpreter, the microcore, the arm64 jit and the llvm backend; both of those on the small microcore and on `core.c` at that size; the run-only sharing line; both virt boards running it and compiling it; and one llvm run with `ZYHOT=1`. 368 passed, 0 failed. stage 31 added one more: a soft-float interpreter matches the float line. 369 passed, 0 failed. stage 32 added twenty-two more: negative zero is false, and a float stays a float through calls, globals and fields, on the interpreter, the microcore, the arm64 jit and the llvm backend; both of those on the small microcore and on `core.c` at that size; the run-only image of the negative-zero program; both virt boards running that program and compiling it and the float-type program; a soft-float check of negative zero; and llvm runs with `ZYHOT=1` for both. 391 passed, 0 failed. stage 33 added ten more for o3 floats: the lifted kernel matches the plain one, a constant expression folds, a NaN minus itself stays a NaN, and negative zero is false inside the region, on the interpreter, the microcore, the arm64 jit and the llvm backend; the same line on the small microcore and on `core.c` at that size; both virt boards compiling it; a soft-float interpreter; and one llvm run with `ZYHOT=1`. 401 passed, 0 failed. stage 34 added thirteen more for the float text: shortest, fixed and scientific forms, a 17-digit tie, and the full finite range, on the interpreter, the microcore, the arm64 jit and the llvm backend; the same line on the small microcore and on `core.c` at that size; the run-only image; both virt boards running it and compiling it; a soft-float interpreter; and one llvm run with `ZYHOT=1`. 414 passed, 0 failed. the jit binary is `aarch64-linux-gnu-gcc -O2 -w -DJTYPE=int -static core.c io_linux.c` (gcc 13.3.0, static, against the aarch64 sysroot) run by `qemu-aarch64` 8.2.2. the llvm binary is host gcc 13.3.0 with `-DZYLLVM` and LLVM 18.1.3 (`llvm-config --cflags --ldflags --libs`). both ran the same program list as the interpreter and self-compiled to the same image. `ZYTRACE=1` on `tests/o3.zc` printed 8 `bytes of arm64` lines and 8 `compiled by llvm` lines. `ZYHOT=1` on the llvm binary made `tests/types.zc` match the interpreter byte for byte. the first jit run failed one check: `tests/enhance.zc` printed `100 0 343 3,2` and then halted. opcode 21 calls a C function that returns a 32-bit `int`. a write to `w0` zeroes the high half of `x0`, so the failure code `-4` (the `noisy` enhancement, whose body does i/o and does not lift) was stored as a large positive cell. the compiler treated the install as a success, emitted the unwired opcode, and the jit halted. the translator now does `sxtw x0, w0` before storing that cell. the Darwin jit (`MAP_JIT` and the write-protect around each flush) was not run. this host is x86_64 Linux, and qemu-user is the arm64 cpu the jit actually executed on. the 64-bit image is not binary-compatible with a 32-bit genome. + +## open ends + +status after stage 48: done from the older lists below are native calls that the optimizer sees, a heap that is no longer limited by the initial map, host-assisted fill, copy and scan, sized integers and f32 with packed arrays and packed struct fields, growable `[]sized`, f32 in `extern` and `cfunc`, the micro-ops `ctz popcnt bswap rotl rotr f2s s2f`, page-indexed invalidation, per-slot install invalidation and per-block llvm resource trackers (the self-modifying benchmark in `bench/selfmod.zc` runs about 7 times faster on the jit). o3 calls on llvm take a shorter path into the callee (about 25 percent off a call-bound loop). not done: struct by value and struct returns on apple arm64, a fully inline llvm-to-llvm o3 call (calls still go through a c helper), loop-invariant motion and cross-block cse in the core's own optimizer, automatic tiering without the `o3` keyword, floats and the f2s and s2f ops in the javascript vm, and re-running the windows scripts and the bare metal boards after the map change. + +fixed in stage 13 (details in `history/13-gap-fixes`): branch and loop joins, free lists that never merged (now a buddy allocator), missing stack checks, stopping at the first error, macro line numbers, required prototypes, `d*` for storing into borrowed objects, `**` declarations, and `?:` and `switch`. fixed in stage 18 (details in `history/18-aliases`): untracked aliases. a pointer computed from a tracked variable (`p + k`, a pointer field, an index whose element is a pointer) is stored as a borrow of that variable, on the same child link the analyzer already keeps, so using it after the owner dies is an error. `free` quarantines the block; the next sweep only reclaims quarantined blocks nothing points at, so a stale alias reads a dead but intact block and a second free is a no-op. fixed in stage 19 (details in `history/19-tools`): memory debug (header checks, allocation lines, `memreport`, poison, interior pinning), `do`/`while`, `enum`, C casts, `include`, a small syscall surface and `lib/std.zc`. fixed in stage 20 (details in `history/20-words`): every cell is 64 bits, on the interpreter, the arm64 jit and the llvm path. fixed in stage 21 (details in `history/21-micro`): `micro.c` is a portable interpreter for the same genome, with the host behind `micro_port.h`. fixed in stage 22 (details in `history/22-size`): the memory map is chosen at build time, with a 221184-word compiler and a 32768-word run-only image. fixed in stage 23 (details in `history/23-baremetal`): the microcore boots with no OS on QEMU's RISC-V and AArch64 `virt` boards and prints on the emulated UART. fixed in stage 24 (details in `history/24-backends`): the arm64 jit and the llvm backend were actually executed, and the jit's install return is sign-extended so a failed enhancement takes its fallback. fixed in stage 25 (details in `history/25-genmap`): one layout generates every memory size. the small compiler, the run-only image and the historical 1m map are presets of it. fixed in stage 26 (details in `history/26-bareapi`): the virt boards answer the syscall gate (console EOF, a hardware clock, exit status, a RAM file store, random, memory info) and `port_stub.c` still returns -1. fixed in stage 27 (details in `history/27-float`): IEEE-754 binary64 on the interpreter, the arm64 jit, the llvm backend, the microcore and both virt boards. the literal is opcode 600 plus the raw bits, and `fops.h` prints and parses the same text everywhere. fixed in stage 28 (details in `history/28-bytes`): byte addresses beside word addresses, opcodes 612..617. fixed in stage 29 (details in `history/29-strings`): packed byte strings (`b"..."`) beside the word strings, with length, index, slice, concat, comparison, `ston`/`ntos`, and syscall ops 10..13. fixed in stage 30 (details in `history/30-sharing`): shared cons cells and strings on the existing heap. bit 8 of the header is the share bit, `free` does not quarantine one, and the sweep collects it when nothing points at it. `LEARN.md` walks through the language. the c abi came later (see "c abi"). a word string is still one character per word; a byte string is eight characters per word. the microcore does not run o3 as a fast path. the small compiler does not self-host, and a 60000-word array does not fit in its heap. still open: + +**the conservative collector.** opcode 619 pushes the data-stack index, and the collector marks from there to the top, so a word the program has already dropped is not a root. `scrub` zeroes the unused region from the bottom up to the live top. the frame stack is still scanned whole. zeroing a frame in the prologue would do the same there, at a few words per call. + +**invalidation.** done in stage 48; see the self-modification paragraph in the jit section. what remains is only that a covered word whose count saturates at 255 is never decremented back to zero until a full flush, which costs a hook call on stores to it and nothing else. + +**automatic tiering.** dropped. the o3 keyword stays the way to get a native region for a function. the reasons (the region record, the calling convention for dynamic arrays, the compile-time o3 checks) are in design/tiering.md. + +**o3's own gaps.** on the jit, an o3 call to another compiled region is a direct call. on llvm a call to a compiled region is now inlined as a spill, a check, a frame setup and an indirect call through the callee's native entry, with no reload on the fast path (fib went from 0.69 s to 0.39 s), and the c helper is only the slow path. it is not yet a register-passing direct call, which costs about 12 ns where c costs 3 to 4. the core now has a global pass after the per block one: a constant lattice per variable across the region's blocks, refolded through the same emitter, so a branch on a known value is folded away. push and pop on a growable array are inline. a value that stays on the vm stack across a branch goes through memory, since blocks only share variables. there is still no loop-invariant motion or cross-block cse in the core (llvm does it on its build), no automatic tiering, and struct by value and struct returns in native calls are done for x86-64 and arm64 (see the extern note above), not for apple arm64. regions aren't built into images, so `rt.zc` and the compiler can't use o3, and o3 code that rewrites its own region sees the change at the next entry. `ZYNOGLOBAL=1` turns the global pass off. + +**generics are checked at their instances.** a generic function's body is not compiled where it is written: its tokens are kept and each set of type arguments gets its own copy, compiled after the item that asked for it, so an error inside a template body shows up when something instantiates it (like a c++ template), and a generic name used as a value has the template's type and halts if it is ever called. a struct passed to a generic parameter by value is passed by pointer, as everywhere else in zc. the template has to be written before the first call that gives it type arguments, since a call to a name that is not yet known as generic is read as an ordinary forward call. an unbound parameter is `word`. + +**check mode and closures.** a closure copies what it uses when it is made, so a closure that changes a captured variable changes its own copy, not the function's. the hints are heuristics on one function at a time: they don't follow a value through a call, and a stack buffer hint doesn't check that the size is what you wanted. after a fatal error in check mode (running out of locals, say) the compiler unwinds and can print one follow-on error. if a document makes the check run for 3 million tokens without unwinding the server stops, which hasn't happened outside of a deliberately broken parse word. the windows scripts were updated by reading, not run. + +**the rest.** the prescan only knows tags, not types, so a call to a typed function that's defined further down gets `word` as its result type until the definition shows up. the llvm backend compiles one module per block, so it warms up slowly. stores done by enhancements don't invalidate compiled code. a parse word that changes the syntax can confuse the prescan. it only records signatures, though, and a real definition always overrides what the prescan guessed. + +--- + diff --git a/docs/history/transcript.md b/docs/history/transcript.md new file mode 100644 index 0000000..9c9f451 --- /dev/null +++ b/docs/history/transcript.md @@ -0,0 +1,257 @@ +# development transcript + +these are historical requests and replies, kept as originally recorded. commands and feature descriptions here may refer to earlier layouts. use the current README.md and LEARN.md for instructions. + + +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 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/`. + +### 11 + +> progress report? +> add types please :) +> mostly as a compiler primitive though, plus type-inspection via reflection +> and a small optional typechecker (default off) +> oh and keep the stuff you write as a history scrapbook +> if it helps, add a path to the hardware which is called "virtual enhancements", and allows up to 512 custom operations to be compiled down via jit into hardware-level speeds and interoped directly into a fast path in the vm to become essentially custom wiring. useful for division and other stuff as a dynamic runtime path + +my answers to the clarifying questions, exactly: + +> types: words + structs + generics +> +> reflection: runtime type of heap objects, function signatures, typeof at compile time +> +> how an enhancement is defined: either actual C or llvm ir code or vm code or micro-ops passed through an optimizer. since for example, micro-ops and vm code are not sufficient for optimizing things like division +> +> scrapbook: notes + code snapshots + +**summary:** the progress report said the previous round was finished and shipped. i then laid out a plan where the core would compile c or llvm ir enhancement sources at runtime with the host toolchain and load the result. part of that reply was stopped by a safety check before it finished, so i stopped and checked in instead of building it. + +### 12 + +> also make the umd syntax like `type.u name`, and casting is multiplication `u*name` +> ideally i'd prefer memory to be unlimited words growing until system oom, but 1m is fine +> core.c plain interp is also nice +> zc0.c own file is fine +> i mentioned llvm for portability to non-arm targets +> yes, d object semantic that was intended +> u object hands up one block and becomes an m, that's fine. the code can make it a u or a d or whatever +> explain your gaps more +> +> wait why safety check? what's wrong with that + +my answers to the clarifying questions, exactly: + +> declarations: c-style, var -> let +> +> tags on untyped values and the names u, m, d: names reserved, bare .u allowed, untype is m by default +> +> llvm: llvm jit backend (Recommended) + +**summary:** on the safety check: nothing was wrong with the request. my best guess was that it tripped on the plan for a program inside the vm handing source text to the system compiler and loading the result into the running process, since that pattern also shows up in malware. with llvm meant for portability, that path wasn't needed. the gaps got the longer explanations that are now under open ends above. then the round itself: + +**syntax.** declarations are c-style (`int x`, `*node.m p`), `let` replaces `var` for untyped and inferred declarations, tags are `.u .m .d` after the type or on their own, recasts are `u*x` / `d*x` / `m*x`, `u m d` are reserved, and an untagged parameter counts as an m lend. + +**types.** a compiler primitive: hash-consed records with structs, generic structs and functions, fixed arrays, function types, `typeof`/`sizeof`, `as` casts and a reflection api, with object headers carrying their type. the typechecker is off by default and turned on with `typecheck on;`. + +**virtual enhancements.** opcode 21 installs, 22 to 533 are the slots. micro-op recipes and lifted vm code go through an optimizer in the core (folding, cse, dce, multiply-high division by constants) and get inlined by both jits. the language's own `/ % <<` now run on them. + +**backends.** a tiered llvm backend (`-DZYLLVM`) for non-arm hosts. + +**bootstrap and history.** it still reaches its fixpoint on all three backends. `history/` holds notes for every stage and code from stages 7, 10 and this one (in 11-types-enhancements). + +### 13 + +> gaps +> 1. when there's a var state change to d, mark that var as dead by default for any other scope that can access it afterwards. u is fine since it just returns +> 2. any suggestions for a cheap fix? +> 3. it's fine, rare occurrence (probably?), suggest a fix +> 4. fix that +> 5. suggest a fix +> 6. fix +> 7. fix + +**summary:** the numbers followed the gap list from my previous chat message. here's what each one got. + +**1. joins.** a variable that became d, or was given away, on any path is dead after the join, and fixup code frees it on the paths that still own it. a loop's exit state is the join of its breaks and its normal exit. giving something away on a path that loops back is still an error. u and borrows don't get the dead treatment. + +**2, 3 and 5.** suggestions only, now under open ends: a quarantine on reuse plus "borrowed from" marks on pointer-typed values for aliases, a stack-depth opcode for the collector, and page-indexed invalidation plus per-slot install tracking for the jit. + +**4. heap.** a buddy allocator. + +**6. stack checks.** all three stacks are checked: data and return at every block exit on all backends, and frames in every prologue. + +**7. the small stuff.** error recovery with up to 20 reported errors, line numbers carried in token lists, a signature prescan over the whole unit so prototypes are optional, storing into a borrowed object moving the object automatically, `?:`, and go-style `switch`. on the side, a 4-token lookahead fixed `**` declarations. + +### 14 + +> how costly is it if we add a counter to each block to see how many times it runs, then run the optimizer on it if it's a hot path? + +> continue + +**summary:** answered without building anything. about 4 instructions per block entry while a block is being counted, and nothing once its optimized translation replaces it. the optimizing pass would reuse the enhancement lifter, optimizer and register allocator. lifting whole blocks would need jz side exits and barriers at calls and i/o. compiling a block that way takes microseconds, against milliseconds for llvm, and keeping values in registers instead of the memory stack likely gives 2 to 4x on tight loops. it's listed under open ends. then the gap fixes continued. + +### 15 + +> write some really cool examples for this language + +> no, wdym building a fresh vm?? just pocs 😭 we already have a compiler and everything + +**summary:** my progress note had said "building a fresh vm", which only meant compiling core.c into a binary to run the examples. eight proofs of concept went into `examples/`: mandel, bf, dump, tree, lang, staged, quine and life, each described under files above and checked by `test.sh` on all three backends. + +### 16 + +> add opt keywords, for example `optim` (or o3, i prefer o3 as the keyword) will cause any vars in a scope to not assign heap type metadata, compiles with opt level o3 and is immediately compiled down to native, and when used with variables they must be always typed and it reduces the perf cost for accessing or modifying them, etc etc. add a `fixed` keyword which says that an array has a fixed size and cannot be resized, etc + +my answers to the clarifying questions, exactly: + +> where o3 goes: functions, blocks and single vars +> +> how far o3 goes: real optimizing tier (Recommended) +> +> what o3 code may give up: type stamps on objects, zero-filling new objects, the address of o3 vars, stack and frame checks, also i don't like the -> return type syntax. please replace it with the c-like syntax +> +> arrays: add growable arrays too (Recommended) + +**summary:** three things changed. + +**return types.** functions are declared c-style now, `int f(int x)`, `*node.u make()`, with fn types written `int(int, *char)`. `->` is gone from the compiler, zc0, the tests and the examples. + +**arrays.** `[]T` grows (`push`, `pop`, `resize`, `len`, `cap`), and `fixed []T` can't change size after `new(fixed []T, n)`. both are bounds-checked. `[n]T` stays as it was, plus a compile-time check for constant indexes. + +**o3.** on functions, blocks and single variables, with the trade-offs you picked, and a real optimizing tier in the core, described in the o3 section above. it compiles at install time on arm64 and llvm and has a region interpreter for the plain build. measured gains are 1.5 to 2.8x on the interpreter, 8 to 100x on llvm and 20 to 43x on arm64 (under qemu) for loop-heavy kernels, and much less for call-heavy ones. on the way, the arm64 jit learned to specialize an enhancement on literal inputs, so `x / 7` is a multiply-high everywhere, not only in o3 code. tests for arrays and o3 turned up an old heap bug: freeing a container could merge one of its children into it while it was still being freed, which corrupted a free list. growable arrays hit it every time. it's fixed. + +### 17 + +> generics should go after fn name and before parens +> we also need some machinery for converting values to/from o3. to is pretty easy, we just hand over the data, and o3 ignores the fat metadata. from is a bit harder, there needs to be a system to get type hints and fatten the metadata for the packed data +> variables just get the latest free register, it's fine for now +> add the fixed array once per region thing +> +> also if you have any tips on how to make the memory system better (aka avoiding gc and leaks/uaf as much as possible) do tell + +**summary:** generics went back after the name, `T first(...)`, with the return type allowed to use them before the list declares them. o3 got fattening on the way out (the section above): `new_raw` keeps the requested size in the type word, and the compiler calls `fatten` with the static type wherever o3 data reaches normal code. registers now follow scopes, so a closed scope's register goes to the next variable. fixed arrays in o3 variables keep their items and length in two hidden register variables. the memory tips were answered in chat, not built. + + +### 18 + +> there's been changes. run a consistency pass, fix comment stylings (change the cringe dry ones to the format you used), bug fixes, fix the lsp, write tests for it, then impl the remaining points in todo.md +> +> the analyzer should be in tandem with the compiler, and immediate words / syntax modifications should affect it just the same. same with the syntax highlighter. + +**summary:** the language server is the compiler now. `src/compiler.zc` has a check mode (errors become records, compiling goes on, hints are reported), and `lsp/server.zc` is only the json-rpc layer, the document store and the token writer on top of it, so parse words and syntax changes apply to the check and the highlighting exactly as they do in a build. the old standalone analyzer (`lsp/zclsp.zc`) is gone. struct methods with `this` and closures are real compiler features (they were only recognised by the old analyzer), pointer types can be written `int*`, `vec*`, `point**` (the prefix form still parses), braces are on the same line across the sources, and there is a webassembly build of the microcore with a browser page. the rest of the sweep is in `history/44-check-mode`. -- cgit v1.2.3