Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

えんいー

未来の部屋

Regexp Assemble for PHP

萌え萌えCSS

sexyhook テスト用の接合部の作成

新潟アクセス修飾子

とある関数の電脳戦(バトルプログラム)

自己紹介

hiphop php でPHPからジェネレートされた

C++コードを読んでみよう

lua構文ハック

perlの魔術的ライブラリ

Regexp AssembleをPHPに移植。

正規表現を機械的に作成する。

テスト用の接合部を

後付で創りだす

必要悪のライブラリ

音声認識を利用して

家電制御を制御する

未来の部屋

自己紹介

こんちにはー

jQueryを

萌え化する

プロセスの乗っ取りを防ぐ

アンチフックの話

そして、攻性防壁の構築。

一部アセンブラ

by rti

public

protected

private

そして niigata

名前: rti

仕事: 起業準備中という名の引きこもり??

肩書き: シーランド公国伯爵

特技: イオナズンが使えます。

最近のトレンド: 音声認識

PHPをC++に変換する

hiphopの変換方式を

めぐる長い旅の話

http://d.hatena.ne.jp/rti7743/

http://rtilabs.net/

https://twitter.com/#!/super_rti

http://d.hatena.ne.jp/rti7743/20100113/1263332839

http://d.hatena.ne.jp/rti7743/20111220/1324389840

http://rtilabs.net/files/2011_11_02/

http://prezi.com/2r6wmrriyeqb/niigata/

http://d.hatena.ne.jp/rti7743/20120104/1325668680

http://rtilabs.net/files/2010_12_24/moemoe_css/

http://d.hatena.ne.jp/rti7743/20111225/1324817155

簡易スクリプトとしての利用

TASでの利用

設定ファイルでの利用

プログラム言語とコメント

答え

luaのコメントは // ではなく -- です。

主に言語の中に組み込む用途に使われることが

多いプログラム言語です。

むかつきますよね。

スクリプト

設定ファイルをプログラム化

//足し算をします

function add(a,b)

return a + b

end

lua構文ハック

村人A.lua

lua

config.lua

lua

欝になりますね。

だけど、

やっぱり、C/C++に組み込む言語だったら、

コメントは // にして統一感を持たせたいです。

今日は夜道に注意しよう・・・

コメントが // で書けない

