<?xml version="1.0" encoding="UTF-8" ?><rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://w.atwiki.jp/toy-lang/">
    <title>toy-lang</title>
    <link>http://w.atwiki.jp/toy-lang/</link>
    <atom:link href="https://w.atwiki.jp/toy-lang/rss10.xml" rel="self" type="application/rss+xml" />
    <atom:link rel="hub" href="https://pubsubhubbub.appspot.com" />
    <description>toy-lang</description>

    <dc:language>ja</dc:language>
    <dc:date>2014-07-29T15:02:53+09:00</dc:date>
    <utime>1406613773</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/1.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/12.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/13.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/17.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/22.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/18.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/21.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/20.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/14.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/toy-lang/pages/11.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/1.html">
    <title>トップページ</title>
    <link>https://w.atwiki.jp/toy-lang/pages/1.html</link>
    <description>
      ** プログラミング言語 toy

プログラミング言語を作っています。
toy といいます。
まだまだオモチャのような言語ですのでこのような名前になっています。

よく、使い物にならない言語が、それは toy 言語だと揶揄されますが、この言語はまさにその目的のために作っています。つまり、自分のためのオモチャですね。
休日に少しずつ作っているので、進捗は遅いです。


*** 最新情報
-2012.7.16: GitHub でもソースを公開はじめました。
-- https://github.com/mitchan0321/toy
-2012.7.16: バージョン 0.3.0 をリリースしました。多倍長整数のサポート、set コマンドによる多値代入のサポートが加わりました。
-2012.6.10: バージョン 0.2.0 をリリースしました。コルーチンサポート、パーサの &#039;:&#039; マクロ、正しいレキシカルスコープへの改善、64ビットOSへの対応などを行いました。
-2011.9.2: [[ビルド方法]]について、PCL(Portable Coroutine Library)のインストールを追記しました。
-2011.8.28: 二年ぶりにバージョン 0.1.3 をリリースしました。→[[ソース公開]]
-2009.11.1: バージョン 0.1.2 をリリースします。末尾再帰を書くための goto コマンドが追加されています。
- 2009.9.23: バージョン 0.1.1 をリリースします。begin コマンド、exec コマンド、read コマンドを追加しています。マニュアルもアップデートしました。
- 2009.9.5: 久しぶりのリリースです。toy-langも1年がたちました。ですので、バージョンを0.1.0としてリリースします。また、マニュアルをひとまず全体を記述しました。
- 2009.8.30: [[マニュアル]]を更新しました。残りは、Object、Real、Stringです。これらのリファレンスについては、もう暫くお待ちください。
- 2009.7.27: 0.0.28をリリースしました。
- 2009.7.6: [[マニュアル]](途中ですが) をリリースします。0.0.27のリリースに同梱してます。



*** どんな言語か？
-インタプリタ
-スクリプト
-オブジェクト指向
--duck type
--プロトタイプベース
-シンタックス無し
-予約語無し
-キーワード引数
-クロージャあります
-例外処理
-リフレクション
-遅延評価

tcl のような syntax 無しな言語になっています。
仕様はどんどん変わります。



*** 開発方針
- とりあえず必要な機能を作ってゆきます。
- まずは、言語全体としての整合性は考えません。
- ある程度機能が増えてきたら整理します。



*** リソース
-[[マニュアル]]
-[[toyの紹介]] (作成途中)
-[[ソース公開]]
-[[ビルド方法]]
-[[サンプル]]
-[[GCとPCLの和解]]



*** 仕様
-[[リファレンス]] (作成途中)



*** ToDo
-[[やりたいこと]]



*** 雑記
-[[開発の記録など]]
-[[作成の動機]]
-[[SandBox]]



*** 連絡先
ご質問、ご要望はこちらまで。
- メールは: mitchan(at_mark)poppy.ocn.ne.jp
- twitterは: mitchan0321






















#right(){
&amp;counter()
}
----    </description>
    <dc:date>2014-07-29T15:02:53+09:00</dc:date>
    <utime>1406613773</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/12.html">
    <title>ソース公開</title>
    <link>https://w.atwiki.jp/toy-lang/pages/12.html</link>
    <description>
      ** ソースを公開しています

高々10,000ステップのソースですが。
ソースも洗練されておりません。
しかも、コメントがほとんどありません、、、
それでも、もし興味があれば、ダウンロードして見て下さい。

最新のソースは、GitHub からでも取得が出来ます。
https://github.com/mitchan0321/toy

実行形式の作成は、[[ビルド方法]]をご参照ください。

-[[20120716&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20120716.tar.gz]]
-- 多倍長整数が扱えるようになりました。
-- 多値代入が出来るよう、set コマンドの書式を拡張しました。

-[[20120610&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20120610.tar.gz]]
-- コルーチン機能の実装（コルーチンでCスタックを使用する処理を書きました）。
-- データタイプを判断するためのコマンドを追加。
--- symbol?/nil?/list?/integer?/real?/string?/rquote?/block?/closure?/func?/object?/dict?/vector?
-- パーサに &#039;:&#039; マクロを追加。以下の様に使います（→が &#039;:&#039; マクロを使用した例）:
--- [[[self] vars] len] + 1 → self : vars : len : + 1
-- スコープのデータ構造・処理を変更。これにより、Yコンビネータが正しく動くようになりました。
-- 64ビット環境での動作。Linux、FreeBSD での64ビットOSに対応しました。

