SlideShare a Scribd company logo
1 of 253
Download to read offline
Squirrelと変人の神隠し
・めるぽんについて
・めるぽんについて
ぽんぽん
・めるぽんについて
ぽんぽん

めるめる
・めるぽんについて
ぽんぽん

めるめる

猫好き
・めるぽんについて
ぽんぽん

めるめる

Twitter: melponn
Blog: id:melpon

猫好き
・タイトルについて
・タイトルについて
・タイトルについて

Squirrelと変人の神隠し
・Squirrelとは
・Squirrelとは
Alberto Demichelis が開発した組み込みスクリプト言語
・Squirrelとは
Alberto Demichelis が開発した組み込みスクリプト言語
Lua を強く意識して作られている
・Squirrelとは
Alberto Demichelis が開発した組み込みスクリプト言語
Lua を強く意識して作られている
Lua 知りません
・Squirrelとは
Alberto Demichelis が開発した組み込みスクリプト言語
Lua を強く意識して作られている
Lua 知りません
スクイレル vs スクワール
・Squirrelとは
Alberto Demichelis が開発した組み込みスクリプト言語
Lua を強く意識して作られている
Lua 知りません
スクイレル vs スクワール
英和: スクイレル
Wikipedia: スクワール
・Squirrelとは
Alberto Demichelis が開発した組み込みスクリプト言語
Lua を強く意識して作られている
Lua 知りません
スクイレル vs スクワール
英和: スクイレル
Wikipedia: スクワール
→どっちでもいいっぽい
・Squirrelの特徴
・Squirrelの特徴
動的型付け
・Squirrelの特徴
動的型付け
組み込み言語
・Squirrelの特徴
動的型付け
組み込み言語
システム関数未使用 (fopen, fprintf 等)
・Squirrelの特徴
動的型付け
組み込み言語
システム関数未使用 (fopen, fprintf 等)
STL 未使用
・Squirrelの特徴
動的型付け
組み込み言語
システム関数未使用 (fopen, fprintf 等)
STL 未使用
malloc,free カスタマイズ可能 (sq_vm_malloc)
・Squirrelの特徴
動的型付け
組み込み言語
システム関数未使用 (fopen, fprintf 等)
STL 未使用
malloc,free カスタマイズ可能 (sq_vm_malloc)
new 未使用 (placement new のみ)
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
M&S は手動で gc_collectgarbage() する
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
M&S は手動で gc_collectgarbage() する
M&S を切ることも可能 (NO_GARBAGE_COLLECTOR)
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
M&S は手動で gc_collectgarbage() する
M&S を切ることも可能 (NO_GARBAGE_COLLECTOR)
循環参照したらアウト
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
M&S は手動で gc_collectgarbage() する
M&S を切ることも可能 (NO_GARBAGE_COLLECTOR)
循環参照したらアウト
weakref があるので結構頑張れる
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
M&S は手動で gc_collectgarbage() する
M&S を切ることも可能 (NO_GARBAGE_COLLECTOR)
循環参照したらアウト
weakref があるので結構頑張れる
gc_collectgarbage の戻り値で回収された数が分かる
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
M&S は手動で gc_collectgarbage() する
M&S を切ることも可能 (NO_GARBAGE_COLLECTOR)
循環参照したらアウト
weakref があるので結構頑張れる
gc_collectgarbage の戻り値で回収された数が分かる
→ デバッグ時のみ有効にして戻り値を監視する
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
約 10000 行
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
約 10000 行
頑張れば読み下せる
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
MITライセンス
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
MITライセンス
昔は zlib/libpng ライセンス
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
MITライセンス
遅い
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
MITライセンス
遅い
Lua の半分ぐらい (参考: Game Scripting Languages)
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
MITライセンス
遅い
Lua の半分ぐらい (参考: Game Scripting Languages)
Squirrel JIT → 行方不明
・Squirrelの特徴
動的型付け
組み込み言語
参照カウント+マーク&スイープなGC
C++ で書かれている
MITライセンス
遅い
VC6(仮想コンパイラ)でコンパイル可能
Squirrel Language
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
local x;
・基本的な構文
local x;
x = 10;
・基本的な構文
local x;
x = 10;
if (x == 10) { }
・基本的な構文
local x;
x = 10;
if (x == 10) { }
for (local i = 0; i < x; i++) { }
・基本的な構文
local x;
x = 10;
if (x == 10) { }
for (local i = 0; i < x; i++) { }
local f = function(x) { return x + 10; }
・基本的な構文
local x;
x = 10;
if (x == 10) { }
for (local i = 0; i < x; i++) { }
local f = function(x) { return x + 10; }
local y = f(20); // y == 30
・基本的な構文
local x;
x = 10;
if (x == 10) { }
for (local i = 0; i < x; i++) { }
local f = function(x) { return x + 10; }
local y = f(20); // y == 30
local f2 = @(x) x + 10;
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・テーブル
・テーブル
キーから値を取り出すアレ
・テーブル
キーから値を取り出すアレ
要するに map<id, any>
・テーブル
キーから値を取り出すアレ
要するに map<id, any>
超重要
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・テーブルの作成
・スロットの設定・破棄
・テーブル委譲
・キーの存在確認
・浅いコピー
・メタメソッド
・テーブルの作成
local
a =
b =
[1]
}