プログラム言語なんて氏ねば(ry

Luaなんて知ってるよ。

って人に質問です。

ゲーム

本体

C/C++

server_ip = "192.168.10.10"

server_port = 80

user_agent = "Hogehoge/v2"

if user == "rti" then

user_agent = "rti/v3"

endif

エミュレータ

本体

プログラム

本体

Luaって何?

speak("山のむらにようこそ");

wait();

local yorn = yorn("前に来たことありますか?");

if yorn == 1 then

speak("またきてくれてありがとう");

else

speak("はじめまして!!");

endif

lua

-- 足し算をします

function add(a,b)

return a + b

end

C // (正確には /* */)

C++ //

C# //

D //

java //

javascript //

PHP //

ruby #

perl #

python #

sh #

lua --

SQL --

haskell --

basic rem

COBOL *

エミュレータに組み込まれているlua。

キー操作などをプログラム化し、

乱数などの最適解を自動で探索させる。

世界記録がどんどん塗り替えられる。

追記回数が減って、作成が容易になる。

なんて、ことは言ってはいけません。

lua

なんで、

C,C++に組み込む言語なのに

コメントが -- なのか?

(ガチCのコメントは /* */ ですけども)

設定ファイルの構文をluaに丸投げ。

httpd.conf とかみたいに階層構造などを持つものだと効果的かも。

ただし、GUIでの設定画面との共存が難しい。

足し算する Lua のコードは動きません。

なぜでしょうか?

さて、

今日は Lua の話をします。

参考:

氏ねとかいうと、

会場の半分以上を

敵に回すので危険が危ないです。

LL言語と SQLの関係に似てます。

最近は、TASさんの友達らしいです。

http://www6.atpages.jp/appsouko/work/TAS/doc/bot.html

既存のコメント

// をつけてあげればいいじゃない。

無事動くと。簡単でしょ。

ブロックコメントの処理も入ってる

なんで pascal調?

lua構文ハック

C/C++から組み込まれることが

多いのわかってんの?

----llex.c---------

case '/': { /* '//' (comment) */

next(ls);

if (ls->current == '/'){ /* short comment */

while (!currIsNewline(ls) && ls->current != EOZ)

next(ls); /* skip until end of line (or end of file) */

break;

}

else {

return '/';

}

}

-------------------

//足し算をします

function add(a,b)

return a + b

end

//足し算をします

function add(a,b) {

return a + b

}

//足し算をします

function add(a,b)

return a + b

end

次にむかつくところを

見てみましょう。

----llex.c---------

case '-': { /* '-' or '--' (comment) */

next(ls);

if (ls->current != '-') return '-';

/* else is a comment */

next(ls);

if (ls->current == '[') { /* long comment? */

int sep = skip_sep(ls);

luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */

if (sep >= 0) {

read_long_string(ls, NULL, sep); /* skip long comment */

luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */

break;

}

}

/* else short comment */

while (!currIsNewline(ls) && ls->current != EOZ)

next(ls); /* skip until end of line (or end of file) */

break;

}

-------------------

//足し算をします

function add(a,b)

return a + b

end

ムカツキますよね。

オープンソースなんだから、

文句があるなら

自分で直せばいいじゃない。

これで、OK

手が勝手にタイプしてしまう。

{} は、テーブル

----llex.c---------

case '/': { /* '//' (comment) */

next(ls);

if (ls->current == '/'){ /* short comment */

while (!currIsNewline(ls) && ls->current != EOZ)

next(ls); /* skip until end of line (or end of file) */

break;

}

else {

return '/';

}

}

-------------------

字句解析 llex ではなく、

構文解析 lparse.c でやる必要がある。

{}も作ってあげれば・・・

そのまま

llex.c でやると

バディングしてしまう。

さっきと同じように、

llex.c で、

{ } の処理を

書けばいいんじゃね?

a = {}

b = {1, 2, 3 , 4}

と、おもうぢゃん

だけど、これ動きません。

lua で

{} は、テーブル(配列兼MAPみたいなもの) になってます。

if文

なぜ else if ではなく elsif なのか。

luaはよく設計されている言語

lua構文ハック

----lparse.c---------------------------------

static void ifstat (LexState *ls, int line) {

FuncState *fs = ls->fs;

int escapelist = NO_JUMP;

test_then_block(ls, &escapelist);

while (ls->t.token == TK_ELSEIF)

test_then_block(ls, &escapelist);

if (testnext(ls, TK_ELSE))

block(ls);

check_match(ls, TK_END, TK_IF, line);

luaK_patchtohere(fs, escapelist);

}

----------------------------------------------

c-like

if (hogehoge == 1) {

func1()

} else if (hogehoge == 2) {

func2()

} else if (hogehoge == 3) {

func3()

} else {

func4()

}

A

だけど、

そんなの関係ないしww

パースを簡単にして速度を稼ぐ。

実に、構文がよく設計されてますね。

B

if (hogehoge == 1) then

func1()

elsif (hogehoge == 2) then

func2()

elsif (hogehoge == 3) then

func3()

else

func4()

end

B

if (hogehoge == 1) then

func1()

elsif (hogehoge == 2) then

func2()

elsif (hogehoge == 3) then

func3()

else

func4()

end

----lparse.c---------------------------------

static void ifstat (LexState *ls, int line) {

FuncState *fs = ls->fs;

int escapelist = NO_JUMP;

test_then_block(ls, &escapelist);

while (ls->t.token == TK_ELSEIF)

test_then_block(ls, &escapelist);

if (testnext(ls, TK_ELSE))

block(ls);

check_match(ls, TK_END, TK_IF, line);

luaK_patchtohere(fs, escapelist);

}

----------------------------------------------

if (hogehoge == 1) then

func1()

elsif (hogehoge == 2) then

func2()

elsif (hogehoge == 3) then

func3()

else

func4()

end

----lparse.c---------------------------------

static void ifstat (LexState *ls, int line) {

FuncState *fs = ls->fs;

int escapelist = NO_JUMP;

test_then_block(ls, &escapelist);

while (ls->t.token == TK_ELSEIF)

test_then_block(ls, &escapelist);

if (testnext(ls, TK_ELSE))

block(ls);

check_match(ls, TK_END, TK_IF, line);

luaK_patchtohere(fs, escapelist);

}

----------------------------------------------

C

----lparse.c-------------------------------------

static void ifstat (LexState *ls, int line) {

FuncState *fs = ls->fs;

int escapelist = NO_JUMP;

int isbracket = 0;

test_then_block(ls, &escapelist,&isbracket);

if (isbracket) {

while(1) {

check_match(ls, '}', TK_IF, line);

if (!testnext(ls, TK_ELSE)) {

break;

}

if ( ls->t.token == TK_IF ) {

test_then_block(ls, &escapelist,&isbracket);

if (!isbracket) {

error_expected(ls, '{');

}

continue;

}

else {

checknext(ls,'{');

block(ls);

}

}

}

else {

while (ls->t.token == TK_ELSEIF)

test_then_block(ls, &escapelist,&isbraket);

if (testnext(ls, TK_ELSE))

block(ls);

check_match(ls, TK_END, TK_IF, line);

}

luaK_patchtohere(fs, escapelist);

}

--------------------------------------------

D

----lparse.c-------------------------------------

static void ifstat (LexState *ls, int line) {

FuncState *fs = ls->fs;

int escapelist = NO_JUMP;

int isbracket = 0;

test_then_block(ls, &escapelist,&isbracket);

if (isbracket) {

while(1) {

check_match(ls, '}', TK_IF, line);

if (!testnext(ls, TK_ELSE)) {

break;

}

if ( ls->t.token == TK_IF ) {

test_then_block(ls, &escapelist,&isbracket);

if (!isbracket) {

error_expected(ls, '{');

}

continue;

}

else {

checknext(ls,'{');

block(ls);

}

}

}

else {

while (ls->t.token == TK_ELSEIF)

test_then_block(ls, &escapelist,&isbraket);

if (testnext(ls, TK_ELSE))

block(ls);

check_match(ls, TK_END, TK_IF, line);

}

luaK_patchtohere(fs, escapelist);

}

--------------------------------------------

----lparse.c---------------------------------

static void ifstat (LexState *ls, int line) {

FuncState *fs = ls->fs;

int escapelist = NO_JUMP;

test_then_block(ls, &escapelist);

while (ls->t.token == TK_ELSEIF)

test_then_block(ls, &escapelist);

if (testnext(ls, TK_ELSE))

block(ls);

check_match(ls, TK_END, TK_IF, line);

luaK_patchtohere(fs, escapelist);

}

----------------------------------------------

then の代わりに

{ を検出したら分岐

c-like な構文と LUAの秘密。

他のロジックもこんな感じで、

よく設計されています。

c-like

既存のluaコードのために

両対応しているので

余計にコードが増えてます。

lua

もし、 else if だったら while(elsif) で

待てないので、字句解析か構文解析に負担。

テストコード

俺は、 elsif ではなく、

else ifと書きたい。

しかも、C言語風に { } で。

lua

だけど・・・

パースを簡単にして速度を稼ぐ。実に、構文がよく設計されてますね。

なんでモードを切り替えないといけないの?

SJISを通すモードを作りました。

Windows/Linuxクロスプラットフォーム

C/C++の憂鬱

日本語windowsの文字コード

luaを

もっとハックしよう

//SJISを有効にするモードへ

lua_setmultibyte(L,1);

UTF-8 BOMあり

UTF-8 BOMなし

SJIS

MS-DOSからの歴史的経緯。

ASCIIと2バイト目が文字がある被る悲しい子。

→ダメ文字 表\ etc..

OK

gcc

NG

OK

LuaをSJISで書くと

ダメ文字問題がある。

オプションが必要

理由

// Luaを開く

lua_State* L = luaL_newstate();

//SJISを有効にするモードへ

lua_setmultibyte(L,1);

UTF16

g++

OK

C#や一部環境はこちら。

昔からプッシュされているけど流行らない不憫な子。

2バイト目に0x00が入るという、

C言語との相性の悪さが光る

オプションが必要

SJISを通そう。

OK

NG

何がダメ文字かどうかは、

文字コードによって変わる。

UTF-8のようにASCIIとの

競合がない文字コードもある。

世の中の人が全員SJISを

使っているわけではない。

visual stuido

(cl.exe)

挙動不審になることがある

UTF8

Web系とかを中心にしたトレンド。

Windowsで一部のソフトが微妙な具合でサポートしてる。

ってゆーか、WindowsのUTF16対応は早すぎたんだよ。

utf16と共にBOMというトリックスターがいるw

唯一、クロスプラットフォームにできそうな

文字コードがSJISぐらいしかない・・・

SJISを通すパッチの先駆者たちに感謝

luaでの this 引き回し

thisを引き回すことを前提にした tag の導入

比較してみよう。ちょっと楽になった?かんじかなぁ

luaからのコールバックには this はない。

初期化部

tag

lightuserdataという

特殊なテーブルに入れる。

名前のラベルは "_this"など

適当に決めるらしい。

luaオリジナル

初期化部

luaを

もっとハックしよう

初期化部

// Luaを開く

lua_State* L = luaL_newstate();

//thisのセット

lua_pushlightuserdata(L ,(void*) this);

lua_setfield(L,"_this");

// Luaを開く

lua_State* L = luaL_newstate();

//this保存

lua_setusertag(L,(void*)this);

C# / Builderの tag のようなものが

あってもいいじゃない

// Luaを開く

lua_State* L = luaL_newstate();

//this保存

lua_setusertag(L,(void*)this);

A

// Luaを開く

lua_State* L = luaL_newstate();

//thisのセット

lua_pushlightuserdata(L ,(void*) this);

lua_setfield(L,"_this");

C++に導入するときに

thisポインタを

引き回したい時が

あります。

class myscript {

//luaに登録する関数 コールバックされる。

static int l_func_callback(lua_State* L)

{

//thisが使いたい

this->method() ....

}

myscript()

{

}

}

A

利用

this引き回しの簡易化

利用

B

//thisを使いたいシーンが来たら、

lua_getfield(L,LUA_REGISTRYINDEX,"_this");

myclass* p = (myclass*)lua_touserdata(L,-1);

lua_pop(L,1);

//p に this が入っているよ!!

p->myFunc();

//thisを追加したシーンが来たら

myclass* p = (myclass*)lua_getusertag(L);

//p に this が入っているよ!!

p->myFunc();

B

//thisを追加したシーンが来たら

myclass* p = (myclass*)lua_getusertag(L);

//p に this が入っているよ!!

p->myFunc();

//thisを使いたいシーンが来たら、

lua_getfield(L,LUA_REGISTRYINDEX,"_this");

myclass* p = (myclass*)lua_touserdata(L,-1);

lua_pop(L,1);

//p に this が入っているよ!!

p->myFunc();

せっかくだから、XSS対策も。

Web制作言語といえばPHP

プログラムとHTMLの反転

余談

HTMLテンプレートエンジン

<b><?lua print func(123) ?></b>

<?php echo "hello world!" ?>

luaを

もっとハックしよう

基本的に、outテーブルのものしか出力させない。

out に突っ込んだものは、

ディフォルトでタグエスケープされる。

アプリの設定画面とか

デザインが作りやすい

webにしたいときあるじゃん

<BR><!--?LE:YThreads--><BR><BR>

<DIV ALIGN="CENTER">

<TD>

<FORM action="../test/bbs.cgi" method=post><BR>

<INPUT type=hidden value="<!--?V:YItaName-->" name=bbs>

</form>

</TD>

</TR>

</TBODY>

PHPの Zend Engineは、

当初は PHP本体から切り離せるよーな

設計思想だったそーですが、

いつの間にかその思想は忘れ去らてしまいました。(と、いう話を聞いた)

仮に切り離せたとしても、

ランタイムが巨大になるとおもいますけども。

print "<b>";print func(123);print "</b>"

PHPなどのように、

luaを使うことはできないか?

luaでweb開発

//計算

out = {"value" = 123}

//HTML表示

webload("index.tpl",out);

<?lua print "hello world!" ?>

HTMLの部分を print に置き換える。

<?lua ?> の中身はそのまま記述。

JSPとかと発想は同じw

windowsSDKで作るより

htmlで作れるとデザインの自由度が上がるし。

文字列リプレースとか、

for とか ifとか自分で作るのはめんどいし。

その他のハックまとめ

静的言語でのeval

CM

C++での言語内言語

http://d.hatena.ne.jp/rti7743/20120312

これらを組み込んだ、

lua

lua構文ハック

C++ libdcompile

サイズが小さい。(300kb程度)

おまけ

音声認識

ホームコントロール

LLVMを利用したソリューション

libやincludeファイルが必要

V8(javascript)

SJIS対応にする拡張

lua_setmultibyte(L,1); //これでSJIS対応

this引き回し簡略化

lua_setusertag(L,(void*)this);

PHPみたいに webに luaを

hello <?= "word" ?><?lua hoge() ?>

chromeのjavascriptエンジン。

動作が超早い。

C# CSharpCodeProvider

naichichi2 作ってます。

オープンソースなんだから、

いろいろ改造して遊びましょう。

boost.python

C#ランタイムに含まれる。

ただ、クロスプラットフォームを考えると・・・

monoだと別のソリューション?

https://github.com/rti7743/kaden_voice/tree/master/naichichi2

使ったことない・・・w

Learn more about creating dynamic, engaging presentations with Prezi