c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

altJSとしてのPiet

[altjs Advent Calendar 2012]( http://partake.in/events/17085fbb-501f-4a78-a4cd-ec6a34484a60 )三日目

最近のaltJS

CoffeeScript = () -> 甘い。
Dart = () => ブラウザでは動かない。Dartiumとか云うよくわからない金属觸媒の上でしか動きません。
JSX = () : void -> 取り敢えず今は、速度を出しにいけます。JavaScriptに於ける速度の出し方は、頭に置いてからJSXコードは書きましょう。
TypeScript = () => JavaScriptに静的型アノテーションを付けて、それに"class"とか"interface"などの構文糖を被せたものです。JavaScriptを書いてる積りで書きます。甘い。

なんだかどれも、ぱっとしませんね!

素晴らしいaltJS

数々の新參altJSに耐え忍び、不動の如く生き延びて来たaltJSを紹介しましょう。

Piet

Piet

ぱっとしてますね! Piet (ぱっと) ですし!!

Pietです。勿論JavaScriptの代わりにWebブラウザで動きます。以下は定番の、Hello World!を実行している様子です。
[Rapapaing - PietDev]( http://www.rapapaing.com/blog/?page_id=6 )

スッテプ実行もできます。さずが!

Piet on JSX

JSXでPietを実装しようとしたのですが、間に合いませんでした。後悔しています。
TypeScriptとJSXは好きです。それなりに大きな、且つ完結したjsアプリケーションは、JSXで書きます。jsと組み合わせたい時は、TypeScriptを使います。お陰で自作のアニメーションライブラリは、打ち捨てられたjs版と、打ち捨てられたDart版と、現役のJSX版と現役のTypeScript版が有って、打ち殺したい。

/**
 * @author ne_Sachirou <utakata.c4se@gmail.com>
 * @license Public Domain
 */

// jsx --output Piet.jsx.js --executable web Piet.jsx
import 'js/web.jsx';

class Piet {
  static var colors = {
    // 'color name': [red, green, blue, hue class [0,5], dark class [0,2]]
    'light red'  : [255, 192, 192, 0, 0], 'light yellow' : [255, 255, 192, 1, 0],
    'light green': [192, 255, 192, 2, 0], 'light cyan'   : [192, 255, 255, 3, 0],
    'light blue' : [192, 192, 255, 4, 0], 'light magenta': [255, 192, 255, 5, 0],

    'red'  : [255, 0, 0, 0, 1], 'yellow' : [255, 255, 0, 1, 1],
    'green': [0, 255, 0, 2, 1], 'cyan'   : [0, 255, 255, 3, 1],
    'blue' : [0, 0, 255, 4, 1], 'magenta': [255, 0, 255, 5, 1],

    'dark red'  : [192, 0, 0, 0, 2], 'dark yellow' : [192, 192, 0, 1, 2],
    'dark green': [0, 192, 0, 2, 2], 'dark cyan'   : [0, 192, 192, 3, 2],
    'dark blue' : [0, 0, 192, 4, 2], 'dark magenta': [192, 0, 192, 5, 2],

    'black': [0, 0, 0], 'white': [255, 255, 255]
  } : Map.<number[]>;

  static function _getImageData(image : HTMLImageElement) : ImageData {
    var canvas = dom.createElement('canvas') as HTMLCanvasElement;
    var context = canvas.getContext('2d') as CanvasRenderingContext2D;
    canvas.width = image.width;
    canvas.height = image.height;
    context.drawImage(image, 0, 0);
    return context.getImageData(0, 0, image.width, image.height);
  }

  static function _detectCodelSize(imageData : ImageData) : int {
    return 1;
  }

  static function _reduceCodelToPixel(imageData : ImageData) : ImageData {
    var canvas = dom.createElement('canvas') as HTMLCanvasElement;
    var context = canvas.getContext('2d') as CanvasRenderingContext2D;
    var codelSize = Piet._detectCodelSize(imageData);
    var reduced = context.createImageData(imageData.width / codelSize,
                                          imageData.height / codelSize);
    for (var i = 0, iz = imageData.data.length, j = 0;
         i < iz;
         i += 4 * codelSize, j += 4)
      reduced.data[j] = imageData.data[i];
      reduced.data[j + 1] = imageData.data[i + 1];
      reduced.data[j + 2] = imageData.data[i + 2];
      reduced.data[j + 3] = imageData.data[i + 3];
    return reduced;
  }

  static function _getColor(r : int, g : int, b : int) : string {
    for (var key in Piet.colors) {
      var color = Piet.colors[key];
      if (r == color[0] && g == color[1] && b == color[2])
        return key;
    }
    return 'white';
  }

  var width : int;
  var height : int;
  var data  = new string[];

  var stack = new int[];

  var programPtr : int = 0;
  var directionPtr = 'right';
  var codelChooser = 'left';

  var stdin = '';
  var stdout = '';

  function constructor(image: HTMLImageElement, stdin : string) {
    var imageData = Piet._getImageData(image);
    imageData = Piet._reduceCodelToPixel(imageData);
    this.width = imageData.width;
    this.height = imageData.height;
    for (var i = 0, iz = imageData.data.length; i < iz; i += 4) {
      this.data.push(Piet._getColor(imageData.data[i],
                                    imageData.data[i + 1],
                                    imageData.data[i + 2]));
    }
    this.stdin = stdin;
  }

  function run() : string {
    return this.stdout;
  }

  function getColorBlock(ptr : int) : int[] {
    var colorBlock = new int[];
    var currentPtr = ptr;
    var isChecked = new boolean[];
    isChecked.length = this.data.length;
    return colorBlock;
  }

  function _toggleCC() : void {
    if (this.codelChooser == 'right')
      this.codelChooser = 'left';
    else
      this.codelChooser = 'right';
  }

  function _rotateDPClockwise() : void {
    switch (this.directionPtr) {
      case 'right': this.directionPtr = 'down'; break;
      case 'down' : this.directionPtr = 'left'; break;
      case 'left' : this.directionPtr = 'up'; break;
      case 'up'   : this.directionPtr = 'right';
    }
  }

  function _rotateDPAntiClockwise() : void {
    switch (this.directionPtr) {
      case 'right': this.directionPtr = 'up'; break;
      case 'up'   : this.directionPtr = 'left'; break;
      case 'left' : this.directionPtr = 'down'; break;
      case 'down' : this.directionPtr = 'right';
    }
  }

  function push(n : int) : void {
    this.stack.push(n);
  }

  function pop() : void {
    this.stack.pop();
  }

  function add() : void {
    var l = this.stack.pop();
    var r = this.stack.pop();
    this.stack.push(l + r);
  }

  function subtract() : void {
    var l = this.stack.pop();
    var r = this.stack.pop();
    this.stack.push(l - r);
  }

  function multiply() : void {
    var l = this.stack.pop();
    var r = this.stack.pop();
    this.stack.push(l * r);
  }

  function divide() : void {
    var l = this.stack.pop();
    var r = this.stack.pop();
    this.stack.push(Math.floor(l / r));
  }

  function mod() : void {
    var l = this.stack.pop();
    var r = this.stack.pop();
    this.stack.push(l % r);
  }

  function not() : void {
    var n = this.stack.pop();
    this.stack.push(n == 0 ? 1 : 0);
  }

  function greater() : void {
    var l = this.stack.pop();
    var r = this.stack.pop();
    this.stack.push(l < r ? 1 : 0);
  }

  function pointer() : void {
    var n = this.stack.pop();
    if (n >= 0)
      while (n > 0) { this._rotateDPClockwise(); --n; }
    else
      while (n < 0) { this._rotateDPAntiClockwise(); ++n; }
  }

  function switch_() : void {
    var n = this.stack.pop();
    if (n % 2 == 1) this._toggleCC();
  }

  function duplicate() : void {
    var n = this.stack[this.stack.length - 1];
    this.stack.push(n);
  }

  function roll() : void {
    var l = this.stack.pop();
    var r = this.stack.pop();
    var roll = (depth : int) : void -> {
      var n = this.stack.pop();
      this.stack.splice(this.stack.length - depth + 1, 0, n);
    };
    var rollOpposite = (depth : int) : void -> {
      var n = this.stack.splice(this.stack.length, 1)[0];
      this.stack.push(n);
    };
    if (r < 0) return;
    if (l >= 0)
      for (; l > 0; --l) roll(r);
    else
      for (; l < 0; ++l) rollOpposite(r);
  }

  function in_() : void {
    var n = this.stdin.charCodeAt(0);
    this.stdin = this.stdin.slice(1);
    this.stack.push(n);
  }

  function out() : void {
    var n = this.stack.pop();
    this.stdout += String.fromCharCode(n);
  }
}

class _Main {
  function main(args : String[]) : void {
    var image = dom.getElementById('image') as HTMLImageElement;
    var stdin = dom.getElementById('stdin').innerHTML;
    var piet = new Piet(image, stdin);
    var stdout = piet.run();
    dom.getElementById('stdout').innerHTML = stdout;
  }
}

明日は[twitter:@y_kimisaki]さま……(〃l _ l)