x = {
10,
function() { return 20; },
= 30,
・テーブルの作成
local x = {
a = 10,
b = function() { return 20; },
[1] = 30,
}
print(x["a"]); // 10
・テーブルの作成
local x = {
a = 10,
b = function() { return 20; },
[1] = 30,
}
print(x["a"]); // 10
print(x.a);
// 10
・テーブルの作成
local x = {
a = 10,
b = function() { return 20; },
[1] = 30,
}
print(x["a"]); // 10
print(x.a);
// 10
print(x.b()); // 20
・テーブルの作成
local x = {
a = 10,
b = function() { return 20; },
[1] = 30,
}
print(x["a"]); // 10
print(x.a);
// 10
print(x.b()); // 20
print(x[1]); // 30
・テーブルの作成
local x = {
a = 10,
b = function() { return 20; },
[1] = 30,
}
print(x["a"]); // 10
print(x.a);
// 10
print(x.b()); // 20
print(x[1]); // 30
print(x.1);
// エラー
・基本的な構文
・テーブル
・テーブルの作成
・スロットの設定・破棄
・テーブル委譲
・キーの存在確認
・浅いコピー
・メタメソッド
・スロットの設定・破棄
local x = { }
・スロットの設定・破棄
local x = { }
x.v = 10; // エラー
・スロットの設定・破棄
local x = { }
x.v = 10; // エラー
x.v <- 10; // OK
・スロットの設定・破棄
local x = { }
x.v = 10; // エラー
x.v <- 10; // OK
x.v = 10; // OK
・スロットの設定・破棄
local x = { }
x.v = 10; // エラー
x.v <- 10; // OK
x.v = 10; // OK
delete x.v;
・スロットの設定・破棄
local x = { }
x.v = 10; // エラー
x.v <- 10; // OK
x.v = 10; // OK
delete x.v;
x.v = 10; // エラー
・基本的な構文
・テーブル
・テーブルの作成
・スロットの設定・破棄
・テーブル委譲
・キーの存在確認
・浅いコピー
・メタメソッド
・テーブル委譲
local
a =
b =
}
local
b =
}

