Fork
1
Fav
1
View
4045
  • Play

Fullscreen

Smart Phone

Fork tree

  • Readme
  • JavaScript 255 lines
  • HTML 442 lines
  • CSS 98 lines

スマートフォン/タブレットからプログラムを書いてみましょう

動作した環境

  • Galaxy II(Android 2.3.3) Firefox19.0
  • SH-02E (Android 4.0.4) Chrome 18.0
  • iPad (iOS 6.1.2) Mobile Safari

※ iOS Safariではプライベートブラウジングをオフにして実行してください。
※ Androidでは、単語の予測入力と、カーソル移動キーがあるソフトウェアキーボードがおすすめです
(Simejiなど)

解説

算術演算 (サンプル:plus)

2 3 + alert

Run を押すと、5 がダイアログボックスに表示される。

  • 数値は、その数値をそのままスタックに積む。
  • +は、スタックから2つ値を取り出し、その合計値をスタックに積む。
  • +の代わりにadd も使える。
  • alert は、スタックから1つ値を取り出し、ダイアログボックスにその値を表示する。

文字列リテラル (サンプル:helloworld)

hello q alert        
world q alert        

Samples から helloworld を選択し、Run を押すと「hello」「world」が順にダイアログボックスに表示される。

  • q は、その手前にある文字列をそのままスタックに積む。 ※ qの直前に改行があると正しく動作しない

  • alertは、スタックから1つ値を取り出し、それをダイアログボックスに表示する。

  • printは、スタックから1つ値を取り出し、それを画面およびコンソールに表示する。

関数定義 (サンプル:function)

10 5 8 add3 alert
a b c add3 def
  a b + c + 

def で終わる行は関数定義の始まりを表す。

関数定義の書式は次のようになる。

引数1 引数2 ... 関数名 def
  命令...

上の例では、 10,5,8 をそれぞれ変数 a,b,c に束縛して add3 を呼び出している

スタック領域は、関数呼び出しごとに独立しており、関数が終了するごとに破棄される。 関数内の命令の最後に到達した時点で、スタックの一番上の値を戻り値として返す。 スタックに値が残っていない場合は値を返さない。

2つ以上の関数を定義するときは、関数定義の後ろに def で終わる行を続ける。 ※関数内にネストした関数を作るには、「ネストした関数」の項を参照

10 5 8 add3 alert
10 5 8 sub3 alert
a b c add3 def  // 関数addの定義
  a b + c + 
a b c sub3 def  // 関数addの定義の終わり、そして、関数subの定義の始まり
  a b - c - 

関数定義の外にある命令(上の例であれば、最初の2行)は「トップレベル関数」として定義される。 トップレベル関数は引数を0個受け取る。

ネストした関数(サンプル:nestfunc)

.のついた関数名は、. より前の名前が表す関数内にネストされた関数になる。 ネストした関数においては、外側の関数で束縛された変数を使うことができる。

サンプルでは、関数 f の中にネストした関数 f.nested を作成している。

関数 f.nested を呼び出すことができるのは、関数fおよび f内のネストした関数からだけである。 f.nested を呼ぶときには、単に nested と書く。

5 f
x f def
  in_f q print
  x print
  8 nested       // ネストした関数 f.nested を呼ぶ(呼ぶときは f. はつけない)
y f.nested def   // ネストした関数 f.nested を定義する
  in_f.nested q print
  x print        // f で束縛された変数 x を参照する
  y print

変数束縛 (サンプル:let)

let 命令を使うと、値を変数に束縛できる(束縛は代入に似ているが、1回しか値を書き込みできない点が異なる) let は、スタックから2つ値を取り出し、最初に取り出した値(文字列)があらわす変数名に、次に取り出した値を束縛する。

5 x q let

は、5を変数x に束縛する。 q がついているのは、その前の x を文字列として扱うため(ないと"x is undefined" となる)

q let は、スペースを開けずに qlet と書くこともできる

5 x qlet

関数内では、トップレベル関数で束縛された値をそのまま参照できる。

5 x qlet
x print  // 5を表示
test
test def 
  x print // 5を表示

関数内で同じ名前に束縛すると、それ以降は新しく束縛された値になる。

5 x qlet
x print  // 5を表示
test
test def 
 x print  // 5を表示
 10 x qlet
 x print // 10を表示

関数は呼び出しごとに別のスコープになっており、呼び出しから抜けると、関数内で束縛された値はなくなる

5 x qlet
x print  // 5を表示
test
x print // 5を表示
test def 
 x print  // 5を表示
 10 x qlet
 x print // 10を表示

同じスコープ内で2回束縛することはできない

5 x qlet
6 x qlet // エラー

再代入(2回以上の書き込み)をしたい場合は参照オブジェクトを使う。

参照オブジェクト( サンプル:ref)

参照オブジェクトは、再代入が可能な変数のように使うことができる。

初期値が5の参照オブジェクトを作り、変数xに束縛する:

5 ref x qlet

参照オブジェクトの値をスタックに積む:

x read

参照オブジェクトの値を6に書き換える:

6 x write

参照オブジェクトの値に1を足し、参照オブジェクトに書き戻す:

x 1 addx

(他に、subx mulx divx modx も使える)

条件分岐(サンプル:if)

then  命令列1 fi
then  命令列1 else 命令列2 fi

スタックから値を1つ取り出し、 値が真であれば、命令列1を実行する。 偽であれば、命令列2があれば実行する。 fi は、関数の最後の場合は省略できる。

サンプルプログラムでは、最初に値の入力を行なっている。 ? 命令は、スタックから1つ値を取り出し、その値をプロンプト文字列として文字列入力ダイアログボックスを表示する。 入力された値をスタックに積む。 number 命令は、文字列を数値に変換する。 また、eq はスタックに積まれた2つの値が等しいかを調べる。== と書くこともできる。 他に、ne、gt、lt、ge、leも使える。それぞれ !=、> 、 < 、>=、<= と書くこともできる。

n=? q ? number n qlet  
n 2 mod 0 eq then   // n を2で割った余りが0ならば
 even q print        // 真の場合、evenを表示
else 
 odd q print        // 偽の場合、oddを表示

上と同じプログラムを次のように書くこともできる:

n=? q ? number n qlet  
n 2 mod 0 eq then   // n を2で割った余りが0ならば
 even q        // 真の場合、evenをスタックに積む
else
 odd q        // 偽の場合、odd をスタックに積む
fi
print // スタックに積んである値(evenかodd)を表示

再帰呼び出し(サンプル:factorial、fibonacci)

10 fact alert
n fact def
 n 1 factl n
n r factl def
  n 0 eq then r 
  else n 1 - r n * factl 

再帰呼び出しの例。(factl は、最後にfactl自身を呼び出している) 最後の命令、またはreturn命令の直前で行われた関数呼び出しは「末尾再帰」となる。 末尾再帰を連続して呼び出してもスタック領域が増え続けることはない。

オブジェクト指向もどき(サンプル:object)

ネストした関数を利用してオブジェクトが作れる。 サンプルの関数 person は、名前と年齢を受け取って人物のオブジェクトを作っている。 関数 person がコンストラクタのような役割をしている。 person の最後にあるself は、現在のスコープで束縛された変数を属性値として含んだオブジェクトを生成する。 ここでは、name、age、birth そしてネストした関数である show を属性値として含んだオブジェクトが生成される。

オブジェクトを変数に束縛すると、その名前と属性値を. でつなげてアクセスできる。 例えば、トップレベル関数で、p1.name や p2.name にように使っている。 また、p1.show のように、属性値が関数である場合はその関数が呼び出される。 この仕組みを使ってメソッド呼び出しのようなことができる。

トップレベル関数の最後から2行目にあるopen命令は、 スタックから1つ値(オブジェクト)をとりだし、すべての属性値を現在のスコープに展開する p1 open とすれば、p1.name を単にname と書くことができる。

Taro q 20 person p1 qlet
Jiro q 17 person p2 qlet
p1.name print
p1.show            
p2.name print
p2.show        
p1 open
name print

name age person def
  2013 age sub birth qlet // 誕生年の計算。 2013-age を birth に束縛
  self
person.show def
  name: q print
  name print
  age: q print
  age print
  birth: q print
  birth print

ライブラリの作成(サンプル:test-mylib、mylib)

他のファイル(ライブラリ)に定義された関数を使うことができる。

qload 命令は、ファイル名で指定されたライブラリを読み込む。

ファイル名 qload

ライブラリは、トップレベル関数の最後にselfが必要になる(self は、ライブラリで定義された すべての関数をオブジェクトにまとめる。)

//-----ファイル:mylib
self  //  add3 と max3 を属性値としてもつオブジェクトを返す
x y z add3 def
  x y + z +
a b c max3 def
  a b gt then
    a c gt then a else c fi
  else 
    b c gt then b else c 
//-----------------

ファイル test-mylib では

mylib qload 

を実行している。これにより、test-mylibから add3 と max3 が使える。

なお、qload を行った側(例えばtest-mylib)にライブラリと同名の関数(例えばadd3) が定義されている場合は、qload を行った側 に定義された関数が呼ばれる。 ライブラリの同名の関数を呼びたい場合は、 ライブラリのファイル名.関数名 で呼び出す。

例えば、もし test-mylib にもadd3 がある場合は、

5 2 10 add3

とすれば、test-mylib の add3 が呼ばれるが、

5 2 10 mylib.add3

とすれば、mylib の add3 が呼ばれる

Javascript連携(サンプル:jqlib、cvlibなど)

Javascript の関数やメソッドを呼ぶことができる。

windowオブジェクトの直下に格納されている関数はその名前でアクセスできる。

例えば、jqueryをロードした状態で(silop.js は標準でjqueryを読み込む)

: <canvas> q $ 

を実行すれば、Javascriptで

$("<canvas>")

を実行し、その戻り値をスタックに積んだのと同じ効果が得られる。

: は、関数呼び出しの引数の終わりを示す値(「Bottom」という)をスタックに積む命令である。 Javascriptの関数を呼び出すときは、スタックに積んである値を、 Bottomを取り出すまで、または、スタックが空になりまで取り出し、 取り出した順の逆順に引数として渡して関数呼び出しを行う。(Bottom自身は渡されない) : の代わりに bt も利用できる。

なお、: は、関数呼び出しの前にスタックが空の場合、特に関数の最初の部分では省略できる。 実際、サンプルプログラムでは次のように省略されている。

width height initcv def  ← 関数の始まり
   <canvas> q $ 
  (プログラム続く)

メソッドを呼び出すには、call という組み込み関数を用いる。

<canvas> q $ 
width q 300 attr q call

これは、Javascriptで

$("<canvas>").attr("width",300); 

を実行し、その戻り値をスタックに積んだことになる。

call は、次のような書式で用いる。

: オブジェクト 引数1 引数2 ... メソッド名  call

上の例は、サンプルプログラムからの引用で、 : は省略されている。 <canvas> q $ で生成されたオブジェクト(つまりメソッド呼び出しの対象) がスタックの最下段にいるため、省略できる。

ちなみに、この呼び出しによって、jqueryの規則に従い、呼び出したオブジェクト自身が 戻り値としてスタック積まれるので、

<canvas> q $ 
width q 300 attr q call
height q 300 attr q call

とすれば、

$("<canvas>").attr("width",300).attr("height",300);

と同じことができる。

  • スマートフォンでプログラミング silop.js
  • silop-profile
  • state-profiler.js
  • silop-vm.js
  • silop-stdfunc.js
  • silop-compiler.js
  • dateformat.js
  • silop-core.js
  • Underscore.js v1.4.3
  • jQuery v1.9.0
  • スマートフォンでプログラミング silop.js

play

Complete!

Description What kind of game?

Control Device

jsdo.it websocket controller

Mouse

keyboard

smartphone

Fullscreen

hoge1e4

Author

ゲーム開発用 AltJSの Tonyu System 2 を開発しています。

Default Panel

Size

  • Width: px
  • Height: px

code

QR Code

Discussion

Questions on this code?

Tags

Favorite by

Forked

sort by