Inside newLISP (6)
以前国勢調査の本を読んだけど、今年が当たり年だった。インターネットで簡単にってんで 依頼用紙が来てたけど、あれ何よ?
住所とIDが既に紐付けられていた。だから、回等の最後にパスワードの新規設定を求め られるんだな。使える記号の種類が限定されてるってどうよ? サイトを作る方の 都合がふんだんに混じってる可能性があるな。まさかレールならあそこまで限定 させることはないだろう。
そうするとJAAVAで作られているのかな?作った所はFNあたりか。そして運用はんttの 子会社かな。
パソコンでもスマホでもOKって、総務のおばちゃんやるじゃん。って、現在では当たり前。 無線局の電子申請がパソコンのしかもWindows限定って、どこの世界の話だ。早く何とか しろよ。
早く何とかしろよは、今回の電子申請でみんな、どんな環境から回答してるか、知りたいな。 ブラウザーの種類とかOSぐらいは取れるだろうから、公表せい。それとプロバイダーだな。 もう地方の弱小プロバイダーは淘汰されてて、携帯屋がやってるプロバイダーしか出て こないかな。
全世帯の何%が、電子回答したんだろう?最近は年寄りでもスマホを使いこなしているから、 結構な率になるかな。日本の動態よりも、こういう下衆な話の方が面白いぞ。
早く公開してね。
minix3
前回minixなんてのを思い出しちゃったので、懐かしくなって入れてみた。 総本山はMINIX 3 Download こちらです。
一番新しいのが良いだろうってんで、3.3.0を落としてきて、vmwareに入れてみた。 基本的には、ただReturnを叩いていくだけ。あっけなくインストール完了。 pkgin in openssh して、sshをインストール。一度rebootすると、よそから入れるように なった。
このpkginは、NetBSD由来みたいだな。連携出来るようになってる。そんな事より、/usr/srcが 無いんですけど。pkgにあるかと思って探してみたけど見当たらず。なんか間違ってませんか?
ちょっと古い、3.2.1ではどうかと思ってやり直し。今度は入っていた。まずは自分のアカウントを 作っておくんだったな。
# useradd -m -d /home/sakae sakae
つぎは、何かshellでも入れておこう。
# pkgin search shell bash-2.05.2.7nb11 The GNU Bourne Again Shell (version 2) bash-4.2nb1 The GNU Bourne Again Shell dialog-1.1.20110707 Display dialog boxes from shell scripts getopt-1.1.4nb1 Program to help shell scripts parse command-line parameters openssh-5.8.2nb5 = Open Source Secure shell client and server (remote login program) pdksh-5.2.14nb5 Free clone of the AT&T Korn shell =: package is installed and up-to-date <: package is installed but newer version is available >: installed package has a greater version than available package # pkgin install pdksh calculating dependencies... done. nothing to upgrade. 1 packages to be installed: pdksh-5.2.14nb5 (318K to download, 717K to install) proceed ? [y/N] y downloading packages... pdksh-5.2.14nb5.tgz 100% 318KB 106.0KB/s 31.5KB/s 00:03 error log can be found in /usr/var/db/pkgin/err.log installing packages... installing pdksh-5.2.14nb5... pdksh-5.2.14nb5: adding /usr/pkg/bin/pdksh to /etc/shells processing local summary... updating database: 100% marking pdksh-5.2.14nb5 as non auto-removable
ソース系
$ cd /usr/src $ ls LICENSE commands drivers kernel sbin tools Makefile common etc lib servers usr.bin benchmarks dist external libexec share usr.sbin bin distrib gnu man sys build.sh docs include releasetools test
パッケージが/usr/pkgの下に入って、srcも有って、Linuxとは一味違う、miniNetBSDって 趣きでしょうか? OS入れるなら、こうでなくちゃ!!
内部の事で参考になりそうな事は、 MINIX 3 Developers Guide を見れば良いのかな。
いたずらで、newlispがコンパイル出来るかやってみたら、デフォのccがうんと古いclangで 歯が立たず。pkgにgcc44が有ったので、取り寄せて実験
$ gmake -f makefile_netbsd gcc -m32 -Wall -Wno-uninitialized -Wno-strict-aliasing -O2 -c -g -DREADLINE -D_BSD nl-filesys.c nl-filesys.c: In function 'processSpawnList': nl-filesys.c:1468: warning: implicit declaration of function 'munmap' nl-filesys.c: In function 'p_spawn': nl-filesys.c:1496: warning: implicit declaration of function 'mmap' nl-filesys.c:1497: error: 'MAP_SHARED' undeclared (first use in this function) nl-filesys.c:1497: error: (Each undeclared identifier is reported only once nl-filesys.c:1497: error: for each function it appears in.) nl-filesys.c: In function 'p_share': nl-filesys.c:2151: error: 'MAP_SHARED' undeclared (first use in this function) gmake: *** [nl-filesys.o] Error 1
っつう事で、MINIXは独自の道を歩んでいるみたい。ソケットの所なんかはボロボロでしたよ。
リベンジ
前回(またかよ)、gambitCに素数検出スクリプトを移植した時、(inc! var) と (inc! var d) を、同時にサポート出来ず、心にわだかまりが残っていた。ちゃんとOn Lispを読めば解決 出来るんだろうけど、ちとLisp-2系と言うか、CommonLispには心が動かなくなっているんで諦めた。
そこで、Lisp-1系のSchemeだけで何とかならんかと、gambitのinfoを見てたんだ。 そしたら使えそうなのが有ったね。condみたいなやつが。
;; gsi -:s xxx.scm ;; gsc -:s -o run -exe xx.scm ;(load "/usr/local/lib/gambit-c/syntax-case") ; comment out for gsc (define-syntax inc! (syntax-rules () ((inc! var) (set! var (+ var 1))) ((inv! var d) (set! var (+ var d))))) (define aa 0) (inc! aa 3) (print aa "\n") (inc! aa) (print aa "\n")
パターンマッチングで、ソースを書き換えてから実行ってやつ。こちらの方が分かり易いな。 但し、これを使うには、コマンドラインにおまじないの -:s ってのが必要。syntax-caseの モジュールを読み込ませる必要が有るので、ちと面倒ではあるけど、微妙な所なんでしょうが ないか。
普通は、普通なマクロを使うのが常識かな、 Schemeのマクロをかじってみる でも、Lisp気質のマクロだしね。どうしてもって時のために、引き出しにしまっておくものですな。
悔しいのはもう一つあった。そう、大きなベクターを取ろうとするヒープがオーバーフロー しちゃう事。今回は、素数/非素数が分かればいいんで、1ビットで事足りる。だったら、小さい数を 記憶するベクターでいいじゃん。s8vectorに変更。これだと8ビットの数値しか扱えない。
対して、汎用のvectorは、何でも入れられるのね。数値でも真偽値でも文字列でも。最初 newLISPでびっくりしたけど、まあ、こんなのも有りって事で、配列に入れられるのは、一つの タイプだけって、固定観念が払拭出来たよ。良い子はマネをしない方が望ましいけど。
大きな数値(define N 10000000) で実験
[ob: t]$ time gsi 2gsi.scm >z 0m45.72s real 0m38.05s user 0m7.19s system [ob: t]$ gsc -o run -exe 2gsi.scm [ob: t]$ time ./run >z 0m2.25s real 0m0.89s user 0m1.31s system
OpenBSDはもっさりしてるんで、比べるなら同じ土俵のウブがいいな。ウブ用のgambitは版が 古くてバイナリーを作成出来なかったので、Gambit v4.7.8の最新版を入れたよ。
sakae@uB:~/z$ time gsi 2gsi.scm >/dev/null real 0m25.352s user 0m25.000s sys 0m0.300s sakae@uB:~/z$ gsc -o run -exe 2gsi.scm sakae@uB:~/z$ time ./run > /dev/null real 0m1.551s user 0m1.356s sys 0m0.192s sakae@uB:~/z$ time ./sieve > /dev/null real 0m2.401s user 0m1.940s sys 0m0.380s
crystalが吐くバイナリーより速かったな。クリスタルさん、頑張ってくださいませ。
newlisp-js
以前から気になっていたnewlisp-js を落としてきた。zipファイルだ。これ一つでnewlispが動くって話。解凍して、index.htmlを 起動したら、デモ画面が出てきた。
テーマで配色を変えられたり、レイアウトで配置を変えられたり、Windowsユーザーが喜びそう (最近ではスマホユーザーか)時代に追いついているかな。
しかけは、infoを見ろって事なんで、うだうだしてると、 JavaScript program統一協会によるemscripten らしい。そこにnewLISP陣営も参加してるのだな。 ざっくり言っちゃうと、C語で書かれたアプリをjavascrit語に変換しちゃいましょ。そうすれば、 ブラウザーだけで動くアプリが出来るじゃんって事。その要になってるのがLLVM。 つらつら見てくとその為の開発環境(SDK)がDL出来るみたいだ。世の中便利だねぇ。
C語のハロワを、
./emcc hello_world.c node a.out.js
出来上がったのをJSの代表、nodeで実行。-o hello.htmlで、埋め込みも出来るんか。 これなら、何処でも動くな。たのしそうだから後でチャレンジしてみるか。 で、この原稿を書きながら、コンパイルしてみたんだけど、DISKが足りなくなってfailした。 3.3G使っても足りないって、どれほどよ。何処かにバイナリーが落ちていないかな。
簡単アプリが有るとな
The app.html demo file shows how to do this. Everything necessary to write your own application is contained in a 3k part of this file. Only app.html and the newlisp-js-lib.js library are required to run this newLISP application client-side in a web browser.
newlispEvalStr(string)と言うのがnewlisp-js-lib.jsに含まれていて、そいつを使って ブラウザーから、JS版のnewLISPにコードを送り込むようだ。
こういうのは、手を動かすに限る。app.htmlをhoge.htmlにコピーし、それとnewlisp-js-lib.js を適当な所に取り出した。で、アクセスしてみると、ローディング中ってなって、先に 進まない。おかしいなってんで、newlisp-js-lib.html.memも持ってきたら動き出した。 嘘の説明ですか。やってみないと分からんな。後は、実行手続きをフィボからfactに 変更したりしてみた。
この例だと、テキストエリアに貼り付けてあるコードを取り出して、評価してから結果を web画面に貼り付けているんだな。ちょっと修正が半端だけど、
<head> : function calcFact() { var num = document.getElementById('fiboinput').value var source = '(fact ' + num + ')' var result = newlispEvalStr(source); var fieldName = document.getElementById('content'); fieldName.innerHTML = result; } : <body> : <script type='text/javascript'> <!-- var Module = { preRun: [], postRun: [(function() { // import newlispEvalStr from newlisp-js-lib.js library newlispEvalStr = Module.cwrap('newlispEvalStr', 'string', ['string']); // preload newLISP functions from code textarea id='code' newlispEvalStr(document.getElementById('code').value); })], : Module.setStatus('Downloading...'); --> </script>
ボタンを押した時に、この関数が実行される。数値を読み取って、S式を組み立てて実行。 結果をWebに表示だな。
このjsになったnewLISPってどう作るかと思ったら、makefile_emscripten_lib_utf8に書いてあった。
OBJS = newlisp.o nl-symbol.o nl-math.o nl-list.o nl-liststr.o nl-string.o nl-filesys.o \ nl-sock.o nl-web.o nl-xml-json.o nl-matrix.o nl-debug.o pcre.o nl-utf8.o unix-lib.o CFLAGS = -m32 -Wall -c -DMAC_OSX -DLIBRARY -DEMSCRIPTEN -DSUPPORT_UTF8 CC = emcc
特徴的なのがunix-lib.cを使ってるのと、コンパイラーの指定がemccって事。 unix-lib.cの中にnewlispEvalStrが定義されてる。
それはそうと、newlisp-js-lib.jsが1.1Mも有る。中身はほとんど数値の羅列だけど、これって JS用のアセンブラ? 多分、newlispが使っていたlibcとかlibmを同梱してるのかな。それとも そんなのは、javascriptのエンジンに入ってるんで、それへの橋渡しをしてるのかな? 余り深く考えるな。
newlisp on ARM
newlisp-jsのバージョンが新しくなっていた。で、ふと本拠を見に行ったら本体の方も開発版という 位置付けながら、新しいのが出てた。これはもう入れてみる鹿。この所失敗続きだからね。 どうせやるなら、新しい器が良いだろう。昔作っておいた、ARMでdebian環境。 そして、お約束のエラー発生。
sakae@arm:~/newlisp-10.6.3$ make ./configure removing old objects and setting correct permissions ... discovering platform and default memory model ... detected memory model ILP32 detected Operating System LINUX creating makefile_build ... to make for ILP32 on LINUX type: make to make for any other system do: make -f makefile_xxx where makefile_xxx is one of the preconfigured makefiles make -f makefile_build make[1]: Entering directory '/home/sakae/newlisp-10.6.3' gcc -fPIC -m32 -Wall -Wno-strict-aliasing -Wno-long-long -c -O2 -g -DREADLINE -DSUPPORT_UTF8 -DLINUX -DFFI -I/usr/local/lib/libffi-3.0.13/include newlisp.c gcc: error: unrecognized command line option ‘-m32’ makefile_build:21: recipe for target 'newlisp.o' failed make[1]: *** [newlisp.o] Error 1 make[1]: Leaving directory '/home/sakae/newlisp-10.6.3' Makefile:31: recipe for target 'default' failed make: *** [default] Error 2
gccが言う事にゃ、糞石32なんてやめれ!! -m32を削除。ついでに、-O2の-O0に変更。
sakae@arm:~/newlisp-10.6.3$ ./newlisp newLISP v.10.6.3 32-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h > (sys-info) (437 268435456 409 1 0 2048 0 16354 10603 1153)
どうやら、ちゃんと動いているな。そんじゃ、アセンブルコードにご対面してみるか。
(gdb) disassemble evaluateExpression Dump of assembler code for function evaluateExpression: 0x00018258 <+0>: push {r4, r11, lr} 0x0001825c <+4>: add r11, sp, #8 0x00018260 <+8>: sub sp, sp, #36 ; 0x24 0x00018264 <+12>: str r0, [r11, #-40] ; 0x28 0x00018268 <+16>: ldr r4, [pc, #1944] ; 0x18a08 <evaluateExpression+1968> 0x0001826c <+20>: add r4, pc, r4 => 0x00018270 <+24>: ldr r3, [pc, #1940] ; 0x18a0c <evaluateExpression+1972> 0x00018274 <+28>: ldr r3, [r4, r3] 0x00018278 <+32>: mov r2, #0 0x0001827c <+36>: str r2, [r3] 0x00018280 <+40>: ldr r3, [pc, #1928] ; 0x18a10 <evaluateExpression+1976> 0x00018284 <+44>: ldr r3, [r4, r3] :
うん、まぎれもなくarmなコードだな。
JavaScript
JavaScriptを中心としたWebアプリ開発の栄枯盛衰まとめ ホットな分野だけに、いろいろとあるんですなあ。 JavascriptVMに多数の言語: CoffeeScript 1.0, StratifiedJS, EmscriptenによるC/C++, Python 上で取り上げたと言うか、初めて知ったEmscriptenにも言及されてる。
ウブに有るかと思ったら、有った。
sakae@uB:~$ sudo apt-get install emscripten Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: libandroid-json-org-java libargs4j-java libatinject-jsr330-api-java libclosure-compiler-java libguava-java libjsr305-java node-amdefine node-async node-optimist node-source-map node-uglify node-wordwrap Suggested packages: libandroid-json-org-java-doc libatinject-jsr330-api-java-doc libclosure-compiler-java-doc libjsr305-java-doc node-uglify-to-browserify The following NEW packages will be installed: emscripten libandroid-json-org-java libargs4j-java libatinject-jsr330-api-java libclosure-compiler-java libguava-java libjsr305-java node-amdefine node-async node-optimist node-source-map node-uglify node-wordwrap 0 upgraded, 13 newly installed, 0 to remove and 0 not upgraded. Need to get 25.5 MB of archives. After this operation, 104 MB of additional disk space will be used.
sakae@uB:~$ emcc -v ============================================================================== Welcome to Emscripten! This is the first time any of the Emscripten tools has been run. A settings file has been copied to ~/.emscripten, at absolute path: /home/sakae/.emscripten It contains our best guesses for the important paths, which are: LLVM_ROOT = /usr/bin NODE_JS = /usr/bin/nodejs EMSCRIPTEN_ROOT = /usr/share/emscripten Please edit the file if any of those are incorrect. This command will now exit. When you are done editing those paths, re-run it. ==============================================================================
無謀にもコンパイルにトライ
sakae@uB:~/newlisp-10.6.3$ make -f makefile_emscripten_lib_utf8 emcc -O2 --closure 1 -m32 -Wall -c -DMAC_OSX -DLIBRARY -DEMSCRIPTEN -DSUPPORT_UTF8 newlisp.c : emcc newlisp.o nl-symbol.o nl-math.o nl-list.o nl-liststr.o nl-string.o nl-filesys.o nl-sock.o nl-web.o nl-xml-json.o nl-matrix.o nl-debug.o pcre.o nl-utf8.o unix-lib.o -m32 -O2 -o newlisp-js-lib.html -s EXPORTED_FUNCTIONS="['_newlispEvalStr']" \ -s MAX_SETJMPS=100 -s TOTAL_MEMORY=33554432 --closure 1 \ --embed-file newlisp-js/readme.txt --embed-file newlisp-js/qa-bench --embed-file newlisp-js/canvas.lsp Traceback (most recent call last): File "/usr/bin/emcc", line 1547, in <module> extra_files_to_link = system_libs.calculate([f for _, f in sorted(temp_files)], in_temp, stdout, stderr, forced=forced_stdlibs) File "/usr/share/emscripten/tools/system_libs.py", line 545, in calculate libfile = shared.Cache.get(name, create) File "/usr/share/emscripten/tools/cache.py", line 36, in get shutil.copyfile(creator(), cachename) File "/usr/share/emscripten/tools/system_libs.py", line 379, in create_libcextra return build_libc('libcextra.bc', libcextra_files, ['-O2']) File "/usr/share/emscripten/tools/system_libs.py", line 60, in build_libc run_commands(commands) File "/usr/share/emscripten/tools/system_libs.py", line 45, in run_commands call_process(command) File "/usr/share/emscripten/tools/system_libs.py", line 14, in call_process raise CalledProcessError(proc.returncode, cmd) subprocess.CalledProcessError: Command '['/usr/bin/python', '/usr/share/emscripten/emcc', '/usr/share/emscripten/system/lib/libc/musl/src/stdio/vfscanf.c', '-o', '/tmp/tmpeLNzGW/vfscanf.c.o', '-I', '/usr/share/emscripten/system/lib/libc/musl/src/internal', '-I', '/usr/share/emscripten/system/lib/libc/musl/arch/js', '-O2']' returned non-zero exit status 1 makefile_emscripten_lib_utf8:29: recipe for target 'default' failed make: *** [default] Error 1
そしてエラー、-DMAC_OSX と -DLINUXは違うものだろーってんで修正してみたけど、同様なエラー。 無理せず、ハロワからだな。