x = {
function() { return 10; },
function() { return 20; },
y = {
function() { return 30; },
・テーブル委譲
local x = {
a = function() { return 10; },
b = function() { return 20; },
}
local y = {
b = function() { return 30; },
}
y.setdelegate(x);
・テーブル委譲
local x = {
a = function() { return 10; },
b = function() { return 20; },
}
local y = {
b = function() { return 30; },
}
y.setdelegate(x);
print(y.a()); // 10
・テーブル委譲
local x = {
a = function() { return 10; },
b = function() { return 20; },
}
local y = {
b = function() { return 30; },
}
y.setdelegate(x);
print(y.a()); // 10
print(y.b()); // 30
・基本的な構文
・テーブル
・テーブルの作成
・スロットの設定・破棄
・テーブル委譲
・キーの存在確認
・浅いコピー
・メタメソッド
・キーの存在確認
if ("v" in x) { }

・浅いコピー
local x = { v = 10, };
local y = clone x;
・基本的な構文
・テーブル
・テーブルの作成
・スロットの設定・破棄
・テーブル委譲
・キーの存在確認
・浅いコピー
・メタメソッド
・メタメソッド
・_add, _sub, _mul, _div, _modulo, _unm
・メタメソッド
・_add, _sub, _mul, _div, _modulo, _unm
local x = {
v = 10,
_add = function(rhs) { this.v + rhs; },
}
・メタメソッド
・_add, _sub, _mul, _div, _modulo, _unm
local x = {
v = 10,
_add = function(rhs) { this.v + rhs; },
}
print(x + 10); // x._add(10)
・メタメソッド
・_add, _sub, _mul, _div, _modulo, _unm
・_set, _get
・メタメソッド
・_add, _sub, _mul, _div, _modulo, _unm
・_set, _get
local x = {
_get = function(key) {
if (key == "hoge") return 10;
throw null;
}
}
・メタメソッド
・_add, _sub, _mul, _div, _modulo, _unm
・_set, _get
local x = {
_get = function(key) {
if (key == "hoge") return 10;
throw null;
}
}
print(x.hoge); // x._get("hoge")
・メタメソッド
・_add, _sub, _mul, _div, _modulo, _unm
・_set, _get
local x = {
_get = function(key) {
if (key == "hoge") return 10;
throw null;
}
}
print(x.hoge); // x._get("hoge")
x.hoge <- 20;
print(x.hoge); // 20
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・クラス
・クラス
テーブルとほとんど同じ
・クラス
テーブルとほとんど同じ
無くても困らないけどあると便利
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・クラス定義
・継承
・テーブルとの違い
・基本的な構文
・テーブル
・クラス
・クラス定義
・継承
・テーブルとの違い
・クラス定義
class hoge {
constructor() { }
function foo() { }
}
・クラス定義
class hoge {
constructor() { }
function foo() { }
}
local h = hoge();
h.foo();
・クラス定義
this.hoge <- class {
constructor() { }
function foo() { }
}
local h = hoge();
h.foo();
・クラス定義
this.hoge <- class {
constructor() { }
foo <- function() { }
}
local h = hoge();
h.foo();
・基本的な構文
・テーブル
・クラス
・クラス定義
・継承
・テーブルとの違い
・継承
・テーブル版
・継承
・テーブル版
this.x <- {
a = function() { return 10; },
b = function() { return 20; },
}
this.y <- {
b = function() { return 30; },
}
y.setdelegate(x);
print(y.a()); // 10
print(y.b()); // 30
・継承
・クラス版
class X {
a <- function() { return 10; }
b <- function() { return 20; }
}
class Y extends X {
b <- function() { return 30; }
}
local y = Y();
print(y.a()); // 10
print(y.b()); // 30
・継承
・クラス版
class X {
a <- function() { return 10; }
b <- function() { return 20; }
}
class Y extends X {
b <- function() { return 30; }
}
local y = Y();
print(y.a()); // 10
print(y.b()); // 30
・基本的な構文
・テーブル
・クラス
・クラス定義
・継承
・テーブルとの違い
・テーブルとの違い
クラス

テーブル
・テーブルとの違い
クラス
local x = X()

テーブル
・テーブルとの違い
クラス
local x = X()

テーブル
local x = clone X;
x.constructor();
・テーブルとの違い
クラス
local x = X()

X は OT_CLASS
x は OT_INSTANCE

テーブル
local x = clone X;
x.constructor();
・テーブルとの違い
クラス

テーブル

local x = X()

local x = clone X;
x.constructor();

X は OT_CLASS

X も x も OT_TABLE

x は OT_INSTANCE
・テーブルとの違い
クラス

テーブル

local x = X()

local x = clone X;
x.constructor();

X は OT_CLASS

X も x も OT_TABLE

x は OT_INSTANCE
if (x instanceof X) { }
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・ジェネレータ
・ジェネレータ
要するにコルーチン
・ジェネレータ
要するにコルーチン
関数の途中で中断→再開できる関数
・ジェネレータ
要するにコルーチン
関数の途中で中断→再開できる関数
yield を使った function を作るとジェネレータになる
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z;
}
}
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z;
}
}
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z;
}
}
local g = f(1,1); // まだ f は実行されない
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z;
}
}
local g = f(1,1); // まだ f は実行されない
foreach (x in g)
print(x+",");
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z;
}
}
local g = f(1,1); // まだ f は実行されない
foreach (x in g)
print(x+","); // 1,
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z;
}
}
local g = f(1,1); // まだ f は実行されない
foreach (x in g)
print(x+","); // 1,1,
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z;
}
}
local g = f(1,1); // まだ f は実行されない
foreach (x in g)
print(x+","); // 1,1,2,
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z; // x=1, y=2
}
}
local g = f(1,1); // まだ f は実行されない
foreach (x in g)
print(x+","); // 1,1,2,
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z; // x=1, y=2
}
}
local g = f(1,1); // まだ f は実行されない
foreach (x in g)
print(x+","); // 1,1,2,3,
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z; // x=1, y=2
}
}
local g = f(1,1); // まだ f は実行されない
foreach (x in g)
print(x+","); // 1,1,2,3,5,8...
・ジェネレータ(コルーチン)
local f = function(x, y) {
yield x; yield y;
while (true) {
local z = x + y;
yield z;
x = y; y = z; // x=1, y=2
}
}
local g = f(1,1); // まだ f は実行されない
local x;
while (x = resume g)
print(x+","); // 1,1,2,3,5,8,...
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・配列
・配列
local xs = [1,"2",@()3,4];
・配列
local xs = [1,"2",function(){return 3;},4];
・配列
local xs = [1,"2",@()3,4];
・配列
local xs = [1,"2",@()3,4];

