├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── main.yml ├── .gitignore ├── Dockerfile ├── Makefile ├── QR.rb ├── README.md ├── SHA256SUMS ├── langs.png ├── src ├── Dockerfile.gen.rb ├── Makefile.gen.rb ├── QR.rb.gen.rb ├── README.md.gen.rb ├── Rakefile ├── SHA256SUMS.gen.rb ├── blc-boot.dat.gen.rb ├── code-gen-pool.rb ├── code-gen.rb ├── dot.github.workflows.main.yml.gen.rb ├── grass-boot.dat.gen.rb ├── langs.png.gen.rb ├── lazyk-boot.dat.gen.rb ├── test.rb ├── thumbnail.png.gen.rb ├── uroboros.svg ├── uroboros.txt └── wasm-tmpl.dat.gen.rb ├── thumbnail.png └── vendor ├── .gitignore ├── Acme-Chef-1.03.tar.gz ├── Makefile ├── README ├── Velato_0_1.zip ├── aheui.rb ├── ante.rb ├── bf.rb ├── blc.rb ├── cfunge-0.9.0.tar.bz2 ├── dummy-wasi-runtime.c ├── false.rb ├── golfscript.rb ├── grass.rb ├── lazyk.c ├── lci-0.10.5.zip ├── npiet-1.3e.tar.gz ├── ook-to-bf.rb ├── spl-1.2.1.tar.gz ├── subleq.rb ├── thue.rb ├── unlambda.rb ├── wasi-runtime.js └── whitespace.rb /.gitattributes: -------------------------------------------------------------------------------- 1 | /Dockerfile linguist-generated 2 | /Makefile linguist-generated 3 | /QR.rb linguist-generated linguist-language=prose 4 | /README.md linguist-generated 5 | /SHA256SUMS linguist-generated 6 | /langs.png linguist-generated 7 | /thumbnail.png linguist-generated 8 | /vendor linguist-vendored 9 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: mame 2 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | - push 4 | - pull_request 5 | - workflow_dispatch 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v1 11 | - name: docker build 12 | run: | 13 | sudo docker build -t quine-relay . 14 | - name: docker run 15 | run: | 16 | sudo docker run --privileged --name qr -e CI=true -t quine-relay 17 | - name: push spoiler 18 | run: | 19 | git clone https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git spoiler --branch spoiler 20 | git -C spoiler rm --quiet -r '*' 21 | sudo docker cp qr:/usr/local/share/quine-relay/QR.rb spoiler/ 22 | sudo docker cp qr:/usr/local/share/quine-relay/QR.rs spoiler/ 23 | sudo docker cp qr:/usr/local/share/quine-relay/QR.scala spoiler/ 24 | sudo docker cp qr:/usr/local/share/quine-relay/QR.scm spoiler/ 25 | sudo docker cp qr:/usr/local/share/quine-relay/QR.sci spoiler/ 26 | sudo docker cp qr:/usr/local/share/quine-relay/QR.sed spoiler/ 27 | sudo docker cp qr:/usr/local/share/quine-relay/QR.spl spoiler/ 28 | sudo docker cp qr:/usr/local/share/quine-relay/QR.sl spoiler/ 29 | sudo docker cp qr:/usr/local/share/quine-relay/QR.nut spoiler/ 30 | sudo docker cp qr:/usr/local/share/quine-relay/QR.sml spoiler/ 31 | sudo docker cp qr:/usr/local/share/quine-relay/QR.sq spoiler/ 32 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ss spoiler/ 33 | sudo docker cp qr:/usr/local/share/quine-relay/QR.tcl spoiler/ 34 | sudo docker cp qr:/usr/local/share/quine-relay/QR.tcsh spoiler/ 35 | sudo docker cp qr:/usr/local/share/quine-relay/QR.t spoiler/ 36 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ts spoiler/ 37 | sudo docker cp qr:/usr/local/share/quine-relay/QR.unl spoiler/ 38 | sudo docker cp qr:/usr/local/share/quine-relay/QR.vala spoiler/ 39 | sudo docker cp qr:/usr/local/share/quine-relay/QR.mid spoiler/ 40 | sudo docker cp qr:/usr/local/share/quine-relay/QR.v spoiler/ 41 | sudo docker cp qr:/usr/local/share/quine-relay/QR.vim spoiler/ 42 | sudo docker cp qr:/usr/local/share/quine-relay/QR.vb spoiler/ 43 | sudo docker cp qr:/usr/local/share/quine-relay/QR.wasm spoiler/ 44 | sudo docker cp qr:/usr/local/share/quine-relay/QR.wat spoiler/ 45 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ws spoiler/ 46 | sudo docker cp qr:/usr/local/share/quine-relay/QR.xslt spoiler/ 47 | sudo docker cp qr:/usr/local/share/quine-relay/QR.yab spoiler/ 48 | sudo docker cp qr:/usr/local/share/quine-relay/QR.yorick spoiler/ 49 | sudo docker cp qr:/usr/local/share/quine-relay/QR.azm spoiler/ 50 | sudo docker cp qr:/usr/local/share/quine-relay/QR.zsh spoiler/ 51 | sudo docker cp qr:/usr/local/share/quine-relay/QR.+ spoiler/ 52 | sudo docker cp qr:/usr/local/share/quine-relay/qr.adb spoiler/ 53 | sudo docker cp qr:/usr/local/share/quine-relay/QR.als spoiler/ 54 | sudo docker cp qr:/usr/local/share/quine-relay/QR.aheui spoiler/ 55 | sudo docker cp qr:/usr/local/share/quine-relay/QR.a68 spoiler/ 56 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ante spoiler/ 57 | sudo docker cp qr:/usr/local/share/quine-relay/QR.aj spoiler/ 58 | sudo docker cp qr:/usr/local/share/quine-relay/QR.asy spoiler/ 59 | sudo docker cp qr:/usr/local/share/quine-relay/QR.dats spoiler/ 60 | sudo docker cp qr:/usr/local/share/quine-relay/QR.awk spoiler/ 61 | sudo docker cp qr:/usr/local/share/quine-relay/QR.bash spoiler/ 62 | sudo docker cp qr:/usr/local/share/quine-relay/QR.bc spoiler/ 63 | sudo docker cp qr:/usr/local/share/quine-relay/QR.bsh spoiler/ 64 | sudo docker cp qr:/usr/local/share/quine-relay/QR.bef spoiler/ 65 | sudo docker cp qr:/usr/local/share/quine-relay/QR.Blc spoiler/ 66 | sudo docker cp qr:/usr/local/share/quine-relay/QR.bf spoiler/ 67 | sudo docker cp qr:/usr/local/share/quine-relay/QR.c spoiler/ 68 | sudo docker cp qr:/usr/local/share/quine-relay/QR.cpp spoiler/ 69 | sudo docker cp qr:/usr/local/share/quine-relay/QR.cs spoiler/ 70 | sudo docker cp qr:/usr/local/share/quine-relay/QR.chef spoiler/ 71 | sudo docker cp qr:/usr/local/share/quine-relay/QR.clj spoiler/ 72 | sudo docker cp qr:/usr/local/share/quine-relay/QR.cmake spoiler/ 73 | sudo docker cp qr:/usr/local/share/quine-relay/QR.cob spoiler/ 74 | sudo docker cp qr:/usr/local/share/quine-relay/QR.coffee spoiler/ 75 | sudo docker cp qr:/usr/local/share/quine-relay/QR.lisp spoiler/ 76 | sudo docker cp qr:/usr/local/share/quine-relay/QR.cr spoiler/ 77 | sudo docker cp qr:/usr/local/share/quine-relay/QR.d spoiler/ 78 | sudo docker cp qr:/usr/local/share/quine-relay/QR.dc spoiler/ 79 | sudo docker cp qr:/usr/local/share/quine-relay/QR.dhall spoiler/ 80 | sudo docker cp qr:/usr/local/share/quine-relay/QR.exs spoiler/ 81 | sudo docker cp qr:/usr/local/share/quine-relay/QR.el spoiler/ 82 | sudo docker cp qr:/usr/local/share/quine-relay/QR.erl spoiler/ 83 | sudo docker cp qr:/usr/local/share/quine-relay/QR.e spoiler/ 84 | sudo docker cp qr:/usr/local/share/quine-relay/QR.fsx spoiler/ 85 | sudo docker cp qr:/usr/local/share/quine-relay/QR.false spoiler/ 86 | sudo docker cp qr:/usr/local/share/quine-relay/QR.fl spoiler/ 87 | sudo docker cp qr:/usr/local/share/quine-relay/QR.fish spoiler/ 88 | sudo docker cp qr:/usr/local/share/quine-relay/QR.fs spoiler/ 89 | sudo docker cp qr:/usr/local/share/quine-relay/QR.f spoiler/ 90 | sudo docker cp qr:/usr/local/share/quine-relay/QR.f90 spoiler/ 91 | sudo docker cp qr:/usr/local/share/quine-relay/QR.gbs spoiler/ 92 | sudo docker cp qr:/usr/local/share/quine-relay/QR.g spoiler/ 93 | sudo docker cp qr:/usr/local/share/quine-relay/QR.gdb spoiler/ 94 | sudo docker cp qr:/usr/local/share/quine-relay/QR.gel spoiler/ 95 | sudo docker cp qr:/usr/local/share/quine-relay/QR.plt spoiler/ 96 | sudo docker cp qr:/usr/local/share/quine-relay/QR.go spoiler/ 97 | sudo docker cp qr:/usr/local/share/quine-relay/QR.gs spoiler/ 98 | sudo docker cp qr:/usr/local/share/quine-relay/QR.gpt spoiler/ 99 | sudo docker cp qr:/usr/local/share/quine-relay/QR.grass spoiler/ 100 | sudo docker cp qr:/usr/local/share/quine-relay/QR.groovy spoiler/ 101 | sudo docker cp qr:/usr/local/share/quine-relay/QR.gz spoiler/ 102 | sudo docker cp qr:/usr/local/share/quine-relay/QR.hs spoiler/ 103 | sudo docker cp qr:/usr/local/share/quine-relay/QR.hx spoiler/ 104 | sudo docker cp qr:/usr/local/share/quine-relay/QR.icn spoiler/ 105 | sudo docker cp qr:/usr/local/share/quine-relay/QR.i spoiler/ 106 | sudo docker cp qr:/usr/local/share/quine-relay/QR.j spoiler/ 107 | sudo docker cp qr:/usr/local/share/quine-relay/QR.java spoiler/ 108 | sudo docker cp qr:/usr/local/share/quine-relay/QR.js spoiler/ 109 | sudo docker cp qr:/usr/local/share/quine-relay/QR.jq spoiler/ 110 | sudo docker cp qr:/usr/local/share/quine-relay/QR.jsfuck spoiler/ 111 | sudo docker cp qr:/usr/local/share/quine-relay/QR.kt spoiler/ 112 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ksh spoiler/ 113 | sudo docker cp qr:/usr/local/share/quine-relay/QR.lazy spoiler/ 114 | sudo docker cp qr:/usr/local/share/quine-relay/qr.li spoiler/ 115 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ls spoiler/ 116 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ll spoiler/ 117 | sudo docker cp qr:/usr/local/share/quine-relay/QR.lol spoiler/ 118 | sudo docker cp qr:/usr/local/share/quine-relay/QR.lua spoiler/ 119 | sudo docker cp qr:/usr/local/share/quine-relay/QR.m4 spoiler/ 120 | sudo docker cp qr:/usr/local/share/quine-relay/QR.mk spoiler/ 121 | sudo docker cp qr:/usr/local/share/quine-relay/QR.mzn spoiler/ 122 | sudo docker cp qr:/usr/local/share/quine-relay/QR.mod spoiler/ 123 | sudo docker cp qr:/usr/local/share/quine-relay/QR.il spoiler/ 124 | sudo docker cp qr:/usr/local/share/quine-relay/QR.mustache spoiler/ 125 | sudo docker cp qr:/usr/local/share/quine-relay/QR.asm spoiler/ 126 | sudo docker cp qr:/usr/local/share/quine-relay/QR.neko spoiler/ 127 | sudo docker cp qr:/usr/local/share/quine-relay/QR.5c spoiler/ 128 | sudo docker cp qr:/usr/local/share/quine-relay/QR.nim spoiler/ 129 | sudo docker cp qr:/usr/local/share/quine-relay/QR.m spoiler/ 130 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ml spoiler/ 131 | sudo docker cp qr:/usr/local/share/quine-relay/QR.octave spoiler/ 132 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ook spoiler/ 133 | sudo docker cp qr:/usr/local/share/quine-relay/QR.gp spoiler/ 134 | sudo docker cp qr:/usr/local/share/quine-relay/QR.p spoiler/ 135 | sudo docker cp qr:/usr/local/share/quine-relay/QR.pas spoiler/ 136 | sudo docker cp qr:/usr/local/share/quine-relay/QR.pl spoiler/ 137 | sudo docker cp qr:/usr/local/share/quine-relay/QR.pl6 spoiler/ 138 | sudo docker cp qr:/usr/local/share/quine-relay/QR.php spoiler/ 139 | sudo docker cp qr:/usr/local/share/quine-relay/QR.png spoiler/ 140 | sudo docker cp qr:/usr/local/share/quine-relay/QR.pike spoiler/ 141 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ps spoiler/ 142 | sudo docker cp qr:/usr/local/share/quine-relay/QR.prolog spoiler/ 143 | sudo docker cp qr:/usr/local/share/quine-relay/QR.pr spoiler/ 144 | sudo docker cp qr:/usr/local/share/quine-relay/QR.py spoiler/ 145 | sudo docker cp qr:/usr/local/share/quine-relay/QR.R spoiler/ 146 | sudo docker cp qr:/usr/local/share/quine-relay/QR.ratfor spoiler/ 147 | sudo docker cp qr:/usr/local/share/quine-relay/QR.rc spoiler/ 148 | sudo docker cp qr:/usr/local/share/quine-relay/QR.rexx spoiler/ 149 | cd spoiler 150 | git add . 151 | GIT_AUTHOR_NAME="$(git show -s --format=%an "$GITHUB_SHA")" \ 152 | GIT_AUTHOR_EMAIL="$(git show -s --format=%ae "$GITHUB_SHA")" \ 153 | GIT_AUTHOR_DATE="$(git show -s --format=%ad "$GITHUB_SHA")" \ 154 | GIT_COMMITTER_NAME='GitHub Actions' \ 155 | GIT_COMMITTER_EMAIL='actions@github.com' \ 156 | TZ=UTC \ 157 | git commit --allow-empty -m "spoiler: $(git show -s --format=%s "$GITHUB_SHA")" 158 | git push --quiet origin spoiler 159 | echo The intermediate sources are available: https://github.com/${GITHUB_REPOSITORY}/tree/spoiler 160 | if: github.event_name == 'push' && github.ref == 'refs/heads/master' 161 | env: 162 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 163 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /QR* 2 | /qr* 3 | /tmp 4 | /nimcache 5 | /.curry 6 | !QR.rb 7 | gst.im 8 | /src/lazyk-boot.dat 9 | /src/blc-boot.dat 10 | /src/grass-boot.dat 11 | *.sw* 12 | tmp.*proj 13 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:25.04 2 | ENV DEBIAN_FRONTEND noninteractive 3 | RUN apt-get update && apt-get upgrade -y 4 | RUN apt-get -qq install -y apt-utils > /dev/null 5 | RUN apt-get -qq install -y moreutils 6 | RUN chronic apt-get -qq install -y afnix algol68g aplus-fsf aspectj && chronic apt-get clean 7 | RUN chronic apt-get -qq install -y asymptote ats2-lang bash bc && chronic apt-get clean 8 | RUN chronic apt-get -qq install -y bison bsh clisp clojure && chronic apt-get clean 9 | RUN chronic apt-get -qq install -y cmake coffeescript crystal curl && chronic apt-get clean 10 | RUN chronic apt-get -qq install -y dc dhall dotnet8 elixir && chronic apt-get clean 11 | RUN chronic apt-get -qq install -y emacs-nox erlang execline f2c && chronic apt-get clean 12 | RUN chronic apt-get -qq install -y fish flex fp-compiler g++ && chronic apt-get clean 13 | RUN chronic apt-get -qq install -y gambas3-gb-pcre gambas3-scripter gap gawk && chronic apt-get clean 14 | RUN chronic apt-get -qq install -y gcc gdb gdc genius && chronic apt-get clean 15 | RUN chronic apt-get -qq install -y gforth gfortran ghc ghostscript && chronic apt-get clean 16 | RUN chronic apt-get -qq install -y gm2 gnat gnucobol4 gnuplot && chronic apt-get clean 17 | RUN chronic apt-get -qq install -y gobjc golang gpt groff && chronic apt-get clean 18 | RUN chronic apt-get -qq install -y groovy guile-3.0 gzip haxe && chronic apt-get clean 19 | RUN chronic apt-get -qq install -y icont iconx intercal iverilog && chronic apt-get clean 20 | RUN chronic apt-get -qq install -y jasmin-sable jq kotlin ksh && chronic apt-get clean 21 | RUN chronic apt-get -qq install -y libevent-dev libgd-dev libpng-dev libpolyml-dev && chronic apt-get clean 22 | RUN chronic apt-get -qq install -y lisaac livescript llvm lua5.3 && chronic apt-get clean 23 | RUN chronic apt-get -qq install -y m4 make minizinc mono-devel && chronic apt-get clean 24 | RUN chronic apt-get -qq install -y nasm neko nickle nim && chronic apt-get clean 25 | RUN chronic apt-get -qq install -y node-typescript nodejs ocaml octave && chronic apt-get clean 26 | RUN chronic apt-get -qq install -y openjdk-11-jdk pari-gp parser3-cgi perl && chronic apt-get clean 27 | RUN chronic apt-get -qq install -y php-cli pike8.0 polyml python3 && chronic apt-get clean 28 | RUN chronic apt-get -qq install -y r-base rakudo ratfor rc && chronic apt-get clean 29 | RUN chronic apt-get -qq install -y regina-rexx ruby ruby-mustache rustc && chronic apt-get clean 30 | RUN chronic apt-get -qq install -y scala scilab-cli sed slsh && chronic apt-get clean 31 | RUN chronic apt-get -qq install -y spin squirrel3 surgescript swi-prolog && chronic apt-get clean 32 | RUN chronic apt-get -qq install -y tcl tcsh valac vim && chronic apt-get clean 33 | RUN chronic apt-get -qq install -y wabt xsltproc yabasic yorick && chronic apt-get clean 34 | RUN chronic apt-get -qq install -y zoem zsh && chronic apt-get clean 35 | ADD . /usr/local/share/quine-relay 36 | WORKDIR /usr/local/share/quine-relay 37 | RUN make -C vendor 38 | CMD make check -j 10000 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MAKEFLAGS += --no-print-directory 2 | 3 | PATH := $(CURDIR)/vendor/local/bin:/usr/games:$(PATH) 4 | CLASSPATH := . 5 | 6 | find_any0 = $(firstword $(foreach x,$(1),$(if $(shell which $(x) 2>/dev/null),$(x),))) 7 | check = $(if $(2),$(2),$(error $(1) interpreter not found!)) 8 | find_any = $(call check,$(1),$(call find_any0,$(2))) 9 | 10 | JAVASCRIPT := $(call find_any,JavaScript,nodejs node js) 11 | SCHEME := $(call find_any,Scheme,guile csi gosh) 12 | GBS := $(call find_any,Gambas script,gbs3 gbs2 gba3) 13 | WASI_RUNTIME := $(call find_any,WASI runtime,wasmtime node) 14 | 15 | ifeq ($(SCHEME),csi) 16 | SCHEME := csi -s 17 | endif 18 | ifeq ($(WASI_RUNTIME),node) 19 | WASI_RUNTIME := node --experimental-wasi-unstable-preview1 vendor/wasi-runtime.js 20 | endif 21 | 22 | .DELETE_ON_ERROR: 23 | 24 | all: QR2.rb 25 | @echo 26 | @echo "#############" 27 | @echo "## CHECK ##" 28 | @echo "#############" 29 | @echo 30 | diff -s QR.rb QR2.rb 31 | 32 | check: all 33 | @sha256sum --quiet -c SHA256SUMS 34 | 35 | QR.rs: QR.rb 36 | @echo 37 | @echo "#######################" 38 | @echo "## 1: Ruby -> Rust ##" 39 | @echo "#######################" 40 | @echo 41 | ruby QR.rb > QR.rs 42 | 43 | QR.scala: QR.rs 44 | @echo 45 | @echo "########################" 46 | @echo "## 2: Rust -> Scala ##" 47 | @echo "########################" 48 | @echo 49 | rustc QR.rs 50 | ./QR > QR.scala 51 | 52 | QR.scm: QR.scala 53 | @echo 54 | @echo "##########################" 55 | @echo "## 3: Scala -> Scheme ##" 56 | @echo "##########################" 57 | @echo 58 | scalac QR.scala 59 | scala QR > QR.scm 60 | 61 | QR.sci: QR.scm 62 | @echo 63 | @echo "###########################" 64 | @echo "## 4: Scheme -> Scilab ##" 65 | @echo "###########################" 66 | @echo 67 | $(SCHEME) QR.scm > QR.sci 68 | 69 | QR.sed: QR.sci 70 | @echo 71 | @echo "########################" 72 | @echo "## 5: Scilab -> sed ##" 73 | @echo "########################" 74 | @echo 75 | scilab-cli -nb -f QR.sci > QR.sed 76 | 77 | QR.spl: QR.sed 78 | @echo 79 | @echo "#############################" 80 | @echo "## 6: sed -> Shakespeare ##" 81 | @echo "#############################" 82 | @echo 83 | sed -E -f QR.sed QR.sed > QR.spl 84 | 85 | QR.sl: QR.spl 86 | @echo 87 | @echo "################################" 88 | @echo "## 7: Shakespeare -> S-Lang ##" 89 | @echo "################################" 90 | @echo 91 | spl2c < QR.spl > QR.spl.c 92 | gcc -z muldefs -o QR -I ./vendor/local/include -L ./vendor/local/lib QR.spl.c -lspl -lm 93 | ./QR > QR.sl 94 | 95 | QR.nut: QR.sl 96 | @echo 97 | @echo "#############################" 98 | @echo "## 8: S-Lang -> Squirrel ##" 99 | @echo "#############################" 100 | @echo 101 | slsh QR.sl > QR.nut 102 | 103 | QR.sml: QR.nut 104 | @echo 105 | @echo "##################################" 106 | @echo "## 9: Squirrel -> Standard ML ##" 107 | @echo "##################################" 108 | @echo 109 | squirrel QR.nut > QR.sml 110 | 111 | QR.sq: QR.sml 112 | @echo 113 | @echo "#################################" 114 | @echo "## 10: Standard ML -> Subleq ##" 115 | @echo "#################################" 116 | @echo 117 | polyc -o QR QR.sml 118 | ./QR > QR.sq 119 | 120 | QR.ss: QR.sq 121 | @echo 122 | @echo "#################################" 123 | @echo "## 11: Subleq -> SurgeScript ##" 124 | @echo "#################################" 125 | @echo 126 | ruby vendor/subleq.rb QR.sq > QR.ss 127 | 128 | QR.tcl: QR.ss 129 | @echo 130 | @echo "##############################" 131 | @echo "## 12: SurgeScript -> Tcl ##" 132 | @echo "##############################" 133 | @echo 134 | surgescript QR.ss > QR.tcl 135 | 136 | QR.tcsh: QR.tcl 137 | @echo 138 | @echo "#######################" 139 | @echo "## 13: Tcl -> tcsh ##" 140 | @echo "#######################" 141 | @echo 142 | tclsh QR.tcl > QR.tcsh 143 | 144 | QR.t: QR.tcsh 145 | @echo 146 | @echo "########################" 147 | @echo "## 14: tcsh -> Thue ##" 148 | @echo "########################" 149 | @echo 150 | tcsh QR.tcsh > QR.t 151 | 152 | QR.ts: QR.t 153 | @echo 154 | @echo "##############################" 155 | @echo "## 15: Thue -> TypeScript ##" 156 | @echo "##############################" 157 | @echo 158 | ruby vendor/thue.rb QR.t > QR.ts 159 | 160 | QR.unl: QR.ts 161 | @echo 162 | @echo "##################################" 163 | @echo "## 16: TypeScript -> Unlambda ##" 164 | @echo "##################################" 165 | @echo 166 | tsc --outFile QR.ts.js QR.ts 167 | $(JAVASCRIPT) QR.ts.js > QR.unl 168 | 169 | QR.vala: QR.unl 170 | @echo 171 | @echo "############################" 172 | @echo "## 17: Unlambda -> Vala ##" 173 | @echo "############################" 174 | @echo 175 | ruby vendor/unlambda.rb QR.unl > QR.vala 176 | 177 | QR.mid: QR.vala 178 | @echo 179 | @echo "##########################" 180 | @echo "## 18: Vala -> Velato ##" 181 | @echo "##########################" 182 | @echo 183 | valac QR.vala 184 | ./QR > QR.mid 185 | 186 | QR.v: QR.mid 187 | @echo 188 | @echo "#############################" 189 | @echo "## 19: Velato -> Verilog ##" 190 | @echo "#############################" 191 | @echo 192 | mono vendor/local/bin/Vlt.exe /s QR.mid 193 | mono QR.exe > QR.v 194 | 195 | QR.vim: QR.v 196 | @echo 197 | @echo "################################" 198 | @echo "## 20: Verilog -> Vimscript ##" 199 | @echo "################################" 200 | @echo 201 | iverilog -o QR QR.v 202 | ./QR -vcd-none > QR.vim 203 | 204 | QR.vb: QR.vim 205 | @echo 206 | @echo "#####################################" 207 | @echo "## 21: Vimscript -> Visual Basic ##" 208 | @echo "#####################################" 209 | @echo 210 | vim -EsS QR.vim > QR.vb 211 | 212 | QR.wasm: QR.vb 213 | @echo 214 | @echo "#######################################################" 215 | @echo "## 22: Visual Basic -> WebAssembly (Binary format) ##" 216 | @echo "#######################################################" 217 | @echo 218 | echo 'Exenet8.0false' > tmp.vbproj 219 | DOTNET_NOLOGO=1 dotnet run --project tmp.vbproj > QR.wasm 220 | 221 | QR.wat: QR.wasm 222 | @echo 223 | @echo "####################################################################" 224 | @echo "## 23: WebAssembly (Binary format) -> WebAssembly (Text format) ##" 225 | @echo "####################################################################" 226 | @echo 227 | $(WASI_RUNTIME) QR.wasm > QR.wat 228 | 229 | QR.ws: QR.wat 230 | @echo 231 | @echo "###################################################" 232 | @echo "## 24: WebAssembly (Text format) -> Whitespace ##" 233 | @echo "###################################################" 234 | @echo 235 | wat2wasm QR.wat -o QR.wat.wasm 236 | $(WASI_RUNTIME) QR.wat.wasm > QR.ws 237 | 238 | QR.xslt: QR.ws 239 | @echo 240 | @echo "##############################" 241 | @echo "## 25: Whitespace -> XSLT ##" 242 | @echo "##############################" 243 | @echo 244 | ruby vendor/whitespace.rb QR.ws > QR.xslt 245 | 246 | QR.yab: QR.xslt 247 | @echo 248 | @echo "###########################" 249 | @echo "## 26: XSLT -> Yabasic ##" 250 | @echo "###########################" 251 | @echo 252 | xsltproc QR.xslt > QR.yab 253 | 254 | QR.yorick: QR.yab 255 | @echo 256 | @echo "#############################" 257 | @echo "## 27: Yabasic -> Yorick ##" 258 | @echo "#############################" 259 | @echo 260 | yabasic QR.yab > QR.yorick 261 | 262 | QR.azm: QR.yorick 263 | @echo 264 | @echo "##########################" 265 | @echo "## 28: Yorick -> Zoem ##" 266 | @echo "##########################" 267 | @echo 268 | yorick -batch QR.yorick > QR.azm 269 | 270 | QR.zsh: QR.azm 271 | @echo 272 | @echo "#######################" 273 | @echo "## 29: Zoem -> zsh ##" 274 | @echo "#######################" 275 | @echo 276 | zoem -i QR.azm > QR.zsh 277 | 278 | QR.+: QR.zsh 279 | @echo 280 | @echo "#####################" 281 | @echo "## 30: zsh -> A+ ##" 282 | @echo "#####################" 283 | @echo 284 | zsh QR.zsh > QR.+ 285 | 286 | qr.adb: QR.+ 287 | @echo 288 | @echo "#####################" 289 | @echo "## 31: A+ -> Ada ##" 290 | @echo "#####################" 291 | @echo 292 | a+ QR.+ > qr.adb 293 | 294 | QR.als: qr.adb 295 | @echo 296 | @echo "########################" 297 | @echo "## 32: Ada -> AFNIX ##" 298 | @echo "########################" 299 | @echo 300 | gnatmake qr.adb 301 | ./qr > QR.als 302 | 303 | QR.aheui: QR.als 304 | @echo 305 | @echo "##########################" 306 | @echo "## 33: AFNIX -> Aheui ##" 307 | @echo "##########################" 308 | @echo 309 | LANG=C LD_LIBRARY_PATH=/usr/lib/afnix axi QR.als > QR.aheui 310 | 311 | QR.a68: QR.aheui 312 | @echo 313 | @echo "#############################" 314 | @echo "## 34: Aheui -> ALGOL 68 ##" 315 | @echo "#############################" 316 | @echo 317 | ruby vendor/aheui.rb QR.aheui > QR.a68 318 | 319 | QR.ante: QR.a68 320 | @echo 321 | @echo "############################" 322 | @echo "## 35: ALGOL 68 -> Ante ##" 323 | @echo "############################" 324 | @echo 325 | a68g QR.a68 > QR.ante 326 | 327 | QR.aj: QR.ante 328 | @echo 329 | @echo "###########################" 330 | @echo "## 36: Ante -> AspectJ ##" 331 | @echo "###########################" 332 | @echo 333 | ruby vendor/ante.rb QR.ante > QR.aj 334 | 335 | QR.asy: QR.aj 336 | @echo 337 | @echo "################################" 338 | @echo "## 37: AspectJ -> Asymptote ##" 339 | @echo "################################" 340 | @echo 341 | ajc QR.aj 342 | java QR > QR.asy 343 | 344 | QR.dats: QR.asy 345 | @echo 346 | @echo "############################" 347 | @echo "## 38: Asymptote -> ATS ##" 348 | @echo "############################" 349 | @echo 350 | asy QR.asy > QR.dats 351 | 352 | QR.awk: QR.dats 353 | @echo 354 | @echo "######################" 355 | @echo "## 39: ATS -> Awk ##" 356 | @echo "######################" 357 | @echo 358 | patscc -o QR QR.dats 359 | ./QR > QR.awk 360 | 361 | QR.bash: QR.awk 362 | @echo 363 | @echo "#######################" 364 | @echo "## 40: Awk -> bash ##" 365 | @echo "#######################" 366 | @echo 367 | awk -f QR.awk > QR.bash 368 | 369 | QR.bc: QR.bash 370 | @echo 371 | @echo "######################" 372 | @echo "## 41: bash -> bc ##" 373 | @echo "######################" 374 | @echo 375 | bash QR.bash > QR.bc 376 | 377 | QR.bsh: QR.bc 378 | @echo 379 | @echo "###########################" 380 | @echo "## 42: bc -> BeanShell ##" 381 | @echo "###########################" 382 | @echo 383 | BC_LINE_LENGTH=4000000 bc -q QR.bc > QR.bsh 384 | 385 | QR.bef: QR.bsh 386 | @echo 387 | @echo "################################" 388 | @echo "## 43: BeanShell -> Befunge ##" 389 | @echo "################################" 390 | @echo 391 | bsh QR.bsh > QR.bef 392 | 393 | QR.Blc: QR.bef 394 | @echo 395 | @echo "###########################" 396 | @echo "## 44: Befunge -> BLC8 ##" 397 | @echo "###########################" 398 | @echo 399 | cfunge QR.bef > QR.Blc 400 | 401 | QR.bf: QR.Blc 402 | @echo 403 | @echo "#############################" 404 | @echo "## 45: BLC8 -> Brainfuck ##" 405 | @echo "#############################" 406 | @echo 407 | ruby vendor/blc.rb < QR.Blc > QR.bf 408 | 409 | QR.c: QR.bf 410 | @echo 411 | @echo "##########################" 412 | @echo "## 46: Brainfuck -> C ##" 413 | @echo "##########################" 414 | @echo 415 | ruby vendor/bf.rb QR.bf > QR.c 416 | 417 | QR.cpp: QR.c 418 | @echo 419 | @echo "####################" 420 | @echo "## 47: C -> C++ ##" 421 | @echo "####################" 422 | @echo 423 | $(CC) -o QR QR.c 424 | ./QR > QR.cpp 425 | 426 | QR.cs: QR.cpp 427 | @echo 428 | @echo "#####################" 429 | @echo "## 48: C++ -> C# ##" 430 | @echo "#####################" 431 | @echo 432 | $(CXX) -o QR QR.cpp 433 | ./QR > QR.cs 434 | 435 | QR.chef: QR.cs 436 | @echo 437 | @echo "######################" 438 | @echo "## 49: C# -> Chef ##" 439 | @echo "######################" 440 | @echo 441 | echo 'Exenet8.0false' > tmp.csproj 442 | DOTNET_NOLOGO=1 dotnet run --project tmp.csproj > QR.chef 443 | 444 | QR.clj: QR.chef 445 | @echo 446 | @echo "###########################" 447 | @echo "## 50: Chef -> Clojure ##" 448 | @echo "###########################" 449 | @echo 450 | PERL5LIB=vendor/local/lib/perl5 compilechef QR.chef QR.chef.pl 451 | perl QR.chef.pl > QR.clj 452 | 453 | QR.cmake: QR.clj 454 | @echo 455 | @echo "############################" 456 | @echo "## 51: Clojure -> CMake ##" 457 | @echo "############################" 458 | @echo 459 | clojure QR.clj > QR.cmake 460 | 461 | QR.cob: QR.cmake 462 | @echo 463 | @echo "##########################" 464 | @echo "## 52: CMake -> Cobol ##" 465 | @echo "##########################" 466 | @echo 467 | cmake -P QR.cmake > QR.cob 468 | 469 | QR.coffee: QR.cob 470 | @echo 471 | @echo "#################################" 472 | @echo "## 53: Cobol -> CoffeeScript ##" 473 | @echo "#################################" 474 | @echo 475 | cobc -O2 -x QR.cob 476 | ./QR > QR.coffee 477 | 478 | QR.lisp: QR.coffee 479 | @echo 480 | @echo "#######################################" 481 | @echo "## 54: CoffeeScript -> Common Lisp ##" 482 | @echo "#######################################" 483 | @echo 484 | coffee --nodejs --stack_size=100000 QR.coffee > QR.lisp 485 | 486 | QR.cr: QR.lisp 487 | @echo 488 | @echo "##################################" 489 | @echo "## 55: Common Lisp -> Crystal ##" 490 | @echo "##################################" 491 | @echo 492 | clisp QR.lisp > QR.cr 493 | 494 | QR.d: QR.cr 495 | @echo 496 | @echo "########################" 497 | @echo "## 56: Crystal -> D ##" 498 | @echo "########################" 499 | @echo 500 | crystal QR.cr > QR.d 501 | 502 | QR.dc: QR.d 503 | @echo 504 | @echo "###################" 505 | @echo "## 57: D -> dc ##" 506 | @echo "###################" 507 | @echo 508 | gdc -o QR QR.d 509 | ./QR > QR.dc 510 | 511 | QR.dhall: QR.dc 512 | @echo 513 | @echo "#######################" 514 | @echo "## 58: dc -> Dhall ##" 515 | @echo "#######################" 516 | @echo 517 | dc QR.dc > QR.dhall || true 518 | 519 | QR.exs: QR.dhall 520 | @echo 521 | @echo "###########################" 522 | @echo "## 59: Dhall -> Elixir ##" 523 | @echo "###########################" 524 | @echo 525 | dhall text --file QR.dhall > QR.exs 526 | 527 | QR.el: QR.exs 528 | @echo 529 | @echo "################################" 530 | @echo "## 60: Elixir -> Emacs Lisp ##" 531 | @echo "################################" 532 | @echo 533 | elixir QR.exs > QR.el 534 | 535 | QR.erl: QR.el 536 | @echo 537 | @echo "################################" 538 | @echo "## 61: Emacs Lisp -> Erlang ##" 539 | @echo "################################" 540 | @echo 541 | emacs -Q --script QR.el > QR.erl 542 | 543 | QR.e: QR.erl 544 | @echo 545 | @echo "##############################" 546 | @echo "## 62: Erlang -> Execline ##" 547 | @echo "##############################" 548 | @echo 549 | escript QR.erl > QR.e 550 | 551 | QR.fsx: QR.e 552 | @echo 553 | @echo "##########################" 554 | @echo "## 63: Execline -> F# ##" 555 | @echo "##########################" 556 | @echo 557 | execlineb QR.e > QR.fsx 558 | 559 | QR.false: QR.fsx 560 | @echo 561 | @echo "#######################" 562 | @echo "## 64: F# -> FALSE ##" 563 | @echo "#######################" 564 | @echo 565 | echo 'Exenet8.0false' > tmp.fsproj 566 | DOTNET_NOLOGO=1 dotnet run --project tmp.fsproj > QR.false 567 | 568 | QR.fl: QR.false 569 | @echo 570 | @echo "#########################" 571 | @echo "## 65: FALSE -> Flex ##" 572 | @echo "#########################" 573 | @echo 574 | ruby vendor/false.rb QR.false > QR.fl 575 | 576 | QR.fish: QR.fl 577 | @echo 578 | @echo "########################" 579 | @echo "## 66: Flex -> Fish ##" 580 | @echo "########################" 581 | @echo 582 | flex -o QR.fl.c QR.fl 583 | gcc -o QR QR.fl.c 584 | ./QR > QR.fish 585 | 586 | QR.fs: QR.fish 587 | @echo 588 | @echo "#########################" 589 | @echo "## 67: Fish -> Forth ##" 590 | @echo "#########################" 591 | @echo 592 | fish QR.fish > QR.fs 593 | 594 | QR.f: QR.fs 595 | @echo 596 | @echo "##############################" 597 | @echo "## 68: Forth -> FORTRAN77 ##" 598 | @echo "##############################" 599 | @echo 600 | gforth QR.fs > QR.f 601 | 602 | QR.f90: QR.f 603 | @echo 604 | @echo "##################################" 605 | @echo "## 69: FORTRAN77 -> Fortran90 ##" 606 | @echo "##################################" 607 | @echo 608 | @mv QR.c QR.c.bak 609 | gfortran -o QR QR.f 610 | ./QR > QR.f90 611 | @mv QR.c.bak QR.c 612 | 613 | QR.gbs: QR.f90 614 | @echo 615 | @echo "######################################" 616 | @echo "## 70: Fortran90 -> Gambas script ##" 617 | @echo "######################################" 618 | @echo 619 | gfortran -o QR QR.f90 620 | ./QR > QR.gbs 621 | 622 | QR.g: QR.gbs 623 | @echo 624 | @echo "################################" 625 | @echo "## 71: Gambas script -> GAP ##" 626 | @echo "################################" 627 | @echo 628 | $(GBS) QR.gbs > QR.g 629 | 630 | QR.gdb: QR.g 631 | @echo 632 | @echo "######################" 633 | @echo "## 72: GAP -> GDB ##" 634 | @echo "######################" 635 | @echo 636 | gap -q QR.g > QR.gdb 637 | 638 | QR.gel: QR.gdb 639 | @echo 640 | @echo "###############################" 641 | @echo "## 73: GDB -> GEL (Genius) ##" 642 | @echo "###############################" 643 | @echo 644 | gdb -q -x QR.gdb > QR.gel 645 | 646 | QR.plt: QR.gel 647 | @echo 648 | @echo "###################################" 649 | @echo "## 74: GEL (Genius) -> Gnuplot ##" 650 | @echo "###################################" 651 | @echo 652 | genius QR.gel > QR.plt 653 | 654 | QR.go: QR.plt 655 | @echo 656 | @echo "#########################" 657 | @echo "## 75: Gnuplot -> Go ##" 658 | @echo "#########################" 659 | @echo 660 | gnuplot QR.plt > QR.go 661 | 662 | QR.gs: QR.go 663 | @echo 664 | @echo "############################" 665 | @echo "## 76: Go -> GolfScript ##" 666 | @echo "############################" 667 | @echo 668 | go run QR.go > QR.gs 669 | 670 | QR.gpt: QR.gs 671 | @echo 672 | @echo "####################################" 673 | @echo "## 77: GolfScript -> G-Portugol ##" 674 | @echo "####################################" 675 | @echo 676 | ruby vendor/golfscript.rb QR.gs > QR.gpt 677 | 678 | QR.grass: QR.gpt 679 | @echo 680 | @echo "###############################" 681 | @echo "## 78: G-Portugol -> Grass ##" 682 | @echo "###############################" 683 | @echo 684 | mv QR.c QR.c.bak 685 | gpt -t QR.c QR.gpt 686 | gcc -o QR QR.c 687 | ./QR > QR.grass 688 | mv QR.c.bak QR.c 689 | 690 | QR.groovy: QR.grass 691 | @echo 692 | @echo "###########################" 693 | @echo "## 79: Grass -> Groovy ##" 694 | @echo "###########################" 695 | @echo 696 | ruby vendor/grass.rb QR.grass > QR.groovy 697 | 698 | QR.gz: QR.groovy 699 | @echo 700 | @echo "##########################" 701 | @echo "## 80: Groovy -> Gzip ##" 702 | @echo "##########################" 703 | @echo 704 | groovy QR.groovy > QR.gz 705 | 706 | QR.hs: QR.gz 707 | @echo 708 | @echo "###########################" 709 | @echo "## 81: Gzip -> Haskell ##" 710 | @echo "###########################" 711 | @echo 712 | gzip -cd QR.gz > QR.hs 713 | 714 | QR.hx: QR.hs 715 | @echo 716 | @echo "###########################" 717 | @echo "## 82: Haskell -> Haxe ##" 718 | @echo "###########################" 719 | @echo 720 | rm -f QR.o 721 | ghc QR.hs 722 | ./QR > QR.hx 723 | 724 | QR.icn: QR.hx 725 | @echo 726 | @echo "########################" 727 | @echo "## 83: Haxe -> Icon ##" 728 | @echo "########################" 729 | @echo 730 | haxe -main QR -neko QR.n 731 | neko QR.n > QR.icn 732 | 733 | QR.i: QR.icn 734 | @echo 735 | @echo "############################" 736 | @echo "## 84: Icon -> INTERCAL ##" 737 | @echo "############################" 738 | @echo 739 | icont -s QR.icn 740 | ./QR > QR.i 741 | 742 | QR.j: QR.i 743 | @echo 744 | @echo "##############################" 745 | @echo "## 85: INTERCAL -> Jasmin ##" 746 | @echo "##############################" 747 | @echo 748 | @mv QR.c QR.c.bak 749 | ick -bfOc QR.i 750 | gcc -static QR.c -I /usr/include/ick-* -o QR -lick 751 | ./QR > QR.j 752 | @mv QR.c.bak QR.c 753 | 754 | QR.java: QR.j 755 | @echo 756 | @echo "##########################" 757 | @echo "## 86: Jasmin -> Java ##" 758 | @echo "##########################" 759 | @echo 760 | jasmin QR.j 761 | java QR > QR.java 762 | 763 | QR.js: QR.java 764 | @echo 765 | @echo "##############################" 766 | @echo "## 87: Java -> JavaScript ##" 767 | @echo "##############################" 768 | @echo 769 | javac QR.java 770 | java QR > QR.js 771 | 772 | QR.jq: QR.js 773 | @echo 774 | @echo "############################" 775 | @echo "## 88: JavaScript -> Jq ##" 776 | @echo "############################" 777 | @echo 778 | $(JAVASCRIPT) QR.js > QR.jq 779 | 780 | QR.jsfuck: QR.jq 781 | @echo 782 | @echo "########################" 783 | @echo "## 89: Jq -> JSFuck ##" 784 | @echo "########################" 785 | @echo 786 | jq -r -n -f QR.jq > QR.jsfuck 787 | 788 | QR.kt: QR.jsfuck 789 | @echo 790 | @echo "############################" 791 | @echo "## 90: JSFuck -> Kotlin ##" 792 | @echo "############################" 793 | @echo 794 | ulimit -s unlimited && $(JAVASCRIPT) --stack_size=100000 QR.jsfuck > QR.kt 795 | 796 | QR.ksh: QR.kt 797 | @echo 798 | @echo "#########################" 799 | @echo "## 91: Kotlin -> ksh ##" 800 | @echo "#########################" 801 | @echo 802 | kotlinc QR.kt -include-runtime -d QR.jar 803 | kotlin QR.jar > QR.ksh 804 | 805 | QR.lazy: QR.ksh 806 | @echo 807 | @echo "#########################" 808 | @echo "## 92: ksh -> Lazy K ##" 809 | @echo "#########################" 810 | @echo 811 | ksh QR.ksh > QR.lazy 812 | 813 | qr.li: QR.lazy 814 | @echo 815 | @echo "############################" 816 | @echo "## 93: Lazy K -> Lisaac ##" 817 | @echo "############################" 818 | @echo 819 | lazyk QR.lazy > qr.li 820 | 821 | QR.ls: qr.li 822 | @echo 823 | @echo "################################" 824 | @echo "## 94: Lisaac -> LiveScript ##" 825 | @echo "################################" 826 | @echo 827 | @mv QR.c QR.c.bak 828 | lisaac -gcc -Wno-implicit-function-declaration qr.li 829 | ./qr > QR.ls 830 | @mv QR.c.bak QR.c 831 | 832 | QR.ll: QR.ls 833 | @echo 834 | @echo "##################################" 835 | @echo "## 95: LiveScript -> LLVM asm ##" 836 | @echo "##################################" 837 | @echo 838 | lsc QR.ls > QR.ll 839 | 840 | QR.lol: QR.ll 841 | @echo 842 | @echo "###############################" 843 | @echo "## 96: LLVM asm -> LOLCODE ##" 844 | @echo "###############################" 845 | @echo 846 | @mv QR.bc QR.bc.bak 847 | llvm-as QR.ll 848 | lli QR.bc > QR.lol 849 | @mv QR.bc.bak QR.bc 850 | 851 | QR.lua: QR.lol 852 | @echo 853 | @echo "##########################" 854 | @echo "## 97: LOLCODE -> Lua ##" 855 | @echo "##########################" 856 | @echo 857 | lci QR.lol > QR.lua 858 | 859 | QR.m4: QR.lua 860 | @echo 861 | @echo "#####################" 862 | @echo "## 98: Lua -> M4 ##" 863 | @echo "#####################" 864 | @echo 865 | lua5.3 QR.lua > QR.m4 866 | 867 | QR.mk: QR.m4 868 | @echo 869 | @echo "##########################" 870 | @echo "## 99: M4 -> Makefile ##" 871 | @echo "##########################" 872 | @echo 873 | m4 QR.m4 > QR.mk 874 | 875 | QR.mzn: QR.mk 876 | @echo 877 | @echo "#################################" 878 | @echo "## 100: Makefile -> MiniZinc ##" 879 | @echo "#################################" 880 | @echo 881 | make -f QR.mk > QR.mzn 882 | 883 | QR.mod: QR.mzn 884 | @echo 885 | @echo "#################################" 886 | @echo "## 101: MiniZinc -> Modula-2 ##" 887 | @echo "#################################" 888 | @echo 889 | minizinc --solver COIN-BC --soln-sep '' QR.mzn > QR.mod 890 | 891 | QR.il: QR.mod 892 | @echo 893 | @echo "#############################" 894 | @echo "## 102: Modula-2 -> MSIL ##" 895 | @echo "#############################" 896 | @echo 897 | gm2 -fiso QR.mod -o QR 898 | ./QR > QR.il 899 | 900 | QR.mustache: QR.il 901 | @echo 902 | @echo "#############################" 903 | @echo "## 103: MSIL -> Mustache ##" 904 | @echo "#############################" 905 | @echo 906 | ilasm QR.il 907 | mono QR.exe > QR.mustache 908 | 909 | QR.asm: QR.mustache 910 | @echo 911 | @echo "#############################" 912 | @echo "## 104: Mustache -> NASM ##" 913 | @echo "#############################" 914 | @echo 915 | mustache QR.mustache QR.mustache > QR.asm 916 | 917 | QR.neko: QR.asm 918 | @echo 919 | @echo "#########################" 920 | @echo "## 105: NASM -> Neko ##" 921 | @echo "#########################" 922 | @echo 923 | nasm -felf QR.asm 924 | ld -m elf_i386 -o QR QR.o 925 | ./QR > QR.neko 926 | 927 | QR.5c: QR.neko 928 | @echo 929 | @echo "###########################" 930 | @echo "## 106: Neko -> Nickle ##" 931 | @echo "###########################" 932 | @echo 933 | nekoc QR.neko 934 | neko QR.n > QR.5c 935 | 936 | QR.nim: QR.5c 937 | @echo 938 | @echo "##########################" 939 | @echo "## 107: Nickle -> Nim ##" 940 | @echo "##########################" 941 | @echo 942 | nickle QR.5c > QR.nim 943 | 944 | QR.m: QR.nim 945 | @echo 946 | @echo "###############################" 947 | @echo "## 108: Nim -> Objective-C ##" 948 | @echo "###############################" 949 | @echo 950 | nim compile QR.nim 951 | ./QR > QR.m 952 | 953 | QR.ml: QR.m 954 | @echo 955 | @echo "#################################" 956 | @echo "## 109: Objective-C -> OCaml ##" 957 | @echo "#################################" 958 | @echo 959 | gcc -o QR QR.m 960 | ./QR > QR.ml 961 | 962 | QR.octave: QR.ml 963 | @echo 964 | @echo "############################" 965 | @echo "## 110: OCaml -> Octave ##" 966 | @echo "############################" 967 | @echo 968 | ocaml QR.ml > QR.octave 969 | 970 | QR.ook: QR.octave 971 | @echo 972 | @echo "###########################" 973 | @echo "## 111: Octave -> Ook! ##" 974 | @echo "###########################" 975 | @echo 976 | mv QR.m QR.m.bak 977 | octave -qf QR.octave > QR.ook 978 | mv QR.m.bak QR.m 979 | 980 | QR.gp: QR.ook 981 | @echo 982 | @echo "############################" 983 | @echo "## 112: Ook! -> PARI/GP ##" 984 | @echo "############################" 985 | @echo 986 | ruby vendor/ook-to-bf.rb QR.ook QR.ook.bf 987 | ruby vendor/bf.rb QR.ook.bf > QR.gp 988 | 989 | QR.p: QR.gp 990 | @echo 991 | @echo "################################" 992 | @echo "## 113: PARI/GP -> Parser 3 ##" 993 | @echo "################################" 994 | @echo 995 | gp -f -q QR.gp > QR.p 996 | 997 | QR.pas: QR.p 998 | @echo 999 | @echo "###############################" 1000 | @echo "## 114: Parser 3 -> Pascal ##" 1001 | @echo "###############################" 1002 | @echo 1003 | parser3 QR.p > QR.pas 1004 | 1005 | QR.pl: QR.pas 1006 | @echo 1007 | @echo "#############################" 1008 | @echo "## 115: Pascal -> Perl 5 ##" 1009 | @echo "#############################" 1010 | @echo 1011 | fpc QR.pas 1012 | ./QR > QR.pl 1013 | 1014 | QR.pl6: QR.pl 1015 | @echo 1016 | @echo "#############################" 1017 | @echo "## 116: Perl 5 -> Perl 6 ##" 1018 | @echo "#############################" 1019 | @echo 1020 | perl QR.pl > QR.pl6 1021 | 1022 | QR.php: QR.pl6 1023 | @echo 1024 | @echo "##########################" 1025 | @echo "## 117: Perl 6 -> PHP ##" 1026 | @echo "##########################" 1027 | @echo 1028 | perl6 QR.pl6 > QR.php 1029 | 1030 | QR.png: QR.php 1031 | @echo 1032 | @echo "########################" 1033 | @echo "## 118: PHP -> Piet ##" 1034 | @echo "########################" 1035 | @echo 1036 | php QR.php > QR.png 1037 | 1038 | QR.pike: QR.png 1039 | @echo 1040 | @echo "#########################" 1041 | @echo "## 119: Piet -> Pike ##" 1042 | @echo "#########################" 1043 | @echo 1044 | npiet QR.png > QR.pike 1045 | 1046 | QR.ps: QR.pike 1047 | @echo 1048 | @echo "###############################" 1049 | @echo "## 120: Pike -> PostScript ##" 1050 | @echo "###############################" 1051 | @echo 1052 | pike QR.pike > QR.ps 1053 | 1054 | QR.prolog: QR.ps 1055 | @echo 1056 | @echo "#################################" 1057 | @echo "## 121: PostScript -> Prolog ##" 1058 | @echo "#################################" 1059 | @echo 1060 | gs -dNODISPLAY -q QR.ps > QR.prolog 1061 | 1062 | QR.pr: QR.prolog 1063 | @echo 1064 | @echo "#####################################" 1065 | @echo "## 122: Prolog -> Promela (Spin) ##" 1066 | @echo "#####################################" 1067 | @echo 1068 | swipl -q -t qr -f QR.prolog > QR.pr 1069 | 1070 | QR.py: QR.pr 1071 | @echo 1072 | @echo "#####################################" 1073 | @echo "## 123: Promela (Spin) -> Python ##" 1074 | @echo "#####################################" 1075 | @echo 1076 | spin -T QR.pr > QR.py 1077 | 1078 | QR.R: QR.py 1079 | @echo 1080 | @echo "########################" 1081 | @echo "## 124: Python -> R ##" 1082 | @echo "########################" 1083 | @echo 1084 | python3 QR.py > QR.R 1085 | 1086 | QR.ratfor: QR.R 1087 | @echo 1088 | @echo "########################" 1089 | @echo "## 125: R -> Ratfor ##" 1090 | @echo "########################" 1091 | @echo 1092 | R --slave -f QR.R > QR.ratfor 1093 | 1094 | QR.rc: QR.ratfor 1095 | @echo 1096 | @echo "#########################" 1097 | @echo "## 126: Ratfor -> rc ##" 1098 | @echo "#########################" 1099 | @echo 1100 | ratfor -o QR.ratfor.f QR.ratfor 1101 | gfortran -o QR QR.ratfor.f 1102 | ./QR > QR.rc 1103 | 1104 | QR.rexx: QR.rc 1105 | @echo 1106 | @echo "#######################" 1107 | @echo "## 127: rc -> REXX ##" 1108 | @echo "#######################" 1109 | @echo 1110 | rc QR.rc > QR.rexx 1111 | 1112 | QR2.rb: QR.rexx 1113 | @echo 1114 | @echo "#########################" 1115 | @echo "## 128: REXX -> Ruby ##" 1116 | @echo "#########################" 1117 | @echo 1118 | rexx ./QR.rexx > QR2.rb 1119 | 1120 | clean: 1121 | @mv QR.rb quine-relay.rb 1122 | rm -f qr QR qr.* QR.* QR2.rb *.class gst.im 1123 | @mv quine-relay.rb QR.rb 1124 | -------------------------------------------------------------------------------- /QR.rb: -------------------------------------------------------------------------------- 1 | eval$s=%q(eval(%w(B=92.chr;g=32.chr;puts(eval(%q(N=10.chr;n=0;e=->s{Q[Q[s,B],?"].K(N,B+?n)};E=->s{'("'+e[s]+'")'};d=->s,t=?"{s.K(t){t+t}};def~f(s,n)s.K(/.{1,#{n*255}}/m){yield$S=E[$s=$&]}end;Q=->s,t=?${s.K(t){B+$&}};R=";return~0;";V=->s,a,z{s.K(/( 2 | #{B*4})+/){a+"#{$&.size/2}"+z}};C=%w(System.Console~Write);$C=C*?.;$D="program~QR";$G="~contents~of"+$F="~the~mix!g~bowl";$L="public~static";$W="s.WriteByte";rp=->s,r{v="";[r.!ject(s){|s,j|o={};m=n=0;s.size.times{|i|o[f=s[i,2]]||=0;c=o[f]+=1;m(p(3+ord~c);Z"-1~0~";c))#{E[~~~~~~%(object"Application"{state"ma!"{foreach(s~![#{f(%(puts~"#{Q[e[%(echo~'a::=`x7e#{Q[Q["let~s=#{E[%(void~p(!t[]c){foreach(!t~v~!~c)stdout.Zf("%c%c",v/25 6 | 6,v%256);}void~mX{!t[]a;p({19796,26724,0,6,0,1,480,19796,29291,#{s=%(module~QR;!itial~beg!~#{f((%(Module~QR`nSub~MX`nDim~c,n:Dim~s~As~Object=#{C[0]}.OpenStandardOutput():Dim~t()As~Short={26,34,86,127,148,158,200}:For~Each~d~!"BasmCBBBCRE`x60F<<<D`x21BE@ABRCABRCABRCA`x4a`x21CE@~B-BB~CACk:CvACqRC~COBMADRCACRCADRCABRCABRC~BACj:B-BBOBMADRCADRCADRCAFRCMM}CBABM`x7e#{40.chr 8 | }BBBCBBB,BBBDBBB0BBBDBBB4BBB=BBB?BBB;BBB~...^t..^n..(module(import~:wasi_snapshot_preview1:~:fd_H:~(func(param~i32~i32~i32~i32)(result~i32)))(memory(export~:memory:)(data~:^08^00^00^00$:))(func(export~:_start:)i32.const~1~i32.const~0~i32.const~1~i 9 | 32.const~0~call~0~drop))":c=Asc(d):If~c=36:For~c=0To~11:#$W(If(c~Mod~3,Asc(#{s="<#{U="xsl:template"}~match='/'><`x21[CDATA[#{%(sub~f(s$ ,n)Z(s$); :for~i=1to~n~Z("Y");:next:end~sub:f("#{V[e[%(H,format="#{y="";f("^H{-}{txt}{#{Q["echo~-E~$'#{Q[Q[E[%(with~Ada.Text_Io;procedure~qr~is~beg!~Ada.Text_Io.Put("#{d[%(trans~B(Buf 11 | fer)`ntrans~O(n){`nB:add(Byte(+~128~n))}`ntrans~f(v ~n){`n O(+( /~n~64)1 07)`nO(n:mod~64)`nO~v}`ntrans~D(n){if(<~n~4){f(+(*~6~n)9)48}{if(n:odd-p){D(-~n~3)`nf~27~48`nf~36~11}{D(/~n~2)`nf~21~48`nf~48~20}}}`ntrans~S(Buffer"#{e[%W[STRINGz: 12 | =~226+~153,a:=z+~166,b:=a+"2"+z+~160,c:=b+"8"+z+~ 165 , t:="#{d[%(class~QR{#$L~void~ma!(SJ[]a){a=#{E["H('#{Q[e["implement~ma!0()=Z"+E["BEGIN {Z#{E[%(echo~'#{%(f(s){System.out.Z(s);}s="389**6+44*6+00p45*," 13 | ;for(c:#{E[(s="#!clude`n!t~mX{std::co ut <<#{E[%(class~Program{#$L~void~MX{#$C("Qu!e~Relay~Coffee.^n^nIn gredients.^n");for(!t~i=9;i++<126;)#$C($"{i}~g~caffe!e~ 14 | {i}^n");#$C("^nMethod.^n");foreach(char~c~!#{ E[%((doseq[s(lazy-cat["IDENTIFICATION~DIVISION.""PROGRAM-ID. ~QR.""PROCEDURE~DIVISION."'DISPLA`x59](map~#(str"~ 15 | ~~~^""(.replace~%1"^"""^"^"")"^"")(re-seq~#" .{1,45}""#{e["(f=(n)->Array(n+1).jo!~'Y');console .log('%s',#{V[E[%((H-l!e"#{e["puts#{E["import~ 16 | std.stdio;void~mX{H(`x60#{"['']p[#{"IO.puts "+E[%((pr!c~"#{e["`nma!(_)->`nio:fH#{d[E[% (echo~"#{e['Zfn("""'+d[?"+"%option~noyywrap 17 | `n%%`n%%`n!t~mX{puts#{E["echo~'#{Q[Q[%(~: ~A~."#{g*9}"~;~:~B~A~."~WRITE(*,*)'"~A~;~ :~C~B~T`x59PE~."~'"~CR~;~:~D~S"~#$D"~C~S 18 | ^"~Z~^"(&"~C~S^"~#{e[%(Z"#{e["s:=Output Text User();WriteAll(s,#{E[%(Zf"#{e[d[f ('set~Z"-";Z'+ E[%(package~ma!;import"fmt";func~mX{f 19 | mt.Pr!t#{E[%(236:j;{119:i;{206i-:i;.48 <{71+ }{[i]^48-*}if}%}:t;"algoritm o~QR;!"[195][173]++'cio~impr ima("'"013141"t"/12131"t~6*"/1:19181 20 | 51:??6271413/4=3626612/2/353251215/`x 5a0` x5a0R"t"#{e[%(z=new~java.ut il.zip.G`x5aIPOutputStream(System.out) ;z.H('#{"ma!=putStr"+E["class~QR{# 21 | $L~function~mX{neko.Lib.Z#{E[%(proced ure~mX;i:=c:=0;s:=#{E[ %(.class~public~QR`n.s uper~#{$T="java/io/Pr!tStream"}`n.method~#$L ~ma!([L#{S="java/lang/S"}J;)V~;] 22 | `n.limit~stack~2`ngetstatic~#{S}ystem /out ~L#$T;`nldc~"#{e[%(class~QR{#$L~vo id~ma!(SJ[]v){SJ~ c[]=new~SJ[99999],y="",z=y,s="#{z=t=(0..r=q=126).m ap{|n|[n,[]]};a="";b=->n{a<<(n% 23 | 78+55)%84+42};(%(P={0:'[+[]]',m:'((+[]) '+(C="['constructor']")+"+[])['11']"};for(R~!~B=( '`x21[]@`x21` x21[]@[][[]]@'+(A="[]['fill']")+"@([]+[])['fontcolor'] ([])@(+('11e20')+[])['split'] 24 | ([])@"+A+C+"('return~escape')()("+A+ ')').split('@'))for(E~!~D=eval(G='('+B[R]+'+[])'))P [T=D[E]]=P[T ]||G+"['"+E+"']";for(G='[',B=0;++B<36;)P[D=B.toSJ(36)]=B<1 0?(G+='+`x21+[]')+']':P[D]|| 25 | "(+('"+B+"'))['to'+([]+[])"+C+"[' name']]('36')";A+=C+"('console.log(unescape(^"";for(E~!~ G=#{E["f un~ma!(a:Array){Z#{Q[E[%(s=();a(){~s+=($(echo~-n~$1|od~-A n~-tu1~-v)~$2);};a~"Section 26 | `x48eader+name:=QR;SectionPublic -ma!<-("~10;t='#{"console.log"+Q[E[%(@s=global[#{i=(s=%(`x48 AI~1 .2`nVISIBLE~"#{"x=sJ.K(#{V[E["changequote(<@,@>)`ndef!e(p,<@#{"al l:`n`t@echo~'#{d["solve~sa 27 | tisfy;output~[#{E["MODULE~QR;F ROM~StrIO~IMPORT~WriteSJ;BEGIN~#{(%(.assembly~t{}.method~#$L~vo id ~MX{.entrypo!t~ldstr"#{e["m{{`x21:~x`nqr:~|-`n~:db`x60#{e[s="$Z#{E["Zf#{E["echo #{E["#import#{N}! 28 | t~mX{puts#{E["Z_sJ"+E["s=dou ble#{E["Z#{E["$console:l!e[#{"#$D(output);beg!~H(#{f((p="eval";%($_ ="#{s, v=rp["$_='#{Q[%($z)&&$i/$z<($c<$w ?ord($s[(!t)($c/3)]):$c- 31 | -%3+2)?$t[2].$t[$c%3%2].$ t[$c%3]:"^0^0^0":"^0")$c=$i%$z;foreach(array("I`x48DR".pack("NNCV",$w+2,128 ,8,2),"IDAT".gzcompress($m),"IEND")as$d)e cho~pack("NA*N",strlen($ 32 | d)-4,$d,crc32($d));).K(B, "`x7f"),?']}';s:g/^x7f/Y/;Z~$_",128..287];s="$_='#{Q[s,c=/['Y]/]}';$n=32;$s= '#{Q[v,c]}';$s=`x7es{..}{$a=$&;$b=chr (--$n&255);`x7es/$b/$a/g 33 | ;}eg;Z";(s+N*(-s.size%6) ).unpack("B*")[0].K(/.{6}/){n=$&.to_i~2;((n+14)/26*6+n+47).chr}}";s|.|$n=ord$&; substr~unpack(B8,chr$n-!t($n/32)*6 -41),2|eg;eval~pack'B*' 34 | ,$_).scan(/[~,-:A-z]+|(. )/){p="s++#{$1?"chr~#{$1.ord}+e":$&+?+};"+p};p),1){"'#$s',"}}'')end.".K(/[:;()]/ ){?`x5e+$&}}]"]};quit"]};t=num2 cell(b=11-ceil(s/13));f 35 | or~n=1:9m={};for~i=1:14 1f=@(x,y,n)repmat(['Ook'~char(x)~'~Ook'~char(y)~'~'],[1~abs(n)]);m(i)=[f(z=46,63,n )~f(q=z-(i<13)*13,q,i-13)~f (33,z,1)~f(63,z,n)];end 36 | ;t(x=b==n)=m(diff([0~s( x)])+13);end;Zf('%%s',t{:})"]]+R}}"]}"]}`n"]};"]}`x60`n~global~_start`n~_start:mov~ edx,#{s.size}`n~mov~ecx, m`n~mov~ebx,1`n~mov~eax, 37 | 4`n~!t~128`n~mov~ebx,0` n~mov~eax,1`n~!t~128`nx:~|`n~}}{{{qr}}}"]}"call~void~[mscorlib]#{C*"::"}(sJ)ret})) . K(/()[#{i=94.chr}"]+| [#{i}']+/){["WriteSJ(",$ 38 | &,");"]*($1??":?')}}END ~QR."]}];",?$].K(?'){"'^''"}}'"}@>)`np"],?&,?&]},'&(%d+)&',function(s)return~sJ. re p('Y',tonu mber (s))end);Z(x)".K(/ [:"]/,":^0")}"`n`x4bT`x4 39 | 8`x58B`x59E~B`x59E)).si ze+1}x~i8]c"#{s.K(/[^"`n`t]/){"^%02`x58"%$&.ord}}^00"declare~i32@puts(i8*)def!e ~ i32@mX{%1=cal l~i32@puts( i8*getelementpt r([#{i}x~i8],[#{i}x~i8]*@ 40 | s,i32~0,i32~0))ret~i32~0 })],?#].K(?',%('"'"'))}';for((i=0;i<${#t};i+=99));do;x=${t:$i:99};a~"^"${x//[ Y ^`"]/Y^0}^".Z; "~10;done;a~") ;";p( ){~echo~-n~$ 1;};f(){~for~x~!~${s[*]}; 41 | do;p~$3;for((j=$2;j--;)) ;do;h~$1~$x~$j;done;done;};p~k^`x60;h(){~p~^`x60${1:$(($2>>$3&1)):2};};f~k ki ~7~'`x60`x60s`x60`x60s`x60`x60s `x60`x60s`x6 0`x60s`x6 0`x60s`x60`x60s`x60`x60si' 42 | ;s=();a~'AG-`x48-`x48Fy.I lD==;=jdlAy=;=jldltldltl{lAulAy=jtlldlAyFy=?=jdlAyGFyFyG2AFy>zlAFFBCjldG yGFy >GFy.AGy=G==n`x48==nlldC=j@=jtll dltldlAut11';h() {~p~${ 1:$(((($2%83-10)>>((2-$3)*2 43 | ))%4)):1};};f~ski^`x60~3)] ]}~}"]})A+="'+`x21[]+'"+G.charCodeAt(E).toSJ(16);for(A+="^".replace(/ '+`x21[] +'/g,^"%^")))')()",R=0;R<9;R++)A =A.replace(/'.*?'/g ,fu nction(B){T=[];for(E=1;B[E+1 44 | ];)T.push(P[B[E++]]);retur n~T.jo!('+')});console.log('"'+A+'"'))).bytes{|n|r,z=z[n]||(b[r/78 ];b[r];q<6 083&&z[n]=[q+=1,[]];t[n])};b[r/78];b[r]}";!t~i=0,n=0 , q=0;for(;++n<126;)c[n]=""+(ch 45 | ar)n;for(;i<#{a.size};){q=q *78+(s.charAt(i)-13)%84;if(i++%2>0){y=qn{L<<(n+62)% 92+35;D};s.bytes{|c|n>0?n-=1:(t[c]=(t[c]||[] ).reject{|j|j4& &x<<[k,j]};x=x.max)?(n,j=x;x=b.size;(u=[x,3999].m! ;D[u%87][u/87];L<0;x=4001+i-j;D[x%87][x/87][n-5]):b<`nchar*p=#{E[L]},s[999999],*q=s; !t~mX{!t~n,m;for(;*p;){n=(*p-5)%92+(p[1]-5)%92*87;p 55 | +=2;if(n>3999)for(m=(*p++-5)%92+6;m--;q++)*q=q[400 0-n];else~for(;n--;)*q++=*p++;}puts(s)#{R}}")]}){s+="00g,";for(m= 1;m<256;m*=2)s+="00g,4,:"+(c/m%2>0?"4+":"")+",";f(s);s= 56 | "4,:,";}f(s+s);for(c:Base64.getDecoder().decode("kaARERE `x58/I0ALn3n5ef6l/Pz8+fnz58/BOf5/7/hE`x58/O`x5azM5mC`x58/Oczm`x5azBPn5+`x58/Ocz MznBL/nM5m`x5azBPu++fPPOc5zngnnO`x5azO`x5agnBMGAW7A==")){c=c<0 57 | ?256+c:c;for(i=0;i++<3;c/=8)f(c%8);f("8*+8*+,");}f("@");).K(?',%('"'"'))}'|sed~-e's/Y/YY/g'~-e's/"/Yq/g'~-e's/.*/Z~"&"^nquit/')]}}"]],?']}');".K(/^+/){"`x5e#{$&.size}`x5e"}]}.split("Y`x5e");for(!t~i=1;i#{U}>";s.size*16+3}.ToSJ("x8")(1`x58or~7-c*2^3)),92)) 60 | :Next:Else:n=(c>124)*(8*c-#{s.size+1294}):Do~While~n>127:#$W(128+(127And~n)):n^=128:Loop:#$W(If(c<125,If((c-1)^7-8,c+66*(c>65And~c<91),t(c-57)),n)):End~If:Next:For~Each~c~!"#{d[s].K~N,'"&~VbLf~&"'}":#$W(Asc(c)):Next:End~Sub:End~Module)).l!es.map{| 61 | s|"let~s=#{E[s]}`nput=s`nZ`n"}.jo!+"qa`x21",3){%($H("%s",#$S);)+N}}end~endmodule);W=s.size*72+4;"%d,%d"%[W/65536,W%65536]}});foreach(!t~c~!#{E[s]}.data)foreach(!t~v~!~a={0,9,7,4,5,c/100*7/6+1,c%100/10*7/6+1,c%10*7/6+1,7})p({144,v=15450+v*256,384,v 62 | });p({255,12032});})]},i=0,t='k';while(s[i])t='^x60.'+s[i++]+t;console.log(t)",B],?`x21].K(?',%('"'"'))}'"^n::=^na")],/[`[`]$]/]}"),4){$S+?,}}])Console.H(s);Application.exit();}})]};Z"0~0~-1");)],127..255];f(%(variable~s=`x60#{s.K(/.{1,234}/){$&.K 63 | ("`x60",%(`x60+"`x60"+`x60))+"`x60+`n`x60"}}`x60,i;for(i=0;i<129;i++)s=strreplace(s,pack("C",255-i),substrbytes(`x60#{v[0,99]}`x60+`n`x60#{v[99..-1]}`x60,i*2+1,2));Zf("%s",s)),7){"f('%s')`n"%$s.unpack("`x48*")}}Zf("^n#[Exeunt]");quit)]}")),196){%( 64 | Z#$S;)}}}"]});})).gsub(/[!HJKXYZ^`~]/){[B*2,:write,B,:tring,:gsub,"ain()",B*4,:print,g,:in][$&.ord%47%12]})))*"")#_buffer_for_future_bug_fixes_#_buffer_for_future_bug_fixes_#_buffer_for_future_bug_fixes_#_buffer_for_future_bug_fixes_#_buffer_for_f 65 | #################################################################################### Quine Relay -- Copyright (c) 2013, 2014 Yusuke Endoh (@mametter), @hirekoke ###################################################################################) 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Quine Relay 2 | 3 | [](https://github.com/mame/quine-relay/actions?query=workflow%3ACI) 4 | 5 | ## What this is 6 | 7 | [QR.rb](https://github.com/mame/quine-relay/blob/master/QR.rb) is a Ruby program that generates 8 | a Rust program that generates 9 | a Scala program that generates 10 | ...(through 128 languages in total)... 11 | a REXX program that generates 12 | the original Ruby code again. 13 | 14 | ![Language Uroboros][langs] 15 | 16 | [langs]: langs.png 17 | 18 | (If you want to see the old 50-language version, see the [50](https://github.com/mame/quine-relay/tree/50) branch.) 19 | 20 | ## Usage 21 | 22 | ### Ubuntu 23 | 24 | If you are using Ubuntu 25.04 (Plucky Puffin), you can follow these steps. 25 | 26 | #### 1. Install all the interpreters/compilers. 27 | 28 | First, you need to type the following apt-get command to install them all. 29 | 30 | $ sudo apt-get install afnix algol68g aplus-fsf aspectj asymptote \ 31 | ats2-lang bash bc bsh clisp clojure cmake coffeescript crystal dc \ 32 | dhall dotnet8 elixir emacs-nox erlang execline f2c fish flex \ 33 | fp-compiler g++ gambas3-gb-pcre gambas3-scripter gap gawk gcc gdb gdc \ 34 | genius gforth gfortran ghc ghostscript gm2 gnat gnucobol4 gnuplot \ 35 | gobjc golang gpt groovy guile-3.0 gzip haxe icont iconx intercal \ 36 | iverilog jasmin-sable jq kotlin ksh libevent-dev libpolyml-dev lisaac \ 37 | livescript llvm lua5.3 m4 make minizinc mono-devel nasm neko nickle \ 38 | nim node-typescript nodejs ocaml octave openjdk-11-jdk pari-gp \ 39 | parser3-cgi perl php-cli pike8.0 polyml python3 r-base rakudo ratfor \ 40 | rc regina-rexx ruby ruby-mustache rustc scala scilab-cli sed slsh spin \ 41 | squirrel3 surgescript swi-prolog tcl tcsh valac vim wabt xsltproc \ 42 | yabasic yorick zoem zsh 43 | 44 | Then, build the bundled interpreters. 45 | 46 | $ sudo apt-get install cmake libpng-dev libgd-dev groff bison curl 47 | $ make -C vendor 48 | 49 | #### 2. Run each program on each interpreter/compiler. 50 | 51 | $ ulimit -s unlimited 52 | $ ruby QR.rb > QR.rs 53 | $ rustc QR.rs && ./QR > QR.scala 54 | $ scalac QR.scala && scala QR > QR.scm 55 | $ guile QR.scm > QR.sci 56 | $ scilab-cli -nb -f QR.sci > QR.sed 57 | $ sed -E -f QR.sed QR.sed > QR.spl 58 | $ spl2c < QR.spl > QR.spl.c && gcc -z muldefs -o QR -I ./vendor/local/include -L ./vendor/local/lib QR.spl.c -lspl -lm && 59 | ./QR > QR.sl 60 | $ slsh QR.sl > QR.nut 61 | $ squirrel QR.nut > QR.sml 62 | $ polyc -o QR QR.sml && ./QR > QR.sq 63 | $ ruby vendor/subleq.rb QR.sq > QR.ss 64 | $ surgescript QR.ss > QR.tcl 65 | $ tclsh QR.tcl > QR.tcsh 66 | $ tcsh QR.tcsh > QR.t 67 | $ ruby vendor/thue.rb QR.t > QR.ts 68 | $ tsc --outFile QR.ts.js QR.ts && nodejs QR.ts.js > QR.unl 69 | $ ruby vendor/unlambda.rb QR.unl > QR.vala 70 | $ valac QR.vala && ./QR > QR.mid 71 | $ mono vendor/local/bin/Vlt.exe /s QR.mid && mono QR.exe > QR.v 72 | $ iverilog -o QR QR.v && ./QR -vcd-none > QR.vim 73 | $ vim -EsS QR.vim > QR.vb 74 | $ echo 'Exenet8.0false' > tmp.vbproj && 75 | DOTNET_NOLOGO=1 dotnet run --project tmp.vbproj > QR.wasm 76 | $ $(WASI_RUNTIME) QR.wasm > QR.wat 77 | $ wat2wasm QR.wat -o QR.wat.wasm && $(WASI_RUNTIME) QR.wat.wasm > QR.ws 78 | $ ruby vendor/whitespace.rb QR.ws > QR.xslt 79 | $ xsltproc QR.xslt > QR.yab 80 | $ yabasic QR.yab > QR.yorick 81 | $ yorick -batch QR.yorick > QR.azm 82 | $ zoem -i QR.azm > QR.zsh 83 | $ zsh QR.zsh > QR.+ 84 | $ a+ QR.+ > qr.adb 85 | $ gnatmake qr.adb && ./qr > QR.als 86 | $ LANG=C LD_LIBRARY_PATH=/usr/lib/afnix axi QR.als > QR.aheui 87 | $ ruby vendor/aheui.rb QR.aheui > QR.a68 88 | $ a68g QR.a68 > QR.ante 89 | $ ruby vendor/ante.rb QR.ante > QR.aj 90 | $ ajc QR.aj && java QR > QR.asy 91 | $ asy QR.asy > QR.dats 92 | $ patscc -o QR QR.dats && ./QR > QR.awk 93 | $ awk -f QR.awk > QR.bash 94 | $ bash QR.bash > QR.bc 95 | $ BC_LINE_LENGTH=4000000 bc -q QR.bc > QR.bsh 96 | $ bsh QR.bsh > QR.bef 97 | $ cfunge QR.bef > QR.Blc 98 | $ ruby vendor/blc.rb < QR.Blc > QR.bf 99 | $ ruby vendor/bf.rb QR.bf > QR.c 100 | $ gcc -o QR QR.c && ./QR > QR.cpp 101 | $ g++ -o QR QR.cpp && ./QR > QR.cs 102 | $ echo 'Exenet8.0false' > tmp.csproj && 103 | DOTNET_NOLOGO=1 dotnet run --project tmp.csproj > QR.chef 104 | $ PERL5LIB=vendor/local/lib/perl5 compilechef QR.chef QR.chef.pl && 105 | perl QR.chef.pl > QR.clj 106 | $ clojure QR.clj > QR.cmake 107 | $ cmake -P QR.cmake > QR.cob 108 | $ cobc -O2 -x QR.cob && ./QR > QR.coffee 109 | $ coffee --nodejs --stack_size=100000 QR.coffee > QR.lisp 110 | $ clisp QR.lisp > QR.cr 111 | $ crystal QR.cr > QR.d 112 | $ gdc -o QR QR.d && ./QR > QR.dc 113 | $ dc QR.dc > QR.dhall || true 114 | $ dhall text --file QR.dhall > QR.exs 115 | $ elixir QR.exs > QR.el 116 | $ emacs -Q --script QR.el > QR.erl 117 | $ escript QR.erl > QR.e 118 | $ execlineb QR.e > QR.fsx 119 | $ echo 'Exenet8.0false' > tmp.fsproj && 120 | DOTNET_NOLOGO=1 dotnet run --project tmp.fsproj > QR.false 121 | $ ruby vendor/false.rb QR.false > QR.fl 122 | $ flex -o QR.fl.c QR.fl && gcc -o QR QR.fl.c && ./QR > QR.fish 123 | $ fish QR.fish > QR.fs 124 | $ gforth QR.fs > QR.f 125 | $ gfortran -o QR QR.f && ./QR > QR.f90 126 | $ gfortran -o QR QR.f90 && ./QR > QR.gbs 127 | $ gbs3 QR.gbs > QR.g 128 | $ gap -q QR.g > QR.gdb 129 | $ gdb -q -x QR.gdb > QR.gel 130 | $ genius QR.gel > QR.plt 131 | $ gnuplot QR.plt > QR.go 132 | $ go run QR.go > QR.gs 133 | $ ruby vendor/golfscript.rb QR.gs > QR.gpt 134 | $ mv QR.c QR.c.bak && gpt -t QR.c QR.gpt && gcc -o QR QR.c && ./QR > QR.grass && 135 | mv QR.c.bak QR.c 136 | $ ruby vendor/grass.rb QR.grass > QR.groovy 137 | $ groovy QR.groovy > QR.gz 138 | $ gzip -cd QR.gz > QR.hs 139 | $ rm -f QR.o && ghc QR.hs && ./QR > QR.hx 140 | $ haxe -main QR -neko QR.n && neko QR.n > QR.icn 141 | $ icont -s QR.icn && ./QR > QR.i 142 | $ ick -bfOc QR.i && gcc -static QR.c -I /usr/include/ick-* -o QR -lick && 143 | ./QR > QR.j 144 | $ jasmin QR.j && java QR > QR.java 145 | $ javac QR.java && java QR > QR.js 146 | $ nodejs QR.js > QR.jq 147 | $ jq -r -n -f QR.jq > QR.jsfuck 148 | $ nodejs --stack_size=100000 QR.jsfuck > QR.kt 149 | $ kotlinc QR.kt -include-runtime -d QR.jar && kotlin QR.jar > QR.ksh 150 | $ ksh QR.ksh > QR.lazy 151 | $ lazyk QR.lazy > qr.li 152 | $ lisaac -gcc -Wno-implicit-function-declaration qr.li && ./qr > QR.ls 153 | $ lsc QR.ls > QR.ll 154 | $ llvm-as QR.ll && lli QR.bc > QR.lol 155 | $ lci QR.lol > QR.lua 156 | $ lua5.3 QR.lua > QR.m4 157 | $ m4 QR.m4 > QR.mk 158 | $ make -f QR.mk > QR.mzn 159 | $ minizinc --solver COIN-BC --soln-sep '' QR.mzn > QR.mod 160 | $ gm2 -fiso QR.mod -o QR && ./QR > QR.il 161 | $ ilasm QR.il && mono QR.exe > QR.mustache 162 | $ mustache QR.mustache QR.mustache > QR.asm 163 | $ nasm -felf QR.asm && ld -m elf_i386 -o QR QR.o && ./QR > QR.neko 164 | $ nekoc QR.neko && neko QR.n > QR.5c 165 | $ nickle QR.5c > QR.nim 166 | $ nim compile QR.nim && ./QR > QR.m 167 | $ gcc -o QR QR.m && ./QR > QR.ml 168 | $ ocaml QR.ml > QR.octave 169 | $ mv QR.m QR.m.bak && octave -qf QR.octave > QR.ook && mv QR.m.bak QR.m 170 | $ ruby vendor/ook-to-bf.rb QR.ook QR.ook.bf && ruby vendor/bf.rb QR.ook.bf > QR.gp 171 | $ gp -f -q QR.gp > QR.p 172 | $ parser3 QR.p > QR.pas 173 | $ fpc QR.pas && ./QR > QR.pl 174 | $ perl QR.pl > QR.pl6 175 | $ perl6 QR.pl6 > QR.php 176 | $ php QR.php > QR.png 177 | $ npiet QR.png > QR.pike 178 | $ pike QR.pike > QR.ps 179 | $ gs -dNODISPLAY -q QR.ps > QR.prolog 180 | $ swipl -q -t qr -f QR.prolog > QR.pr 181 | $ spin -T QR.pr > QR.py 182 | $ python3 QR.py > QR.R 183 | $ R --slave -f QR.R > QR.ratfor 184 | $ ratfor -o QR.ratfor.f QR.ratfor && gfortran -o QR QR.ratfor.f && 185 | ./QR > QR.rc 186 | $ rc QR.rc > QR.rexx 187 | $ rexx ./QR.rexx > QR2.rb 188 | 189 | You will see that `QR.rb` is the same as `QR2.rb`. 190 | 191 | $ diff QR.rb QR2.rb 192 | 193 | Alternatively, just type `make`. 194 | 195 | $ make 196 | 197 | Note: It may take a lot of memory to compile some files. 198 | 199 | ### Docker 200 | 201 | Simply build the image and run a container as follows: 202 | 203 | $ docker build -t qr . 204 | $ docker run --privileged --rm -e CI=true qr 205 | 206 | Note: You must run in privileged mode, otherwise the `maxima` command will fail. 207 | 208 | If you want to check the generated files, you can mount the local directory in the Docker container (but still use the `vendor` directory of the container), as follows: 209 | 210 | $ docker run --privileged --rm -e CI=true -v $(pwd):/usr/local/share/quine-relay -v /usr/local/share/quine-relay/vendor qr 211 | 212 | ### Other platforms 213 | 214 | You may find [instructions for other platforms in the wiki](https://github.com/mame/quine-relay/wiki/Installation). 215 | 216 | If you do not use these Linux distributions, please find your own way. 217 | If you manage it, please let me know. I wish you good luck. 218 | 219 | ## Interpreter/compiler versions tested 220 | 221 | I used the following Ubuntu deb packages to test this program. 222 | 223 | \# |language |ubuntu package |version 224 | ----|----------------------------|----------------------------------|--------------------------------- 225 | 1 |Ruby |ruby |1:3.3\~ubuntu3 226 | 2 |Rust |rustc |1.84.0ubuntu1 227 | 3 |Scala |scala |2.11.12-6 228 | 4 |Scheme |guile-3.0 |3.0.10+really3.0.10-4 229 | 5 |Scilab |scilab-cli |2024.1.0+dfsg-6build5 230 | 6 |sed |sed |4.9-2build1 231 | 7 |Shakespeare |*N/A* |- 232 | 8 |S-Lang |slsh |2.3.3-5 233 | 9 |Squirrel |squirrel3 |3.1-8.2 234 | 10 |Standard ML |polyml, libpolyml-dev |5.7.1-5build1 235 | 11 |Subleq |*N/A* |- 236 | 12 |SurgeScript |surgescript |0.5.4.4-1.1 237 | 13 |Tcl |tcl |8.6.14build1 238 | 14 |tcsh |tcsh |6.24.13-2 239 | 15 |Thue |*N/A* |- 240 | 16 |TypeScript |node-typescript |4.9.5+ds1-2 241 | 17 |Unlambda |*N/A* |- 242 | 18 |Vala |valac |0.56.18-2 243 | 19 |Velato |*N/A* |- 244 | 20 |Verilog |iverilog |12.0-2build2 245 | 21 |Vimscript |vim |2:9.1.0967-1ubuntu4 246 | 22 |Visual Basic |dotnet8 |8.0.115-8.0.15-0ubuntu1 247 | 23 |WebAssembly (Binary format) |wabt |1.0.34+dsfg2+\~cs1.0.32-1ubuntu2 248 | 24 |WebAssembly (Text format) |wabt |1.0.34+dsfg2+\~cs1.0.32-1ubuntu2 249 | 25 |Whitespace |*N/A* |- 250 | 26 |XSLT |xsltproc |1.1.39-0exp1ubuntu4 251 | 27 |Yabasic |yabasic |1:2.91.1-1 252 | 28 |Yorick |yorick |2.2.04+dfsg1-14 253 | 29 |Zoem |zoem |21-341-1 254 | 30 |zsh |zsh |5.9-6ubuntu3 255 | 31 |A+ |aplus-fsf |4.22.1-13 256 | 32 |Ada |gnat |14.1ubuntu1 257 | 33 |AFNIX |afnix |3.8.0-1.1ubuntu1 258 | 34 |Aheui |*N/A* |- 259 | 35 |ALGOL 68 |algol68g |3.1.2-1 260 | 36 |Ante |*N/A* |- 261 | 37 |AspectJ |aspectj |1.9.6-1 262 | 38 |Asymptote |asymptote |2.95+ds-1 263 | 39 |ATS |ats2-lang |0.4.2-3 264 | 40 |Awk |gawk |1:5.2.1-2build3 265 | 41 |bash |bash |5.2.37-1.1ubuntu1 266 | 42 |bc |bc |1.07.1-4 267 | 43 |BeanShell |bsh |2.0b4-20 268 | 44 |Befunge |*N/A* |- 269 | 45 |BLC8 |*N/A* |- 270 | 46 |Brainfuck |*N/A* |- 271 | 47 |C |gcc |4:14.2.0-1ubuntu1 272 | 48 |C++ |g++ |4:14.2.0-1ubuntu1 273 | 49 |C# |dotnet8 |8.0.115-8.0.15-0ubuntu1 274 | 50 |Chef |*N/A* |- 275 | 51 |Clojure |clojure |1.12.0-1 276 | 52 |CMake |cmake |3.31.6-1ubuntu1 277 | 53 |Cobol |gnucobol4 |4.0\~early\~20200606-7 278 | 54 |CoffeeScript |coffeescript |2.7.0+dfsg1-2 279 | 55 |Common Lisp |clisp |1:2.49.20241123.git9ff8aed-1 280 | 56 |Crystal |crystal, libevent-dev |1.14.0+dfsg-1 281 | 57 |D |gdc |4:14.2.0-1ubuntu1 282 | 58 |dc |dc |1.07.1-4 283 | 59 |Dhall |dhall |1.42.1-1build2 284 | 60 |Elixir |elixir |1.18.1.dfsg-1.1 285 | 61 |Emacs Lisp |emacs-nox |1:30.1+1-5ubuntu1 286 | 62 |Erlang |erlang |1:27.3+dfsg-1ubuntu1.1 287 | 63 |Execline |execline |2.9.6.1-1 288 | 64 |F# |dotnet8 |8.0.115-8.0.15-0ubuntu1 289 | 65 |FALSE |*N/A* |- 290 | 66 |Flex |flex |2.6.4-8.2build1 291 | 67 |Fish |fish |4.0.1-1 292 | 68 |Forth |gforth |0.7.3+dfsg-9build4.1 293 | 69 |FORTRAN77 |f2c |20240504-1 294 | 70 |Fortran90 |gfortran |4:14.2.0-1ubuntu1 295 | 71 |Gambas script |gambas3-scripter, gambas3-gb-pcre |3.20.2-1build1 296 | 72 |GAP |gap |4.14.0-3 297 | 73 |GDB |gdb |16.2-8ubuntu1 298 | 74 |GEL (Genius) |genius |1.0.27-1build4 299 | 75 |Gnuplot |gnuplot |6.0.2+dfsg1-1 300 | 76 |Go |golang |2:1.24\~2 301 | 77 |GolfScript |*N/A* |- 302 | 78 |G-Portugol |gpt |1.1-8 303 | 79 |Grass |*N/A* |- 304 | 80 |Groovy |groovy |2.4.21-10 305 | 81 |Gzip |gzip |1.13-1ubuntu3 306 | 82 |Haskell |ghc |9.6.6-4 307 | 83 |Haxe |haxe |1:4.3.6-3 308 | 84 |Icon |icont, iconx |9.5.24a-2 309 | 85 |INTERCAL |intercal |30:0.30-6 310 | 86 |Jasmin |jasmin-sable |2.5.0-3 311 | 87 |Java |openjdk-11-jdk |11.0.26+4-1ubuntu1 312 | 88 |JavaScript |nodejs |20.18.1+dfsg-1ubuntu2 313 | 89 |Jq |jq |1.7.1-3ubuntu1 314 | 90 |JSFuck |nodejs |20.18.1+dfsg-1ubuntu2 315 | 91 |Kotlin |kotlin |1.3.31+ds1-2 316 | 92 |ksh |ksh |20240113-1.0.10-2 317 | 93 |Lazy K |*N/A* |- 318 | 94 |Lisaac |lisaac |1:0.39\~rc1-3.1 319 | 95 |LiveScript |livescript |1.6.1+dfsg-3 320 | 96 |LLVM asm |llvm |1:20.0-63ubuntu1 321 | 97 |LOLCODE |*N/A* |- 322 | 98 |Lua |lua5.3 |5.3.6-2build2 323 | 99 |M4 |m4 |1.4.19-7 324 | 100 |Makefile |make |4.4.1-1 325 | 101 |MiniZinc |minizinc |2.9.2+dfsg1-1 326 | 102 |Modula-2 |gm2 |4:14.2.0-1ubuntu1 327 | 103 |MSIL |mono-devel |6.12.0.199+dfsg-3 328 | 104 |Mustache |ruby-mustache |1.1.1-2 329 | 105 |NASM |nasm |2.16.03-1 330 | 106 |Neko |neko |2.4.0-2 331 | 107 |Nickle |nickle |2.102 332 | 108 |Nim |nim |1.6.14-1ubuntu2 333 | 109 |Objective-C |gobjc |4:14.2.0-1ubuntu1 334 | 110 |OCaml |ocaml |5.3.0-2 335 | 111 |Octave |octave |9.4.0-1 336 | 112 |Ook! |*N/A* |- 337 | 113 |PARI/GP |pari-gp |2.17.2-1 338 | 114 |Parser 3 |parser3-cgi |3.5.1-2 339 | 115 |Pascal |fp-compiler |3.2.2+dfsg-46 340 | 116 |Perl 5 |perl |5.40.1-2ubuntu0.1 341 | 117 |Perl 6 |rakudo |2022.12-1 342 | 118 |PHP |php-cli |2:8.4+96ubuntu1 343 | 119 |Piet |*N/A* |- 344 | 120 |Pike |pike8.0 |8.0.1738-1.4build1 345 | 121 |PostScript |ghostscript |10.05.0dfsg1-0ubuntu1 346 | 122 |Prolog |swi-prolog |9.0.4+dfsg-3.1ubuntu4 347 | 123 |Promela (Spin) |spin |6.5.2+dfsg-2 348 | 124 |Python |python3 |3.13.3-1 349 | 125 |R |r-base |4.4.3-1 350 | 126 |Ratfor |ratfor |1.07-1 351 | 127 |rc |rc |1.7.4+97.gceb59bb-5build2 352 | 128 |REXX |regina-rexx |3.9.5+dfsg1-0.1 353 | 354 | Note that some languages are not available in Ubuntu (marked as *N/A*). 355 | This repository contains their implementations in `vendor/`. 356 | See also `vendor/README` for detail. 357 | 358 | 359 | ## Frequently asked questions 360 | 361 | ### Q. Why? 362 | 363 | A. [Take your pick](https://github.com/mame/quine-relay/issues/11). 364 | 365 | ### Q. How? 366 | 367 | A. Good news: I have published a book, ["The World of Obfuscated, Esoteric, Artistic Programming"](http://gihyo.jp/book/2015/978-4-7741-7643-7). 368 | It explains how to write a quine, an ascii-art quine, and an uroboros quine like this quine-relay. 369 | You can buy my book on [amazon.co.jp](http://www.amazon.co.jp/dp/4774176435). 370 | 371 | (It also contains my almost all of my (about forty) works, including 372 | [alphabet-only Ruby program](http://www.slideshare.net/mametter/ruby-esoteric-obfuscated-ruby-programming-5088683), 373 | [radiation-hardened quine](https://github.com/mame/radiation-hardened-quine), 374 | etc., and explains many techniques for writing such programs.) 375 | 376 | Bad news: It is written in Japanese. 377 | I hope you can translate it into English and help me earn royalties. 378 | 379 | ### Q. Language XXX is missing! 380 | 381 | A. See [the language inclusion criteria][criteria] in detail. (In short, please create a deb package and contribute it to Ubuntu.) 382 | 383 | See also [:heart:][sponsors]. 384 | 385 | [criteria]: https://github.com/mame/quine-relay/wiki/Language-inclusion-criteria 386 | [sponsors]: https://github.com/sponsors/mame 387 | 388 | 389 | ### Q. Does it really work? 390 | 391 | A. [](https://github.com/mame/quine-relay/actions?query=workflow%2ACI) 392 | 393 | ### Q. How long did it take you? 394 | 395 | A. [Are you trying to cross the world line?](https://github.com/mame/quine-relay/issues/60) 396 | 397 | ### Q. The code does not fit in my screen! 398 | 399 | A. [Here you go][thumbnail]. 400 | 401 | [thumbnail]: thumbnail.png 402 | 403 | ### Q. How was the code generated? 404 | 405 | A. 406 | 407 | $ sudo apt-get install rake ruby-cairo ruby-rsvg2 ruby-gdk-pixbuf2 \ 408 | optipng advancecomp ruby-chunky-png 409 | $ cd src 410 | $ rake2.0 clobber 411 | $ rake2.0 412 | 413 | ## History 414 | 415 | ## for Ubuntu 13.04 416 | 417 | [50 languages](https://github.com/mame/quine-relay/tree/ad3f8222c796969db8cfb1bae015a46c2387b3d6) 418 | 419 | Added: Ruby, Scala, Scheme, bash, Smalltalk, Unlambda, Tcl, Whitespace, Verilog, Vala, Ada, ALGOL 68, Awk, Brainfuck, Boo, C, C++, C#, Cobol, Clojure, Fortran90, FORTRAN77, Forth, Common Lisp, CoffeeScript, Groovy, Go, INTERCAL, Icon, Haskell, Jasmin, Java, LLVM asm, Logo, Lua, Makefile, MSIL, Objective-C, JavaScript, OCaml, Octave, Parrot asm, Pascal, Perl, PHP, Pike, Prolog, Python, R, REXX 420 | 421 | ## for Ubuntu 13.10 422 | 423 | [50 languages](https://github.com/mame/quine-relay/tree/ea4d39fb1ebc7ee23ec6f60ca7bfa0d465b5806a) 424 | 425 | ## for Ubuntu 14.04 426 | 427 | [50 languages](https://github.com/mame/quine-relay/tree/d16bf072e3063dc476dc440c8f3e33d7426e98db) 428 | 429 | ## for Ubuntu 14.10 430 | 431 | [64 languages](https://github.com/mame/quine-relay/tree/e449baba456d4885102482cbd365335be59241b2) 432 | 433 | Added: Scilab, S-Lang, SPL, LOLCODE, Maxima, NASM, Neko, Nickle, Ook!, PARI/GP, Piet, PPT (Punched tape), PostScript, Ratfor 434 | 435 | ## for Ubuntu 15.04 436 | 437 | [100 languages](https://github.com/mame/quine-relay/tree/7749715289ca162eb1c1eb1ff1ed1393edc41630) 438 | 439 | Added: Subleq, Standard ML, Thue, Visual Basic, XSLT, Yorick, Zoem, A+, AFNIX, Ante, Asymptote, ATS, BLC8, Befunge, bc, Chef, CDuce, D, dc, eC, Emacs Lisp, Erlang, F#, Falcon, FALSE, Gambas script, GAP, GEL (Genius), Gnuplot, G-Portugol, Gri, Haxe, Julia, Lisaac, Lazy K, Kaya 440 | 441 | ## for Ubuntu 15.10 442 | 443 | [100 languages](https://github.com/mame/quine-relay/tree/f45035f867c7c8f7b4e12fa63e7c8eef9aabecad) 444 | 445 | Removed: Boo, Falcon, Kaya 446 | 447 | Added: Elixir, Jq, Nim 448 | 449 | ## for Ubuntu 16.04 450 | 451 | [100 languages](https://github.com/mame/quine-relay/tree/233ba8b4e1d7e4c59a46d64481048a8ea7f4400e) 452 | 453 | ## for Ubuntu 17.04 454 | 455 | [100 languages](https://github.com/mame/quine-relay/tree/e65a798da23df0367d9eb5e4d46f00d87e6cb342) 456 | 457 | Removed: SPL, Gri, Logo, Parrot asm 458 | 459 | Added: Squirrel, Dafny, Grass, MiniZinc 460 | 461 | ## for Ubuntu 17.10 462 | 463 | [100 languages](https://github.com/mame/quine-relay/tree/943b83801a1bd019ebf348adc78df2cdfde06513) 464 | 465 | Removed: CDuce 466 | 467 | Added: Rust 468 | 469 | ## for Ubuntu 18.04 470 | 471 | [128 languages](https://github.com/mame/quine-relay/tree/6e173d76e972e1da7992b84768bf9f4c788949ed) 472 | 473 | Removed: Gambas script, Perl 474 | 475 | Added: Shakespeare, sed, tcsh, TypeScript, Velato, Vimscript, Yabasic, zsh, Aheui, AspectC++, AspectJ, BeanShell, CMake, Flex, Fish, GDB, GolfScript, Gzip, Gri, JSFuck, ksh, LiveScript, M4, Mustache, nesC, Parser 3, Perl 5, Perl 6, Promela (Spin), rc 476 | 477 | ## for Ubuntu 19.04 478 | 479 | [128 languages](https://github.com/mame/quine-relay/tree/c8898351500682cea02219313e9203da7eca5505) 480 | 481 | Removed: Scilab, G-Portugol, nesC 482 | 483 | Added: Curry, Gambas script, GeneratorScriptingLanguage 484 | 485 | ## for Ubuntu 19.10 486 | 487 | [128 languages](https://github.com/mame/quine-relay/tree/13041dbf3f80a90c9221ef94f8e8bc385800b6fd) 488 | 489 | Removed: Gri 490 | 491 | Added: Scilab 492 | 493 | ## for Ubuntu 20.04 494 | 495 | [128 languages](https://github.com/mame/quine-relay/tree/62e2cc2d61d99719328094d185d899bc03a851fb) 496 | 497 | ## for Ubuntu 20.10 498 | 499 | [128 languages](https://github.com/mame/quine-relay/tree/114f44fefd610812d2f5e3032603762752ed51b2) 500 | 501 | Removed: AspectC++, eC 502 | 503 | Added: SurgeScript, Dhall 504 | 505 | ## for Ubuntu 21.04 506 | 507 | [128 languages](https://github.com/mame/quine-relay/tree/d8df33bad3693afd0bd3bf1c2b1cedd5753325dc) 508 | 509 | Removed: Curry 510 | 511 | Added: G-Portugol 512 | 513 | ## for Ubuntu 21.10 514 | 515 | [128 languages](https://github.com/mame/quine-relay/tree/158b6251d36a48122ec0006feaf759d8b1973b0f) 516 | 517 | ## for Ubuntu 22.04 518 | 519 | [128 languages](https://github.com/mame/quine-relay/tree/7b81d8704549d31814499c5300be2be9568467c8) 520 | 521 | Removed: Julia, Nim, Pike 522 | 523 | Added: WebAssembly (Text format), WebAssembly (Binary format), Kotlin 524 | 525 | ## for Ubuntu 22.10 526 | 527 | [128 languages](https://github.com/mame/quine-relay/tree/362962dd2d55d7c36dd9fa3e0d4c0c52c0e6a18f) 528 | 529 | ## for Ubuntu 23.04 530 | 531 | [128 languages](https://github.com/mame/quine-relay/tree/5dfdada5aa58f6a97ae85b84f86c7eb091225a8c) 532 | 533 | Removed: Squirrel, GeneratorScriptingLanguage 534 | 535 | Added: Crystal, Nim 536 | 537 | ## for Ubuntu 23.10 538 | 539 | [128 languages](https://github.com/mame/quine-relay/tree/74c4cc7d79fccbb1c8315070b9efea03cb787755) 540 | 541 | Removed: Smalltalk 542 | 543 | Added: Modula-2 544 | 545 | ## for Ubuntu 24.04 546 | 547 | [128 languages](https://github.com/mame/quine-relay/tree/20d7f437c053b8e0b301ba996d124a4b812e3571) 548 | 549 | Removed: PPT (Punched tape) 550 | 551 | Added: Pike 552 | 553 | ## for Ubuntu 24.10 554 | 555 | 128 languages 556 | 557 | Removed: Dafny, Maxima 558 | 559 | Added: Execline, Squirrel 560 | 561 | ## License 562 | 563 | The MIT License applies to all resources 564 | *except* the files in the `vendor/` directory. 565 | 566 | The files in the `vendor/` directory are from third-parties 567 | and are distributed under different licenses. 568 | See `vendor/README` in detail. 569 | 570 | --- 571 | 572 | The MIT License (MIT) 573 | 574 | Copyright (c) 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Yusuke Endoh (@mametter), @hirekoke 575 | 576 | Permission is hereby granted, free of charge, to any person obtaining 577 | a copy of this software and associated documentation files (the 578 | "Software"), to deal in the Software without restriction, including 579 | without limitation the rights to use, copy, modify, merge, publish, 580 | distribute, sublicense, and/or sell copies of the Software, and to 581 | permit persons to whom the Software is furnished to do so, subject to 582 | the following conditions: 583 | 584 | The above copyright notice and this permission notice shall be 585 | included in all copies or substantial portions of the Software. 586 | 587 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 588 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 589 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 590 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 591 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 592 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 593 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 594 | -------------------------------------------------------------------------------- /SHA256SUMS: -------------------------------------------------------------------------------- 1 | 2ed68f2d9319fe3caad724ce5e8130bbbb825b54f1e287cb0407e254f214d39a *QR.rb 2 | 519564e959dfc2a38104724ebdf744165dc389d2ed53579ba996049c066e20b3 *QR.rs 3 | 94f3b3eaf275dcf08f4b5c610906d3f37ff8309cfc17e0f2cae2a7e53ecf7780 *QR.scala 4 | 3126187ec97cc96017ea1ab6eb7f2431c185c5248eee3370513c5959c3f33701 *QR.scm 5 | 4d0e5e06a60044d87bd5857506407da9d7b83d3738c81c823181585c114c7810 *QR.sci 6 | 05e07ad3d568ed685adee74f8d5e2d330c0847b96fdbe030c779e791eede53c7 *QR.sed 7 | 0fce43ac58631bac0fde5a46a75e8fa2804e08b6882c5366c631ac7bbcf127df *QR.spl 8 | c6142883a366692a4688ba3ef129cb2f9cdc9edbdf89fb1edf9a49e271a74fcb *QR.sl 9 | 058337e5f4685604c03ea8487e8d274f3fad7c7fb108f27ecdb01a04ac219b9b *QR.nut 10 | 9be9a1191562fc0dfceddaaf5d1a1c32e2c25cc31e23ecc8bf91456ddb213fb2 *QR.sml 11 | c8cffeec2fbc0890413347adac32e58f85fc8f48fe0132e78bccda2607a0a327 *QR.sq 12 | 4a29b6296632faabb99c4715bfb3fffe8c956811fb361d3b5402eee8cc48646f *QR.ss 13 | 39c0e31bdb10c88361750bd5f5187d55f4a7776f4c4bffbeefd2a822069f9fac *QR.tcl 14 | 9e35c4d85dd8dfa61882313ba363e1f6f378fcc9739f6314677445571a9fb5ea *QR.tcsh 15 | 829175e602426a8b0036e56950db0d6cb884f5ca027ffb125d2e5994f6ca94e7 *QR.t 16 | cc8afe0b8dd4959ba4c2e5ebb3b58f3fdd03f3fd56f8fa580ce6434f95cedb60 *QR.ts 17 | c27f476d9e040f5ce6926ffba97fa8eda9819ea65e6631df6ec30821cd975343 *QR.unl 18 | 51e6c5bd85dfe45af78d5fcea7a9a9841321517c5c159ebd29608c26062d931c *QR.vala 19 | c6c79e88647cb99477d875bf728a3fdd809f86c1ddba0ae01ad34da10be742a3 *QR.mid 20 | ca36a78f456007b51bef2ff583f310c646f44595ff13cb059e2891dbefe0eea7 *QR.v 21 | 9162117b8710bd2e786c4069395111c39093424a4e9fc5dc0f47cfb1e3f5342f *QR.vim 22 | 87822be612a19d3f2feaaa83f78dc8125b8f4328f449950d6a84420cc4aedf20 *QR.vb 23 | 8f2bb146beaedd4115c20f47fc845c6e03101d848e5c47063f39137e400de2f6 *QR.wasm 24 | 9f4c0744281a49b679ee0621c06a4be8b15b168e7c619bd3f6af17af55e61451 *QR.wat 25 | bc0ccf95507e7a22bab3501c5d37c3543c2b7ba373771d36729a85a555b46cc6 *QR.ws 26 | e80deb350785985a560eda7b9c1a9769506e2e3c4d1d2bc10f57bab6ac1705d0 *QR.xslt 27 | 68e9f04f4b5d1c9d646cf082d906977718b86ccef9d575d863ebd7a700cac19e *QR.yab 28 | c803d1e4171eb65a8f794b3700abac2de11da2fc693bb1551d983ad29f95d260 *QR.yorick 29 | 815923a3cab0e74c998c404ecea01ae21366442585bed769767463012f777583 *QR.azm 30 | c397516e6be141ef41bc0d9e942ed96001e312e2047b66f7ae559d297db59d52 *QR.zsh 31 | f03d910e9900983006c6aa303a14c239a9353fafc9096d1f5c5b10d449254ae1 *QR.+ 32 | 0488ef95222d697b49a939210652096d5d154fa08a97d7a66dfbbcd110d55aed *qr.adb 33 | 2a3e5fe2f28b8288a92388a8dcd18a12742d24ec40e1b475a00c4fb5c0d4cb50 *QR.als 34 | 258acaf3a9bce348136d2518094c99f7e9c9ef38693c14ea64d3cdc03739768e *QR.aheui 35 | 358c4506bedc6c5d90b6c7675b24382a39ce42466c76b12fd6bd7f990d72bcff *QR.a68 36 | 8cd902eacadddc90cbdd522955c99642a2f5391339b9e5fb398cc875d329b3cb *QR.ante 37 | f312d7e2eb494b135e67fd56f867ad925f432d38f1713d4cb355f4a2e6afee8c *QR.aj 38 | 7798b246ff887e55516d834393254b56258ad7c78007ef5cf3944908b0423e43 *QR.asy 39 | 804d64bd2110b020012d500c1ac7a91c0c4009611a901734ba483aee1cb29261 *QR.dats 40 | c112a98d69f5456297d0d8e86ee2b918a3ea272e1eeae55f7b10e31aaef0b2ff *QR.awk 41 | cda91175825418d37145d4d69950b777f1f4a4c4c3d76ec379ebc69b94d4a318 *QR.bash 42 | 09a4478cd3f8c0050350b2f9230ebbe14563aabeb1b55907074851afbc3e4664 *QR.bc 43 | afede07b06b37048d93e005b13eb5bf0dca9508e5c6bc08743aedab4a3393b36 *QR.bsh 44 | 8368747257d317300bb64e3f0e283782cda414545e6a36b6356eca5cea1ea2ad *QR.bef 45 | f1956707638570aa984a137be2d5e09121a7f73568338e697c040b0bef09f7a1 *QR.Blc 46 | d1587bf97bd127f906d4ce788b274db633d13f610cffce284473b0527781954d *QR.bf 47 | 7ce80571626dcf6723d6ea1efa0edf5c92a9a9cb2fd0c9aea6263994a77a3a09 *QR.c 48 | dce7072694e611bf5e84fc58bac86df6651b84545bac37cdb2720b0738874659 *QR.cpp 49 | 808a3a626df447c2c13f16268c7dc002d8e0d9948395dd81f82073c68468c776 *QR.cs 50 | 4027cdf1dbb91e78d3bc49c3ab2ea0cfc80b80542193cf32ba9b88ecef998738 *QR.chef 51 | 413fb4a0c5c3bea8b98dd4832b4bd50af780256031faa5ef9e1419e227a9f8b3 *QR.clj 52 | ab95d7d72bccc93d8cf399679baf6c73a24c83f30d4bd5909ec20dd240fcff40 *QR.cmake 53 | 5f2f9fe43ffc9bf8c39d5ed959072b49fa5d5908b4ad7b79800f48146decf9f4 *QR.cob 54 | f1eb1c905cdeb267ee2f24fbe2ae087d4150a0f52835cdec277d08ead06e7756 *QR.coffee 55 | 555142aac4ed4fcf745c9178e02e807447100552dc7286b3bfe926a5c6dfbdbb *QR.lisp 56 | a3f914f843c84b5aba60b5b55efdcc6fb68d76a0828619ef87b19124135c3fd4 *QR.cr 57 | 17530a2b4a3a578d97de8097fbbd1904cbbb9ef014939cd88e3fbdad5e95e016 *QR.d 58 | c723484ccf500ea2b3e464629883367d847c0492a613b2761a83472148af4a40 *QR.dc 59 | c924dfb314b8b124d1aadef6efe4d75c5b457a591e5ab66ee4fd283d79452e4c *QR.dhall 60 | 4f9aada1b747a2fa6a29bde22933c30371f78fd331c54d1026b67338f9b00735 *QR.exs 61 | 39b4e5d29db926c8e59cfa971d5cbe8213e41c30a7d4b303c1138fa0238a651e *QR.el 62 | 8419ffccc526b2d71e5e47bb2a04ecfb21c2017604904933f5abaeb377792ce3 *QR.erl 63 | 461ffd9b27c66faaa69e1d540fec69bf87248043eeaad1b363ae5a9ec93fefa9 *QR.e 64 | f6f606e3c18388ab51dde55dc3bb41abd4d3a488e898ad77a6d7edc8a81f2333 *QR.fsx 65 | b39659971f3d9e20760cb8ef92477693e40c805534b7f4cd60905e4ad81f2ad9 *QR.false 66 | 61d485e85321baf0f5681837df6bcf57491a8edcc3f785cbb86a0bd84e6ffac3 *QR.fl 67 | 9c50f80dd3bbc52c06d98a48d56f96cba526cc7c143eb1fdb24cc35c355625ee *QR.fish 68 | f2652039728c1fc66d9b1b88cfc22132264926d8336cfde655c4f14e93f178f4 *QR.fs 69 | 1c1c728246bc4e9c772a5f9d92e743ac95db3d183be35f505bd6599343aaefb1 *QR.f 70 | dc6a7cf379116b7b2c11f2aa4ee0ab9c97eced74d3652da441d14595b9e26a69 *QR.f90 71 | 1c1fd393ce3aa283eb30cdbddc9e456f558e493ddf9909cd41e99f75f0fe95fb *QR.gbs 72 | 539eb8366e14b9e5596a1cca61804d26a6a62f15d132f4742012fe82babbe07b *QR.g 73 | 19a7d9631926f76ea0252144dc174bde54078345166dab166396708b6240a6cc *QR.gdb 74 | 387dcc80c91f1f0079e215be076e898ee8065f0a0d69ddbeb5661d38b2cd3cb5 *QR.gel 75 | ef32b6a6e20a4dcb6b69945cae0cf15f110f312cf40d40181d6dd664ec3aebbd *QR.plt 76 | eb4a79adbd3b6865d97b62bf69ecd76022d159cae89a40ad6952590e11a64ce6 *QR.go 77 | 8b01ac1f6dbd275a6d521e50ae31f1d82ef6549d5149d8e8879965c394cdba8e *QR.gs 78 | c9e07c85200f18c6411b275c70adbe8eab70fc5b34e1cffa109d982e50acffd4 *QR.gpt 79 | 98f0426cda0dc9b28d002a7e2caad0e0557cd9545725273d271b6b65cf608a1c *QR.grass 80 | 94f6537981e87bd6ccf801bcd90fc92237a39e59f98ee7b2a3d770dcc5b32bb7 *QR.groovy 81 | d34ffde6e5667d9fda307d79cba1ccd6f0e3c1daac7e0305aff4d9dc9751bbf5 *QR.gz 82 | cdcff0f61cb9f51cd2fa60a8d58bba0ea0682497403dbae4bed92010c330e6d6 *QR.hs 83 | edea1f903f2246dcc183224bc99b983353ab9c12e19f3c4b1149ea48e1cc85b6 *QR.hx 84 | 576f2d592b16cf9245c2347d44c6ce051a0c8026f0406127e315ff568a371a8e *QR.icn 85 | 43b818fbc19ff21d5546b3c746cd57510342e1e33ca53d8af0727c056ac081ff *QR.i 86 | b1c40dea38955fde4d3bd0455d2ef7cb1a4a7628fc96b0027db1f45375439e85 *QR.j 87 | 3e6ad29f07b8d81de1c606b85a2964a8975cb058bf0bced8da70a52e23197dcf *QR.java 88 | 6bc18b4b2cae7aaebd9911c542478108b7baefb42d15a23db690c1d3cda7d2c4 *QR.js 89 | f7a8c5820f9b31ec6e313302235f4903e798e2a9168c7389a673ce021ba0aa0d *QR.jq 90 | a7620f946b36440cb3fba6aeab2d619a78091541f1b7b6f617d89e5a5f8fc052 *QR.jsfuck 91 | 205fd8d80370d9baf312d51c089432e227b006cd6a32844cf0880320790761ee *QR.kt 92 | 9c9eccad18dcf3fa88ed3af6704a65cbdf4feedc4dd7f5179aa7ceb510d0a7b1 *QR.ksh 93 | 8a1cebe9f5f0d9ecbb08930d152de565775a704f52ad85dd94841e609fdaa24c *QR.lazy 94 | 5f9e1e213070b9a8d69378de64bd0c2350011bca729ca0d4e374a4d03d354508 *qr.li 95 | def8a65acf4cf4870ce0ebb72fdbb9f50a77989005c192a9ee872b89e3528d66 *QR.ls 96 | 11cc40467832d62741e4d560c44a38b0698a12145660b5b6c60331dd7b5452af *QR.ll 97 | 75cd14eee09667ed64050d36321beee5d730b37b20418b0be147ad9c1b3287c0 *QR.lol 98 | 523faf97d77cc7c3765504e95ca355e279128634f9feb1aa897a3ab76c322c15 *QR.lua 99 | bcd5d7839be8a2050c2f60360d99164d5bd82151cb1f75884736542a82da9a36 *QR.m4 100 | 1a00b00bec278e2c0e3e501f27c5a9b58e3430349717e6bca68ddaf322e10641 *QR.mk 101 | e91dd8ca5e90bf77b697dc97dcf5bbdd0f5386448533ae81d3cbe89b1d202782 *QR.mzn 102 | fd7a447346275f3effbf1d7c715b3c6ae5d155d7b359401dff6d0e81ac2554b4 *QR.mod 103 | 337d9cbd642fdfd17e0aa37189310c338177a972b47586346a613cac8a22865a *QR.il 104 | 52f27e28cf0d3564397098e6751bd61a2fea3c9467dee076068fec6eacbee27f *QR.mustache 105 | 99bac67ed1acd2342b3833198187126af0598f22cd6bec0e174b8bea70d3700d *QR.asm 106 | 76172f798d41df453a7d90107364b6a082eca5bd782a0ced635f2c2949549124 *QR.neko 107 | 7847fdf95de6f67c4e40b47473fb81b17f21cb49e22380b623ffaa6ea1ae3e32 *QR.5c 108 | df5eb8033d6e4d4208e00a638497a697a367c58d31fb5b4b6c18d1ccb050b4db *QR.nim 109 | 441e00880dd5013b4785b7a6add5b69353f5c4f257616ab866f72f6a7feade1d *QR.m 110 | 7a1f599a21b37a9cdd9f457029cf660efbb2670c751632aeebb54ef36b8fd0f2 *QR.ml 111 | dc13771e7f5ef7ee38feeb480602c3c35398af09eef01c0033a5649974c1708b *QR.octave 112 | 1531bf3fbb1eadfbae21b8c7d217c5d71f893c4fba9095f942f6749aa81564d7 *QR.ook 113 | 68c697201e0d40015d845485930439d6611a72f63ff6fe4e7c99f98720d1f1b3 *QR.gp 114 | 9ed4737a55cd8bb23c4437e1be9e272a0d8f44343a629fb3bc50ea56bcd04f62 *QR.p 115 | 28ebbab2f56917f6dd8f1836cc50315b0e237e6a693d68a1249152b1c6d9c06a *QR.pas 116 | 881815cc8ac99e346fe52dfa2e8d29d99bf7e53c1527adad9f0c2e59bc179338 *QR.pl 117 | 3b9416bea50dbc88d58d17386a73e166335ea9f239a2a5b0368b1608510a00a3 *QR.pl6 118 | 8fcb994017b63425f0e97f842379585cf0c962700c073bf030ebb4303a9bc43f *QR.php 119 | 00ec0c2dd1c7807bd91d48049cf660c67dca5e9055a68689ae098c62412c84fb *QR.png 120 | b2f07a0d08fa0f85b97c363ee6a38f271860c953093e29146fe6edeb4e07c4c2 *QR.pike 121 | 181d6f849e2edd3324e9e010d1a14dfb344b7da6ad4f9b7b2329b95fbb53b68a *QR.ps 122 | 5118af4c809d0dc393ac8938f5a2d933fd7acc9ccd960534cf59656fa24c740d *QR.prolog 123 | 6497c658d645f63a423eeb157d710a304afb2990ed81583112fc07c37c23e4e3 *QR.pr 124 | 790c905f02a659ffa2f46ac4fa3eb6863b01f4fcf8f95912693ed369c8d40bad *QR.py 125 | 507d99209394c76d007fce4758d7ff8ff033589e232a66acf659fba5b86283ae *QR.R 126 | 9300fd699a79f6fdf96b96c835ac8874fd6ce81e7315101b394493040d313b6d *QR.ratfor 127 | ec91acdf2de50735e14590e98a5a47dfd23db57756156a3262ac1b7c6a50eeee *QR.rc 128 | bd3e5f2c65c933b8c3c10704cce3af91c445a96f12252ed6ae93edc6a23ff097 *QR.rexx 129 | -------------------------------------------------------------------------------- /langs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/langs.png -------------------------------------------------------------------------------- /src/Dockerfile.gen.rb: -------------------------------------------------------------------------------- 1 | require_relative "code-gen" 2 | 3 | apts = RunSteps.flat_map {|s| s.apt } 4 | other_packages = %w(libpng-dev libgd-dev groff flex bison curl) 5 | 6 | apts = [*apts.flatten.compact.uniq, *other_packages].uniq.sort 7 | 8 | dockerfile = [] 9 | dockerfile << "FROM ubuntu:#{ `bash -c 'source /etc/os-release && echo $VERSION_ID'`.chomp }" 10 | dockerfile << "ENV DEBIAN_FRONTEND noninteractive" 11 | dockerfile << "RUN apt-get update && apt-get upgrade -y" 12 | dockerfile << "RUN apt-get -qq install -y apt-utils > /dev/null" 13 | dockerfile << "RUN apt-get -qq install -y moreutils" 14 | apts.each_slice(4) do |apt| 15 | dockerfile << "RUN chronic apt-get -qq install -y #{ apt.join(" ") } && chronic apt-get clean" 16 | end 17 | dockerfile << "ADD . /usr/local/share/quine-relay" 18 | dockerfile << "WORKDIR /usr/local/share/quine-relay" 19 | dockerfile << "RUN make -C vendor" 20 | dockerfile << "CMD make check -j 10000" 21 | 22 | File.write("../Dockerfile", dockerfile.join("\n") + "\n") 23 | -------------------------------------------------------------------------------- /src/Makefile.gen.rb: -------------------------------------------------------------------------------- 1 | require_relative "code-gen" 2 | 3 | OUT = [] 4 | 5 | def banner(s1, s2=nil, i=nil) 6 | s = "## #{ "#{ i + 1 }: " if i }#{ s1 }#{ ' -> ' + s2 if s2 } ##" 7 | OUT << "\t@echo" 8 | OUT << "\t@echo \"#{ "#" * s.size }\"" 9 | OUT << "\t@echo \"#{ s }\"" 10 | OUT << "\t@echo \"#{ "#" * s.size }\"" 11 | OUT << "\t@echo" 12 | end 13 | 14 | OUT << <<-END 15 | MAKEFLAGS += --no-print-directory 16 | 17 | PATH := $(CURDIR)/vendor/local/bin:/usr/games:$(PATH) 18 | CLASSPATH := . 19 | 20 | find_any0 = $(firstword $(foreach x,$(1),$(if $(shell which $(x) 2>/dev/null),$(x),))) 21 | check = $(if $(2),$(2),$(error $(1) interpreter not found!)) 22 | find_any = $(call check,$(1),$(call find_any0,$(2))) 23 | 24 | JAVASCRIPT := $(call find_any,JavaScript,nodejs node js) 25 | SCHEME := $(call find_any,Scheme,guile csi gosh) 26 | GBS := $(call find_any,Gambas script,gbs3 gbs2 gba3) 27 | WASI_RUNTIME := $(call find_any,WASI runtime,wasmtime node) 28 | 29 | ifeq ($(SCHEME),csi) 30 | SCHEME := csi -s 31 | endif 32 | ifeq ($(WASI_RUNTIME),node) 33 | WASI_RUNTIME := node --experimental-wasi-unstable-preview1 vendor/wasi-runtime.js 34 | endif 35 | 36 | .DELETE_ON_ERROR: 37 | END 38 | OUT << "all: QR2.rb" 39 | banner("CHECK") 40 | OUT << "\tdiff -s QR.rb QR2.rb" 41 | OUT << "" 42 | OUT << "check: all" 43 | OUT << "\t@sha256sum --quiet -c SHA256SUMS" 44 | 45 | [*RunSteps, RunStep["Ruby", "QR2.rb"]].each_cons(2).with_index do |(s1, s2), i| 46 | cmd = s1.cmd_make.gsub("OUTFILE", s2.src) 47 | 48 | OUT << "" 49 | OUT << "#{ s2.src }: #{ s1.src }" 50 | banner(s1.name, s2.name, i) 51 | if s1.backup 52 | if s1.backup.is_a?(String) 53 | OUT << "\t@mv #{ s1.backup } #{ s1.backup }.bak" 54 | else 55 | OUT << "\t@#{ s1.backup[0] }" 56 | end 57 | end 58 | cmd.split("&&").each {|c| OUT << "\t" + c.strip.gsub(/^!/, "ulimit -s unlimited && ") } 59 | if s1.backup 60 | if s1.backup.is_a?(String) 61 | OUT << "\t@mv #{ s1.backup }.bak #{ s1.backup }" 62 | else 63 | OUT << "\t@#{ s1.backup[1] }" 64 | end 65 | end 66 | end 67 | 68 | OUT << <<-END 69 | 70 | clean: 71 | \t@mv QR.rb quine-relay.rb 72 | \trm -f qr QR qr.* QR.* QR2.rb *.class gst.im 73 | \t@mv quine-relay.rb QR.rb 74 | END 75 | 76 | File.write("../Makefile", OUT.join("\n")) 77 | -------------------------------------------------------------------------------- /src/QR.rb.gen.rb: -------------------------------------------------------------------------------- 1 | require_relative "code-gen" 2 | 3 | gen_prologue_1 = GenPrologue.split(?;)[0, 2].join(?;) 4 | gen_prologue_2 = GenPrologue.split(?;)[2..-1].join(?;) 5 | 6 | s = 7 | gen_prologue_2 + ?; + 8 | GenSteps[0..-2].inject('"eval$s=%q(#$s)"') {|code, s| s.code.sub("PREV"){ code }.chomp } 9 | 10 | if false 11 | # search characters rarely used 12 | h = {} 13 | 32.upto(126) {|c| h[c.chr] = 0 } 14 | s.chars.group_by {|c| c }.map do |c, a| 15 | h[c] = a.size 16 | end 17 | %w(( ) [ ] { } \ \\ \").each {|c| h.delete(c) } 18 | p *h.sort_by {|k, v| v } 19 | exit 20 | end 21 | 22 | if false 23 | # search sequences that often appear 24 | h = Hash.new(0) 25 | 2.upto(10) do |n| 26 | s.chars.each_cons(n) do |a| 27 | h[a.join] += n-1 28 | end 29 | end 30 | p *h.sort_by {|k, v| v }.reverse 31 | exit 32 | end 33 | 34 | # a table of short-hand character for sequences that often appear 35 | ABBREV = { 36 | ?~ => " ", 37 | ?` => "\\", 38 | ?^ => "``", 39 | ?Z => "print", 40 | ?X => "ain()", 41 | ?J => "tring", 42 | ?H => "write", 43 | ?K => "gsub", 44 | ?! => "in", 45 | ?Y => "^^", 46 | } 47 | 48 | s = s.gsub(/[#{ ABBREV.keys.join }]/){"\\x%02x" % $&.ord} 49 | 50 | # search perfect and simplest hash 51 | a = ABBREV.keys.join.bytes 52 | max = 1000 53 | a.size.upto(90) do |n| 54 | a.size.upto(90) do |m| 55 | b = a.map {|c| c%n%m } 56 | if b.uniq.size >= a.size&&b.max#{ TEMPLATE.count("#") - width }" 103 | end 104 | PADDING = "".ljust(width, "#_buffer_for_future_bug_fixes_") 105 | COPYRIGHT = 106 | " Quine Relay -- Copyright (c) 2013, 2014 Yusuke Endoh (@mametter), @hirekoke ". 107 | center(width, "#")[0..-2] 108 | 109 | code = TEMPLATE.gsub(/#+/) { w = $&.size; code.slice!(0, w).ljust(w, PADDING) }.chomp 110 | code[-1] = ")" 111 | 112 | code[-1 - COPYRIGHT.size, COPYRIGHT.size] = COPYRIGHT 113 | 114 | File.write("../QR.rb", code + "\n") 115 | -------------------------------------------------------------------------------- /src/README.md.gen.rb: -------------------------------------------------------------------------------- 1 | require_relative "code-gen" 2 | require "erb" 3 | require "cairo" 4 | 5 | other_packages = %w(cmake libpng-dev libgd-dev groff bison curl) 6 | other_packages.each do |package| 7 | `dpkg -s #{ package }` # just check the packages 8 | end 9 | 10 | pkg_versions = {} 11 | apts = RunSteps.map {|s| s.apt } 12 | `which apt-get >/dev/null && dpkg -s #{ apts.join(" ") }`.b.split("\n\n").each do |s| 13 | name = s[/^Package: (.*)$/, 1] 14 | version = s[/^Version: (.*)$/, 1] 15 | pkg_versions[name] = version if name && version 16 | end 17 | 18 | rows = [["\\#", "language", "ubuntu package", "version"]] 19 | rows += RunSteps.map.with_index do |s, idx| 20 | if s.apt.is_a?(Array) 21 | apt = s.apt.join(", ") 22 | ver = pkg_versions.values_at(*s.apt) 23 | #raise if ver.uniq.size > 1 24 | ver = ver.first 25 | else 26 | apt = s.apt || "*N/A*" 27 | ver = pkg_versions[apt] 28 | end 29 | ver = ver.gsub("~") { "\\~" } if ver 30 | [(idx + 1).to_s, s.name, apt, ver || "-"] 31 | end 32 | 33 | ws = rows.transpose.map {|row| row.map {|s| s.size }.max + 1 } 34 | rows[1, 0] = [ws.map {|w| "-" * w }] 35 | rows = rows.map do |col| 36 | (col.zip(ws).map {|s, w| s.ljust(w) } * "|").rstrip 37 | end 38 | 39 | apt_get = "sudo apt-get install #{ [*apts.flatten.compact.uniq].sort * " " }" 40 | apt_get.gsub!(/.{,70}( |\z)/) do 41 | $&[-1] == " " ? $& + "\\\n " : $& 42 | end 43 | 44 | cmds = [*RunSteps, RunStep["Ruby", "QR2.rb"]].each_cons(2).map do |s1, s2| 45 | cmd = s1.cmd_raw 46 | src = s2.src 47 | cmd = cmd.gsub("OUTFILE", src) 48 | 49 | cmd = cmd.gsub(/^!/, "") 50 | cmd = cmd.gsub(/.{60,}?&&/, "\\0\n ") 51 | 52 | cmd 53 | end 54 | 55 | File.write("../README.md", ERB.new(DATA.read, trim_mode: "%").result(binding)) 56 | 57 | 58 | __END__ 59 | # Quine Relay 60 | 61 | [](https://github.com/mame/quine-relay/actions?query=workflow%3ACI) 62 | 63 | ## What this is 64 | 65 | [QR.rb](https://github.com/mame/quine-relay/blob/master/QR.rb) is a <%= RunSteps[0].name %> program that generates 66 | a <%= RunSteps[1].name %> program that generates 67 | a <%= RunSteps[2].name %> program that generates 68 | ...(through <%= RunSteps.size %> languages in total)... 69 | a <%= RunSteps[-1].name %> program that generates 70 | the original <%= RunSteps[0].name %> code again. 71 | 72 | ![Language Uroboros][langs] 73 | 74 | [langs]: langs.png 75 | 76 | (If you want to see the old 50-language version, see the [50](https://github.com/mame/quine-relay/tree/50) branch.) 77 | 78 | ## Usage 79 | 80 | ### Ubuntu 81 | 82 | If you are using Ubuntu <%= `bash -c 'source /etc/os-release && echo $VERSION'`.chomp %>, you can follow these steps. 83 | 84 | #### 1. Install all the interpreters/compilers. 85 | 86 | First, you need to type the following apt-get command to install them all. 87 | 88 | $ <%= apt_get %> 89 | 90 | Then, build the bundled interpreters. 91 | 92 | $ sudo apt-get install <%= other_packages.join(" ") %> 93 | $ make -C vendor 94 | 95 | #### 2. Run each program on each interpreter/compiler. 96 | 97 | $ ulimit -s unlimited 98 | % cmds.each do |cmd| 99 | $ <%= cmd %> 100 | % end 101 | 102 | You will see that `QR.rb` is the same as `QR2.rb`. 103 | 104 | $ diff QR.rb QR2.rb 105 | 106 | Alternatively, just type `make`. 107 | 108 | $ make 109 | 110 | Note: It may take a lot of memory to compile some files. 111 | 112 | ### Docker 113 | 114 | Simply build the image and run a container as follows: 115 | 116 | $ docker build -t qr . 117 | $ docker run --privileged --rm -e CI=true qr 118 | 119 | Note: You must run in privileged mode, otherwise the `maxima` command will fail. 120 | 121 | If you want to check the generated files, you can mount the local directory in the Docker container (but still use the `vendor` directory of the container), as follows: 122 | 123 | $ docker run --privileged --rm -e CI=true -v $(pwd):/usr/local/share/quine-relay -v /usr/local/share/quine-relay/vendor qr 124 | 125 | ### Other platforms 126 | 127 | You may find [instructions for other platforms in the wiki](https://github.com/mame/quine-relay/wiki/Installation). 128 | 129 | If you do not use these Linux distributions, please find your own way. 130 | If you manage it, please let me know. I wish you good luck. 131 | 132 | ## Interpreter/compiler versions tested 133 | 134 | I used the following Ubuntu deb packages to test this program. 135 | 136 | % rows.each do |row| 137 | <%= row %> 138 | % end 139 | 140 | Note that some languages are not available in Ubuntu (marked as *N/A*). 141 | This repository contains their implementations in `vendor/`. 142 | See also `vendor/README` for detail. 143 | 144 | 145 | ## Frequently asked questions 146 | 147 | ### Q. Why? 148 | 149 | A. [Take your pick](https://github.com/mame/quine-relay/issues/11). 150 | 151 | ### Q. How? 152 | 153 | A. Good news: I have published a book, ["The World of Obfuscated, Esoteric, Artistic Programming"](http://gihyo.jp/book/2015/978-4-7741-7643-7). 154 | It explains how to write a quine, an ascii-art quine, and an uroboros quine like this quine-relay. 155 | You can buy my book on [amazon.co.jp](http://www.amazon.co.jp/dp/4774176435). 156 | 157 | (It also contains my almost all of my (about forty) works, including 158 | [alphabet-only Ruby program](http://www.slideshare.net/mametter/ruby-esoteric-obfuscated-ruby-programming-5088683), 159 | [radiation-hardened quine](https://github.com/mame/radiation-hardened-quine), 160 | etc., and explains many techniques for writing such programs.) 161 | 162 | Bad news: It is written in Japanese. 163 | I hope you can translate it into English and help me earn royalties. 164 | 165 | ### Q. Language XXX is missing! 166 | 167 | A. See [the language inclusion criteria][criteria] in detail. (In short, please create a deb package and contribute it to Ubuntu.) 168 | 169 | See also [:heart:][sponsors]. 170 | 171 | [criteria]: https://github.com/mame/quine-relay/wiki/Language-inclusion-criteria 172 | [sponsors]: https://github.com/sponsors/mame 173 | 174 | 175 | ### Q. Does it really work? 176 | 177 | A. [](https://github.com/mame/quine-relay/actions?query=workflow%2ACI) 178 | 179 | ### Q. How long did it take you? 180 | 181 | A. [Are you trying to cross the world line?](https://github.com/mame/quine-relay/issues/60) 182 | 183 | ### Q. The code does not fit in my screen! 184 | 185 | A. [Here you go][thumbnail]. 186 | 187 | [thumbnail]: thumbnail.png 188 | 189 | ### Q. How was the code generated? 190 | 191 | A. 192 | 193 | $ sudo apt-get install rake ruby-cairo ruby-rsvg2 ruby-gdk-pixbuf2 \ 194 | optipng advancecomp ruby-chunky-png 195 | $ cd src 196 | $ rake2.0 clobber 197 | $ rake2.0 198 | 199 | ## History 200 | 201 | ## for Ubuntu 13.04 202 | 203 | [50 languages](https://github.com/mame/quine-relay/tree/ad3f8222c796969db8cfb1bae015a46c2387b3d6) 204 | 205 | Added: Ruby, Scala, Scheme, bash, Smalltalk, Unlambda, Tcl, Whitespace, Verilog, Vala, Ada, ALGOL 68, Awk, Brainfuck, Boo, C, C++, C#, Cobol, Clojure, Fortran90, FORTRAN77, Forth, Common Lisp, CoffeeScript, Groovy, Go, INTERCAL, Icon, Haskell, Jasmin, Java, LLVM asm, Logo, Lua, Makefile, MSIL, Objective-C, JavaScript, OCaml, Octave, Parrot asm, Pascal, Perl, PHP, Pike, Prolog, Python, R, REXX 206 | 207 | ## for Ubuntu 13.10 208 | 209 | [50 languages](https://github.com/mame/quine-relay/tree/ea4d39fb1ebc7ee23ec6f60ca7bfa0d465b5806a) 210 | 211 | ## for Ubuntu 14.04 212 | 213 | [50 languages](https://github.com/mame/quine-relay/tree/d16bf072e3063dc476dc440c8f3e33d7426e98db) 214 | 215 | ## for Ubuntu 14.10 216 | 217 | [64 languages](https://github.com/mame/quine-relay/tree/e449baba456d4885102482cbd365335be59241b2) 218 | 219 | Added: Scilab, S-Lang, SPL, LOLCODE, Maxima, NASM, Neko, Nickle, Ook!, PARI/GP, Piet, PPT (Punched tape), PostScript, Ratfor 220 | 221 | ## for Ubuntu 15.04 222 | 223 | [100 languages](https://github.com/mame/quine-relay/tree/7749715289ca162eb1c1eb1ff1ed1393edc41630) 224 | 225 | Added: Subleq, Standard ML, Thue, Visual Basic, XSLT, Yorick, Zoem, A+, AFNIX, Ante, Asymptote, ATS, BLC8, Befunge, bc, Chef, CDuce, D, dc, eC, Emacs Lisp, Erlang, F#, Falcon, FALSE, Gambas script, GAP, GEL (Genius), Gnuplot, G-Portugol, Gri, Haxe, Julia, Lisaac, Lazy K, Kaya 226 | 227 | ## for Ubuntu 15.10 228 | 229 | [100 languages](https://github.com/mame/quine-relay/tree/f45035f867c7c8f7b4e12fa63e7c8eef9aabecad) 230 | 231 | Removed: Boo, Falcon, Kaya 232 | 233 | Added: Elixir, Jq, Nim 234 | 235 | ## for Ubuntu 16.04 236 | 237 | [100 languages](https://github.com/mame/quine-relay/tree/233ba8b4e1d7e4c59a46d64481048a8ea7f4400e) 238 | 239 | ## for Ubuntu 17.04 240 | 241 | [100 languages](https://github.com/mame/quine-relay/tree/e65a798da23df0367d9eb5e4d46f00d87e6cb342) 242 | 243 | Removed: SPL, Gri, Logo, Parrot asm 244 | 245 | Added: Squirrel, Dafny, Grass, MiniZinc 246 | 247 | ## for Ubuntu 17.10 248 | 249 | [100 languages](https://github.com/mame/quine-relay/tree/943b83801a1bd019ebf348adc78df2cdfde06513) 250 | 251 | Removed: CDuce 252 | 253 | Added: Rust 254 | 255 | ## for Ubuntu 18.04 256 | 257 | [128 languages](https://github.com/mame/quine-relay/tree/6e173d76e972e1da7992b84768bf9f4c788949ed) 258 | 259 | Removed: Gambas script, Perl 260 | 261 | Added: Shakespeare, sed, tcsh, TypeScript, Velato, Vimscript, Yabasic, zsh, Aheui, AspectC++, AspectJ, BeanShell, CMake, Flex, Fish, GDB, GolfScript, Gzip, Gri, JSFuck, ksh, LiveScript, M4, Mustache, nesC, Parser 3, Perl 5, Perl 6, Promela (Spin), rc 262 | 263 | ## for Ubuntu 19.04 264 | 265 | [128 languages](https://github.com/mame/quine-relay/tree/c8898351500682cea02219313e9203da7eca5505) 266 | 267 | Removed: Scilab, G-Portugol, nesC 268 | 269 | Added: Curry, Gambas script, GeneratorScriptingLanguage 270 | 271 | ## for Ubuntu 19.10 272 | 273 | [128 languages](https://github.com/mame/quine-relay/tree/13041dbf3f80a90c9221ef94f8e8bc385800b6fd) 274 | 275 | Removed: Gri 276 | 277 | Added: Scilab 278 | 279 | ## for Ubuntu 20.04 280 | 281 | [128 languages](https://github.com/mame/quine-relay/tree/62e2cc2d61d99719328094d185d899bc03a851fb) 282 | 283 | ## for Ubuntu 20.10 284 | 285 | [128 languages](https://github.com/mame/quine-relay/tree/114f44fefd610812d2f5e3032603762752ed51b2) 286 | 287 | Removed: AspectC++, eC 288 | 289 | Added: SurgeScript, Dhall 290 | 291 | ## for Ubuntu 21.04 292 | 293 | [128 languages](https://github.com/mame/quine-relay/tree/d8df33bad3693afd0bd3bf1c2b1cedd5753325dc) 294 | 295 | Removed: Curry 296 | 297 | Added: G-Portugol 298 | 299 | ## for Ubuntu 21.10 300 | 301 | [128 languages](https://github.com/mame/quine-relay/tree/158b6251d36a48122ec0006feaf759d8b1973b0f) 302 | 303 | ## for Ubuntu 22.04 304 | 305 | [128 languages](https://github.com/mame/quine-relay/tree/7b81d8704549d31814499c5300be2be9568467c8) 306 | 307 | Removed: Julia, Nim, Pike 308 | 309 | Added: WebAssembly (Text format), WebAssembly (Binary format), Kotlin 310 | 311 | ## for Ubuntu 22.10 312 | 313 | [128 languages](https://github.com/mame/quine-relay/tree/362962dd2d55d7c36dd9fa3e0d4c0c52c0e6a18f) 314 | 315 | ## for Ubuntu 23.04 316 | 317 | [128 languages](https://github.com/mame/quine-relay/tree/5dfdada5aa58f6a97ae85b84f86c7eb091225a8c) 318 | 319 | Removed: Squirrel, GeneratorScriptingLanguage 320 | 321 | Added: Crystal, Nim 322 | 323 | ## for Ubuntu 23.10 324 | 325 | [128 languages](https://github.com/mame/quine-relay/tree/74c4cc7d79fccbb1c8315070b9efea03cb787755) 326 | 327 | Removed: Smalltalk 328 | 329 | Added: Modula-2 330 | 331 | ## for Ubuntu 24.04 332 | 333 | [128 languages](https://github.com/mame/quine-relay/tree/20d7f437c053b8e0b301ba996d124a4b812e3571) 334 | 335 | Removed: PPT (Punched tape) 336 | 337 | Added: Pike 338 | 339 | ## for Ubuntu 24.10 340 | 341 | 128 languages 342 | 343 | Removed: Dafny, Maxima 344 | 345 | Added: Execline, Squirrel 346 | 347 | ## License 348 | 349 | The MIT License applies to all resources 350 | *except* the files in the `vendor/` directory. 351 | 352 | The files in the `vendor/` directory are from third-parties 353 | and are distributed under different licenses. 354 | See `vendor/README` in detail. 355 | 356 | --- 357 | 358 | The MIT License (MIT) 359 | 360 | Copyright (c) 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Yusuke Endoh (@mametter), @hirekoke 361 | 362 | Permission is hereby granted, free of charge, to any person obtaining 363 | a copy of this software and associated documentation files (the 364 | "Software"), to deal in the Software without restriction, including 365 | without limitation the rights to use, copy, modify, merge, publish, 366 | distribute, sublicense, and/or sell copies of the Software, and to 367 | permit persons to whom the Software is furnished to do so, subject to 368 | the following conditions: 369 | 370 | The above copyright notice and this permission notice shall be 371 | included in all copies or substantial portions of the Software. 372 | 373 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 374 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 375 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 376 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 377 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 378 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 379 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 380 | -------------------------------------------------------------------------------- /src/Rakefile: -------------------------------------------------------------------------------- 1 | require "rake/clean" 2 | 3 | CLEAN.include("../QR.*") 4 | CLEAN.include("../qr.*") 5 | CLEAN.include("../QR$*") 6 | CLEAN.include("../QR") 7 | CLEAN.include("../qr") 8 | CLEAN.include("../QR2.rb") 9 | CLEAN.include("../README.md") 10 | CLEAN.include("../langs.png") 11 | CLEAN.include("../Makefile") 12 | 13 | LIBS = %w(code-gen.rb code-gen-pool.rb lazyk-boot.dat blc-boot.dat grass-boot.dat wasm-tmpl.dat) 14 | 15 | file "lazyk-boot.dat" => "lazyk-boot.dat.gen.rb" do 16 | ruby "lazyk-boot.dat.gen.rb" 17 | end 18 | 19 | file "blc-boot.dat" => "blc-boot.dat.gen.rb" do 20 | ruby "blc-boot.dat.gen.rb" 21 | end 22 | 23 | file "grass-boot.dat" => "grass-boot.dat.gen.rb" do 24 | ruby "grass-boot.dat.gen.rb" 25 | end 26 | 27 | file "wasm-tmpl.dat" => "wasm-tmpl.dat.gen.rb" do 28 | ruby "wasm-tmpl.dat.gen.rb" 29 | end 30 | 31 | file "../QR.rb" => ["QR.rb.gen.rb", *LIBS, "uroboros.txt"] do 32 | ruby "QR.rb.gen.rb" 33 | end 34 | 35 | file "../README.md" => ["README.md.gen.rb", *LIBS] do 36 | ruby "README.md.gen.rb" 37 | end 38 | 39 | file "../langs.png" => ["langs.png.gen.rb", "uroboros.svg", *LIBS] do 40 | ruby "langs.png.gen.rb" 41 | end 42 | 43 | file "../thumbnail.png" => ["thumbnail.png.gen.rb", "../QR.rb"] do 44 | ruby "thumbnail.png.gen.rb" 45 | end 46 | 47 | file "../Makefile" => ["Makefile.gen.rb", *LIBS] do 48 | ruby "Makefile.gen.rb" 49 | end 50 | 51 | file "../.github/workflows/main.yml" => ["dot.github.workflows.main.yml.gen.rb", *LIBS] do 52 | ruby "dot.github.workflows.main.yml.gen.rb" 53 | end 54 | 55 | file "../Dockerfile" => ["Dockerfile.gen.rb", *LIBS] do 56 | ruby "Dockerfile.gen.rb" 57 | end 58 | 59 | task :test do 60 | ruby "test.rb" 61 | end 62 | 63 | task :default => %w( 64 | ../QR.rb 65 | ../README.md 66 | ../langs.png 67 | ../thumbnail.png 68 | ../Makefile 69 | ../.github/workflows/main.yml 70 | ../Dockerfile 71 | ) 72 | 73 | task "../SHA256SUMS" => ["SHA256SUMS.gen.rb", *LIBS] do 74 | ruby "SHA256SUMS.gen.rb" 75 | end 76 | 77 | task :run => :default do 78 | sh "make -C .." 79 | end 80 | 81 | task :gen => [:run, "../SHA256SUMS"] 82 | -------------------------------------------------------------------------------- /src/SHA256SUMS.gen.rb: -------------------------------------------------------------------------------- 1 | require_relative "code-gen" 2 | 3 | Dir.chdir("..") do 4 | system("sha256sum", "-b", *RunSteps.map {|s| s.src }, out: "SHA256SUMS") 5 | end 6 | -------------------------------------------------------------------------------- /src/blc-boot.dat.gen.rb: -------------------------------------------------------------------------------- 1 | def dump(e, env) 2 | if e.is_a?(Symbol) 3 | ?1 * (env.index(e) + 1) + ?0 4 | elsif e[0] == :abs! 5 | vs = [*e[1]].reverse 6 | "00" * vs.size + dump(e[2], vs + env) 7 | else 8 | "01" * (e.size - 1) + e.map {|x| dump(x, env) } * "" 9 | end 10 | end 11 | 12 | L = -> x, y { [:abs!, x, y] } 13 | Let = -> v, x, y { [L[v, y], x] } 14 | Cons = -> x, y { L[:f, [:f, x, y]] } 15 | False = L[[:x, :y], :y] 16 | True = L[[:x, :y], :x] 17 | 18 | Num = -> n { 19 | [n[7] == 1 ? :ConsFalse : :ConsTrue, 20 | [n[6] == 1 ? :ConsFalse : :ConsTrue, 21 | [n[5] == 1 ? :ConsFalse : :ConsTrue, 22 | [n[4] == 1 ? :ConsFalse : :ConsTrue, 23 | [n[3] == 1 ? :ConsFalse : :ConsTrue, 24 | [n[2] == 1 ? :ConsFalse : :ConsTrue, 25 | [n[1] == 1 ? :ConsFalse : :ConsTrue, 26 | [n[0] == 1 ? :ConsFalse : :ConsTrue, False]]]]]]]] 27 | } 28 | 29 | OutBF = -> tl { [:Cons, Num[?..ord], [:ConsGt, tl]] } 30 | DblBF = # [->++<]> 31 | L[:tl, 32 | Let[:ConsTrue, :ConsTrue, 33 | Let[:ConsFalse, :ConsFalse, 34 | [:Cons, Num[?[.ord], 35 | [:Cons, Num[?-.ord], 36 | [:ConsGt, 37 | [:ConsPlus, 38 | [:ConsPlus, 39 | [:Cons, Num[?<.ord], 40 | [:Cons, Num[?].ord], 41 | [:ConsGt, :tl]]]]]]]]]]] 42 | 43 | # each_bit bit tl = 44 | # ("[->++<]>" concat (tl each_bit)) 45 | EachBit = 46 | [L[:x, [:x, :x]], # recursive 47 | L[[:self, :bit, :tl, :next], 48 | [:tl, [:self, :self], [:DblBF, [:bit, [:ConsPlus, :next], :next]]]]] 49 | 50 | # each_byte byte tl = 51 | # (byte each_bit ".>") concat (tl each_byte) 52 | EachByte = 53 | [L[:x, [:x, :x]], # recursive 54 | L[[:self, :byte, :tl], 55 | Let[:Cons, L[[:x, :y, :f], [:f, :x, :y]], 56 | Let[:ConsTrue, [:Cons, True], 57 | Let[:ConsFalse, [:Cons, False], 58 | Let[:ConsPlus, [:Cons, Num[?+.ord]], 59 | Let[:ConsGt, [:Cons, Num[?>.ord]], 60 | Let[:DblBF, DblBF, 61 | [:byte, EachBit, OutBF[[:tl, [:self, :self]]]]]]]]]]]] 62 | 63 | tree = EachByte 64 | boot = "10" + dump(tree, []) 65 | 66 | # 20 x ? boot = 00010100 x ? boot = \a (\b x) ? boot = \a x boot 67 | # 22 x y = 00010110 x y = \a a x y = cons x y 68 | # 4 222 = 00000100 11011110 = \a \b (\c b) (????) = \a \b b = false 69 | # 4 226 = 00000100 11100010 = \a \b (\c a) (\c c) = \a \b a = true 70 | if ARGV[0] 71 | $stderr.puts(boot.size, (boot.size + 7) / 8) 72 | a = [20] 73 | ("foo" * 100 + "\n").each_byte do |b| 74 | a << 22 75 | 0.upto(7) do |i| 76 | a << 22 << 4 << 222 + b[i] * 4 77 | end 78 | a << 4 << 222 79 | end 80 | a << 4 << 222 81 | print a.pack("C*") + [boot].pack("B*") 82 | else 83 | File.write("blc-boot.dat", [boot].pack("B*")) 84 | end 85 | -------------------------------------------------------------------------------- /src/code-gen-pool.rb: -------------------------------------------------------------------------------- 1 | original_list_size = CodeGen::List.size 2 | 3 | #class NesC < CodeGen 4 | # Name = "nesC" 5 | # File = "QR.nc" 6 | # Cmd = "nescc -o QR QR.nc && ./QR > OUTFILE" 7 | # Apt = "nescc" 8 | # def code 9 | # <<-'END'.lines.map {|l| l.strip }.join 10 | # %( 11 | # #include\n 12 | # module QR{}implementation{ 13 | # int main()__attribute__((C,spontaneous)){ 14 | # puts#{E[PREV]}; 15 | # return 0; 16 | # } } 17 | # ) 18 | # END 19 | # # avoid "}}" because of Mustache 20 | # end 21 | #end 22 | 23 | #class Nim_NVSPL2 < CodeGen 24 | # After = Nim 25 | # Obsoletes = Nim 26 | # File = ["QR.nim", "QR.nvspl2"] 27 | # Cmd = ["nim c QR.nim && ./QR > OUTFILE", "ruby vendor/nvspl2.rb QR.nvspl2 > OUTFILE"] 28 | # Apt = ["nim", nil] 29 | # Code = %q(%((for i, c in#{E[PREV]}:echo ",",int(c),"CO");echo "Q")) 30 | #end 31 | 32 | CodeGen::List.slice!(original_list_size..-1).each do |s| 33 | i = CodeGen::List.find_index(s::After) 34 | CodeGen::List.insert(i, s) 35 | [*s::Obsoletes].each {|s_| CodeGen::List.delete(s_) } if defined?(s::Obsoletes) 36 | end 37 | 38 | CodeGen::List.delete(GeneratorScriptingLanguage) 39 | -------------------------------------------------------------------------------- /src/dot.github.workflows.main.yml.gen.rb: -------------------------------------------------------------------------------- 1 | require "yaml" 2 | require_relative "code-gen" 3 | 4 | apts = RunSteps.flat_map {|s| s.apt } 5 | apts = apts.flatten.map {|apt| apt }.compact 6 | apts.delete("ruby2.1") 7 | 8 | srcs = RunSteps.flat_map {|s| s.src } 9 | 10 | cp_cmds = srcs.map do |s| 11 | " sudo docker cp qr:/usr/local/share/quine-relay/#{ s } spoiler/" 12 | end.join("\n") 13 | 14 | File.write(File.join(__dir__, "../.github/workflows/main.yml"), <" % self.object_id) 3 | @name = name.to_s 4 | end 5 | 6 | def inspect 7 | @name 8 | end 9 | 10 | def [](*others) 11 | prev = self 12 | others.each do |other| 13 | sym = Sym.new 14 | $prog << [:app, sym, prev, other] 15 | prev = sym 16 | end 17 | prev 18 | end 19 | end 20 | 21 | w = Sym.new(:W) 22 | succ = Sym.new(:Succ) 23 | out = Sym.new(:Out) 24 | 25 | def fn(name, &blk) 26 | params = blk.parameters.map {|_, param_name| Sym.new(param_name) } 27 | sym = Sym.new(name) 28 | $prog << [:abs, sym, params] 29 | blk[*params] 30 | $prog << [:ret] 31 | sym 32 | end 33 | 34 | $result = [] 35 | [10, 32].each do |smallest_char| 36 | $prog = [] 37 | 38 | succ2 = fn(:succ2) {|n| succ[succ[n]] } 39 | succ4 = fn(:succ4) {|n| succ2[succ2[n]] } 40 | succ8 = fn(:succ8) {|n| succ4[succ4[n]] } 41 | succ16 = fn(:succ16) {|n| succ8[succ8[n]] } 42 | succ32 = fn(:succ32) {|n| succ16[succ16[n]] } 43 | succ64 = fn(:succ64) {|n| succ32[succ32[n]] } 44 | succ128 = fn(:succ128) {|n| succ64[succ64[n]] } 45 | 46 | add_num = ->(n, v) do 47 | ary = [succ128, succ64, succ32, succ16, succ8, succ4, succ2, succ] 48 | until v == 0 49 | f = ary.pop 50 | n = f[n] if v % 2 == 1 51 | v /= 2 52 | end 53 | n 54 | end 55 | 56 | next_char = fn(:next_char) do |n| 57 | sc = add_num[n, 129 + smallest_char] 58 | # n == 127 ? c10 : succ[n] 59 | add_num[w, 8][n, sc, add_num[n, 1]] 60 | end 61 | 62 | sub = fn(:sub) do |magic, n, _, m| 63 | out[n] 64 | magic[magic, next_char[m]] 65 | end 66 | 67 | # http://d.hatena.ne.jp/kikx/20080914 68 | app23 = fn(:app23) {|x, y| y } 69 | magic = fn(:magic) {|magic_, n, g| g[app23, sub[magic_], n] } 70 | 71 | #main = fn(:main) do |n120,n121,n122,n123,n124,n125,n126,n127,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35,n36,n37,n38,n39,n40,n41,n42,n43,n44,n45,n46,n47,n48,n49,n50,n51,n52,n53,n54,n55,n56,n57,n58,n59,n60,n61,n62,n63,n64,n65,n66,n67,n68,n69,n70,n71,n72,n73,n74,n75,n76,n77,n78,n79,n80,n81,n82,n83,n84,n85,n86,n87,n88,n89,n90,n91,n92,n93,n94,n95,n96,n97,n98,n99,n100,n101,n102,n103,n104,n105,n106,n107,n108,n109,n110,n111,n112,n113,n114,n115,n116,n117,n118,n119| 72 | # $prog << [:raw, "!"] 73 | # n120 = n119[n33] 74 | # n121 = n120[n33] 75 | # n122 = n121[n33] 76 | # n123 = n122[n33] 77 | # n124 = n123[n33] 78 | # n125 = n124[n33] 79 | # n126 = n125[n33] 80 | #end 81 | main = Sym.new(:main) 82 | $prog << [:abs, main, (smallest_char..127).map { Sym.new }] 83 | $prog << [:raw, "!"] 84 | $prog << [:ret] 85 | 86 | start = fn(:start) do |start_, main_, n| 87 | m = main_[magic[magic, n]] 88 | w[n, start_, start_[start_, m]][next_char[n]] 89 | end 90 | 91 | fn(:kick) {|_kick| start[start, main, next_char[w]] } 92 | 93 | stacks = [] 94 | stack = [out, succ, w] 95 | a = [] 96 | $prog[0..-2].each do |type, *args| 97 | case type 98 | when :abs 99 | new_sym, params = args 100 | a << "w" * params.size 101 | stacks << ([new_sym] + stack) 102 | stack = params.reverse + stack 103 | when :app 104 | new_sym, sym0, sym1 = args 105 | a << " " + "W" * (stack.index(sym0) + 1) + "w" * (stack.index(sym1) + 1) 106 | stack.unshift(new_sym) 107 | when :ret 108 | stack = stacks.pop 109 | a << "v" 110 | when :raw 111 | a << args.first 112 | end 113 | end 114 | 115 | prologue, epilogue = a.join.split.join.split("!") 116 | def dump(s) 117 | aa = [*"0".."Z"] 118 | a = "" 119 | s.scan(/(v|W*)(w{1,#{aa.size-1}})/) do |s1, s2| 120 | a << (s1 == "v" ? "/" : aa[s1.size]) << aa[s2.size] 121 | end 122 | "#{ a.dump }" 123 | end 124 | epilogue = dump(epilogue) 125 | prologue = dump(prologue) 126 | $result << 128 - smallest_char 127 | $result << prologue 128 | $result << epilogue 129 | end 130 | 131 | open("grass-boot.dat", "w") do |f| 132 | $result.each do |e| 133 | f.puts e 134 | end 135 | end 136 | -------------------------------------------------------------------------------- /src/langs.png.gen.rb: -------------------------------------------------------------------------------- 1 | require_relative "code-gen" 2 | require "cairo" 3 | require "rsvg2" 4 | 5 | # You need to install the two fonts: Raleway and UnifrakturCook. 6 | # * https://www.google.com/fonts/specimen/Raleway 7 | # * https://www.google.com/fonts/specimen/UnifrakturCook 8 | 9 | %w(Raleway UnifrakturCook).each do |font| 10 | if `fc-list #{ font }`.strip.empty? && !ENV["SKIP_FONT_CHECK"] 11 | raise "Font `#{ font }' is not available; to skip this check, set SKIP_FONT_CHECK=1" 12 | end 13 | end 14 | 15 | W = H = 750 16 | surface = Cairo::ImageSurface.new(W, H) 17 | ctx = Cairo::Context.new(surface) 18 | 19 | ctx.line_width = 1 20 | ctx.set_source_rgb(1, 1, 1) 21 | ctx.rectangle(0, 0, W, H) 22 | ctx.fill 23 | ctx.set_source_rgb(0, 0, 0) 24 | 25 | ctx.translate(W / 2, H / 2) 26 | ctx.select_font_face("Raleway") 27 | ctx.antialias = Cairo::Antialias::GRAY 28 | 29 | BaseFontSize = 13 30 | SubFontSize = 10 31 | 32 | Radius = 210.0 33 | RunSteps.each_with_index do |s, i| 34 | ctx.save do 35 | angle = i / (RunSteps.size / 4.0) 36 | dir = 1 < angle && angle <= 3 ? 1 : -1 37 | ctx.rotate(Math::PI / 2 * (dir < 0 ? -angle : 2 - angle + 0.02)) 38 | s.name =~ /^(.*?)(\(.*\))?$/ 39 | name, sub_name = $1, $2 || "" 40 | ctx.font_size = BaseFontSize; e1 = ctx.text_extents(name) 41 | ctx.font_size = SubFontSize ; e2 = ctx.text_extents(sub_name) 42 | ctx.move_to(dir * (Radius + 10) - (dir < 0 ? e1.x_advance + e2.x_advance : 0), 0) 43 | ctx.font_size = BaseFontSize; ctx.show_text(name) 44 | ctx.font_size = SubFontSize ; ctx.show_text(sub_name) 45 | end 46 | end 47 | 48 | ArrowCount = 7 49 | ArrowCount.times do |i| 50 | ctx.save do 51 | ctx.rotate(Math::PI * (2 * i) / ArrowCount - Math::PI + 0.1) 52 | 53 | ctx.line_width = 2 54 | ctx.line_cap = Cairo::LineCap::SQUARE 55 | ctx.new_path 56 | ctx.arc(0, 0, Radius, 0.0, Math::PI * 2 / ArrowCount - 0.1) 57 | ctx.stroke 58 | 59 | ctx.line_width = 1 60 | ctx.move_to(Radius , -8) 61 | ctx.line_to(Radius - 6, 2) 62 | ctx.line_to(Radius + 6, 2) 63 | ctx.fill 64 | end 65 | end 66 | 67 | Uroboros = 350.0 68 | ctx.select_font_face("UnifrakturCook") 69 | ctx.font_size = 25 70 | Title = "#{ RunSteps.size }-Language Uroboros Quine" 71 | e = ctx.text_extents(Title) 72 | height = Uroboros / 2 + e.height + 20 73 | ctx.move_to(-e.width / 2, height / 2) 74 | ctx.show_text(Title) 75 | ctx.save do 76 | svg = RSVG::Handle.new_from_file("uroboros.svg") 77 | ctx.translate(-Uroboros / 2, -height / 2) 78 | ctx.scale(Uroboros / svg.width, Uroboros / svg.width) 79 | ctx.render_rsvg_handle(svg) 80 | end 81 | 82 | surface.write_to_png("../langs.png") 83 | unless ENV["NO_PNG_OPT"] 84 | system 'optipng -fix -i0 -o7 -strip all ../langs.png' 85 | system 'advdef -z4 ../langs.png' 86 | system 'advpng -z4 ../langs.png' 87 | end 88 | 89 | # convert svg to template 90 | # 91 | #require "cairo" 92 | #require "rsvg2" 93 | #H = 52.0 94 | #W = H * 4 95 | #surface = Cairo::ImageSurface.new(W, H) 96 | #ctx = Cairo::Context.new(surface) 97 | #svg = RSVG::Handle.new_from_file("uroboros2.svg") 98 | #ctx.translate(4, 2) 99 | #ctx.rotate(-0.014) 100 | #ctx.scale((W - 8) / svg.width, (H - 4) / svg.height) 101 | #ctx.render_rsvg_handle(svg) 102 | #data = surface.data.unpack("C*") 103 | #M = (0...H).map do |y| 104 | # (0...W).map do |x| 105 | # idx = y * surface.stride + x * 4 106 | # data[idx] < 40 && data[idx + 3] > 48 ? " " : "#" 107 | # end.join 108 | #end 109 | #puts *M 110 | -------------------------------------------------------------------------------- /src/lazyk-boot.dat.gen.rb: -------------------------------------------------------------------------------- 1 | Var = Struct.new(:name) 2 | Abs = Struct.new(:var, :exp) 3 | App = Struct.new(:exp1, :exp2) 4 | Comb = Struct.new(:type) 5 | S, K, I = Comb[:S], Comb[:K], Comb[:I] 6 | 7 | class Var 8 | def fvs 9 | { name => 1 } 10 | end 11 | def remove_abs 12 | self 13 | end 14 | def remove_var(n) 15 | if n == name 16 | I 17 | else 18 | App[K, self] 19 | end 20 | end 21 | def inspect(need_paren = true) 22 | name.to_s 23 | end 24 | end 25 | 26 | class Abs 27 | def fvs 28 | @fvs ||= ( 29 | s = exp.fvs.dup 30 | s.delete(var) 31 | s 32 | ) 33 | end 34 | def remove_abs 35 | exp.remove_abs.remove_var(var) 36 | end 37 | def remove_var(v) 38 | if exp.fvs[v] 39 | exp.remove_abs.remove_var(v) 40 | else 41 | App[K, self] 42 | end 43 | end 44 | def inspect(need_paren = true) 45 | vs, e = [var], exp 46 | while e.is_a?(Abs) 47 | vs << e.var 48 | e = e.exp 49 | end 50 | "(\\#{ vs * " " }. #{ e.inspect(false) })" 51 | end 52 | end 53 | class App 54 | def fvs 55 | @fvs ||= ( 56 | s = exp1.fvs.dup 57 | exp2.fvs.each do |v, n| 58 | s[v] ||= 0 59 | s[v] += n 60 | end 61 | s 62 | ) 63 | end 64 | def remove_abs 65 | App[exp1.remove_abs, exp2.remove_abs] 66 | end 67 | def remove_var(v) 68 | if fvs[v] 69 | if exp2.is_a?(Var) && exp2.name == v && !exp1.fvs[v] 70 | exp1 71 | else 72 | App[App[S, exp1.remove_var(v)], exp2.remove_var(v)] 73 | end 74 | else 75 | App[K, self] 76 | end 77 | end 78 | def inspect(need_paren = true) 79 | s = "%s %s" % [exp1.inspect(false), exp2.inspect(true)] 80 | s = "(#{ s })" if need_paren 81 | s 82 | end 83 | def to_unlambda 84 | "`" + exp1.to_unlambda + exp2.to_unlambda 85 | end 86 | def simplify 87 | if exp1 == I 88 | exp2.simplify # I x -> x 89 | elsif exp1.is_a?(App) 90 | if exp1.exp1 == K 91 | exp1.simplify # K x y -> x 92 | elsif exp1.exp1.is_a?(App) && exp1.exp1.exp1 == S 93 | if exp1.exp1.exp2.is_a?(App) && exp1.exp1.exp2.exp1 == K 94 | App[exp1.exp1.exp2.exp2, App[exp1.exp2, exp2]].simplify # S (K x) y z -> x (y z) 95 | elsif exp1.exp2.is_a?(App) && exp1.exp2.exp1 == K 96 | App[App[exp1.exp1.exp2, exp2], exp1.exp2.exp2].simplify # S x (K y) z -> x z y 97 | else 98 | App[exp1.simplify, exp2.simplify] 99 | end 100 | else 101 | App[exp1.simplify, exp2.simplify] 102 | end 103 | else 104 | App[exp1.simplify, exp2.simplify] 105 | end 106 | end 107 | end 108 | 109 | class Comb 110 | def fvs 111 | {} 112 | end 113 | def remove_abs 114 | self 115 | end 116 | def remove_var(v) 117 | App[K, self] 118 | end 119 | def inspect(need_paren = true) 120 | type.to_s 121 | end 122 | def to_unlambda 123 | type.to_s.downcase 124 | end 125 | def simplify 126 | self 127 | end 128 | end 129 | 130 | def ary2app(exp) 131 | if exp.is_a?(Array) 132 | exp = exp.map {|e| ary2app(e) } 133 | e1 = App[*exp.shift(2)] 134 | exp.each {|e2| e1 = App[e1, e2] } 135 | e1 136 | elsif exp.is_a?(Abs) 137 | Abs[exp.var, ary2app(exp.exp)] 138 | else 139 | exp 140 | end 141 | end 142 | 143 | def to_unlambda(exp) 144 | ary2app(exp).remove_abs.simplify.to_unlambda 145 | end 146 | 147 | def abs(&b) 148 | vars = b.parameters.map {|type, name| name } 149 | exp = yield(*vars.map {|name| Var[name] }) 150 | vars.reverse_each {|v| exp = Abs[v, exp] } 151 | exp 152 | end 153 | 154 | Zero = abs {|s, z| z } 155 | One = abs {|s, z| [s, z] } 156 | Two = abs {|s, z| [s, [s, z]] } 157 | Three = abs {|s, z| [s, [s, [s, z]]] } 158 | Six = abs {|s| [Two, [Three, s]] } 159 | N256 = [abs {|n| [n, n] }, [abs {|n| [n, n] }, abs {|s, z| [s, [s, z]] }]] 160 | Inc = abs {|n, s, z| [s, [[n, s], z]] } 161 | Dbl = abs {|n, s| [n, abs {|x| [s, [s, x]] }] } 162 | Cons = abs {|hd, tl| abs {|f| [f, hd, tl] } } 163 | Pow = abs {|n, m| [m, n] } 164 | IfLE6 = -> m, t, e { [[m, Pow, [K, t]], [Six, Pow, [K, e]]] } 165 | Main = 166 | [ 167 | abs {|x| [x, x, Zero, Zero] }, 168 | abs {|main, count, num, code| 169 | IfLE6[count, 170 | [main, main, [Inc, count], [code, I, Inc, [Dbl, num]]], 171 | [Cons, num, code] 172 | ] 173 | } 174 | ] 175 | 176 | if ARGV[0] 177 | puts "k`" 178 | "foobar\n".bytes do |c| 179 | print "``s" * 8 + "i" 180 | 6.downto(0) {|j| print "`" + "kki"[c[j], 2] } 181 | puts 182 | end 183 | puts "`k`k" + to_unlambda(N256) + to_unlambda(Main) 184 | else 185 | File.write("lazyk-boot.dat", "`k`k" + to_unlambda(N256) + to_unlambda(Main)) 186 | end 187 | -------------------------------------------------------------------------------- /src/test.rb: -------------------------------------------------------------------------------- 1 | # usage: 2 | # ruby test.rb # test all Steps 3 | # ruby test.rb Perl # test only Perl Step 4 | 5 | require_relative "code-gen" 6 | 7 | ENV["PATH"] = "vendor/local/bin:#{ ENV["PATH"] }" 8 | 9 | dir = File.join(File.dirname(__dir__), "tmp") 10 | Dir.mkdir(dir) unless File.directory?(dir) 11 | Dir.chdir(dir) 12 | File.symlink("../vendor", "vendor") unless File.symlink?("vendor") 13 | 14 | gens = ARGV[0] ? [eval(ARGV[0]).gen_step] : GenSteps[0..-2] 15 | text = ARGV[1] || "Hello" 16 | 17 | all_check = true 18 | 19 | gens.each do |gen_step| 20 | puts "test: %s" % gen_step.name 21 | 22 | code = Object.new.instance_eval(GenPrologue + gen_step.code.sub("PREV") { text.dump }) + "\n" 23 | code.sub!("%%", "%") if gen_step.name == "Octave_Ook" 24 | 25 | steps = [*gen_step.run_steps, RunStep[nil, "QR.txt"]] 26 | 27 | File.write(steps.first.src, code) 28 | 29 | steps.each_cons(2) do |src, dst| 30 | cmd = src.cmd_raw.gsub("OUTFILE", dst.src) 31 | puts "cmd: " + cmd 32 | system(cmd) || raise("failed") 33 | end 34 | 35 | check = File.read("QR.txt").strip == text 36 | all_check &&= check 37 | puts "result: #{ check ? "OK" : "NG" }" 38 | puts 39 | end 40 | 41 | puts all_check ? "all ok" : "something wrong" 42 | -------------------------------------------------------------------------------- /src/thumbnail.png.gen.rb: -------------------------------------------------------------------------------- 1 | require "chunky_png" 2 | 3 | # zcat /usr/share/fonts/X11/misc/4x6.pcf.gz | 4 | # pcf2bdf | 5 | # ruby -e '$<.each("") {|s| (n = $1.to_i; puts " %3d => 0x%s," % [n, $2.split.map {|n| n[0] }.join] if 32 <= n && n <= 126) if s =~ /ENCODING (\d+).*BITMAP(.*)ENDCHAR/m }' 6 | 7 | FONT = { 8 | 32 => 0x000000, 33 => 0x444040, 34 => 0xAA0000, 35 => 0xAFAFA0, 9 | 36 => 0x4EC2E4, 37 => 0x824820, 38 => 0x4A4A50, 39 => 0x440000, 10 | 40 => 0x244442, 41 => 0x844448, 42 => 0xA4E4A0, 43 => 0x44E440, 11 | 44 => 0x000048, 45 => 0x00E000, 46 => 0x000040, 47 => 0x224880, 12 | 48 => 0x4AEA40, 49 => 0x4C44E0, 50 => 0x4A24E0, 51 => 0xE242C0, 13 | 52 => 0xAAE220, 53 => 0xE8C2C0, 54 => 0x68CA40, 55 => 0xE24880, 14 | 56 => 0x6A4AC0, 57 => 0x4A62C0, 58 => 0x040040, 59 => 0x040048, 15 | 60 => 0x248420, 61 => 0x0E0E00, 62 => 0x842480, 63 => 0xC24040, 16 | 64 => 0x6AA860, 65 => 0x4AEAA0, 66 => 0xCACAC0, 67 => 0x4A8A40, 17 | 68 => 0xCAAAC0, 69 => 0xE8C8E0, 70 => 0xE8C880, 71 => 0x68AA60, 18 | 72 => 0xAAEAA0, 73 => 0xE444E0, 74 => 0x222A40, 75 => 0xAACAA0, 19 | 76 => 0x8888E0, 77 => 0xAEEAA0, 78 => 0x2AEA80, 79 => 0x4AAA40, 20 | 80 => 0xCAC880, 81 => 0x4AAA42, 82 => 0xCACAA0, 83 => 0x6842C0, 21 | 84 => 0xE44440, 85 => 0xAAAAE0, 86 => 0xAAAE40, 87 => 0xAAEEA0, 22 | 88 => 0xAA4AA0, 89 => 0xAA4440, 90 => 0xE248E0, 91 => 0x644460, 23 | 92 => 0x884220, 93 => 0xC444C0, 94 => 0x4A0000, 95 => 0x00000E, 24 | 96 => 0x420000, 97 => 0x06AA60, 98 => 0x8CAAC0, 99 => 0x068860, 25 | 100 => 0x26AA60, 101 => 0x04AC60, 102 => 0x24E440, 103 => 0x06A62C, 26 | 104 => 0x8CAAA0, 105 => 0x40C4E0, 106 => 0x20222C, 107 => 0x8ACAA0, 27 | 108 => 0xC444E0, 109 => 0x0AEAA0, 110 => 0x0CAAA0, 111 => 0x04AA40, 28 | 112 => 0x0CAC88, 113 => 0x06AA62, 114 => 0x0AC880, 115 => 0x06C2C0, 29 | 116 => 0x4E4420, 117 => 0x0AAA60, 118 => 0x0AAA40, 119 => 0x0AAEA0, 30 | 120 => 0x0A44A0, 121 => 0x0AA62C, 122 => 0x0E24E0, 123 => 0x24C442, 31 | 124 => 0x444440, 125 => 0x846448, 126 => 0x5A0000 32 | } 33 | 34 | src = File.foreach("../QR.rb").to_a 35 | 36 | w = src.map {|line| line.chomp.size }.max 37 | h = src.size 38 | 39 | png = ChunkyPNG::Image.new(w * 4, h * 8, :black) 40 | src.each_with_index do |line, j| 41 | line.chomp.chars.each_with_index do |ch, i| 42 | 6.times do |y| 43 | 4.times do |x| 44 | png[i * 4 + 3 - x, j * 8 + y + 1] = 45 | [:black, :white][FONT[ch.ord][x + (5 - y) * 4]] 46 | end 47 | end 48 | end 49 | end 50 | png.save('../thumbnail.png') 51 | -------------------------------------------------------------------------------- /src/uroboros.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/uroboros.txt: -------------------------------------------------------------------------------- 1 | ################################################################################################################################################################################################################### 2 | ################################################################################################################################################################################################################### 3 | ################################################################################################################################################################################################################### 4 | ################################################################################################################################################################################################################### 5 | ################################################################################################################################################################################################################### 6 | ################################################################################################################################################################################################################### 7 | ############################################ ######### ########################################################################################################################################################### 8 | ################################# ###### #### ######## ################################################################################################################################################ 9 | ############################### ### # #################################################################################### ############################################# 10 | ############################# ## ############################################################### ##################################### 11 | ########################### ############################################################ ################################ 12 | ########################## ################################################# ############################ 13 | ######################### ########################################## ######################### 14 | ####################### ######################################### ###################### 15 | ##################### #### ################################## ############## ################### 16 | #################### ##### ############################ ############################ ################## 17 | ################### #### ########################### ###################################### ################ 18 | ################### ###################### ###################### ############################################ ############## 19 | ################### #### ################################## ################# ################################################## ############# 20 | ##################### ################################################# ############# ###################################################### ########### 21 | ################## ################################################### ############ ########################################################## ########## 22 | ############### ######################################################## ######## ############################################################# ######### 23 | ############## ############################################################ #### ################################################################# ######## 24 | ############ ############################################################### ## ############################################################################### ######## 25 | ########## ################################################################### ###### ############################################################### ####### 26 | ######### ###################################################################### ################################################### ###### 27 | ######## ######################################################################## ############################################## ###### 28 | ####### ########################################################################### ######################################### ###### 29 | ####### ############################################################################ ##################################### ###### 30 | ###### ############################################################################### ################################## ##### 31 | ###### ################################################################################ ############################### ##### 32 | ##### ################################################################################## ########################### ##### 33 | ##### ################################################################################### ######################## ###### 34 | ##### ################################################################################## # ##################### ###### 35 | ##### ################################################################################ ## ########## #### ################## ###### 36 | ##### ############################################################################### # ############# ########### ############### ####### 37 | ###### ############################################################################# # ############## ############## ##### ############ ####### 38 | ###### ########################################################################## ## ############################### ############ ######### ######## 39 | ####### ######################################################################## #### ################################ ################ ###### ######### 40 | ######## ##################################################################### ######## ################################ ################### ### ########## 41 | ######## ################################################################## ########## #################################################### # ########### 42 | ######### ############################################################### ############## ################################################# ############ 43 | ########## ############################################################ ################## ############################################# ############## 44 | ############ ####################################################### ##################### ####################################### ############### 45 | ############# ################################################### ######################## ############################### ################# 46 | ############### ############################################# ############################ ################## ################### 47 | ################# ####################################### ################################## ##################### 48 | ################### ############################## ###################################### ####################### 49 | ##################### ############### ############################################ ########################## 50 | ######################## ################################################## ############################# 51 | ########################### ######################################################### ################################# 52 | ################################ ################################################################# ##################################### 53 | ###################################### ############################################################################### ############################################ 54 | ################################################################################################################################################################################################################### 55 | ################################################################################################################################################################################################################### 56 | ################################################################################################################################################################################################################### 57 | ################################################################################################################################################################################################################### 58 | ################################################################################################################################################################################################################### 59 | ################################################################################################################################################################################################################### 60 | -------------------------------------------------------------------------------- /src/wasm-tmpl.dat.gen.rb: -------------------------------------------------------------------------------- 1 | def f(s) 2 | enc = -> n { [n].pack("V").unpack1("H*").gsub(/../){"\\"+$&} } 3 | esc = -> s { s.gsub(?\\){'\\\\'}.gsub(?"){'\\"'} } 4 | 5 | wasm_txt_pre = <<-'END'.lines.map {|s| s.strip }.join + enc[s.size * 16 + 3] 6 | (module 7 | (import "wasi_snapshot_preview1" "fd_write" (func(param i32 i32 i32 i32)(result i32))) 8 | (memory(export "memory")(data "\08\00\00\00 9 | END 10 | 11 | raise unless wasm_txt_pre.size % 4 == 0 12 | 13 | wasm_txt_post = <<-'END'.lines.map {|s| s.strip }.join 14 | ")) 15 | (func(export "_start")i32.const 1 i32.const 0 i32.const 1 i32.const 0 call 0 drop) 16 | ) 17 | END 18 | 19 | txt = <<-END 20 | (module 21 | (import "wasi_snapshot_preview1" "fd_write"(func $fd_write(param i32 i32 i32 i32)(result i32))) 22 | (memory 64) 23 | (export "memory"(memory 0)) 24 | (data(i32.const 0)"#{ 25 | enc[8*5]+enc[1] # " " 26 | }#{ 27 | enc[8*5+4]+enc[2] # "\t" 28 | }#{ 29 | enc[8*5+8]+enc[2] # "\n" 30 | }#{ 31 | enc[8*5+12]+enc[wasm_txt_pre.size] 32 | }#{ 33 | enc[8*5+12+wasm_txt_pre.size]+enc[wasm_txt_post.size] 34 | } ...\\\\t..\\\\n..#{ esc[wasm_txt_pre] }#{ esc[wasm_txt_post] }#{ s }") 35 | (func $out(param i32) 36 | i32.const 1 37 | local.get 0 38 | i32.const 8 39 | i32.mul 40 | i32.const 1 41 | i32.const #{ 8 * 5 + 12 } 42 | call $fd_write 43 | drop 44 | ) 45 | (func(export "_start") 46 | (local $idx i32) 47 | (local $shift i32) 48 | 49 | i32.const 3 50 | call $out 51 | 52 | i32.const #{ 8*5+12+wasm_txt_pre.size+wasm_txt_post.size } 53 | local.set $idx 54 | (loop 55 | i32.const 0 call $out (; out << 32 ;) 56 | i32.const 0 call $out (; out << 32 ;) 57 | i32.const 0 call $out (; out << 32 ;) 58 | 59 | i32.const 8 60 | local.set $shift 61 | (loop 62 | local.get $idx 63 | i32.load8_u 64 | local.get $shift 65 | i32.const 1 66 | i32.sub 67 | local.tee $shift 68 | i32.shr_u 69 | i32.const 1 70 | i32.and 71 | call $out (; out << 32 - c[7-i] * 23 ;) 72 | 73 | local.get $shift 74 | br_if 0 75 | ) 76 | i32.const 2 call $out (; out << 10 ;) 77 | i32.const 1 call $out (; out << 9 ;) 78 | i32.const 2 call $out (; out << 10 ;) 79 | i32.const 0 call $out (; out << 32 ;) 80 | i32.const 0 call $out (; out << 32 ;) 81 | 82 | local.get $idx 83 | i32.const 1 84 | i32.add 85 | local.tee $idx 86 | i32.load8_u 87 | br_if 0 88 | ) 89 | i32.const 2 call $out (; out << 10 ;) 90 | i32.const 2 call $out (; out << 10 ;) 91 | i32.const 2 call $out (; out << 10 ;) 92 | 93 | i32.const 4 94 | call $out 95 | ) 96 | ) 97 | END 98 | end 99 | 100 | File.write("ABCD.wat", f("abcd")) 101 | File.write("ABCDE.wat", f("abcde")) 102 | system("wat2wasm ABCD.wat", exception: true) 103 | system("wat2wasm ABCDE.wat", exception: true) 104 | abcd = File.binread("ABCD.wasm") 105 | abcde = File.binread("ABCDE.wasm") 106 | i = (0..).find {|i| abcd[i] != abcde[i] } 107 | j = (abcd.size - 4).downto(0).find {|i| abcd[i] != abcde[i] } 108 | 109 | data1 = abcd[0, i] 110 | raise unless data1 == abcde[0, i] 111 | data2 = abcd[i + 2, 5] 112 | raise unless data2 == abcde[i + 2, 5] 113 | data3 = abcd[i + 2 + 5 + 2...j-1] 114 | raise unless data3 == abcde[i + 2 + 5 + 2...j-1] 115 | data4 = abcd[j + 12-1...-4] 116 | 117 | # wasm template: 118 | # data1 + LSB128(length+const) + data2 + LSB128(length+const) + data3 + Hexdump(length) + data4 119 | 120 | 121 | A = [26, 34, 86, 127, 148, 158, 200] 122 | def e(data) 123 | enc = "".b 124 | data.bytes do |n| 125 | case 126 | when n < 0x1a 127 | enc << [n + ?B.ord].pack("C*") 128 | when ?9.ord <= n && n < ?9.ord + A.size 129 | raise 130 | when n < 32 || n == ?".ord || (?B.ord <= n && n <= ?Z.ord) || n >= 127 131 | enc << [?9.ord + A.index(n)].pack("C*") 132 | else 133 | enc << n 134 | end 135 | end 136 | enc 137 | end 138 | 139 | def d(data) 140 | data.gsub(/./) { "9" <= $& && $& < "@" ? [A[$&.ord - ?9.ord]].pack("C*") : "A" < $& && $& < "Z" ? [$&.ord - ?B.ord].pack("C*") : $& } 141 | end 142 | 143 | [data1, data2, data3, data4].each do |data| 144 | raise unless data == d(e(data)) 145 | end 146 | 147 | File.open("wasm-tmpl.dat", "w") do |f| 148 | f.puts A.join(",") 149 | f.puts e(data1) 150 | f.puts e(data2) 151 | f.puts e(data3) 152 | f.puts e(data4) 153 | end 154 | 155 | d=->s,t=?"{s.gsub(t){t+t}}; 156 | out = "ABCDE" 157 | 158 | # test code 159 | raise if data3.size + data4.size + 18 != 292 160 | n = 292+out.size 161 | m = (n.bit_length - 1) / 7 162 | puts <124)*(#{6+m}*c-#{m+n+125*(6+m)}) 174 | Do While n>127 175 | s.WriteByte(128+(127And n)) 176 | n\\=128 177 | Loop 178 | s.WriteByte(If(c<125,If((c-1)\\7-8,c+66*(c>65And c<91),t(c-57)),n)) 179 | End If 180 | Next 181 | For Each c in"#{d[out]}" 182 | s.WriteByte(Asc(c)) 183 | Next 184 | End Sub 185 | End Module 186 | END 187 | -------------------------------------------------------------------------------- /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/thumbnail.png -------------------------------------------------------------------------------- /vendor/.gitignore: -------------------------------------------------------------------------------- 1 | Spl/ 2 | goaheui/ 3 | lci-*/ 4 | npiet-*/ 5 | cfunge-*/ 6 | Acme-Chef-*/ 7 | local/ 8 | spl-*/ 9 | -------------------------------------------------------------------------------- /vendor/Acme-Chef-1.03.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/vendor/Acme-Chef-1.03.tar.gz -------------------------------------------------------------------------------- /vendor/Makefile: -------------------------------------------------------------------------------- 1 | LCI := lci-0.10.5 2 | NPIET := npiet-1.3e 3 | CFUNGE := cfunge-0.9.0 4 | ACME_CHEF := Acme-Chef-1.03 5 | SPL := spl-1.2.1 6 | LOCAL := $(CURDIR)/local 7 | 8 | .NOTPARALLEL: 9 | all: $(LOCAL)/bin/lci $(LOCAL)/bin/npiet $(LOCAL)/bin/cfunge $(LOCAL)/bin/compilechef $(LOCAL)/bin/lazyk $(LOCAL)/bin/spl2c $(LOCAL)/bin/Vlt.exe 10 | 11 | $(LOCAL)/bin/lci: 12 | unzip -q $(LCI).zip 13 | (cd $(LCI) && cmake -DCMAKE_INSTALL_PREFIX=$(LOCAL) . && make && make install) 14 | 15 | $(LOCAL)/bin/npiet: 16 | tar xzf $(NPIET).tar.gz 17 | (cd $(NPIET) && ./configure --prefix=$(LOCAL) && make && make install) 18 | 19 | $(LOCAL)/bin/cfunge: 20 | tar xjf $(CFUNGE).tar.bz2 21 | (cd $(CFUNGE) && cmake -DCMAKE_INSTALL_PREFIX=$(LOCAL) . && make && make install) 22 | 23 | $(LOCAL)/bin/compilechef: 24 | tar xzf $(ACME_CHEF).tar.gz 25 | (cd $(ACME_CHEF) && perl Makefile.PL INSTALL_BASE=$(LOCAL) && make && make install) 26 | 27 | $(LOCAL)/bin/lazyk: 28 | $(CC) lazyk.c -o $@ 29 | 30 | $(LOCAL)/bin/spl2c: 31 | tar xzf $(SPL).tar.gz 32 | (cd $(SPL) && ln -s ../local spl && make spl2c CCFLAGS="-O0 -g -Wall" && make install) 33 | 34 | $(LOCAL)/bin/Vlt.exe: 35 | unzip -d $(LOCAL)/bin -q Velato_0_1.zip 36 | 37 | clean: 38 | rm -rf $(LOCAL)/ $(LCI)/ $(NPIET)/ $(CFUNGE)/ $(ACME_CHEF)/ $(SPL)/ 39 | -------------------------------------------------------------------------------- /vendor/README: -------------------------------------------------------------------------------- 1 | Unlambda: unlambda.rb 2 | * self-made 3 | * License: MIT 4 | 5 | Whitespace: whitespace.rb 6 | * self-made 7 | * License: MIT 8 | 9 | Subleq: subleq.rb 10 | * self-made 11 | * License: MIT 12 | 13 | Thue: thue.rb 14 | * self-made 15 | * License: MIT 16 | 17 | Ook!: ook-to-bf.rb 18 | * self-made 19 | * License: MIT 20 | 21 | BLC8: blc.rb 22 | * self-made 23 | * License: MIT 24 | 25 | FALSE: false.rb 26 | * self-made 27 | * License: MIT 28 | 29 | Aheui: aheui.rb 30 | * self-made 31 | * License: MIT 32 | 33 | ante: ante.rb 34 | * https://github.com/michaeldv 35 | * License: MIT 36 | 37 | Befunge: cfunge-0.9.0.tar.bz2 38 | * http://sourceforge.net/projects/cfunge/ 39 | * License: GPL3 40 | 41 | Chef: Acme-Chef-1.03.tar.gz 42 | * https://metacpan.org/pod/Acme::Chef 43 | * License: the same terms as Perl (Artistic License) 44 | 45 | Grass: grass.rb 46 | * http://www.blue.sky.or.jp/grass/ 47 | * License: BSD 2-Clause 48 | * slightly modified for Ruby 2+ 49 | 50 | GolfScript: golfscript.rb 51 | * http://www.golfscript.com/golfscript/ 52 | * License: MIT 53 | 54 | LOLCODE: lci-0.10.5.zip 55 | * http://lolcode.org/ 56 | * License: GPL3+ 57 | 58 | Piet: npiet-1.3e.tar.gz 59 | * http://www.bertnase.de/npiet/ 60 | * License: GPL2 61 | 62 | Lazy K: lazyk.c 63 | * https://github.com/irori/lazyk 64 | * License: GPL2+ 65 | 66 | Shakespeare: spl-1.2.1.tar.gz 67 | * http://shakespearelang.sourceforge.net/ 68 | * License: GPL 69 | 70 | Velato: Velato_0_1.zip 71 | * http://velato.net/ 72 | * License: freeware 73 | -------------------------------------------------------------------------------- /vendor/Velato_0_1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/vendor/Velato_0_1.zip -------------------------------------------------------------------------------- /vendor/aheui.rb: -------------------------------------------------------------------------------- 1 | # https://aheui.readthedocs.io/en/latest/specs.en.html 2 | 3 | code = $<.each_line.map do |s| 4 | s.chomp.unpack("U*").map do |c| 5 | if 0xac00 <= c && c <= 0xd7a3 6 | c -= 0xac00 7 | # Hangul initial consonant, vowel, final consonant 8 | [c / 21 / 28, c / 28 % 21, c % 28] 9 | end 10 | end 11 | end 12 | 13 | def read_int 14 | s = "" 15 | while true 16 | ch = $stdin.getc 17 | case ch 18 | when /\d+/ then s << ch 19 | when /\s+/ then break 20 | else raise "Integer expected" 21 | end 22 | end 23 | s.to_i 24 | end 25 | 26 | STROKE_TABLE = [0,2,4,4,2,5,5,3,5,7,9,9,7,9,9,8,4,4,6,2,4,nil,3,4,3,4,4,nil] 27 | 28 | x, y, dx, dy, s = 0, 0, 0, 1, 0 29 | ss = (0..27).map { [] } 30 | def (ss[21]).pop; shift; end # queue 31 | ss[27] = nil # extension protocol 32 | 33 | check_size = -> n do 34 | if ss[s].size >= n 35 | true 36 | else 37 | dx, dy = -dx, -dy 38 | false 39 | end 40 | end 41 | 42 | while true 43 | ic, vo, fc = code[y][x] 44 | 45 | case ic 46 | when 11 # null 47 | when 18 then exit # terminate 48 | when 3 then check_size[2] && (a, b = ss[s].pop, ss[s].pop; ss[s] << b + a) 49 | when 4 then check_size[2] && (a, b = ss[s].pop, ss[s].pop; ss[s] << b * a) 50 | when 2 then check_size[2] && (a, b = ss[s].pop, ss[s].pop; ss[s] << b / a) 51 | when 16 then check_size[2] && (a, b = ss[s].pop, ss[s].pop; ss[s] << b - a) 52 | when 5 then check_size[2] && (a, b = ss[s].pop, ss[s].pop; ss[s] << b % a) 53 | when 6 # pop 54 | if check_size[1] 55 | v = ss[s].pop 56 | case fc 57 | when 21 then puts v 58 | when 27 then print v.chr("UTF-8") 59 | end 60 | end 61 | when 7 # push 62 | case fc 63 | when 21 then ss[s] << read_int 64 | when 27 then ss[s] << $stdin.getc.ord 65 | else ss[s] << STROKE_TABLE[fc] 66 | end 67 | when 8 then check_size[1] && ss[s] << ss[s][s != 21 ? -1 : 0] # duplicate 68 | when 17 # swap 69 | if check_size[2] 70 | r = s != 21 ? (-2..-1) : (0..1) 71 | ss[s][r] = ss[s][r].reverse 72 | end 73 | when 9 then s = fc # select 74 | when 10 then check_size[1] && ss[fc] << ss[s].pop # transfer 75 | when 12 # compare 76 | check_size[2] && ss[fc] << (ss[s].pop <= ss[s].pop ? 1 : 0) 77 | when 14 # fork 78 | dx, dy = -dx, -dy if check_size[1] && ss[fc].pop != 0 79 | end 80 | 81 | case vo 82 | when 0 then dx, dy = 1, 0 83 | when 2 then dx, dy = 2, 0 84 | when 4 then dx, dy = -1, 0 85 | when 6 then dx, dy = -2, 0 86 | when 8 then dx, dy = 0, -1 87 | when 12 then dx, dy = 0, -2 88 | when 13 then dx, dy = 0, 1 89 | when 17 then dx, dy = 0, 2 90 | when 18 then dy = -dy 91 | when 19 then dx, dy = -dx, -dy 92 | when 20 then dx = -dx 93 | end 94 | 95 | x, y = x + dx, y + dy 96 | end 97 | -------------------------------------------------------------------------------- /vendor/ante.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # encoding: utf-8 3 | # 4 | # Copyright (c) 2013 Michael Dvorkin 5 | # 6 | # Ante is an esoteric programming language where all you've got is 7 | # a deck of cards. 8 | # 9 | # 95% of this code was developed on the way back from RubyConf 2013 10 | # during 5-hour flight from Miami to San Francisco. 11 | # 12 | ### require "awesome_print" 13 | 14 | class Array 15 | def rank; self[0] end 16 | def suit; self[1] end 17 | def rank=(value); self[0] = value end 18 | def suit=(value); self[1] = value end 19 | end 20 | 21 | class Ante 22 | def initialize() 23 | @♦, @♥, @♠, @♣ = 0, 0, 0, 0 24 | @line, @pc = 0, 0 25 | @code, @labels = [], {} 26 | end 27 | 28 | def run(source) 29 | parse(source) 30 | ### ap @code; ap @labels 31 | 32 | while card = @code[@pc] 33 | @pc += 1 34 | case card.rank 35 | when nil then newline(card) 36 | when "K" then jump(card) 37 | when "Q" then next 38 | when "J" then dump(card, :char) 39 | when 10 then dump(card) 40 | else assign(card) 41 | end 42 | end 43 | end 44 | 45 | def parse(source) 46 | lines = source.split("\n").map { |line| line.sub(/#.*$/, "").strip } 47 | ### ap lines 48 | 49 | # Turn source file into array of cards. Each card is 2-item 50 | # array of rank and suit. 51 | lines.each_with_index do |line, i| 52 | @code += [[ nil, i + 1 ]] # <-- Line number cards have nil rank. 53 | @code += line.scan(/(10|[2-9JQKA])([♦♥♠♣])/) 54 | end 55 | 56 | # A pass to convert ranks to Fixnum and extract labels. 57 | pc = 0 58 | while card = @code[pc] 59 | pc += 1 60 | if card.rank =~ /\d/ 61 | card.rank = card.rank.to_i 62 | elsif card.rank == "Q" 63 | queen = card.suit 64 | while @code[pc] && @code[pc].rank == "Q" && @code[pc].suit == card.suit 65 | queen += card.suit 66 | pc += 1 67 | end 68 | @labels[queen] = pc 69 | end 70 | end 71 | end 72 | 73 | def newline(card) 74 | # puts "newline #{card}" 75 | @line = card.suit 76 | end 77 | 78 | def assign(card) 79 | # puts "assign #{card.inspect}" 80 | operands = remaining(card) 81 | expression(operands) 82 | end 83 | 84 | def jump(card) 85 | # puts "jump #{card.inspect}, pc: #{@pc.inspect}, #{@labels.inspect}" 86 | suit = card.suit 87 | while @code[@pc] && @code[@pc].rank == "K" && @code[@pc].suit == card.suit 88 | suit += card.suit 89 | @pc += 1 90 | end 91 | 92 | if instance_variable_get("@#{suit[0]}") != 0 93 | # puts "jumping to " << "Q#{suit[0]}" * suit.size 94 | if @labels[suit] 95 | @pc = @labels[suit] 96 | else 97 | exception("can't find " << "Q#{suit[0]}" * suit.size << " to go to") 98 | end 99 | end 100 | end 101 | 102 | def dump(card, char = nil) 103 | # puts "dump #{card.inspect} => " 104 | value = instance_variable_get("@#{card.suit}") 105 | if char 106 | if value.between?(0, 255) 107 | print value.chr 108 | else 109 | exception("character code #{value} is out of 0..255 range") 110 | end 111 | else 112 | print value 113 | end 114 | end 115 | 116 | # Fetch the rest of the assignment expression. 117 | def remaining(card) 118 | operands = [ card ] 119 | while card = @code[@pc] 120 | break if card.rank.nil? || card.rank.to_s =~ /[KQJ]/ 121 | operands += [ card ] 122 | @pc += 1 123 | end 124 | ### ap "remaining: #{operands.inspect}" 125 | operands 126 | end 127 | 128 | def expression(operands) 129 | initial, target = operands.shift 130 | initial = instance_variable_get("@#{target}") if initial == "A" 131 | operands.each do |rank, suit| 132 | # puts "rank: #{rank.inspect}, suit: #{suit.inspect}" 133 | rank = instance_variable_get("@#{suit}") if rank == "A" 134 | case suit 135 | when "♦" then initial += rank 136 | when "♥" then initial *= rank 137 | when "♠" then initial -= rank 138 | when "♣" then 139 | if rank != 0 140 | initial /= rank 141 | else 142 | exception("division by zero") 143 | end 144 | end 145 | end 146 | instance_variable_set("@#{target}", initial) 147 | # dump_registers 148 | end 149 | 150 | def exception(message) 151 | abort("Ante exception: #{message} on line #{@line} (pc:#{@pc})") 152 | end 153 | 154 | def dump_registers 155 | instance_variables.each do |i| 156 | puts " #{i}: " + instance_variable_get("#{i}").to_s if i.size == 2 157 | end 158 | end 159 | end 160 | 161 | if ARGV[0] 162 | Ante.new.run(IO.read(ARGV[0], encoding: "UTF-8")) 163 | else 164 | puts "usage: ante filename.ante" 165 | end 166 | -------------------------------------------------------------------------------- /vendor/bf.rb: -------------------------------------------------------------------------------- 1 | code = File.read($*[0]).unpack("C*") 2 | data = [0] 3 | i = j = 0 4 | while code[i] 5 | case code[i] 6 | when 60 # < 7 | j -= 1 8 | when 62 # > 9 | j += 1 10 | data[j] ||= 0 11 | when 43 # + 12 | data[j] += 1 13 | when 45 # - 14 | data[j] -= 1 15 | when 91 # [ 16 | if data[j] == 0 17 | d = 0 18 | i += 1 19 | until d == 0 && code[i] == 93 # ] 20 | case code[i] 21 | when 91 # [ 22 | d += 1 23 | when 93 # ] 24 | d -= 1 25 | end 26 | i += 1 27 | end 28 | end 29 | when 93 # ] 30 | d = 0 31 | i -= 1 32 | until d == 0 && code[i] == 91 # [ 33 | case code[i] 34 | when 91 # [ 35 | d -= 1 36 | when 93 # ] 37 | d += 1 38 | end 39 | i -= 1 40 | end 41 | next 42 | when 46 # . 43 | putc(data[j]) 44 | when 44 # , 45 | data[j] = $stdin.getc 46 | end 47 | i += 1 48 | end 49 | -------------------------------------------------------------------------------- /vendor/blc.rb: -------------------------------------------------------------------------------- 1 | # Binary lambda calculus interpreter 2 | # 3 | # (C) Copyright 2014, 2015, Yusuke Endoh 4 | # License: MIT 5 | # 6 | # See in detail: http://tromp.github.io/cl/cl.html 7 | 8 | # BLC8 or not 9 | binary_mode = ARGV.empty? 10 | $stdout.sync = true 11 | 12 | # abstract syntax tree 13 | Var = -> v { [:var, v] } 14 | Abs = -> e { [:abs, e] } 15 | App = -> e1, e2 { [:app, e1, e2] } 16 | 17 | # bit stream 18 | current_byte, bit_offset = nil, 0 19 | get_byte = -> do 20 | bit_offset = binary_mode ? 8 : 1 21 | current_byte = $stdin.getbyte 22 | end 23 | get_bit = -> do 24 | get_byte[] if bit_offset == 0 25 | bit_offset -= 1 26 | current_byte ? current_byte[bit_offset] == 0 : false 27 | end 28 | 29 | # parse 30 | stack, acc = [:exp], nil 31 | until stack.empty? 32 | v = stack.pop 33 | acc = case v 34 | when :exp 35 | if get_bit[] 36 | stack << (get_bit[] ? :abs : :app1) << :exp 37 | nil 38 | else 39 | v = 0 40 | v += 1 until get_bit[] 41 | Var[v] 42 | end 43 | when :abs then Abs[acc] 44 | when :app1 then stack << acc << :exp; nil 45 | else App[v, acc] # parsing two exps of app finished 46 | end 47 | end 48 | bit_offset = 0 # force to align bit offset 49 | 50 | # I/O 51 | cons = -> a, b { Abs[App[App[Var[0], a], b]] } 52 | bool = -> b { Abs[Abs[Var[b ? 1 : 0]]] } 53 | if binary_mode 54 | read = -> i { i > 0 ? cons[bool[get_bit[]], read[i - 1]] : bool[false] } 55 | in_ = [:in, -> { get_byte[] ? cons[read[8], in_] : bool[false] }] 56 | outc = 0 57 | out0, out1 = [0, 1].map {|n| [:out, -> { outc = (2 * outc + n) & 255 }] } 58 | out0[2] = out1[2] = App[Var[0], cons[out0, out1]] 59 | outn = [:out, -> { putc(outc) }] 60 | out_ = outn[2] = App[Var[0], cons[cons[out0, out1], outn]] 61 | else 62 | in_ = [:in, -> { get_byte[] ? cons[bool[get_bit[]], in_] : bool[false] }] 63 | out0, out1 = [0, 1].map {|n| [:out, -> { print(n) }] } 64 | out_ = out0[2] = out1[2] = App[Var[0], cons[out0, out1]] 65 | end 66 | 67 | # eval-loop 68 | exp = App[Abs[out_], App[acc, in_]] 69 | env, stack = [], [[nil, nil]] 70 | while true 71 | case exp[0] 72 | when :var 73 | exp[1].times { env = env[2] } 74 | if env.frozen? 75 | valexp, valenv = env # already forced 76 | else # not forced yet 77 | stack.last << env 78 | exp, env = env[0], env[1] 79 | next 80 | end 81 | when :app 82 | stack << [exp[2], env] 83 | next exp = exp[1] 84 | when :abs 85 | valexp, valenv = exp[1], env 86 | when :in then next exp = exp[1][] 87 | when :out then exp[1][]; valexp, valenv = exp[2], env 88 | end 89 | env = stack.pop 90 | until env.size == 2 91 | th = env.pop 92 | th[0] = valexp # force 93 | th[1] = valenv 94 | th.freeze 95 | end 96 | break unless env[0] 97 | exp = valexp 98 | env[2] = valenv 99 | end 100 | -------------------------------------------------------------------------------- /vendor/cfunge-0.9.0.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/vendor/cfunge-0.9.0.tar.bz2 -------------------------------------------------------------------------------- /vendor/dummy-wasi-runtime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define/* 4 | 5 | f = ARGV[0] 6 | system("wasm2c", f, "-o", f + ".c", exception: true) 7 | system("gcc", "-DWASM_RT_MODULE_PREFIX=Z_" + File.basename(f, ".wasm").gsub(".", "Z2E"), "-o", "dummy-wasi-exec", f + ".c", __FILE__, "-include", f + ".h", "-lwasm-rt-impl", "-I.", exception: true) 8 | exec("./dummy-wasi-exec") 9 | __END__ 10 | */DUMMY 11 | 12 | #ifndef WASM_RT_ADD_PREFIX 13 | #define WASM_RT_PASTE_(x, y) x ## y 14 | #define WASM_RT_PASTE(x, y) WASM_RT_PASTE_(x, y) 15 | #define WASM_RT_ADD_PREFIX(x) WASM_RT_PASTE(WASM_RT_MODULE_PREFIX, x) 16 | #endif 17 | 18 | // This is a dummy WASI implementation based on wasm2c. 19 | // It supports only "wasi_snapshot_preview1.fd_write" for stdout. 20 | // This should be replaced if a proper WASI implementation 21 | // (such as wasmtime) becomes available. 22 | // 23 | // Usage: 24 | // ruby dummy-wasi-runtime.c foo.wasm 25 | 26 | u32 fd_write(u32 fd, u32 iovs, u32 iovsLen, u32 size) { 27 | if (fd != 1) abort(); 28 | 29 | u32 total_len = 0; 30 | u8 *mem = WASM_RT_ADD_PREFIX(Z_memory)->data; 31 | for (; iovsLen--; iovs += 8) { 32 | u32 ptr = *(u32*)&mem[iovs]; 33 | u32 len = *(u32*)&mem[iovs + 4]; 34 | fwrite(&mem[ptr], 1, len, stdout); 35 | total_len += len; 36 | } 37 | *(u32*)&mem[size] = total_len; 38 | 39 | return 0; 40 | } 41 | 42 | u32 (*Z_wasi_snapshot_preview1Z_fd_write)(u32, u32, u32, u32) = fd_write; 43 | 44 | int main() { 45 | WASM_RT_ADD_PREFIX(_init)(); 46 | WASM_RT_ADD_PREFIX(Z__start)(); 47 | WASM_RT_ADD_PREFIX(_free)(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /vendor/false.rb: -------------------------------------------------------------------------------- 1 | code = File.read($*[0]) 2 | stack = [] 3 | 4 | pos = 0 5 | 6 | parse = ->(re) do 7 | m = code.match(re, pos) 8 | pos = m.end(0) - 1 9 | m[1] 10 | end 11 | 12 | while code[pos] 13 | case code[pos] 14 | when /\d/ then s = parse[/(\d+)/]; stack << s.to_i 15 | when /[a-z]/ then stack << code[pos].to_sym 16 | when ?+ then a, b = stack.pop, stack.pop; stack << b + a 17 | when ?- then a, b = stack.pop, stack.pop; stack << b - a 18 | when ?* then a, b = stack.pop, stack.pop; stack << b * a 19 | when ?/ then a, b = stack.pop, stack.pop; stack << b / a 20 | when ?& then a, b = stack.pop, stack.pop; stack << b & a 21 | when ?| then a, b = stack.pop, stack.pop; stack << b | a 22 | when ?_ then stack << -stack.pop 23 | when ?~ then stack << ~stack.pop 24 | when ?= then a, b = stack.pop, stack.pop; stack << (b == a ? -1 : 0) 25 | when ?> then a, b = stack.pop, stack.pop; stack << (b > a ? -1 : 0) 26 | when ?% then stack.pop 27 | when ?$ then stack << stack.last 28 | when ?\\ then a, b = stack.pop, stack.pop; stack << a << b 29 | when ?@ then a, b, c = stack.pop, stack.pop, stack.pop; stack << b << a << c 30 | when ?O then a = stack.pop; stack << stack[-1 - a] 31 | when ?: then a, b = stack.pop, stack.pop; vars[a] = b 32 | when ?; then a = stack.pop; stack << vars[a] 33 | when ?. then print "%d" % stack.pop 34 | when ?, then print stack.pop.chr 35 | when ?^ then stack << $stdin.getc 36 | when ?B then $stdin.flush; $stdout.flush 37 | when ?" then s = parse[/"(.*?)"/]; print s 38 | when ?{ then s = parse[/\}/] 39 | when ?' then stack << code[pos += 1].ord 40 | when ?` then raise 41 | when ?[ 42 | stack << [:func, pos] 43 | m = code.match(/(?\[(\g|\{.*?\}|\".*?\"|[^\{\}\"\[\]])*\])/) 44 | pos = m.end(0) - 1 45 | when ?] 46 | case npos = ret.pop 47 | when :det 48 | if stack.pop == 0 49 | pos = ret.pop 50 | ret.pop; ret.pop 51 | else 52 | ret << :body 53 | pos = ret[-3] 54 | end 55 | when :body 56 | stack << :det 57 | pos = ret[-4] 58 | else 59 | pos = npos 60 | end 61 | when ?! then ret << pos; pos = stack.pop[1] 62 | when ?? 63 | tpos = stack.pop[1]; b = stack.pop; (ret << pos; pos = tpos) if b 64 | when ?# 65 | body = stack.pop[1] 66 | det = stack.pop[1] 67 | ret << det << body << pos << :det 68 | pos = det 69 | when /\A\s\z/ 70 | else 71 | raise "unknown symbol: %p" % code[pos] 72 | end 73 | pos += 1 74 | end 75 | -------------------------------------------------------------------------------- /vendor/golfscript.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | #(c) Copyright 2008 Darren Smith. All Rights Reserved. 3 | $lb = [] 4 | class Gtype 5 | def go 6 | $stack<(rhs) 32 | @val<=>rhs.val 33 | end 34 | end 35 | 36 | class Gint < Gtype 37 | def initialize(i) 38 | @val = case i 39 | when true then 1 40 | when false then 0 41 | else;i 42 | end 43 | end 44 | def factory(a) 45 | Gint.new(a) 46 | end 47 | def to_gs 48 | Gstring.new(@val.to_s) 49 | end 50 | def to_int #for pack 51 | @val 52 | end 53 | def ginspect 54 | to_gs 55 | end 56 | def class_id; 0; end 57 | def coerce(b) 58 | [if b.class == Garray 59 | Garray.new([self]) 60 | elsif b.class == Gstring 61 | to_gs 62 | else #Gblock 63 | to_gs.to_s.compile 64 | end,b] 65 | end 66 | 67 | def ~ 68 | Gint.new(~@val) 69 | end 70 | def notop 71 | Gint.new(@val == 0) 72 | end 73 | '*/%<>'.each_byte{|i| 74 | eval'def %c(rhs) 75 | Gint.new(@val %c rhs.val) 76 | end'%[i,i] 77 | } 78 | def equalop(rhs) 79 | Gint.new(@val == rhs.val) 80 | end 81 | def question(b) 82 | Gint.new(@val**b.val) 83 | end 84 | def base(a) 85 | if Garray===a 86 | r=0 87 | a.val.each{|i| 88 | r*=@val 89 | r+=i.val 90 | } 91 | Gint.new(r) 92 | else 93 | i=a.val.abs 94 | r=[] 95 | while i!=0 96 | r.unshift Gint.new(i%@val) 97 | i/=@val 98 | end 99 | Garray.new(r) 100 | end 101 | end 102 | def leftparen 103 | Gint.new(@val-1) 104 | end 105 | def rightparen 106 | Gint.new(@val+1) 107 | end 108 | end 109 | 110 | class Garray < Gtype 111 | def initialize(a) 112 | @val = a || [] 113 | end 114 | def factory(a) 115 | Garray.new(a) 116 | end 117 | def to_gs 118 | @val.inject(Gstring.new("")){|s,i|s+i.to_gs} 119 | end 120 | def flatten #maybe name to_a ? 121 | # Garray.new(@val.inject([]){|s,i|s+case i 122 | # when Gstring then i.val 123 | # when Gint then [i] 124 | # when Garray then i.flatten.val 125 | # when Gblock then i.val 126 | # end 127 | # }) 128 | # end 129 | #use Peter Taylor's fix to avoid quadratic flatten times 130 | Garray.new(flatten_append([])) 131 | end 132 | def flatten_append(prefix) 133 | @val.inject(prefix){|s,i|case i 134 | when Gint then s<(b) 233 | if b.class == Gint 234 | factory(@val[[b.val,-@val.size].max..-1]) 235 | else 236 | Gint.new(@val>b.val) 237 | end 238 | end 239 | def sort 240 | factory(@val.sort) 241 | end 242 | def zip 243 | r=[] 244 | @val.size.times{|x| 245 | @val[x].val.size.times{|y| 246 | (r[y]||=@val[0].factory([])).val<<@val[x].val[y] 247 | } 248 | } 249 | Garray.new(r) 250 | end 251 | def ~ 252 | val 253 | end 254 | end 255 | 256 | class Gstring < Garray 257 | def initialize(a) 258 | @val=case a 259 | when NilClass then [] 260 | when String then a.unpack('C*').map{|i|Gint.new(i)} 261 | when Array then a 262 | when Garray then a.flatten.val 263 | end 264 | end 265 | def factory(a) 266 | Gstring.new(a) 267 | end 268 | def to_gs 269 | self 270 | end 271 | def ginspect 272 | factory(to_s.inspect) 273 | end 274 | def to_s 275 | @val.pack('C*') 276 | end 277 | def class_id; 2; end 278 | def coerce(b) 279 | if b.class == Gblock 280 | [to_s.compile,b] 281 | else 282 | b.coerce(self).reverse 283 | end 284 | end 285 | def question(b) 286 | if b.class == Gstring 287 | Gint.new(to_s.index(b.to_s)||-1) 288 | elsif b.class == Garray 289 | b.question(self) 290 | else 291 | Gint.new(@val.index(b)||-1) 292 | end 293 | end 294 | def ~ 295 | to_s.compile.go 296 | nil 297 | end 298 | end 299 | 300 | class Gblock < Garray 301 | def initialize(_a,_b=nil) 302 | @val=Gstring.new(_b).val 303 | @native = eval("lambda{#{_a}}") 304 | end 305 | def go 306 | @native.call 307 | end 308 | def factory(b) 309 | Gstring.new(b).to_s.compile 310 | end 311 | def class_id; 3; end 312 | def to_gs 313 | Gstring.new("{"+Gstring.new(@val).to_s+"}") 314 | end 315 | def ginspect 316 | to_gs 317 | end 318 | def coerce(b) 319 | b.coerce(self).reverse 320 | end 321 | 322 | def +(b) 323 | if b.class != self.class 324 | a,b=coerce(b) 325 | a+b 326 | else 327 | Gstring.new(@val+Gstring.new(" ").val+b.val).to_s.compile 328 | end 329 | end 330 | def *(b) 331 | if b.class == Gint 332 | b.val.times{go} 333 | else 334 | gpush b.val.first 335 | (b.val[1..-1]||[]).each{|i|$stack<','gpush a>b'.order 470 | var'!','gpush a.notop'.cc1 471 | var'?','gpush a.question(b)'.order 472 | var'$','gpush (a.class==Gint ? $stack[~a.val] : a.sort)'.cc1 473 | var',','gpush case a 474 | when Gint then Garray.new([*0...a.val].map{|i|Gint.new(i)}) 475 | when Gblock then a.select(gpop) 476 | when Garray then Gint.new(a.val.size) 477 | end'.cc1 478 | var')','gpush a.rightparen'.cc1 479 | var'(','gpush a.leftparen'.cc1 480 | 481 | var'rand','gpush Gint.new(rand([1,a.val].max))'.cc1 482 | var'abs','gpush Gint.new(a.val.abs)'.cc1 483 | var'print','print a.to_gs'.cc1 484 | var'if',"#{var'!'}.go;(gpop.val==0?a:b).go".cc2 485 | var'do',"loop{a.go; #{var'!'}.go; break if gpop.val!=0}".cc1 486 | var'while',"loop{a.go; #{var'!'}.go; break if gpop.val!=0; b.go}".cc2 487 | var'until',"loop{a.go; #{var'!'}.go; break if gpop.val==0; b.go}".cc2 488 | var'zip','gpush a.zip'.cc1 489 | var'base','gpush b.base(a)'.cc2 490 | 491 | '"\n":n; 492 | {print n print}:puts; 493 | {`puts}:p; 494 | {1$if}:and; 495 | {1$\if}:or; 496 | {\!!{!}*}:xor; 497 | '.compile.go 498 | code.compile.go 499 | gpush Garray.new($stack) 500 | 'puts'.compile.go 501 | -------------------------------------------------------------------------------- /vendor/grass.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby -Ku 2 | # 3 | # grass.rb - Grass interpreter 4 | # http://www.blue.sky.or.jp/grass/ 5 | # 6 | # Copyright (C) 2006, 2007 UENO Katsuhiro. All rights reserved. 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions 10 | # are met: 11 | # 1. Redistributions of source code must retain the above copyright 12 | # notice, this list of conditions and the following disclaimer. 13 | # 2. Redistributions in binary form must reproduce the above copyright 14 | # notice, this list of conditions and the following disclaimer in 15 | # the documentation and/or other materials provided with the 16 | # distribution. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 22 | # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 | # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 28 | # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | # 30 | # History: 31 | # 32 | # 2007-10-02 33 | # - Follow the latest changes of the definition of Grass. 34 | # 2007-09-20 35 | # - First version. 36 | # 37 | 38 | require 'pp' 39 | 40 | class Grass 41 | 42 | RELEASE_DATE = '2007-10-02' 43 | 44 | class Error < StandardError ; end 45 | class RuntimeError < Error ; end 46 | class IllegalState < Error ; end 47 | 48 | Machine = Struct.new(:code, :env, :dump) 49 | 50 | class Value 51 | def char_code 52 | raise RuntimeError, "not a char" 53 | end 54 | 55 | def app(m, arg) 56 | raise RuntimeError, "app undefined" 57 | end 58 | end 59 | 60 | class Insn 61 | end 62 | 63 | class App < Insn 64 | def initialize(m, n) 65 | @m, @n = m, n 66 | end 67 | 68 | def eval(m) 69 | f, v = m.env[-@m], m.env[-@n] 70 | raise "out of bound" unless f and v 71 | f.app m, v 72 | end 73 | 74 | def pretty_print(q) 75 | q.text 'App' 76 | q.group(4, '(', ')') { q.seplist([@m,@n]) { |i| q.text "#{i}" } } 77 | end 78 | alias inspect pretty_print_inspect 79 | end 80 | 81 | class Abs < Insn 82 | def initialize(body) 83 | @body = body 84 | end 85 | 86 | def eval(m) 87 | m.env.push Fn.new(@body, m.env.dup) 88 | end 89 | 90 | def pretty_print(q) 91 | q.text 'Abs' 92 | q.group(4, '(', ')') { @body.pretty_print(q) } 93 | end 94 | alias inspect pretty_print_inspect 95 | end 96 | 97 | class Fn < Value 98 | def initialize(code, env) 99 | @code, @env = code, env 100 | end 101 | 102 | def app(m, arg) 103 | m.dump.push [m.code, m.env] 104 | m.code, m.env = @code.dup, @env.dup 105 | m.env.push arg 106 | end 107 | end 108 | 109 | ChurchTrue = Fn.new([Abs.new([App.new(3,2)])], [Fn.new([],[])]) 110 | ChurchFalse = Fn.new([Abs.new([])], []) 111 | 112 | class CharFn < Value 113 | def initialize(char_code) 114 | @char_code = char_code 115 | end 116 | attr_reader :char_code 117 | 118 | def app(m, arg) 119 | ret = @char_code == arg.char_code ? ChurchTrue : ChurchFalse 120 | m.env.push ret 121 | end 122 | end 123 | 124 | class Succ < Value 125 | def app(m, arg) 126 | m.env.push CharFn.new((arg.char_code + 1) & 255) 127 | end 128 | end 129 | 130 | class Out < Value 131 | def app(m, arg) 132 | $stdout.print arg.char_code.chr 133 | $stdout.flush 134 | m.env.push arg 135 | end 136 | end 137 | 138 | class In < Value 139 | def app(m, arg) 140 | ch = $stdin.getc 141 | ret = ch ? CharFn.new(ch) : arg 142 | m.env.push ret 143 | end 144 | end 145 | 146 | private 147 | 148 | def eval(m) 149 | while true 150 | insn = m.code.shift 151 | if insn then 152 | insn.eval m 153 | else 154 | break if m.dump.empty? 155 | ret = m.env.last 156 | raise IllegalState, "no return value" unless ret 157 | m.code, m.env = m.dump.pop 158 | m.env.push ret 159 | end 160 | end 161 | raise IllegalState, "illegal final machine state" unless m.env.size == 1 162 | m.env.first 163 | end 164 | 165 | InitialEnv = [In.new, CharFn.new(?w.ord), Succ.new, Out.new] 166 | InitialDump = [[[], []], [[App.new(1, 1)], []]] 167 | 168 | def start(code) 169 | eval Machine.new(code, InitialEnv, InitialDump) 170 | end 171 | 172 | def parse(src) 173 | code = [] 174 | src = src.sub(/\A[^ww]*/, '').gsub(/[^wwWWvv]/, '') 175 | src.split(/[vv]+/).each { |s| 176 | a = s.scan(/[ww]+|[WW]+/).map { |i| i.split(//).size } 177 | arity = 0 178 | arity = a.shift if /\A[ww]/ =~ s 179 | raise "parse error at app" unless a.size % 2 == 0 180 | body = [] 181 | 0.step(a.size - 1, 2) { |i| body.push App.new(a[i], a[i+1]) } 182 | insn = (0...arity).inject(body) { |body,| [Abs.new(body)] } 183 | code.concat insn 184 | } 185 | code 186 | end 187 | 188 | public 189 | 190 | def run(src) 191 | start parse(src) 192 | end 193 | 194 | end 195 | 196 | if $0 == __FILE__ then 197 | $stderr.puts "Grass #{Grass::RELEASE_DATE}" if $VERBOSE 198 | Grass.new.run $<.read 199 | end 200 | 201 | 202 | # Local Variables: 203 | # coding: utf-8 204 | # End: 205 | -------------------------------------------------------------------------------- /vendor/lazyk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Lazy K interpreter 3 | * 4 | * Copyright 2008 irori 5 | * This code is licensed under the MIT License (see LICENSE file for details). 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define VERSION "1.0.0" 17 | 18 | #define INITIAL_HEAP_SIZE 128*1024 19 | #define RDSTACK_SIZE 100000 20 | 21 | // Verbosity levels 22 | enum { 23 | V_NONE, 24 | V_STATS, 25 | V_GC, 26 | } verbosity = V_NONE; 27 | 28 | /********************************************************************** 29 | * Storage management 30 | **********************************************************************/ 31 | 32 | /* TAG STRUCTURE 33 | * 34 | * -------- -------- -------- ------00 Pair 35 | * -------- -------- -------- ------01 Int 36 | * -------- -------- -------- ------10 Combinator 37 | * -------- -------- -------- -----011 Character 38 | * -------- -------- -------- -----111 Miscellaneous 39 | */ 40 | 41 | struct tagPair; 42 | typedef struct tagPair *Cell; 43 | #define CELL(x) ((Cell)(x)) 44 | #define TAG(c) ((intptr_t)(c) & 0x03) 45 | 46 | /* pair */ 47 | typedef struct tagPair { 48 | Cell car; 49 | Cell cdr; 50 | } Pair; 51 | #define ispair(c) (TAG(c) == 0) 52 | #define car(c) ((c)->car) 53 | #define cdr(c) ((c)->cdr) 54 | #define SET(c,fst,snd) ((c)->car = (fst), (c)->cdr = (snd)) 55 | 56 | /* integer */ 57 | #define isint(c) (TAG(c) == 1) 58 | #define mkint(n) CELL(((n) << 2) + 1) 59 | #define intof(c) ((intptr_t)(c) >> 2) 60 | 61 | /* combinator */ 62 | #define iscomb(c) (TAG(c) == 2) 63 | #define mkcomb(n) CELL(((n) << 2) + 2) 64 | #define combof(c) ((intptr_t)(c) >> 2) 65 | #define COMB_S mkcomb(0) 66 | #define COMB_K mkcomb(1) 67 | #define COMB_I mkcomb(2) 68 | #define COMB_IOTA mkcomb(3) 69 | #define COMB_KI mkcomb(4) 70 | #define COMB_READ mkcomb(5) 71 | #define COMB_WRITE mkcomb(6) 72 | #define COMB_INC mkcomb(7) 73 | #define COMB_CONS mkcomb(8) 74 | 75 | /* character */ 76 | #define ischar(c) (((intptr_t)(c) & 0x07) == 0x03) 77 | #define mkchar(n) CELL(((n) << 3) + 0x03) 78 | #define charof(c) ((intptr_t)(c) >> 3) 79 | 80 | /* immediate objects */ 81 | #define isimm(c) (((intptr_t)(c) & 0x07) == 0x07) 82 | #define mkimm(n) CELL(((n) << 3) + 0x07) 83 | #define NIL mkimm(0) 84 | #define COPIED mkimm(1) 85 | #define UNUSED_MARKER mkimm(2) 86 | 87 | Pair *heap_area, *free_ptr; 88 | int heap_size, next_heap_size; 89 | 90 | double total_gc_time = 0.0; 91 | 92 | void gc_run(Cell *save1, Cell *save2); 93 | void rs_copy(void); 94 | Cell copy_cell(Cell c); 95 | 96 | void errexit(char *fmt, ...) 97 | { 98 | va_list arg; 99 | va_start(arg, fmt); 100 | vfprintf(stderr, fmt, arg); 101 | va_end(arg); 102 | 103 | exit(1); 104 | } 105 | 106 | void storage_init(int size) 107 | { 108 | heap_size = size; 109 | heap_area = malloc(sizeof(Pair) * heap_size); 110 | if (heap_area == NULL) 111 | errexit("Cannot allocate heap storage (%d cells)\n", heap_size); 112 | assert(((intptr_t)heap_area & 3) == 0 && (sizeof(Pair) & 3) == 0); 113 | 114 | free_ptr = heap_area; 115 | heap_area += heap_size; 116 | next_heap_size = heap_size * 3 / 2; 117 | } 118 | 119 | Cell pair(Cell fst, Cell snd) 120 | { 121 | Cell c; 122 | if (free_ptr >= heap_area) 123 | gc_run(&fst, &snd); 124 | 125 | assert(free_ptr < heap_area); 126 | c = free_ptr++; 127 | car(c) = fst; 128 | cdr(c) = snd; 129 | return c; 130 | } 131 | 132 | Cell alloc(int n) 133 | { 134 | Cell p; 135 | if (free_ptr + n > heap_area) 136 | gc_run(NULL, NULL); 137 | 138 | assert(free_ptr + n <= heap_area); 139 | p = free_ptr; 140 | free_ptr += n; 141 | return p; 142 | } 143 | 144 | 145 | void gc_run(Cell *save1, Cell *save2) 146 | { 147 | static Pair* free_area = NULL; 148 | int num_alive; 149 | Pair *scan; 150 | clock_t start = clock(); 151 | 152 | if (free_area == NULL) { 153 | free_area = malloc(sizeof(Pair) * next_heap_size); 154 | if (free_area == NULL) 155 | errexit("Cannot allocate heap storage (%d cells)\n", 156 | next_heap_size); 157 | } 158 | 159 | free_ptr = scan = free_area; 160 | free_area = heap_area - heap_size; 161 | heap_area = free_ptr + next_heap_size; 162 | 163 | rs_copy(); 164 | if (save1) 165 | *save1 = copy_cell(*save1); 166 | if (save2) 167 | *save2 = copy_cell(*save2); 168 | 169 | while (scan < free_ptr) { 170 | car(scan) = copy_cell(car(scan)); 171 | cdr(scan) = copy_cell(cdr(scan)); 172 | scan++; 173 | } 174 | 175 | num_alive = free_ptr - (heap_area - next_heap_size); 176 | if (verbosity >= V_GC) 177 | fprintf(stderr, "GC: %d / %d\n", num_alive, heap_size); 178 | 179 | if (heap_size != next_heap_size || num_alive * 8 > next_heap_size) { 180 | heap_size = next_heap_size; 181 | if (num_alive * 8 > next_heap_size) 182 | next_heap_size = num_alive * 8; 183 | 184 | free(free_area); 185 | free_area = NULL; 186 | } 187 | 188 | total_gc_time += (clock() - start) / (double)CLOCKS_PER_SEC; 189 | } 190 | 191 | Cell copy_cell(Cell c) 192 | { 193 | Cell r; 194 | 195 | if (!ispair(c)) 196 | return c; 197 | if (car(c) == COPIED) 198 | return cdr(c); 199 | 200 | r = free_ptr++; 201 | car(r) = car(c); 202 | if (car(c) == COMB_I) { 203 | Cell tmp = cdr(c); 204 | while (ispair(tmp) && car(tmp) == COMB_I) 205 | tmp = cdr(tmp); 206 | cdr(r) = tmp; 207 | } 208 | else 209 | cdr(r) = cdr(c); 210 | car(c) = COPIED; 211 | cdr(c) = r; 212 | return r; 213 | } 214 | 215 | /********************************************************************** 216 | * Reduction Machine 217 | **********************************************************************/ 218 | 219 | typedef struct { 220 | Cell *sp; 221 | Cell stack[RDSTACK_SIZE]; 222 | } RdStack; 223 | 224 | RdStack rd_stack; 225 | 226 | void rs_init(void) 227 | { 228 | int i; 229 | rd_stack.sp = rd_stack.stack + RDSTACK_SIZE; 230 | 231 | for (i = 0; i < RDSTACK_SIZE; i++) 232 | rd_stack.stack[i] = UNUSED_MARKER; 233 | } 234 | 235 | void rs_copy(void) 236 | { 237 | Cell *c; 238 | for (c = rd_stack.stack + RDSTACK_SIZE - 1; c >= rd_stack.sp; c--) 239 | *c = copy_cell(*c); 240 | } 241 | 242 | int rs_max_depth(void) 243 | { 244 | int i; 245 | for (i = 0; i < RDSTACK_SIZE; i++) { 246 | if (rd_stack.stack[i] != UNUSED_MARKER) 247 | break; 248 | } 249 | return RDSTACK_SIZE - i; 250 | } 251 | 252 | void rs_push(Cell c) 253 | { 254 | if (rd_stack.sp <= rd_stack.stack) 255 | errexit("runtime error: stack overflow\n"); 256 | *--rd_stack.sp = c; 257 | } 258 | 259 | #define TOP (*rd_stack.sp) 260 | #define POP (*rd_stack.sp++) 261 | #define POP_ (rd_stack.sp++) 262 | #define PUSH(c) rs_push(c) 263 | #define PUSHED(n) (*(rd_stack.sp+(n))) 264 | #define DROP(n) (rd_stack.sp += (n)) 265 | #define ARG(n) cdr(PUSHED(n)) 266 | #define APPLICABLE(n) (bottom - rd_stack.sp > (n)) 267 | 268 | /********************************************************************** 269 | * Loader 270 | **********************************************************************/ 271 | 272 | Cell read_one(FILE *fp, int i_is_iota); 273 | Cell read_many(FILE *fp, int closing_char); 274 | 275 | Cell load_program(const char *fname) 276 | { 277 | FILE *fp; 278 | Cell c; 279 | 280 | if (fname == NULL) 281 | fp = stdin; 282 | else { 283 | fp = fopen(fname, "r"); 284 | if (fp == NULL) 285 | errexit("cannot open %s\n", fname); 286 | } 287 | 288 | c = read_many(fp, EOF); 289 | 290 | if (fname != NULL) 291 | fclose(fp); 292 | 293 | return c; 294 | } 295 | 296 | int next_char(FILE *fp) 297 | { 298 | int c; 299 | do { 300 | c = fgetc(fp); 301 | if (c == '#') { 302 | while (c = fgetc(fp), c != '\n' && c != EOF) 303 | ; 304 | } 305 | } while (isspace(c)); 306 | return c; 307 | } 308 | 309 | Cell read_many(FILE *fp, int closing_char) 310 | { 311 | int c; 312 | Cell obj; 313 | 314 | c = next_char(fp); 315 | if (c == closing_char) 316 | return COMB_I; 317 | ungetc(c, fp); 318 | 319 | PUSH(read_one(fp, 0)); 320 | while ((c = next_char(fp)) != closing_char) { 321 | ungetc(c, fp); 322 | obj = read_one(fp, 0); 323 | obj = pair(TOP, obj); 324 | TOP = obj; 325 | } 326 | return POP; 327 | } 328 | 329 | Cell read_one(FILE *fp, int i_is_iota) 330 | { 331 | int c; 332 | Cell obj; 333 | 334 | c = next_char(fp); 335 | switch (c) { 336 | case '`': case '*': 337 | PUSH(read_one(fp, c == '*')); 338 | obj = read_one(fp, c == '*'); 339 | obj = pair(TOP, obj); 340 | POP_; 341 | return obj; 342 | case '(': 343 | obj = read_many(fp, ')'); 344 | return obj; 345 | case 's': case 'S': return COMB_S; 346 | case 'k': case 'K': return COMB_K; 347 | case 'i': return i_is_iota ? COMB_IOTA : COMB_I; 348 | case 'I': return COMB_I; 349 | case '0': case '1': { 350 | obj = COMB_I; 351 | do { 352 | if (c == '0') 353 | obj = pair(pair(obj, COMB_S), COMB_K); 354 | else 355 | obj = pair(COMB_S, pair(COMB_K, obj)); 356 | c = next_char(fp); 357 | } while (c == '0' || c == '1'); 358 | ungetc(c, fp); 359 | return obj; 360 | } 361 | case EOF: 362 | errexit("parse error: unexpected EOF\n"); 363 | return NULL; 364 | default: 365 | errexit("parse error: %c\n", c); 366 | return NULL; 367 | } 368 | } 369 | 370 | /********************************************************************** 371 | * Reducer 372 | **********************************************************************/ 373 | 374 | int reductions; 375 | 376 | void eval(Cell root) 377 | { 378 | Cell *bottom = rd_stack.sp; 379 | PUSH(root); 380 | 381 | for (;;) { 382 | while (ispair(TOP)) 383 | PUSH(car(TOP)); 384 | 385 | if (TOP == COMB_I && APPLICABLE(1)) 386 | { /* I x -> x */ 387 | POP_; 388 | TOP = cdr(TOP); 389 | } 390 | else if (TOP == COMB_S && APPLICABLE(3)) 391 | { /* S f g x -> f x (g x) */ 392 | Cell a = alloc(2); 393 | SET(a+0, ARG(1), ARG(3)); /* f x */ 394 | SET(a+1, ARG(2), ARG(3)); /* g x */ 395 | DROP(3); 396 | SET(TOP, a+0, a+1); /* f x (g x) */ 397 | } 398 | else if (TOP == COMB_K && APPLICABLE(2)) 399 | { /* K x y -> I x */ 400 | Cell x = ARG(1); 401 | DROP(2); 402 | SET(TOP, COMB_I, x); 403 | TOP = cdr(TOP); /* shortcut reduction of I */ 404 | } 405 | else if (TOP == COMB_IOTA && APPLICABLE(1)) 406 | { /* IOTA x -> x S K */ 407 | Cell xs = pair(ARG(1), COMB_S); 408 | POP_; 409 | SET(TOP, xs, COMB_K); 410 | } 411 | else if (TOP == COMB_KI && APPLICABLE(2)) 412 | { /* KI x y -> I y */ 413 | DROP(2); 414 | car(TOP) = COMB_I; 415 | } 416 | else if (TOP == COMB_CONS && APPLICABLE(3)) 417 | { /* CONS x y f -> f x y */ 418 | Cell fx, y; 419 | fx = pair(ARG(3), ARG(1)); 420 | y = ARG(2); 421 | DROP(3); 422 | SET(TOP, fx, y); 423 | } 424 | else if (TOP == COMB_READ && APPLICABLE(2)) 425 | { /* READ NIL f -> CONS CHAR(c) (READ NIL) f */ 426 | intptr_t c = getchar(); 427 | Cell a = alloc(2); 428 | SET(a+0, COMB_CONS, mkchar(c == EOF ? 256 : c)); 429 | SET(a+1, COMB_READ, NIL); 430 | POP_; 431 | SET(TOP, a+0, a+1); 432 | } 433 | else if (TOP == COMB_WRITE && APPLICABLE(1)) 434 | { /* WRITE x -> putc(eval((car x) INC NUM(0))); WRITE (cdr x) */ 435 | Cell a = alloc(3); 436 | SET(a+0, ARG(1), COMB_K); /* (car x) */ 437 | SET(a+1, a+0, COMB_INC); /* (car x) INC */ 438 | SET(a+2, a+1, mkint(0)); /* (car x) INC NUM(0) */ 439 | POP_; 440 | eval(a+2); 441 | 442 | if (!isint(TOP)) 443 | errexit("invalid output format (result was not a number)\n"); 444 | if (intof(TOP) >= 256) 445 | return; 446 | 447 | putchar(intof(TOP)); 448 | POP_; 449 | a = pair(cdr(TOP), COMB_KI); 450 | cdr(TOP) = a; 451 | } 452 | else if (TOP == COMB_INC && APPLICABLE(1)) 453 | { /* INC x -> eval(x)+1 */ 454 | Cell c = ARG(1); 455 | POP_; 456 | eval(c); 457 | 458 | c = POP; 459 | if (!isint(c)) 460 | errexit("invalid output format (attempted to apply inc to a non-number)\n"); 461 | SET(TOP, COMB_I, mkint(intof(c) + 1)); 462 | } 463 | else if (ischar(TOP) && APPLICABLE(2)) { 464 | intptr_t c = charof(TOP); 465 | if (c <= 0) { /* CHAR(0) f z -> z */ 466 | Cell z = ARG(2); 467 | DROP(2); 468 | SET(TOP, COMB_I, z); 469 | } 470 | else { /* CHAR(n+1) f z -> f (CHAR(n) f z) */ 471 | Cell a = alloc(2); 472 | Cell f = ARG(1); 473 | SET(a+0, mkchar(c-1), f); /* CHAR(n) f */ 474 | SET(a+1, a+0, ARG(2)); /* CHAR(n) f z */ 475 | DROP(2); 476 | SET(TOP, f, a+1); /* f (CHAR(n) f z) */ 477 | } 478 | } 479 | else if (isint(TOP) && APPLICABLE(1)) 480 | errexit("invalid output format (attempted to apply a number)\n"); 481 | else 482 | return; 483 | reductions++; 484 | } 485 | } 486 | 487 | void eval_print(Cell root) 488 | { 489 | eval(pair(COMB_WRITE, 490 | pair(root, 491 | pair(COMB_READ, NIL)))); 492 | } 493 | 494 | /********************************************************************** 495 | * Main 496 | **********************************************************************/ 497 | 498 | void help(const char *progname) { 499 | printf("Usage: %s [options] sourcefile\n", progname); 500 | printf(" -h print this help and exit\n"); 501 | printf(" -u disable stdout buffering\n"); 502 | printf(" -v print version and exit\n"); 503 | printf(" -v[0-2] set verbosity level (default: 0)\n"); 504 | } 505 | 506 | int main(int argc, char *argv[]) 507 | { 508 | Cell root; 509 | clock_t start; 510 | char *prog_file = NULL; 511 | int i; 512 | 513 | for (i = 1; i < argc; i++) { 514 | if (argv[i][0] == '-' && argv[i][1] == 'v' && isdigit(argv[i][2])) { 515 | verbosity = argv[i][2] - '0'; 516 | } else if (strcmp(argv[i], "-h") == 0) { 517 | help(argv[0]); 518 | return 0; 519 | } else if (strcmp(argv[i], "-u") == 0) { 520 | setbuf(stdout, NULL); 521 | } else if (strcmp(argv[i], "-v") == 0) { 522 | printf("Lazy K interpreter " VERSION " by irori\n"); 523 | return 0; 524 | } else if (argv[i][0] == '-') { 525 | fprintf(stderr, "bad option %s (Try -h for more information).\n", argv[i]); 526 | return 1; 527 | } else { 528 | prog_file = argv[i]; 529 | } 530 | } 531 | 532 | storage_init(INITIAL_HEAP_SIZE); 533 | rs_init(); 534 | 535 | root = load_program(prog_file); 536 | 537 | start = clock(); 538 | eval_print(root); 539 | 540 | if (verbosity >= V_STATS) { 541 | double evaltime = (clock() - start) / (double)CLOCKS_PER_SEC; 542 | 543 | printf("\n%d reductions\n", reductions); 544 | printf(" total eval time --- %5.2f sec.\n", evaltime - total_gc_time); 545 | printf(" total gc time --- %5.2f sec.\n", total_gc_time); 546 | printf(" max stack depth --- %d\n", rs_max_depth()); 547 | } 548 | return 0; 549 | } 550 | -------------------------------------------------------------------------------- /vendor/lci-0.10.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/vendor/lci-0.10.5.zip -------------------------------------------------------------------------------- /vendor/npiet-1.3e.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/vendor/npiet-1.3e.tar.gz -------------------------------------------------------------------------------- /vendor/ook-to-bf.rb: -------------------------------------------------------------------------------- 1 | RE = /\G(?:\s*Ook(?.)\s*Ook(?.)|(?)\s*\z|(?))/ 2 | 3 | T = { 4 | ".?" => ">", 5 | "?." => "<", 6 | ".." => "+", 7 | "!!" => "-", 8 | ".!" => ",", 9 | "!." => ".", 10 | "!?" => "[", 11 | "?!" => "]", 12 | } 13 | 14 | if $*.size != 2 15 | $stderr.puts "usage: #$0 in.ook out.bf" 16 | exit 1 17 | end 18 | 19 | c = "" 20 | File.read($*[0]).scan(RE) do 21 | if $~[:c1] 22 | c << T[$~[:c1] + $~[:c2]] 23 | elsif $~[:error] 24 | raise "Ook? Ook? Ook?" 25 | end 26 | end 27 | File.write($*[1], c) 28 | -------------------------------------------------------------------------------- /vendor/spl-1.2.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mame/quine-relay/b9c8056cad4589fe650163a3fd0cea4b3055fce4/vendor/spl-1.2.1.tar.gz -------------------------------------------------------------------------------- /vendor/subleq.rb: -------------------------------------------------------------------------------- 1 | IN_ADDR = -1 2 | OUT_ADDR = -1 3 | 4 | mem = File.read(ARGV[0]).split.map do |v| 5 | if v.start_with?(?#) 6 | case v 7 | when "#IN" then IN_ADDR 8 | when "#OUT" then OUT_ADDR 9 | else raise "Unresolved register: #{ v }" 10 | end 11 | else 12 | v.to_i 13 | end 14 | end 15 | 16 | ip = 0 17 | while 0 <= ip && ip < mem.size 18 | a, b, c = mem[ip], mem[ip + 1], mem[ip + 2] 19 | ip += 3 20 | 21 | if a == IN_ADDR 22 | ma = -($stdin.getc || -1).ord 23 | else 24 | ma = mem[a] 25 | end 26 | 27 | if b == OUT_ADDR 28 | putc ma 29 | else 30 | mb = mem[b] -= ma 31 | ip = c if mb <= 0 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /vendor/thue.rb: -------------------------------------------------------------------------------- 1 | RE = /^\s*::=.*\n(?(?m:.*))|^(?.+?)::=(?.*)$/ 2 | 3 | rules, body = {}, "" 4 | File.binread($*[0]).scan(RE) do 5 | $~[:lhs] ? rules[$~[:lhs]] = $~[:rhs] : body = $~[:body].delete("\n") 6 | end 7 | 8 | loop do 9 | #puts body 10 | targets = [] 11 | rules.each do |lhs, rhs| 12 | pos = 0 13 | while npos = body.index(lhs, pos) 14 | targets << [npos, lhs, rhs] 15 | pos = npos + 1 16 | end 17 | end 18 | break if targets.empty? 19 | pos, lhs, rhs = targets.sample 20 | case rhs 21 | when ":::" then rhs = gets 22 | when /^~/ then print $'; rhs = "" 23 | end 24 | body[pos, lhs.size] = rhs 25 | end -------------------------------------------------------------------------------- /vendor/unlambda.rb: -------------------------------------------------------------------------------- 1 | tokens = [] 2 | File.read($*[0]).scan(/\.(?.)|(?[r`ikscd])|#.*/) do 3 | if $~[:out] 4 | tokens << [:o, $~[:out]] 5 | elsif $~[:insn] 6 | case $~[:insn] 7 | when ?r then tokens << [:o, ?\n] 8 | when ?` then tokens << :a 9 | else tokens << $~[:insn].to_sym 10 | end 11 | end 12 | end 13 | tokens.reverse! 14 | 15 | stack = [nil, :S] 16 | acc = nil 17 | while stack 18 | stack, cmd = stack 19 | acc = if cmd == :S 20 | stack = [stack, acc] if acc 21 | insn, arg = tokens.pop 22 | case insn 23 | when :o then [:o, arg] 24 | when :a then stack = [[stack, :S], :S]; nil 25 | when nil then raise "EOF" 26 | else [insn] 27 | end 28 | else 29 | [:a, cmd, acc] 30 | end 31 | end 32 | 33 | stack = [nil, :E, acc] 34 | acc = nil 35 | while stack 36 | stack, cmd, cls = stack 37 | acc = if cmd == :E 38 | if acc && acc[0] == :d 39 | [:d1, cls] 40 | else 41 | stack = [stack, :A, acc] if acc 42 | cls[0] == :a ? (stack = [[stack, :E, cls[2]], :E, cls[1]]; nil) : cls 43 | end 44 | else 45 | type, x, y = cls 46 | case type 47 | when :o then print x; acc 48 | when :i then acc 49 | when :k then [:k1, acc] 50 | when :k1 then x 51 | when :s then [:s1, acc] 52 | when :s1 then [:s2, x, acc] 53 | when :s2 then stack = [stack, :E, [:a, [:a, x, acc], [:a, y, acc]]]; nil 54 | when :c then stack = [stack, :A, acc]; [:c1, stack[0]] 55 | when :c1 then stack = x; acc 56 | when :d then acc 57 | when :d1 then stack = [stack, :E, [:a, x, acc]]; nil 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /vendor/wasi-runtime.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const { WASI } = require('wasi'); 5 | const wasi = new WASI({ version: "preview1" }); 6 | const importObject = { wasi_snapshot_preview1: wasi.wasiImport }; 7 | 8 | (async () => { 9 | const wasm = await WebAssembly.compile(fs.readFileSync(process.argv[2])); 10 | const instance = await WebAssembly.instantiate(wasm, importObject); 11 | wasi.start(instance); 12 | })(); 13 | -------------------------------------------------------------------------------- /vendor/whitespace.rb: -------------------------------------------------------------------------------- 1 | RE = /\G(?[01]+){0}(?[01]*){0} 2 | ( 00 (? )\g2 3 | | 010 (? )\g2 4 | | 012 (?)\g2 5 | | 020 (?) 6 | | 021 (?) 7 | | 022 (?) 8 | | 1000(?) 9 | | 1001(?) 10 | | 1002(?) 11 | | 1010(?) 12 | | 1011(?) 13 | | 110 (?) 14 | | 111 (?) 15 | | 1200(?) 16 | | 1201(?) 17 | | 1210(?) 18 | | 1211(?) 19 | | 200 (?)\g2 20 | | 201 (?)\g2 21 | | 202 (?)\g2 22 | | 210 (?)\g2 23 | | 211 (?)\g2 24 | | 212 (?) 25 | | 222 (?) 26 | | (?)\z 27 | | (?) 28 | )/x 29 | 30 | names = RE.names.map {|n| n.to_sym } - [:num, :label] 31 | code, labels = [], {} 32 | File.read($*[0]).gsub(/[^ \t\n]/m, "").tr(" \t\n", "012").scan(RE) do 33 | insn = names.find {|n| $~[n] } 34 | arg = $~[:num] 35 | arg = arg[1..-1].to_i(2) * (arg[0] == ?0 ? 1 : -1) if arg 36 | arg = $~[:label] if $~[:label] 37 | raise "Unrecognised input" if insn == :error 38 | insn == :mark ? labels[arg] = code.size : code << [insn, arg] 39 | end 40 | 41 | def read_int 42 | s = "" 43 | while true 44 | ch = $stdin.getc 45 | case ch 46 | when /\d+/ then s << ch 47 | when /\s+/ then break 48 | else raise "Integer expected" 49 | end 50 | end 51 | s.to_i 52 | end 53 | 54 | pc, call, stack, heap = 0, [], [], Hash.new(0) 55 | loop do 56 | insn, arg = code[pc] 57 | pc += 1 58 | case insn 59 | when :push then stack << arg 60 | when :dup then stack << stack.last 61 | when :copy then stack << stack[-arg - 1] 62 | when :slide then n = stack.pop; stack.pop(arg); stack << n 63 | when :swap then n = stack.pop; m = stack.pop; stack << n << m 64 | when :pop then stack.pop 65 | when :add then n = stack.pop; stack << stack.pop + n 66 | when :sub then n = stack.pop; stack << stack.pop - n 67 | when :mul then n = stack.pop; stack << stack.pop * n 68 | when :div then n = stack.pop; stack << stack.pop / n 69 | when :mod then n = stack.pop; stack << stack.pop % n 70 | when :set then n = stack.pop; heap[stack.pop] = n 71 | when :get then stack << heap[stack.pop] 72 | when :outc then putc stack.pop 73 | when :readc then heap[stack.pop] = $stdin.getc.ord 74 | when :outn then print stack.pop 75 | when :readn then heap[stack.pop] = read_int 76 | when :call then call << pc; pc = labels[arg] 77 | when :jump then pc = labels[arg] 78 | when :jz then pc = labels[arg] if stack.pop == 0 79 | when :jn then pc = labels[arg] if stack.pop < 0 80 | when :ret then pc = call.pop 81 | when :end then break 82 | when :eof then raise("Reached EOF") 83 | end 84 | end 85 | --------------------------------------------------------------------------------