-[[20110828&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20110828.tar.gz]]
--Hashクラス/Arrayクラスにかわるdict型、vector型を追加。
--辞書を取得するコマンド各種を追加
---dict-local / dict-object / dict-func / dict-global / dict-class
--eq?コマンド追加。
--connectコマンド(TCPソケットのクライアント側)追加。
--loopコマンド追加。
--injectコマンド追加(Rubyからの輸入)。
--String::int、String::real、String::number を追加(それぞれ数値に変換)。
--Integer に real、&lt;&lt;、&gt;&gt;、||、&amp;&amp;、^^、~~ を追加(それぞれ、realに変換、左シフト、右シフト、ビット or、and、xor、not)。
--関数呼び出しのパラメータについて、基本的に遅延評価により呼び出すように変更。
--hash.cのバグ修正。
--String::fmt を追加。
--memoiz 関数を作成する memoiz.toy をライブラリに追加。
-[[20091101&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20091101.tar.gz]]
--String::split メソッド。
--goto コマンド。
-[[20090923&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090923.tar.gz]]
--ローカル変数のスコープを抑止する begin コマンド。
--外部プロセスを起動する exec。
--print/println と対になる read コマンド。
--Block::&lt;&lt; メソッド。
--オブジェクトのメソッド一覧を表示する flat コマンド。
-[[20090905&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090905.tar.gz]]
--Fileクラスのコンストラクタ。
--メソッドキャッシュ。Makefile に HAS_GCACHE を指定してください。
--call コマンドのシンタックス変更。メソッドも呼べるように。
--最適化を少々。
-[[20090727&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090727.tar.gz]]
--マニュアルをコマンドリファレンスまで作成。
--コンストラクタの書式を変更。
--Cのスタックを消費しつくすバグを修正。
--デフォルトのインタプリタスタックサイズを変更(1024→4096*4)。
--メモリ不足時の処理を変更。
-[[20090706&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090706.tar.gz]]
--case コマンドのシンタックス変更。
--cond コマンド追加。
--lazy コマンド追加。
--Object::string のバグフィックス。
--Object::method? メソッド追加。メソッドをサーチします。
--Hash::each メソッド追加。
--unknown バグフィックス。
--あと、マニュアル(途中ですが)追加。doc の下においてあります。
-[[20090517&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090517.tar.gz]]
--遅延評価もどきの機能を導入してみた。竹内(たらい回し)関数が一瞬で終わる！ [[サンプル]]を参照ください。正直、これほど効果があるとは思わなかった。
-[[20090510&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090510.tar.gz]]
--rubyに似たイテレータ構文を導入。
--そのた色々変更。
-[[20090308&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090308.tar.gz]]
--trace コマンドを追加。
--exit コマンドを追加。
--デフォルトのオプティマイズオプションを -O3 に変更。
--イベントドリブンに実行する対話形式インタプリタを追加。lib/interp.toy で、toysh から &quot;interp&quot; として実行する。SysQueue を使って多重にイベントを扱う仕組み。
--List:.. を追加。1 .. 100 で 1 から 100 までのリストを表します。
-[[20090301&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090301.tar.gz]]
--msort (merge sort) のサンプルをライブラリに追加。
--List::&gt;&gt; (shift), List::&lt;&lt; (unshift), List::-&gt;&gt; (pop), List::&lt;&lt;- (push) を追加。
-[[20090222&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090222.tar.gz]]
--lsort のバグ修正。
--to_string_call にあった奇妙なバグを修正。
--toysh で、result の出力文字数のリミットを設定。
-[[20090221&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090221.tar.gz]]
--if 文のコンディションがブロック以外でも動くよう文法を拡張した。
--List::flat、Array::list、String::&gt;,&gt;=,&lt;,&lt;= メソッドを追加。
--setup.toy を整理し、$LIB_PATH 配下に配置した。
--global.c へ各定数を分離した。
-[[20090219&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090219.tar.gz]]
--unknown を実装。$LIB_PATH から自動的に　関数名 + &quot;.toy&quot; ファイルをロードし、実行します。
--全体的にイテレータのシンタックスを変更 var: x -&gt; in: x にしてみた。Ruby 的なイテレータを実装すべきなんだろうな。
-[[20090215&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20090215.tar.gz]]
--List::eval メソッド追加。
--sleep コマンド追加。
--Block::&gt;&gt; メソッド追加(setup.toy 内)
--setvar コマンド追加。これに伴い、defvar コマンドの動作を変更。
--setup.toy ファイルのインストール先を変更(/usr/local/lib/toy)。
--file コマンド追加。
--exists? コマンド追加。
--$HOME/.toyrc ファイル読み込み。
--List::filter メソッド追加。
--List::map メソッド追加。
-[[20080904&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080904.tar.gz]]
--new コマンドの糖衣構文を追加。
--キーワード引数の糖衣構文を追加。
--Hash/Array のコンストラクタを作成。
-[[20080831&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080831.tar.gz]]
--String::sub 部分文字列取得のメソッド追加。
--String::=~ のバグ修正。
--init メソッドでパラメータを渡せるように。
--Object::string methods.c/commands.c 内部の ::string 呼び出しをオブジェクトのメソッド呼び出しに変更。
-[[20080824&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080824.tar.gz]]
--正規表現による文字列マッチングができるようになりました。
-[[20080823&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080823.tar.gz]]
--原始的な install を書きました。
--pwd/cd/alias コマンドを書きました。
--グローバル変数に ENV 変数をセットアップ。VERSION 文字列をセットアップ。
-[[20080822&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080822.tar.gz]]
--sdirコマンド--スクリプトの一覧を返す関数--を追加。
--List::append! のバグを修正。
-[[20080819&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080819.tar.gz]]
--論理演算コマンド ! (not) / and / or を追加。
--load コマンド追加。stack-trace でも load したファイルのファイル名が出るようにした。
--そのほか細々とした最適化(根本的な効果は非常に薄かった)。
-[[20080816&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080816.tar.gz]]
-- trap コマンドでシグナルを扱えるようになった。
-- stack-trace コマンドでその時点のスタックトレースを取得できる。
-- function/method でクロージャの変数を参照できるようになった。
-[[20080813&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080813.tar.gz]]
-- exception 発生時に、グローバル変数の &#039;@stack-trace&#039; にスタックトレースを出力するようになりました。仕様としては良くないですが、とりあえず実装してみたものです。
-[[20080808&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080808.tar.gz]]
-- print / println が、@out 変数、stdout 変数の File オブジェクトに出力するようになった。
-- argv をローカルからグローバルのスロットに移動し、ARGV に変更。
-- グローバルスロットの stdin / stdout / stderr を初期生成。
-[[20080805&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080805.tar.gz]]
-- File クラスの追加。
-- Array クラスの追加。
-- get マクロ (ex. [$objec get $key] → $obj,$key に展開。
-- 引数展開のアルゴリズムを改良。
-[[20080727&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080727.tar.gz]]
-- Hash の追加。
-- コンストラクタ(init メソッド) を呼べるように。
-[[20080726&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=12&amp;file=toy-20080726.tar.gz]]

















----    </description>
    <dc:date>2012-07-16T18:44:24+09:00</dc:date>
    <utime>1342431864</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/13.html">
    <title>ビルド方法</title>
    <link>https://w.atwiki.jp/toy-lang/pages/13.html</link>
    <description>
      ** ビルド方法

1. お助けライブラリの準備
1.1 GCに Boehm GC ライブラリを使いますので、以下のURLより入手してインストールしてください。
http://www.hpl.hp.com/personal/Hans_Boehm/gc/

1.2 正規表現ライブラリに鬼車を使わせていただきました。以下のURLより(バージョン 5.9.1を)入手してインストールしてください
http://www.geocities.jp/kosako3/oniguruma/index_ja.html

1.3 バージョン0.1.3よりコルーチンのサポートを入れ始めました(未完成)。コルーチンの実現には、PCL(Portable Coroutine Library)を使用しています。
以下のURLよりダウンロードしてインストールしてください。
http://www.xmailserver.org/libpcl.html

ただし、PCLについて、Windows CYGWIN 環境ではコンパイルでエラーがでます。取り急ぎ以下の対処をしてしのいでいます。

    ソース: pcl/pcl.c
    #if defined(CO_HAS_SIGSTACK)
    ....
    #endif

上記ブロック(3箇所ほどあります)をまとめてコメントアウトしています。

1.4 多倍長整数演算にGMPを使用します。以下のURLよりダウンロードしてインストールしてください。
http://gmplib.org/

基本的に、1.1～1.4のライブラリについて、./configure; make; make install でインストールできています(PREFIX が /usr/local の場合)。

2. [[ソース公開]]からダウンロードした tar ball を展開して、

2.0 展開したディレクトリに入ります。

   cd toy

2.1 最初に、Makefile の PREFIX を調整してください。

2.2 その後、

    make

とすると実行ファイルができます。

2.3 最後に、

    make install

とすると、PREFIX にインストールされます。

2.4 テスト

    cd test
    ./testall

で、簡単なテストを実行します。OK と出れば OK。



----
configure など用意しておりません。すみません。

コンパイル、動作を確認したプラットフォームは以下のとおりです。

***動作確認環境
- FreeBSD 7.1R
- Linux Ubuntu 8.04 / Kernel 2.6.24
- Windows CYGWIN 環境でも動いたそうです。ただし、BoehmGC は 7.1 のコンパイルが成功しないため、6.8 で動かしているとのこと。@damedamon さん、情報ありがとうございました。















----    </description>
    <dc:date>2012-07-16T18:40:06+09:00</dc:date>
    <utime>1342431606</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/17.html">
    <title>サンプル</title>
    <link>https://w.atwiki.jp/toy-lang/pages/17.html</link>
    <description>
      **サンプル

***円周率計算
    defun pi () {
        set (k a b a1 b1) (2 4 1 12 4);
    
        loop {
            set (p q k)
                ([$k * $k] [[2 * $k] + 1] [$k + 1]);
            set (a b a1 b1)
                ($a1 $b1 [[$p * $a] + [$q * $a1]] [[$p * $b] + [$q * $b1]]);
    
            set (d d1) ([$a / $b] [$a1 / $b1]);
    
            while {$d = $d1} do: {
                print file: $stdout $d;
                $stdout flush;
    
                set (a a1) ([10 * [$a % $b]] [10 * [$a1 % $b1]]);
                set (d d1) ([$a / $b] [$a1 / $b1]);
            };
        };
    };

実行例:
    $ toysh
    *** Start toy-lang interpreter version 0.3.0.
    &gt; pi
    31415926535897932384626433832795028841971693993751058209....

上記プログラムは1995年頃、rubyが公開されて間もない頃 rubyで書いたもの(現在rubyのsampleとしてソースと同時に配布されている)ですが、それを今回 toy-lang に書き換えたものです。

***Yコンビネータ（本体）
    defun Y(f) {
        [fun (g) {
            fun (m) {
                [$f [$g $g]] $m;
            }
        }] [fun (g) {
            fun (m) {
                [$f [$g $g]] $m;
            }
        }];
    };

***Yコンビネータ適用例 - fact(10)
    [Y [
        fun (f) {
            fun (x) {
                if {$x &lt;= 1} then: {return 1};
                $x * [$f [$x - 1]];
            }
        }
    ]] 10
    
    =&gt; 3628800

***goto による末尾再帰

    defun fact-recur (n) {
        fact-recur-sub $n 1;
    };
    
    defun fact-recur-sub (n a) {
        if {$n &lt; 1} then: {return $a};
        goto fact-recur-sub [$n - 1] [$n * $a];
    };

***flat コマンド - オブジェクトで使えるメソッドの一覧を出す。

    defun flat (o) {
        set h `Hash;
        flat-sub $o $h;
    
        set l ();
        $h each do: {| m c |
            $l append! [&quot;&quot; . $c &quot;::&quot; $m];
        };
        [lsort $l] each do: {| p | println $p};
    };
    
    defun flat-sub (o h) {
        [$o vars] each do: {| m |
    
            case [type? [$o var? $m]]
            NATIVE {
                if {$h set? $m} else: {$h set $m $o};
            }
            FUNC {
                if {$h set? $m} else: {$h set $m $o};
            };
        };
    
        [$o delegate?] each do: {| c |
            flat-sub $c $h;
        };
    };

***grep コマンド
UNIX の grep に似たコマンド。

    defun grep (pat file) {
        set f `File(mode: i $file);
        try {
            set n 1;
            $f each do: {| r |
                if {$r =~ $pat} then: {
                    print $file &quot;:&quot; $n &quot;: &quot; $r;
                };
                $n ++;
            };
        }
        fin: {
            $f close;
        };
        println;
    
        true;
    };

***たらい回し関数(遅延評価バージョン)
たらい回し関数を遅延評価バージョンで作ってみました。ソースは以下のような感じ。

     # tarai function lazy version
 
     defun tarai-lazy (&amp;x &amp;y &amp;z) {
        if [$x &lt;= $y]
        then: $y
        else: {
            tarai-lazy 
                 {tarai-lazy [$x - 1] $y $z}
                 {tarai-lazy [$y - 1] $z $x}
                 {tarai-lazy [$z - 1] $x $y}
        };
     };

通常バージョンとの実行時間の差は以下のとおり。

 * time {tarai 12 6 0}
 Elapsed time: 74.655180
 result[INTEGER]=&gt; 12
 * time {tarai-lazy 12 6 0}
 Elapsed time: 0.008021
 result[INTEGER]=&gt; 12

一瞬で終わります。
遅延評価関数定義の引数に &#039;&amp;’ を付けて、遅延評価関数を呼ぶときに eval ではなく ([...] ではなく) クロージャを({...} を) 渡すことにより、遅延評価関数内でその引数の参照時に一度だけ計算します。
呼び出し側も遅延評価の呼び出しであることを意識することが必要ですが。

***クイックソート

    defun lsort (l order: cmp) {
        if {[$l len] &lt;= 1} then: {return $l};
        if [set? cmp] else: {set cmp &gt;};
        set pivot [$l car];
        set l [$l cdr];
    
        return [[lsort [$l filter {| i | $pivot $cmp $i}] order: $cmp]
            concat $pivot
             [lsort [$l filter {| i | ! [$pivot $cmp $i]}] order: $cmp]];
    };


***素数を求める

    # calc prime
    
    defun prime (n) {
      set prime (3 5);
      set last [$prime last];
      set cand [$last item];
      set c 0;
    
      while {true} do: {
        if {$c &gt; $n} then: {return $prime};
    
        $cand ++ 2;
        $prime each do: {| i |
          if {[$i * 2] &gt; $cand} then: {break};
          if {[$cand % $i] = 0} then: {$cand ++ 2; retry};
        };
        #found prime
        set last [$last + $cand];
        set cand [$last item];
        $c ++;
      };
    };
    
    time {prime 1000;};

***たらい回し関数

    # tarai function
    
    defun tarai (x y z) {
        if {$x &lt;= $y}
            then: {return $y}
            else: {
                tarai [tarai [$x - 1] $y $z]
                      [tarai [$y - 1] $z $x]
                      [tarai [$z - 1] $x $y];
        };
    };
    
    time {tarai 12 6 0};


***クラスの継承ツリーを表示

    defun class-tree (class indent: ind) {
        if {set? ind} else: {set ind 0};
    
        # print indent
        if {$ind &gt; 0} then: {1 each to: $ind do: {| i | print &quot;  &quot;}};
    
        println $class;
        if {&quot;Object&quot; = $class} then: {return;};
    
        [$class delegate?] each do: {| i |
            class-tree $i indent: [$ind + 1];
        };
    };


*** コンストラクタを delegate の継承関係を遡って実行する。
コンストラクタは、オブジェクト生成時に指定したクラスの init メソッドしか呼ばれないので、init メソッドの中に apply-constructor の呼び出しを書くことで、存在するすべての init メソッドを呼べます。

    defun apply-constructor () {
        [[self] delegate?] each do: {| i |
            apply-constructor-sub $i;
        };
    };
    
    defun apply-constructor-sub (o) {
        set l [$o delegate?];
        if {$l null?} then: {return};
    
        $l each do: {| i |
             apply-constructor-sub $i;
             try {
                 [$i var? init];
             }
             catch: {};
        };
    };
 













----     </description>
    <dc:date>2012-07-16T18:34:35+09:00</dc:date>
    <utime>1342431275</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/22.html">
    <title>GCとPCLの和解</title>
    <link>https://w.atwiki.jp/toy-lang/pages/22.html</link>
    <description>
      GCとPCLの和解
2011.12.23


*はじめに

toy-lang にコルーチンを実装するにあたって、BoehmGC と PCL(Portable Coroutine Library) の間で色々不都合があったのでこれに対応を行ったのでその際の方法をメモとして公開します。

現在の開発中の版ではこれらのライブラリを組み合わせた際の問題はわかっており、すでに解決していますが、解決に至る中でわかったことやプログラミング上のテクニックについて参考になればと思いメモを公開します。

*BoehmGCの動作について

toy-langを実装するにあたっては、できる限り汎用のライブラリを使用して実装することにしています。
toy-langにおいては、GC(ガベージコレクション)はBoehmGCを、コルーチンの実装には PCL を使用しています。

2年ほど前、コルーチンを実装していてどうしてもうまく動かなくて悩んでいました。

まず、GCの動作について非常に簡単ですが説明したいと思います。(Fig.1)

#image(http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=22&amp;file=gc_and_coroutine.fig1.jpg,)


この構成の場合、メモリが足りなくなりGCが発動すると、「Fig.2GCの行われ方」のように、

-①ヒープ領域のGC
-②スタック領域のGC

が実行され、ごみ(どこからも参照されない)と判断されたメモリ領域の回収プロセスが実行されます。
特に②のスタック領域のGCでは、スタックのトップ(現在のスタックポインタ)からボトムに向かってGCが実行されます。

#image(http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=22&amp;file=gc_and_coroutine.fig2.jpg,)


*問題発生
 
上に書いたとおり、当初は各コルーチンのスタック領域はヒープ領域に確保していました。
そして、このようにすると、GCのタイミングでプロセスが確実に落ちます。
これでしばらくの間悩んでいました。2008年の冬から2009年の春ころまでです。
この間 BoehmGC のソースを眺めたり google を検索したりと原因を突き止めようとしていました。

*原因

最終的にたどりついた本現象の原因は「Fig.3問題発生」のようなことではないかと推測するに至りました。

#image(http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=22&amp;file=gc_and_coroutine.fig3.jpg,)


コルーチンが起動されると、それまでのスタックからコルーチンのスタックに切り替わります。
この時点でGCが発動されると、コルーチンのスタックトップから、もともとのマシンスタックのボトムに向かってGCが行われます。
そうすると、コルーチンのスタックはヒープ領域にとられているため、GCの途中でプロセスがアクセスできない領域にアクセスすることになります。
これがプロセスが落ちる原因ということであると推測しました。2009年の春頃です。

その後しばらくプログラミングから遠ざかるわけですが。

*対策

で、今年よりまたプログラミングを再開し、上記問題に対応するようなコードを書きました。
それが「Fig.4解決方法」に示す内容です。

#image(http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=22&amp;file=gc_and_coroutine.fig4.jpg,)


つまり、GCがスタックのトップからボトムまでをスキャンするのであれば、これを妨げるものを排除するため、コルーチンのスタック領域をすべてマシンスタックの上に配置することにしました。

実際には、プロセスが利用できるスタック領域のリソースは有限であるため、これをプログラムで知るための仕組みも作りました。

こうすることで、確かにコルーチンコールからGCが発動されても落ちることはなくなりました。推測は正しかったことになります。

あと、各コルーチンが他のコルーチンのスタックを壊さないよう、スタックの上部 4Kにバリア領域を設定しています。ここに書き込むとやはり落ちますので、今後はこのハンドルを実装しようとしています。




toy-langにコルーチンを実装しようと思い立ってからすでに三年が過ぎましたが、ようやく解決の出口がみつかりました。
次のバージョンではコルーチンをサポートしたものとなると思います。

































#eof    </description>
    <dc:date>2012-03-02T10:30:51+09:00</dc:date>
    <utime>1330651851</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/18.html">
    <title>開発の記録など</title>
    <link>https://w.atwiki.jp/toy-lang/pages/18.html</link>
    <description>
      ** 2009.11.1
バージョン 0.1.2 をリリースしました。
末尾再帰を書くための goto コマンドを追加しています。
使い方は [[サンプル]] のコードを参考にしてください。
あと、String::split を作りました。今まで無かったのが手抜きなのです。

** 2009.9.23
バージョン 0.1.1 をリリースしました。

** 2009.9.5
toy-langを開発しはじめておおよそ1年。それを記念してバージョンを0.1.0としてリリースしました。[[マニュアル]]も、稚拙ながら全体をとりあえず記述しました。
全体的に最適化など施すも、効果は薄かった。高速化を考えるのであれば、VMの導入を考える必要がありますな。できないけど。

** 2009.8.30
BoehmGC alpha2 が出ていますね。そのうち検証してみなくちゃ。
昨日はLLTVに行ってきました。gaushe の川合さんのお話が面白かった。無印良品の基幹システムすべてをshで作ったという話。これも面白かった。情報システム部門の判断は英断だよな。そのほかについては、レイヤーが上の話が多くて、あまり言語実装のヒントになるようなネタは拾えませんでした。

** 2009.7.6
久しぶりですが、0.0.27をリリースします。
マニュアル(まだベータ版でかつ[[リファレンス]]がありませんが)も一緒にリリースしました。

** 2009.6.30
マニュアルがなかなか進みません。
case のシンタックスを変更しました。
Lisp の cond と似た条件分岐コマンドを作ってみました。

** 2009.6.1
6月なのに寒いですね。
プログラミングは一旦お休みして、現在マニュアルを書いています。
今までちゃんと解説をしたことがなかったので。

** 2009.5.17
遅延評価の仕組みを導入。
関数のパラメータ定義の仮引数に &#039;&amp;&#039; を付けることで、参照時にはじめてその引数(クロージャ)を一度だけ実行します。たらい回し関数が一瞬で終わります。ただし、ソートのような全ての引数を評価するような関数にはほとんど効果がありません。

** 2009.5.10
しばらく間が空いてしまいましたが、細々と続けています。
今回は、イテレータの構文に変更を加えました。
相変わらずマニュアルはありませんが、lib/*.toy などのソースを参照願います。
-- (古い構文) List::each in: i do: {println $i}
-- (新しい構文) List::each do: {| i | println $i}
こんな感じ。
パーサは手抜き。
その他、前回から色々手が入っているが、忘れてしまった。。。
call/cc に興味があって実装を試みているが、まだ出来ていない。setjmp/longjmp を自前で（asmで）実装する必要があるかも。

** 2009.3.1
quick sort と merge sort との速度比較など(特に整列済みデータ)。

** 2009.2.21
ソースコードを少し整理。
quick sort を書いてみた。Haskell のクイックソートが一行で書かれているのが理解できなかったのだが、実際に書いてみて何をやっているのか理解した。1行ではないけど。

** 2009.2.19
unknown を実装。なんか思ったより大変だった。

** 2009.2.15
半年ぶりの更新になりました。
非常にゆっくりとですが、まだ続けています。

** 2008.9.7
昨日は飲みすぎた。
いくつかの修正。
-init メソッドに引数を指定できるようにした。
-Hash/Array に引数を指定できるようにした。
-new コマンドの糖衣構文を導入した。
これで、何ができるかというと、このように書くオブジェクトの初期化が、

 set o [new Hash arg: (((a . 1) (b . 2)))]

このように書けるようになった。

 set o `Hash((a . 1) (b . 2))

というだけなんだけど。とりあえず、お試し機能ということで。

あと、キーワード引数の糖衣構文も作った。

 foo switch: 1

は、

 foo :switch

と等価です。&quot;switch:&quot;　キーワード引数の変数に非 nil が設定される。



** 2008.8.31
夏休みも終わりですな。
昨日はバンド練習＆焼肉。
正規表現のロジック変更。鬼車の使い方がこれで良いのかいまひとつわからない。
to_string の呼び出しを to_string_call に変更し、NATIVE からの string 変換の呼び出しをメソッド呼び出しにするようにした。

** 2008.8.24
String::=~ を実装。regex のライブラリには鬼車を使用させて頂きました。
まだ、毎回正規表現をコンパイルしたりと、性能的に使い方がよくないが、今後直してゆくつもり。

** 2008.8.23
cd コマンド、pwd コマンドを実装しました。
alias コマンドを実装しました。昨日書いた upvar(Tcl流) を、実装の際に名前変えました。

 alias a i;

とすると、a の値を i で参照できます。呼び出し元のスタックの変数を参照する場合は、up: 1 とします。

 defun foo (x) {
     alias up: 1 $x i;
     println $i;
 }
 set n 100
 foo n

とすると、100 が表示されます。

make install を書いた。原始的ですみません。
環境変数を、グローバル変数の $ENV で参照できるようになりました。
システムのバージョンを、グローバル変数の $VERSION で参照できるようになりました。

やぐら亭＠初台の宇宙一辛い味噌ラーメン、撃沈。。。

** 2008.8.22
List::append! がバグっていました。
これから、スタックフレーム上の変数を参照するためのコマンドを作成します。
 upvar 1 var name
こうすると var で、上位のスタックフレームにある name を参照できるようにします(Tcl にもあるコマンドですね)。制御構造などを書くときに使います。

Array バージョンの素数計算サンプルを作ってみました。が、予想通りリストバージョンに比べて早くありません。予想していたとおりなんですけど。
まず、eval の実行が全体に占める割合が非常に多い。
あと、array をコンテナで持つのでその操作にコストがかかっている、、、
ためだと予想しています。
パフォーマンスチューニングは、また別の機会に。

** 2008.8.19
以前の版だと、gcc -O2 としていたら core を吐いていたんだけど、今のはなぜかOKだ。なぜだ?
load コマンドなどを追加。

** 2008.8.17
相変わらず細々とコード書いてます。
今日は、改めて valgrind がすばらしいと思った。
こんなコード
 p = malloc(strlen(str));
なんだけど、非常に初歩的なミスですね。
hash.c を書き換えていてやってしまった。
不可解な動作をするので valgrind かけたら一発でわかった。
あー、素晴らしい。

** 2008.8.16
stack-traceコマンド追加。
trapコマンド追加。
function/method でクロージャの変数を参照できるようになった。

 defun foo (i) {
     return [fun () {$i ++}];
 };
 set x [foo 100];
 $x; # =&gt; 101
 $x; # =&gt; 102

このようになります。
今までは、No such variable になっていた。
で、クロージャの変数は block でしか参照できなかった。
このように。

 defun foo (i) {
     return {$i ++};
 };
 set x [foo 100];
 $x eval; # =&gt; 101;
 $x eval; # =&gt; 102;

朝PCを立ち上げたら、VMware が立ち上らなくてあせった。

** 2008.8.13
とりあえず、グローバルの &#039;@stack-trace&#039; にスタックトレースを出力します。この仕様は整理が必要です。

** 2008.8.10
stack trace を取得するための仕組み作り。
Exception オブジェクトのメソッドを定義したが、先に評価器にエラーと判断されてしまった。仕方が無いので、変数に stack-trace を設定したが、美しくない。
もう少し考える。
World Happiness＠夢の島陸上競技場。HASYMO を聴きに。

** 2008.8.9
矢野顕子＠あきるの市キララホール。
一曲目の Children in the summer でノックアウト。

** 2008.8.8
FreeBSD に valgrind を入れてみた。
Purify は、その昔国内で SRA が販売を始めたころから使っていて、Linux や FreeBSD などの PC-UNIX でも使えると良いなと思っていたが、今日、Linux で valgrind というツールが使え、Purify とほぼ同じような機能を実現していることを知る。
早速、FreeBSD 6.3R に入れてみる。
BoehmGC との相性が気になったが、案の定 Bus error を吐いて死ぬ。
Makefile.nogc でビルドして、BoehmGC を使わずに実行するときちんと動作はする。やはり BoehmGC との共存は無理なのかな。
実際、デバッグ途中に core を吐くことはあっても、それ以外で落ちることは今のところ無いが、valgrind でも特に気になるエラーは報告されなかった。
すばらしいツールがフリーで手に入ることがわかった。

File::gets と print / println を変更。print / println は、デフォルトで、@out 変数(File オブジェクト)、stdout (初期化時にグローバルに定義される File オブジェクト) の順に探し、最初に見つかったオブジェクトに対して出力するようにしてみた。
    set @out [new File]; $@out open &quot;XXX&quot;
とすることで、そのオブジェクトからの print / println の呼び出しは、XXX ファイルに出力される。何も指定しなければ stdout に出力される。

** 2008.8.7
矢野顕子＠調布市グリーンホールのリサイタルへ行く。
相変わらずすばらしいピアノが聴けた。
その後、昔からのファン仲間と飲み会。























----    </description>
    <dc:date>2009-11-01T23:02:50+09:00</dc:date>
    <utime>1257084170</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/21.html">
    <title>マニュアル</title>
    <link>https://w.atwiki.jp/toy-lang/pages/21.html</link>
    <description>
      ** toy-lang マニュアル

(2009.9.23) バージョン 0.1.1 に対応しました。

[[ここ&gt;http://www31.atwiki.jp/toy-lang?cmd=upload&amp;act=open&amp;pageid=21&amp;file=manual.pdf]]からダウンロードできます。

























----    </description>
    <dc:date>2009-09-23T18:28:52+09:00</dc:date>
    <utime>1253698132</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/20.html">
    <title>SandBox</title>
    <link>https://w.atwiki.jp/toy-lang/pages/20.html</link>
    <description>
      **誰でも書き込めます。
コメントがあればどうぞ。

#comment






























----    </description>
    <dc:date>2009-02-15T20:59:19+09:00</dc:date>
    <utime>1234699159</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/14.html">
    <title>リファレンス</title>
    <link>https://w.atwiki.jp/toy-lang/pages/14.html</link>
    <description>
      **型
- nil
-- ソース中では nil で表現されます。
- SYMBOL
-- シンボルです。英数字と記号で表現します。
- REF
-- シンボルの先頭に &#039;$&#039; をつけたもので、シンボルの内容を現します。
- LIST
-- &#039;(&#039; と &#039;)&#039; で囲まれた任意の型表現です。
- INTEGER
-- 整数です。
- REAL
-- 浮動小数点です。
- STRING
-- &quot; と &quot; で囲まれた文字列です。
- BLOCK
-- &#039;{&#039; と &#039;}&#039; で囲まれたスクリプトです。実行時にはクロージャになります。
- EVAL
-- &#039;[&#039; と &#039;]&#039; で囲まれたスクリプトで、行が実行される際に事前に評価されます。
- OBJECT
-- オブジェクトです。new コマンドと class コマンドによって生成されます。
- EXCEPTION
-- 例外です。throw コマンドによって生成されます。
- CLOSURE
-- BLOCK が実行されるとクロージャになります。クロージャは実行時の環境(ローカル変数、オブジェクト)を保持します。
- FUNC
-- 関数です。fun コマンド、defun コマンドや、method コマンドで生成されます。
- CONTROL
-- return/break/continue/redo/retry により生成されます。
- RQUOTE
-- 正規表現を記述します。シングルクオート(&#039;) で囲んだ文字列です。

**評価の方法

-スクリプトは、複数の行から構成されます。
-各行は &#039;;&#039; (セミコロン) で終了します。
-スクリプトの各行が順次実行されます。
-各行の評価方法は次のとおりです：
--行内の各、REF(ex. $XXX)、EVAL(ex. [XXX; ...]) を評価します。
--行の先頭のシンボルを調べ、これが関数の場合は、その行の残りをパラメータとして関数を実行します。
--行の先頭がオブジェクトの場合、2番目のシンボルを調べ、オブジェクトのメソッドであれば、3番目以降を引数としてメソッドを実行します。
-すべての関数、制御構造は、上記のとおり関数として実行します。

例:

    if {$i &gt; 10} then: {println &quot;true&quot;};

上記の場合、まず、&#039;if&#039; という関数が存在するかを調べ、この関数に対して {$i &gt; 10} 、then: {println &quot;true&quot;} を引数として渡します。
if 関数は、{$i &gt; 10} を評価し、この結果により then: ブロック(もしくは else: ブロック)を実行します。

    $x foo 1;

上記の場合、$x がオブジェクトの場合、$x のメソッドとして &#039;foo&#039; が存在するかを調べます。foo が見つかった場合、$x のオブジェクト環境を設定し、foo の引数として 1 を渡し、実行します。


**コマンドリファレンス
組み込みのコマンド(関数)の一覧です。

-false
--nil を返します。toy の場合、nil のみが偽として扱われます。
-true
--true を返します。
-set
--ローカル変数に値を設定します。
-sets
--インスタンス変数に値を設定します。
-defvar/setvar
--グローバル変数に値を設定します。defvar は、グローバルに設定されていない場合に実行可能です。setvar は、すでに存在するグローバル変数の内容を変更します。
-fun
--名前無しの関数を生成します。
-defun
--名前つきの関数を生成します。
-info
--引数により次の情報を返します。local:ローカル変数、self:インスタンス変数、func:コマンド、class:クラス、global:グローバル変数。
-return
--引数を伴い関数から抜けます。
-break
--while/each から抜けます。引数を指定すると、while/each の戻り値となります。
-continue
--while/each の次のイテレーションを実行します。
-redo
--while/each の現在のイテレーションを再実行します。
-retry
--while/each を最初からやり直します。try コマンドの catch: ブロックで使うと、tryを最初からやり直します。
-new
--オブジェクトを作成します。
-if
--コンディションの真偽により、then:ブロック、else:ブロックのいずれかを実行します。
-while
--コンディションが真の間中、do:ブロックを実行します。
-print
--引数を表示します。改行はしません。
-println
--引数を表示し、改行します。
-time
--ブロックの実行時間を秒で表示します。
-class
--クラスを生成します。
-try
--ブロックを実行し、EXCEPTIONが発生した場合、catch: ブロックを実行します。そのさい、var: で指定した変数で EXCEPTIONを参照できます。fin: ブロックが定義されていた場合、try の終了時点で必ず実行されます。
-throw
--EXCEPTIONを発生します。
-case
--第一引数の内容にマッチするブロックを実行します。
-set?
--ローカル変数が設定されていれば真を返します。
-sets?
--インスタンス変数が設定されていれば真を返します。
-defvar?
--グローバル変数が設定されていれば真を返します。
-unset
--ローカル変数を消去します。
-unsets
--インスタンス変数を消去します。
-self
--自オブジェクトを返す関数です(変数ではありません)。
-stack-trace
--スタックトレースを示す文字列を返します。
-trap
--UNIXシグナルのハンドラを設定します。ハンドラを省略した場合、ハンドラは削除されます。
-load
--スクリプトをロードし、評価します。
-sid
--関数の script-id を返します。(デバッグ用)
-!/and/or
--論理演算の 否定/積/和 です。
-sdir
--ロードされたスクリプトのリストを返します。
-alias
--変数の別名を定義します。変数 i の別名を a として定義する場合、次のようにします。
 alias i a
--また、up: 数値 を指定すると、コールスタックを遡り参照ができます。
-sleep
--ミリ秒単位で sleep します。
-file
--ファイルに関する問い合わせコマンドです。
---file exists?
----ファイルが存在すれば真を返します。
---file dir?
----ファイルがディレクトリであれば真を返します。
---file read?
----ファイルが読み込み可能であれば真を返します。
---file write?
----ファイルが書き込み可能であれば真を返します。
---file exec?
----ファイルが実行可能であれば真を返します。
---file list
----指定したディレクトリのファイルリスとを返します。
-exists?
--変数が存在すれば真を返します。変数の存在チェック順序は、$による参照順序と同じです。

**Objectクラスのメソッド
- vars
--インスタンス変数のシンボルをリストで返します。
- method
--メソッドを定義します。
- var?
--インスタンス変数の内容を返します。
- set!
--インスタンス変数に外部から値を設定します。
- type?
--オブジェクトのタイプのシンボルを返します。
- delegate?
--オブジェクトのデレゲータとして設定されているオブジェクトのリストを返します。
- string
--オブジェクトの文字列表現を返します。

**Integerクラスのメソッド
- +,-,*,/,%
-- 四則演算、剰余演算。
- =,!=,&gt;,&lt;,&gt;=,&lt;=
-- 比較演算。
- ++,--
-- インクリメント/デクリメント演算。オブジェクトの内容が直接変更されます。
- each
-- オブジェクトの値から、to: で指定された値まで、do: ブロックを実行します。その際、var: で指定した変数が設定されます。

**Realクラスのメソッド
- +,-,*,/
-- 四則演算。
- =,!=,&gt;,&lt;,&gt;=,&lt;=
-- 比較演算

**Listクラスのメソッド
- last
-- リストの最終要素を返します。
- item/car
-- リストの先頭要素を返します。
- next/cdr
-- リストの2番目以降の要素を返します。
- append!/+
-- リストに要素を追加します。元のオブジェクトが変更されます。
- each
-- リストの要素が順番に取り出され、do:ブロックが実行されます。その際、要素は var: で指定した変数で参照できます。
- len
-- リストの長さを返します。
- null?
-- リストが空のとき真を返します。
- join
-- リストの各要素を STRING へ変換し結合します。sep: キーワードが指定された場合は、要素間にセパレータ文字列を挿入します。
- add
-- リストに要素を追加し、オブジェクト全体を返します。
- .
-- リスとに要素を追加しますが、元の変数は変更されません。
- filter
-- ブロックの実行結果が真である要素のみのリストを返します。
- map
-- ブロックの実行結果による要素のリストを返します。

**Stringクラスのメソッド
- len
-- 文字列の長さを返します。
- =,!=
-- 比較演算。比較対象は、Object::string により変換されるため、どのようなオブジェクトも文字列として比較されます。
- +
-- STRING オブジェクトに引数の要素を追加します。
- eval
-- 文字列をスクリプトとして評価します。
- =~ / match
-- 文字列に対して、引数で指定された正規表現(RQote … &#039;regex&#039;)がマッチすれば、そのマッチした情報(開始位置、終了位置)のリストを返します。

**Hashクラスのメソッド
- init
-- Hashのコンストラクタ。
- set
-- Hashに値を設定します。
- get
-- Hashから値を取り出します。
- set?
-- Hashに値が設定されていれば真を返します。
- keys
-- Hashに設定されたすべてのkeyをリストで返します。
- pairs
-- Hashに設定されたすべてのkey、value の対をドット対のリストで返します。
- len
-- Hashの要素数を返します。
- unset
-- Hashから値を削除します。

**Blockクラスのメソッド
- eval
-- クロージャを実行します。
- &gt;&gt;
-- ブロックの実行結果をファイルへ出力します。

**Fileクラスのメソッド
- open
-- ファイルをオープンします。mode: でオープンモードを指定します(i: 入力(デフォルト)、o: 出力、a: 追加書き出し)。
- close
-- ファイルをクローズします。
- gets
-- ファイルを行単位(\nで区切られた行)で読み込みます。
- puts
-- ファイルに書き出します。
- flush
-- ファイルに書き出した内容をフラッシュします。
- stat
-- ファイルの状態を表示します。
- eof?
-- ファイルが EOF に達している場合、非 nil を返します。
- ready?
-- ファイルが読み書き可能な状態であれば真を返します。

**Arrayクラスのメソッド
- + , append
-- Array の最後の要素に値を追加します。要素数は自動拡張します。
- set
-- Array の指定位置にオブジェクトを設定します。
- get
-- Array の指定位置のオブジェクトを返します。
- len
-- Array の要素数を返します。
- each
--Arrayの要素が順番に取り出され、do:ブロックが実行されます。その際、要素は var: で指定した変数で参照できます。


















----    </description>
    <dc:date>2009-02-15T20:42:46+09:00</dc:date>
    <utime>1234698166</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/toy-lang/pages/11.html">
    <title>toyの紹介</title>
    <link>https://w.atwiki.jp/toy-lang/pages/11.html</link>
    <description>
      まずはインタプリタを起動します。
ソースを make すると toysh という実行ファイルができます。


    csh(162)&gt; toysh



hello world はこう書きます。


    &gt; println &quot;Hello world!&quot;
    Hello world!
    result[NIL]=&gt; nil



ローカル変数への値の設定は set を使います。


    &gt; set a 100
    result[INTEGER]=&gt; 100



a という変数に、整数の 100 を設定しました。
これを参照するには、シンボル(a のこと) に &#039;$&#039; をつけて参照します。
シェルのようですね。


    &gt; println $a
    100
    result[NIL]=&gt; nil



変数 a の内容を b という新しい変数に設定してみます。


    &gt; set b $a
    result[INTEGER]=&gt; 100
    &gt; println $b
    100
    result[NIL]=&gt; nil



関数を作ってみます。


    &gt; set foo [fun (a) {println $a}]
    result[FUNC]=&gt; (a) {println $a;}



ここでは、名前なしの関数を作って、変数 foo に設定しました。
fun は関数を作る関数、(a) は引数リスト、その後の &#039;{&#039; と &#039;}&#039; で囲まれた部分が実行の本体です。

では、呼び出してみます。


    &gt; $foo &quot;Hello world!&quot;
    Hello world!
    result[NIL]=&gt; nil



関数の本体は、変数 foo に格納されていますので、$foo として参照し、引数を与えて実行します。

もちろん、名前つきの関数も定義できます。
defun という関数で定義します。


    &gt; defun foo (a) {println $a}
    result[FUNC]=&gt; (a) {println $a;}
    &gt; foo &quot;Hello world!&quot;
    Hello world!
    result[NIL]=&gt; nil



関数の中から戻り値を返すには return を使います。


    &gt; defun foo (a) {return $a}
    result[FUNC]=&gt; (a) {return $a;}
    &gt; foo &quot;Hello world&quot;
    result[STRING]=&gt; Hello world
    &gt; println [foo &quot;Hello world&quot;]
    Hello world
    result[NIL]=&gt; nil



&#039;[’ と &#039;]&#039; に囲まれた部分は、その行が実行される前に評価され、引数として渡されます。
上の例だと、println の引数である [foo &quot;Hello world&quot;] の部分ですね。
tcl を知っている人は似ていると思いますよね。


次に、オブジェクトを生成してみます。


    &gt; set x [new]
    result[OBJECT]=&gt; (object)Object



new という関数がオブジェクトを生成します。
この場合、デフォルトで Object というオブジェクトにデレゲートするオブジェクトが生成されます。
その後、x という変数にオブジェクトを設定しました。

今作ったオブジェクト(x に設定されている) のメンバを見てみます。
vars というメソッドを実行してみます。


    &gt; $x vars
    result[LIST]=&gt; ((@name Object))



@name というメンバしかいません。
では、Object オブジェクトのメンバを見てみます。


    &gt; Object vars
    result[LIST]=&gt; (set! delegate? method vars type? @name var? eq)


いくつかのメンバがいますね。
そのなかには、method というのもいますね。これでメソッドを定義できます。


    &gt; $x method foo (args: a) {$a each var: i do: {print $i &quot; &quot;}; println}
    result[FUNC]=&gt; (args: a) {$a each var: i do: {print $i  ;};println;}



x に設定されているオブジェクトに対して、foo というメソッドを定義しました。
foo の引数は args: a となっています。これは、可変長引数を a で受け取るという意味です。

実行してみますと、


    &gt; $x foo &quot;Hello&quot; &quot;world&quot; &quot;!&quot;
    Hello world ! 
    result[NIL]=&gt; nil


foo の処理内容は、args: a で受けた引数のリストを、List オブジェクトの each メソッドで順番に表示するというものです。


今度はクラスを定義してみます。


    &gt; class myclass
    result[OBJECT]=&gt; (object)Object



class という関数を使います。
これで、名前つき（この場合は myclass)のクラスができました。
実は、クラスというのは便宜上の呼び方で、名前をつけたオブジェクトをクラスと呼んでいるに過ぎません。

クラスからオブジェクトを生成します。


    &gt; set x [new myclass]
    result[OBJECT]=&gt; (object)myclass



new に先ほど作ったクラス名を指定するだけです。
こうすると、新しく作ったオブジェクトのデレゲート先が myclass になるということです。

myclass にメソッドを定義します。
これは、さっき $x にメソッドを定義したのと同じです。


    &gt; myclass method foo (args: a) {$a each var: i do: {print $i &quot; &quot;}; println}
    result[FUNC]=&gt; (args: a) {$a each var: i do: {print $i  ;};println;}



で、myclass にデレゲートするオブジェクト x に対して、今作ったメソッドを適用してみます。

    &gt; $x foo &quot;Hello&quot; &quot;world&quot; &quot;!&quot;
    Hello world ! 
    result[NIL]=&gt; nil


呼べました。 


Hash や Array の使い方は以下のとおりです。

    &gt; set h [new Hash]
    &gt; $h set key &quot;value&quot;
    &gt; $h get key
    result[STRING]=&gt; &quot;value&quot;


インスタンスの内容にアクセスするための簡易な方法があります。

    &gt; [$h get key]

と、

    &gt; $h,key

というのは等価な操作となります。
つまり、

    set h [new Hash];
    $h set key &quot;abc&quot;;
    println [$h get key];

は、

    set h [new Hash];
    $h set key &quot;abc&quot;;
    println $h,key;

と書ける。


(この頁書きかけ)






















----    </description>
    <dc:date>2008-08-16T14:20:49+09:00</dc:date>
    <utime>1218864049</utime>
  </item>
  </rdf:RDF>