それテーブルでできるよ!
・配列
local xs = [1,"2",@()3,4];

それテーブルでできるよ!
local ys = {
[0] = 1,
[1] = "2",
[2] = @()3,
[3] = 4,
}
・配列
local xs = [1,"2",@()3,4];

それテーブルでできるよ!
local ys = {
[0] = 1,
[1] = "2",
[2] = @()3,
[3] = 4,
}

テーブルより配列の方が高速
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・foreach
テーブル・クラス
foreach (value in array) { }
foreach (key,value in array) { }
・foreach
テーブル・クラス
文字列
foreach (char in "hoge") { }
foreach (index,char in "hoge") { }
・foreach
テーブル・クラス
文字列
配列
foreach (value in array) { }
foreach (index,value in array) { }
・foreach
テーブル・クラス
文字列
配列
ジェネレータ
foreach (value in gen) { }
・foreach
テーブル・クラス
文字列
配列
ジェネレータ
_nexti メタメソッド
・foreach
_nexti メタメソッド
class X {
_nexti = function(v) {
return v == null ? 0 : v+1;
}
}
local x = X();
foreach (v in x) { }
・foreach
テーブル・クラス
文字列
配列
ジェネレータ
_nexti メタメソッド
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・束縛
・束縛
local x = 10;
local f = function(y) {
return x + y;
}
・束縛
local x = 10;
local f = function(y) {
return x + y;
}
・束縛
local x = 10;
local f = function(y) {
return x + y;
} // x を束縛
・束縛
local x = 10;
local f = function(y) {
return x + y;
} // x を束縛
f(20); // 30
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20);
}
}
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20);
}
}
y.apply(x.foo);
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20); // エラー(hoge が見つからない)
}
}
y.apply(x.foo);
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20); // x.f(20); ×
}
}
y.apply(x.foo);
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20); // this.f(20);
}
}
y.apply(x.foo);
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20); // エラー(hoge が見つからない)
}
}
y.apply(x.foo);
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20); // エラー(hoge が見つからない)
}
}
y.apply(x.foo); →this を勝手に束縛しない
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20);
}
}
y.apply(x.foo.bindenv(x));
・束縛
local x = {
hoge = 10,
foo = function(fuga) {
return hoge + fuga;
},
}
local y = {
apply = function(f) {
f(20); // x.f(20);
}
}
y.apply(x.foo.bindenv(x));
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛
・基本的な構文
・テーブル
・クラス
・ジェネレータ
・配列
・foreach
・束縛

・標準ライブラリ
・標準ライブラリ
・標準ライブラリ
Squirrel本体とは別プロジェクト
・標準ライブラリ
Squirrel本体とは別プロジェクト
時間の取得
・標準ライブラリ
Squirrel本体とは別プロジェクト
時間の取得
I/O
・標準ライブラリ
Squirrel本体とは別プロジェクト
時間の取得
I/O
数学関数
・標準ライブラリ
Squirrel本体とは別プロジェクト
時間の取得
I/O
数学関数
正規表現
・標準ライブラリ
Squirrel本体とは別プロジェクト
時間の取得
I/O
数学関数
正規表現
→C標準関数を使用
組み込み
・実行環境
・実行環境
仮想マシン(SquirrelVM)上で動作する
・実行環境
仮想マシン(SquirrelVM)上で動作する
各命令は 64bit 固定
・実行環境
仮想マシン(SquirrelVM)上で動作する
Squirrel ソースをコンパイル→VM 用命令に変換
・実行環境
仮想マシン(SquirrelVM)上で動作する
Squirrel ソースをコンパイル→VM 用命令に変換
C++とのインターフェースにはスタックを使う
・実行環境
仮想マシン(SquirrelVM)上で動作する
Squirrel ソースをコンパイル→VM 用命令に変換
C++とのインターフェースにはスタックを使う
Squirrelソース
local x=10;
y <- function(){}
...
・実行環境
仮想マシン(SquirrelVM)上で動作する
Squirrel ソースをコンパイル→VM 用命令に変換
C++とのインターフェースにはスタックを使う
Squirrelソース
local x=10;
compile
y <- function(){}
...
・実行環境
仮想マシン(SquirrelVM)上で動作する
Squirrel ソースをコンパイル→VM 用命令に変換
C++とのインターフェースにはスタックを使う
Squirrelソース
local x=10;
compile _OP_ADD
_OP_JMP
y <- function(){}
_OP_CALL
...
...
・実行環境
仮想マシン(SquirrelVM)上で動作する
Squirrel ソースをコンパイル→VM 用命令に変換
C++とのインターフェースにはスタックを使う
Squirrelソース
local x=10;
compile _OP_ADD run
_OP_JMP
y <- function(){}
_OP_CALL
...
...

