Skip to content

Instantly share code, notes, and snippets.

@KeenS
Created June 8, 2014 03:56
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save KeenS/f3deeca6295d7454cb17 to your computer and use it in GitHub Desktop.
Save KeenS/f3deeca6295d7454cb17 to your computer and use it in GitHub Desktop.
(ql:quickload :parenscript)
(ql:quickload :cl-who)
(ql:quickload :clack)
(in-package :ps)
(defvar *canvas-id* "alien-canvas")
(clack:clackup
(lambda (env)
(list 200
'(:content-type "text/html")
(list
(who:with-html-output-to-string (*standard-output* nil :prologue t :indent t)
(:html
(:head
(:script :type "text/javascript"
(who:fmt "~A"
(ps (defvar x 0)
(defvar y 0)
(defvar dx 1)
(defvar dy 1)
(defvar img (new -image))
(setf (@ img src) "http://www.lisperati.com/lisplogo_alien_128.png")
(set-interval "draw()" 5)
(defun draw ()
(let ((w 128)
(h 75)
(canvas ((@ document get-element-by-id) #.*canvas-id*)))
(if (or (not canvas) (not (@ canvas get-context)))
(return false))
(let ((ctx ((@ canvas get-context) "2d")))
((@ ctx fill-rect) 0 0 500 500)
(if (and (<= (+ x dx w) 500) (<= 0 (+ x dx)))
(setf x (+ x dx))
(setf dx (* dx -1)))
(if (and (<= (+ y dy h) 500) (<= 0 (+ y dy)))
(setf y (+ y dy))
(setf dy (* dy -1)))
((@ ctx draw-image) img x y))))))))
(:body (:canvas :id *canvas-id* :width 500 :height 500))))))))

(S式で書く(altJS)達)

天下一altJS武闘会(#tenka1altJS) @渋谷プライムプラザ四階

自己紹介

  • κeen
  • 東大数学科の4年生
  • Twit : @blackenedgold
  • Github : KeenS
  • Blog : κeenのHappy Hacκing Blog
  • Shibuya.lispにいます。(2014-06〜運営になりました)
  • Lisp, Ruby, OCaml, Shell Scriptあたりを書きます

お品書き

  • (ボツ) Shen.js
  • (ボツ) Embedable Common Lisp with Emscripten
  • (ボツ) Picrin with Emscripten
  • (ボツ) オレオレaltJSの作り方の話
  • ParenScript

Shen.js

Shenの公式ページより

  • パターンマッチ
  • λ計算ベース
  • マクロ
  • 遅延評価も可能
  • 静的型検査
  • 関数的なPrologの統合
  • ビルトインコンパイラコンパイラ

これのJS実装もある。

(define factorial
  0 -> 1
  X -> (* X (factorial (- X 1))))

そもそもaltJSじゃない…

ボツ

ECL with Emscripten

  • ANSI Common Lisp準拠のCommon Lisp処理系
  • LispをコンパイルしてCを吐く
  • Emscriptenでコンパイルすれば…

#include <ecl/ecl-cmp.h> が悪さをしてコンパイル出来ない

ボツ

picrin

  • R7RS small準拠を目指すScheme処理系
  • R7RS準拠の中では唯一Emscriptenで コンパイル出来るらしい
  • SDLもEmscriptenで動くらしいから 組み合わせればウハウハじゃね?

コンパイル出来ない… (va_argsは64bit x Clang3.3では コンパイル出来ないとか言われる。回避策も効かない)

ボツ

オレオレaltJSの作り方の話

escodegenを使う

{
    type: 'BinaryExpression',
    operator: '+',
    left: { type: 'Literal', value: 40 },
    right: { type: 'Literal', value: 2 }
}
→40 + 2

オレオレaltJS(S式) ↓ read リスト ↓ 変換 (find-file “~/Lisp/translate.lisp”) リスト ↓ cl-json JSON ↓ escodegen JS

escodegenのドキュメントがあんまりない…

ボツ

ParenScript

  • Common Lisp製
  • Weblocks(WAF)に採用されるなどの実績/伝統
  • Common LispのサブセットをJSにコンパイル
  • 実際はCommon Lispのマクロなので Common Lispに組み込んで使える
  • ランタイムライブラリは必要ない
  • Lispを無理矢理変換するというより LispっぽくJSを書ける感じ

~/Lisp/parenscript.lisp (@ obj property) でプロパティ参照 (chain obj function/property) でメソッドチェーン など

以上

(defun translate (x)
(match x
((list '+ left right) (list :type "BinaryExpression"
:operator "+"
:left (translate left)
:right (translate right)))
((type 'number) (list :type "Literal"
:value x))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment