LoginSignup
2

More than 1 year has passed since last update.

swfはスタックマシン その2

Last updated at Posted at 2015-12-07

概要

swfスタックマシンのアセンブラの処理系を作った。仕様は、俺々。

ニーモニック

push "x"    スタックに"x"を積む
add         スタックの二番目と一番目を文字列連結
+           スタックの二番目と一番目を足す
-           スタックの二番目から一番目を引く
/           スタックの二番目を一番目で割る
*           スタックの二番目と一番目を掛ける
set         スタックの二番目を変数として、一番目の値をセット
get         スタックの一番目を変数として、その値をセット
++          スタックの一番目をインクリメント
<           スタックの二番目を一番目で比較
>           スタックの二番目を一番目で比較
!           スタックの一番目を反転
if  skip    スタックの一番目が真ならskipに飛ぶ
jp loop     loopに飛ぶ
int         スタックの一番目を整数化
end         停止

サンプルコード

function run() {
    var c1, c2, c3, a, i, j;
    var pc = 0;
    var la = new Array(10);
    var r = new Array(200);
    var src = document.getElementById('src0').value;
    var m = src.split("\n");
    for (j = 0; j < m.length ; j++)
    {
        var cm = m[j].split("  ");
        if (cm[0] != "")
        {
            la[cm[0]] = pc + 2;
        }
        switch (cm[1])
        {
        case "if":
            r[pc] = 0x9D;
            pc++;
            r[pc] = 0x02;
            pc++;
            r[pc] = 0x00;
            pc++;
            if (la[cm[2]] > 1)
            {
                c3 = 255 + la[cm[2]] - pc - 3;
                r[pc] = c3;
                pc++;
                r[pc] = 0xFF;
                pc++;
            }
            else
            {
                r[pc] = cm[2];
                pc++;
                r[pc] = 0x00;
                pc++;
            }
        break;
        case "jp":
            r[pc] = 0x99;
            pc++;
            r[pc] = 0x02;
            pc++;
            r[pc] = 0x00;
            pc++;
            if (la[cm[2]] > 1)
            {
                c3 = 255 + la[cm[2]] - pc - 3;
                r[pc] = c3;
                pc++;
                r[pc] = 0xFF;
                pc++;
            }
            else
            {
                r[pc] = cm[2];
                pc++;
                r[pc] = 0x00;
                pc++;
            }
        break;
        case "push":
            r[pc] = 0x96;
            pc++;
            c1 = cm[2].indexOf("\"") + 1;
            c2 = cm[2].indexOf("\"", 1) - c1;
            a = cm[2].substr(c1, c2);
            c3 = c2 + 2;
            r[pc] = c3;
            pc++;
            r[pc] = 0x00;
            pc++;
            r[pc] = 0x00;
            pc++;
            for (i = 0; i < c2; i++)
            {
                r[pc] = a.charCodeAt(i);
                pc++;
            }
            r[pc] = 0x00;
            pc++;
        break;
        case "end":
            r[pc] = 0x00;
            pc++;
        break;
        case "+":
            r[pc] = 0x0A;
            pc++;
        break;
        case "-":
            r[pc] = 0x0B;
            pc++;
        break;
        case "*":
            r[pc] = 0x0C;
            pc++;
        break;
        case "/":
            r[pc] = 0x0D;
            pc++;
        break;
        case "=":
            r[pc] = 0x0E;
            pc++;
        break;
        case ">":
            r[pc] = 0x0F;
            pc++;
        break;
        case "&":
            r[pc] = 0x10;
            pc++;
        break;
        case "|":
            r[pc] = 0x11;
            pc++;
        break;
        case "!":
            r[pc] = 0x12;
            pc++;
        break;
        case "eq":
            r[pc] = 0x13;
            pc++;
        break;
        case "len":
            r[pc] = 0x14;
            pc++;
        break;
        case "pop":
            r[pc] = 0x17;
            pc++;
        break;
        case "int":
            r[pc] = 0x18;
            pc++;
        break;
        case "get":
            r[pc] = 0x1C;
            pc++;
        break;
        case "++":
            r[pc] = 0x50;
            pc++;
        break;
        case "dp":
            r[pc] = 0x4C;
            pc++;
        break;        
        case "set":
            r[pc] = 0x1D;
            pc++;
        break;
        case "add":
            r[pc] = 0x21;
            pc++;
        break;
        case "rnd":
            r[pc] = 0x30;
            pc++;
        break;
        case "time":
            r[pc] = 0x34;
            pc++;
        break;
        }
    }       
    for (var a in la) 
    {

        for (i = 0; i < pc; i++)
        {
            if (r[i] == a)
            {

                c3 = la[a] - i - 4;
                r[i] = c3;
            }
        }
    }
    for (i = 0; i < pc; i++)
    {
        swf21[i + 31] = r[i];
    }
        var b = _arrayBufferToBase64(swf21);
    var h = '<embed src ="';
    var l = '" type="application/x-shockwave-flash" width="100" height="100"></embed>';
    var swf = h + tob(b) + l;
    var out = document.getElementById('out');
    out.innerHTML = swf;
}

アセンブラコード

1から100まで表示。

push "x"
push ""
set
push "i"
push "0"
set
loop push "i"
push "i"
get
++
set
get
push "x"
push "x"
get
push "i"
get
add
set
push "x"
push "x"
get
push " "
add
set
push "i"
get
push "100"
">
!
if skip
jp loop
skip end

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2