SquirrelVM
・実行環境
仮想マシン(SquirrelVM)上で動作する
Squirrel ソースをコンパイル→VM 用命令に変換
C++とのインターフェースにはスタックを使う
Squirrelソース
local x=10;
compile _OP_ADD run
_OP_JMP
y <- function(){}
_OP_CALL
...
...

SquirrelVM
C++
VMスタック
OT_BOOL
OT_TABLE
OT_ARRAY

...
・sq_call
SquirrelVM

C++
VMスタック
・sq_call
SquirrelVM

C++
sq_compile
VMスタック

OT_CLOSURE
・sq_call
SquirrelVM

C++
sq_pushroottable
VMスタック

OT_CLOSURE
OT_TABLE
・sq_call
SquirrelVM

C++
sq_pushinteger
VMスタック

OT_CLOSURE
OT_TABLE
OT_INTEGER
・sq_call
SquirrelVM

C++
sq_call(vm, 2, SQTrue, SQFalse);
VMスタック

OT_CLOSURE
OT_TABLE
OT_INTEGER
・sq_call
引数の数
SquirrelVM

C++
sq_call(vm, 2, SQTrue, SQFalse);
VMスタック

OT_CLOSURE
OT_TABLE
OT_INTEGER
・sq_call
戻り値の有無
SquirrelVM

C++
sq_call(vm, 2, SQTrue, SQFalse);
VMスタック

OT_CLOSURE
OT_TABLE
OT_INTEGER
・sq_call
エラーハンドリングの有無
SquirrelVM

C++
sq_call(vm, 2, SQTrue, SQFalse);
VMスタック

OT_CLOSURE
OT_TABLE
OT_INTEGER
・sq_call
SquirrelVM

C++
VMスタック

OT_CLOSURE
OT_INSTANCE
・sq_call
SquirrelVM

C++
sq_pop(vm, 2);
VMスタック

OT_CLOSURE
OT_INSTANCE
・sq_call
SquirrelVM

C++
VMスタック
・sq_call
SquirrelVM

C++
VMスタック

→めんどい
・組み込み
// Squirrel 実行環境作成
SQUIRRELVM vm = sq_open(1024);
・組み込み
// Squirrel 実行環境作成
SQUIRRELVM vm = sq_open(1024);
// print 用の関数を登録
sq_setprintfunc(vm, &print_func, &error_print_func);
・組み込み
// Squirrel 実行環境作成
SQUIRRELVM vm = sq_open(1024);
// print 用の関数を登録
sq_setprintfunc(vm, &print_func, &error_print_func);
// コンパイルエラー用の関数を登録
sq_setcompilererrorhandler(vm_, &compiler_error_func);
・組み込み
// Squirrel 実行環境作成
SQUIRRELVM vm = sq_open(1024);
// print 用の関数を登録
sq_setprintfunc(vm, &print_func, &error_print_func);
// コンパイルエラー用の関数を登録
sq_setcompilererrorhandler(vm_, &compiler_error_func);
// 実行時エラー用の関数を登録
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
・組み込み
// Squirrel 実行環境作成
SQUIRRELVM vm = sq_open(1024);
// print 用の関数を登録
sq_setprintfunc(vm, &print_func, &error_print_func);
// コンパイルエラー用の関数を登録
sq_setcompilererrorhandler(vm_, &compiler_error_func);
// 実行時エラー用の関数を登録
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
・組み込み
// print 用の関数を登録
sq_setprintfunc(vm, &print_func, &error_print_func);
// コンパイルエラー用の関数を登録
sq_setcompilererrorhandler(vm_, &compiler_error_func);
// 実行時エラー用の関数を登録
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
// コンパイル
sq_compile(vm, &file_reader, fp, "main.nut", SQTrue);
・組み込み
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
SQInteger file_reader(SQUserPointer file) {
char c = 0;
std::fread(&c,sizeof(c),1,static_cast<FILE*>(file));
return c;
}
// コンパイル
sq_compile(vm, &file_reader, fp, "main.nut", SQTrue);
・組み込み
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
// コンパイル
sq_compile(vm, &file_reader, fp, "main.nut", SQTrue);
OT_CLOSURE
・組み込み
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
// コンパイル
sq_compile(vm, &file_reader, fp, "main.nut", SQTrue);
// this を push
OT_CLOSURE
sq_pushroottable(vm);
OT_TABLE
・組み込み
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
// コンパイル
sq_compile(vm, &file_reader, fp, "main.nut", SQTrue);
// this を push して呼び出し
OT_CLOSURE
sq_pushroottable(vm);
sq_call(vm, 1, SQFalse, SQTrue);
・組み込み
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
// コンパイル
sq_compile(vm, &file_reader, fp, "main.nut", SQTrue);
// this を push して呼び出し
sq_pushroottable(vm);
sq_call(vm, 1, SQFalse, SQTrue);
// 後片付け
sq_pop(vm, 1);
・組み込み
sq_newclosure(vm, &error_func, 0);
sq_seterrorhandler(vm);
FILE* fp = std::fopen("main.nut", "rb");
// コンパイル
sq_compile(vm, &file_reader, fp, "main.nut", SQTrue);
// this を push して呼び出し
sq_pushroottable(vm);
sq_call(vm, 1, SQFalse, SQTrue);
// 後片付け
sq_pop(vm, 1);
// VM 終了
sq_close(vm);
・C++ → Squirrel 関数の呼び出し
・C++ → Squirrel 関数の呼び出し
→めんどい
・C++ → Squirrel 関数の呼び出し
→めんどい

・Squirrel → C++ 関数の呼び出し
・C++ → Squirrel 関数の呼び出し
→めんどい

・Squirrel → C++ 関数の呼び出し
SQInteger func(HSQUIRRELVM vm) {
SQInteger v; // 引数
sq_getinteger(vm, -2, &v);
...
}
sq_newclosure(vm, &func, 0);
sq_newslot(vm, ...);
・C++ → Squirrel 関数の呼び出し
→めんどい

・Squirrel → C++ 関数の呼び出し
→めんどい
・C++ → Squirrel 関数の呼び出し
→めんどい

・Squirrel → C++ 関数の呼び出し
→めんどい

・バインダを使おう
・バインダ
・バインダ
class image {
void load(const char* str);
int width() const;
int height() const;
};
・バインダ
class image {
void load(const char* str);
int width() const;
int height() const;
};
root.Bind("image", Sqrat::Class<image>(vm)
.Func("load", &image::load)
.Func("width", &image::width)
.Func("height", &image::height));
・バインダ
Sqrat
・バインダ
Sqrat
SqPlus
・バインダ
Sqrat
SqPlus
Squadd
・バインダ
Sqrat
SqPlus
Squadd
jkBind
・バインダ
Sqrat
SqPlus
Squadd
jkBind
lazuli
・適当に作ってみた
・適当に作ってみた
結論:
・適当に作ってみた
結論:
既存ライブラリはバインダを使ってもめんどい
・適当に作ってみた
結論:
既存ライブラリはバインダを使ってもめんどい
自作クラスならすごく幸せになれる
・デバッガ
・デバッガ
SQDBG
・デバッガ
SQDBG
SQDEV
・デバッガ
SQDBG
SQDEV
Visual Studio Integration
・デバッガ
SQDBG
SQDEV
Visual Studio Integration
使うと楽に開発できる
・デバッガ
SQDBG
SQDEV
Visual Studio Integration
使うと楽に開発できる
しかしデバッガ自体に問題があることも
SQDEV (Eclipse) or
VS Integration

program
SQDBG
program

SQDEV (Eclipse) or
VS Integration
SQDBG
program

SQDEV (Eclipse) or
VS Integration
SQDBG

sq_rdbg_waitforconnection
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)
ab 10 main.nut

sq_rdbg_waitforconnection
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection

ab 10 main.nut
debughook('l',9,"main.nut")
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection

ab 10 main.nut
debughook('l',9,"main.nut")
debughook('l',10,"main.nut")
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection

ab 10 main.nut
debughook('l',9,"main.nut")
<break line="10"
src="main.nut" ...>
...
</break>

debughook('l',10,"main.nut")
program

SQDEV (Eclipse) or
VS Integration
SQDBG

sq_rdbg_waitforconnection
<break line="10" src="main.nut" type="breakpoint">
connect (port:1234)
<objs>
<o type="x" ref="2">
<e kt="s" kv="ratio" vt="f" v="0.00208333"/>
ab 10 main.nut
<e kt="s" kv="gen_" vt="g" v="g"/>
debughook('l',9,"main.nut")
<e kt="s" kv="rratio" vt="i" v="480"/>
</o>
<o type="x" ref="1">
debughook('l',10,"main.nut")
<e kt="s" kv="scene" vt="x" v="2"/>
</o>
<o type="a" ref="3"/>
<o type="r" ref="0"/>
</objs>
<calls>
<call fnc="unknown" src="sqript/main.nut" line="16">
<l name="this" type="x" val="1"/>
</call>
<call fnc="main" src="eval" line="1">
<l name="vargv" type="a" val="3"/>
<l name="this" type="t" val="0"/>
</call>
</calls>
</break>
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection

ab 10 main.nut
debughook('l',9,"main.nut")
<break line="10"
src="main.nut" ...>
...
</break>

debughook('l',10,"main.nut")
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection

ab 10 main.nut
debughook('l',9,"main.nut")
<break line="10"
src="main.nut" ...>
...
</break>
so

debughook('l',10,"main.nut")
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection

ab 10 main.nut
debughook('l',9,"main.nut")
<break line="10"
src="main.nut" ...>
...
</break>

debughook('l',10,"main.nut")

so
debughook('l',11,"main.nut")
program

SQDEV (Eclipse) or
VS Integration
SQDBG
connect (port:1234)

sq_rdbg_waitforconnection

ab 10 main.nut
debughook('l',9,"main.nut")
<break line="10"
src="main.nut" ...>
...
</break>

debughook('l',10,"main.nut")

so
debughook('l',11,"main.nut")
<break ...>...</break>
・終わりに
・終わりに
Squirrel を使うにあたっての心構え
・終わりに
Squirrel を使うにあたっての心構え
・バグが起きても言語を信じろ
・終わりに
Squirrel を使うにあたっての心構え
・バグが起きても言語を信じろ
・デバッガがおかしくなったら自分で直せ
・終わりに
Squirrel を使うにあたっての心構え
・バグが起きても言語を信じろ
・デバッガがおかしくなったら自分で直せ
・どんな困難に遭遇しても挫けるな
・終わりに
Squirrel を使うにあたっての心構え
・バグが起きても言語を信じろ
・デバッガがおかしくなったら自分で直せ
・どんな困難に遭遇しても挫けるな
・めるめるかわいい
おわり

More Related Content

What's hot

ゲーム向けな美味しい乱数を生成する(再アップ版)
ゲーム向けな美味しい乱数を生成する(再アップ版)ゲーム向けな美味しい乱数を生成する(再アップ版)
ゲーム向けな美味しい乱数を生成する(再アップ版)
ai BlogOnly
 
継続的インテグレーションとテストの話
継続的インテグレーションとテストの話継続的インテグレーションとテストの話
継続的インテグレーションとテストの話
Preferred Networks
 

What's hot (20)

リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜 リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
Ruby での外部コマンドの実行について
Ruby での外部コマンドの実行についてRuby での外部コマンドの実行について
Ruby での外部コマンドの実行について
 
充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろ
 
WASM(WebAssembly)入門 ペアリング演算やってみた
WASM(WebAssembly)入門 ペアリング演算やってみたWASM(WebAssembly)入門 ペアリング演算やってみた
WASM(WebAssembly)入門 ペアリング演算やってみた
 
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
最適化計算の概要まとめ
最適化計算の概要まとめ最適化計算の概要まとめ
最適化計算の概要まとめ
 
Wireshark だけに頼らない! パケット解析ツールの紹介
Wireshark だけに頼らない! パケット解析ツールの紹介Wireshark だけに頼らない! パケット解析ツールの紹介
Wireshark だけに頼らない! パケット解析ツールの紹介
 
幾何と機械学習: A Short Intro
幾何と機械学習: A Short Intro幾何と機械学習: A Short Intro
幾何と機械学習: A Short Intro
 
Docker volume基礎/Project Longhorn紹介
Docker volume基礎/Project Longhorn紹介Docker volume基礎/Project Longhorn紹介
Docker volume基礎/Project Longhorn紹介
 
圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド
 
ゲーム向けな美味しい乱数を生成する(再アップ版)
ゲーム向けな美味しい乱数を生成する(再アップ版)ゲーム向けな美味しい乱数を生成する(再アップ版)
ゲーム向けな美味しい乱数を生成する(再アップ版)
 
継続的インテグレーションとテストの話
継続的インテグレーションとテストの話継続的インテグレーションとテストの話
継続的インテグレーションとテストの話
 
Getting started with MLOps
Getting started with MLOpsGetting started with MLOps
Getting started with MLOps
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
BridgePointを使ったモデル駆動開発(ETロボコン環境のご紹介)
BridgePointを使ったモデル駆動開発(ETロボコン環境のご紹介)BridgePointを使ったモデル駆動開発(ETロボコン環境のご紹介)
BridgePointを使ったモデル駆動開発(ETロボコン環境のご紹介)
 
KPTの基本と、その活用法
KPTの基本と、その活用法KPTの基本と、その活用法
KPTの基本と、その活用法
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
 
機械学習で泣かないためのコード設計 2018
機械学習で泣かないためのコード設計 2018機械学習で泣かないためのコード設計 2018
機械学習で泣かないためのコード設計 2018
 

Viewers also liked

近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜
近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜
近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜
俊仁 小林
 
Boost.Timer
Boost.TimerBoost.Timer
Boost.Timer
melpon
 

Viewers also liked (6)

近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜
近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜
近頃のオンラインゲームの Agile っぽい開発手法とか 〜ONE-UP における10の取り組み〜
 
Boost.Timer
Boost.TimerBoost.Timer
Boost.Timer
 
たのしいうぇっぶくろーら #pyfes
たのしいうぇっぶくろーら #pyfesたのしいうぇっぶくろーら #pyfes
たのしいうぇっぶくろーら #pyfes
 
ヒューレットパッカード社の 社員の離職リスク予測 第一回機械学習ビジネス研究会 #ml_business
ヒューレットパッカード社の社員の離職リスク予測 第一回機械学習ビジネス研究会 #ml_business ヒューレットパッカード社の社員の離職リスク予測 第一回機械学習ビジネス研究会 #ml_business
ヒューレットパッカード社の 社員の離職リスク予測 第一回機械学習ビジネス研究会 #ml_business
 
DAUを評価指標から捨てた会社の話 #tokyowebmining
DAUを評価指標から捨てた会社の話 #tokyowebminingDAUを評価指標から捨てた会社の話 #tokyowebmining
DAUを評価指標から捨てた会社の話 #tokyowebmining
 
スマホマーケットの概要と、 マーケティングの失敗例と改善 (アナリティクス アソシエーション 特別セミナー)
スマホマーケットの概要と、マーケティングの失敗例と改善 (アナリティクス アソシエーション 特別セミナー)スマホマーケットの概要と、マーケティングの失敗例と改善 (アナリティクス アソシエーション 特別セミナー)
スマホマーケットの概要と、 マーケティングの失敗例と改善 (アナリティクス アソシエーション 特別セミナー)
 

Similar to Squirrel (12)

20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
 
Implicit Explicit Scala
Implicit Explicit ScalaImplicit Explicit Scala
Implicit Explicit Scala
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
Clojure
ClojureClojure
Clojure
 
Processing資料(1) Processingの基本
Processing資料(1) Processingの基本Processing資料(1) Processingの基本
Processing資料(1) Processingの基本
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
Go と Couchbase で microservices を作るには?
Go と Couchbase で microservices を作るには?Go と Couchbase で microservices を作るには?
Go と Couchbase で microservices を作るには?
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
すごいHaskell読書会 in 大阪 2週目 #5 第5章:高階関数 (2)
すごいHaskell読書会 in 大阪 2週目 #5 第5章:高階関数 (2)すごいHaskell読書会 in 大阪 2週目 #5 第5章:高階関数 (2)
すごいHaskell読書会 in 大阪 2週目 #5 第5章:高階関数 (2)
 
Actor&stm
Actor&stmActor&stm
Actor&stm
 
Pythonintro
PythonintroPythonintro
Pythonintro
 

Squirrel