Linux Gazette 4月号

今月の Linux Gazette の内容


今月のニュース

Linux Journal 4月号発売中。今月の特集はインターネット

▼▼▼ディストリビューション関連ニュース▼▼▼

SuSE と Mandrake

SuSE、Mandrake、Linux Network Computing は今後の開発で提携することになった。SuSE と Mandrake はよく知られた Linux のディストリビュータだ。Linux Network はディスクレスの Linux ネットワークコンピューティング開発企業だ。その製品は Linbox Net Station や Linbox Net Server として知られている。Linbox と Linux ディストリビュータ2社の提携により Linbox Network アーキテクチャのオープンな開発が行われることになる。

Best

SOT は同社初の Best Linux 英語版を出荷する。発表は2月24日に CeBIT の会場で行われる予定。Best Linux 2000 の特徴は無期限のサポートとアップデートだ。ユーザには自動的に最新バージョンが送られる。ボックス版もリリースされる予定。
http://www.bestlinux.net

Caldera

Caldera の株式公開は期待はずれ

Mandrake

Macmillan USA はプロのサーバ管理者用の Secure Server 7.0 を発表した。これは Linux−Mandrake(tm) 7.0 に基づいた Linux ウェブサーバだ。

MaxOS (Alta Terra)

Mosaic Technologies Corp. の Linux トレーニングプログラムが Alta Terra Ventures Corp. の Linux OS にバンドルされることになった。両社は Linux を PC デスクトップして普及させることを目標にしており、Mosaic は Windows 環境で動作する Linux を提供する予定。
Mosaic Technologis Corporation
Alta Terra Ventures Corp.

SuSE

SCO と SuSE Linux AG が提携。SuSE のユーザはSCO プロフェッショナルサービスを受けられるようになる。SCO のプロフェッショナルサービスは SuSE inux システムの企画、インストール、環境設定、配備などの支援をする。

TurboLinux

Lutris Technologies Inc. と TurboLinux Inc. はオープンソース e-business プラットフォームの強化に向け協力することになった。Lutris の Enhydra Java/XML アプリケーションサーバが TurboLinux OS に組み込まれ、Lutris はサポート、トレーニング、プロフェッショナルサービスを提供する。

▼▼▼その他のニュース▼▼▼ ▼▼▼ソフトウェア関連ニュース▼▼▼

KDevelop 1.1 ファイナル

KDevelop 1.1 のファイナルバージョンが発表された。いくつかの新機能と多数のバグフィックスを含んでいる。これは KDE 1.1.2 の最終バージョンになる予定だ。次のバージョンはKDevelop 2.xになる。ファイナルバージョンではテンプレートの増加、デバッガ内臓、充実したドキュメント、エディタの改善、コンポーネント、dlg、クラスビューアなど機能が充実しており、Linux、NetBSD、FreeBSD、Solaris、Unixwareなどに対応している。
http://www.kdevelop.org

PROGRESS の SonicMQ が Linux をサポート

Progress Software Coporation の Progress SonicMQ インターネットメッセージングサーバが Linux に対応する。SonicMQ は現在のところ Sun の Java 仕様に基づいた唯一のメッセージングサーバだ。
www.progress.com

その他のソフトウェア Linux 対応のJava 製品

More 2¢ Tips

インターネットで辞書を利用する

次のようなスクリプトを作成してコマンドラインで


  dict 語彙

のようにタイプすると語彙の意味が表示される。

スクリプト(ファイル名:dict)

lynx "http://www.m-w.com/cgi-bin/dictionary?book=Dictionary&va=$*"

FAQ を作成するPerlスクリプト

faq_builder.pl を使えばアスキーテキストファイルをFAQに変換してくれる。

winmodem

Winmodem は Linux では使えなかったが試しに linmodems.org をチェックしてみよう。LUCENT は LT MODEMS のバイナリを公開しているしその他のドライバでも開発中のものがある。

Linux に関する本

www.infocom.cqu.edu.aut99/85321 では "An Introduction to Linux Systems Administration (David Jones and Bruce Jamieson 著) という優れた本がオンラインで公開されている。

ページ番号を入れたページを印刷するには

テキストファイルなら "pr -f - | 55 somefile.txt | lpr" と打ち込めばできる。html ファイルなら "html2ps" というツールを使う。ワープロならアプリケーションの中で操作できるはず。その他 "man pr", "man nenscript" など自分で調べることを促すもの。mpage を使って "mpage -2 -H document | lpr" など。

安価で強力な分散処理型のデータベースは

Linux.org のアプリケーションセクションをチェックする。商用なら DB2、Oracle、Informix、Ingres など。フリーなら PostgreSQL、MySQL など。

IP Masquerade での接続が不調

Red Hat 6.1 なら PPP パッケージにバグがある。アップデートしよう。

Linux と win98 でインターネット接続の共有

winroute.com から WinRoute をダウンロードして Win98 にセットアップしよう。Win98 マシンを「デフォルトゲートウェイ」に設定すれば Linux マシンからもインターネットへアクセスできる。

AS/400 エミュレーション

tn5250 で AS/400 にアクセスできる。
http://www-4.ibm/software/network/hostondemand で IBM がjava ベースのクライアントを公開しており Linux でも動作すると報告されている。

FD、CD などのマウントを迅速に

オートマウントや "mount", "umount" などのコマンドも使わずにマウントを処理するスクリプト。


#!/bin/bash

d="/mnt/fd0"

if [ -n "$(mount $d 2>&1)" ]; then umount $d; fi

応用すれば他のデバイスにも利用できる。

Red Hat Linux 6.0 用の アンチバイルスプログラムは?

いくつかのプログラムが利用できる。 http://freshmeat.net/appindex/daemons/anti-virus.html をチェックしよう。

モデムが反応するがダイアルしない

setserial コマンドを使って設定をやり直す。


  setserial /dev/ttyS2 irq 5 uart 16550S

ブート時の設定ファイルに入れておけばいい。

FD/CD のスロットが一つのラップトップに Linux をインストール

Debian
Windows パーティションに C:\linux のようなディレクトリを作成してディストリビューション CD-ROM から "loadlin.exe, root.bin, linux" をコピーする。
再起動して DOS を立ち上げる。Linux ディレクトリに移動し


   loadlin linux root=/dev/ram initrd=root.bin

Red Hat
ディストリビューション CD-ROM の "dosutils" から "loadlin.exe, vmlinuz, intrd.img" を上と同じように Linux ディレクトリにコピーする。再起動後 DOS を立ち上げて Linux ディレクトリに移動し

   loadlin vmlinuz initrd=initrd.img

Mandrake 7.0 で vi 風のエディットモードを使用する

ルート権限で /etc/inputrc ファイルを別のファイル名で保存し、/etc/inputrc の内容を次のように変更する。


   set conveet-meta off

   set input-meta on

   set output-meta on

   set keymap vi

   set editing-mode vi

Red Hat 6.1 でダイアルインがハングアップする

ppp を ppp-2.3.11-1、カーネルを 2.2.14 にしたら不具合が解消した。

Linux 起動時に64MB 以上のメモリを認識させる

Lilo 設定ファイルに 「append = "mem=128M" 」を追加する。または起動時にコマンドラインからの引数として渡す。

Linux で複数のビデオカードを利用する

XFree4.0 を待つg

Linux で画面のキャプチャ

ImageMagick の import コマンドを利用したスクリプトを使う。


#!/bin/bash



max=5                   # キャプチャする画面の枚数

pause=1                 # キャプチャの間隔



count=1



while

        [ $count -le $max ]

do

        sleep $pause

        import -window root shot$x.gif

        let count=count+1

done                                                              


マイクロソフトのドタバタ (By Mark Bolzern)

マイクロソフトは独占禁止法に違反していると告発されて以来何度も意見を変えてきた。ほとんど脅威にもなっていない Linux を競争的な OS と表現したかと思えば株主への説明では絵に描いた餅と表現している。司法の場では驚異的な OS と言い、実際には取るに足らないもの言っている。しかし Linux は多数の プラットフォームに対応した非常に優れた OS です。現在ではサーバとして Windows NT や Windows 2000 にも競合する OS となっています。

GUI に関してはどうでしょうか。裁判では KDE が Winodws 98 のようなデスクトップ環境を提供していると言い、Linux Myth ではカーネルの複雑さと GUI の未熟さとでユーザにはかなりのトレーニングが必要になると言っている。実際には Corel の KDE インタフェースは非常に優れたものでありユーザフレンドリとなっている。Linux コミュニティの支持を考えればこれらデスクトップ環境が近い将来非常に使いやすいものになる可能性がある。

OS は GUI として認識されているとしよう。ではアプリケーションはどうだろう。裁判でのマイクロソフトの意見は多数の開発者がアプリケーション開発に従事しており、将来も継続されるだろうというものだが、Linux Myth では デスクトップ OS としては問題外、ユーザにとってはアプリケーションが少なく直感的に操作することもできないと評価している。訴訟と実際とでは意見が異なっています。実際には Wine のようなフリーで公開されているエミュレーションアプリケーションにより Windows のアプリケーションを動作させることも可能になっています。VM-Ware を使えば Linux と Windows を同時に動作させることも可能です。それに Windows のアプリケーションを Linux に移植しようという試みはますます加速するでしょう。マイクロソフトはこの問題に関しては正直ではない。現に Windows 2000 はかなりの互換性の問題を抱えている。今後64ビット OS が登場すれば Linux も Windows と同じ土俵に立てるだろう。

ハードウェアの対応はどうだろう。ここでもマイクロソフトは意見を巧妙に区別している。司法の場では Sun、Dell、Gateway、東芝、IBM、Silicon Graphics など多数の企業が Linux をサポートしていると言っているが Linux Myth では現実的なバックアップがないと言っている。マイクロソフトの顧客リストはすばらしいものだろうが Linux のそれにもフォーチュン2000の顧客が多数リストアップされている。この記事を書いている現在でも Linux 対応のハードウェアを出したいという企業は増加している。

ユーザサポートに対してもマイクロソフトの意見は「Linux はサポートにコストがかかりすぎる」というものだが、現実に多数のユーザが存在している。今後ますます増加するだろう。それにマイクロソフトは Linux OS のコストに関しては言及していない。Windows NT/2000 をサーバとして運用している企業はかなりのコストがかかりる。それに問題が発生した場合には Windows は再起動を要求される。Linux はほとんと再起動をする必要がなく連続で動作させることができる。

Linux はいずれ優れた OS となるだろう。その開発も止むことはない。マイクロソフトは非常に戦略的に優れた企業ですから意見があちこちで相違を見るのも当然なのかもしれません。今後の問題はLinux がデスクトップとして利用できるかどうかではなく一般的に受け入れられるかどうかなのです。


Copyright © 2000, Mark Bolzern
Published in Issue 52 of Linux Gazette, April 2000

HelpDex (By Shane Collinge)

今月の HelpDex は こちらを ご覧ください。


今月の Linux サイト (By Sean Lamb)

毎月 Linux に関連したサイトを一つ取り上げて紹介していくコーナーです。今月紹介するのは Glade (http://glade.pn.org/) です。

GUI に慣れてしまうとコマンドラインを使うというのは面倒になることが多く、プログラマの観点からもエディタとコンパイラで GUI のアプリケーションを作るのは時間がかかる。こう言う場合に役に立つのがこのサイトだ。Glade は GTK+ を使ったインタフェース構築を容易にする。GNOME がインストールされていれば ネーティブのGNOME インタフェースを構築する。さらに C、C++、Ada95、Python、Perl などのコードを作ることも可能。Glade はまだ開発途上で最新バージョンは現在 0.5.7だ。

Glade のウェブサイトは派手なサイトではないが、大きな画像をダウンロードするのに時間がかかるサイトよりも好感が持てる。Glade の機能紹介のページは Glade 自身で作られている。リンクセクションからは Glade を使ったページ、Glade に対応したページへ移動することができる。規模の大きなサイトではないがそれを質でカバーしている。このサイトだけで Glade のインストール、アプリケーションの構築、サンプルプログラムの参照など一通りのことが間に合ってしまう。


Copyright © 2000, Sean Lamb
Published in Issue 52 of Linux Gazette, April 2000

ログイン時の bash の "Permission denied" エラー (By Ben Okopnik)

記事を書く前に遭遇した話題から。MUA/MTA をインストールしたら root 以外のユーザでログインできなくなった。そのときのエラーメッセージが "Cannot execute /bin/bash: Permission denied" だった。原因を調べようと /etc/password, /etc/groupe をチェックし、/etc 以下のファイルも調べたが異常がない。通常ならログインに失敗すると "Login incorrect" が表示されるはず。/bin 以下のファイルのパーミションもチェックするが異常はない。/home のパーミションも同じように異常はない。一番簡単な解決法はOS の再インストールだがそれでは原因がわからない。"System Administrator's Guide" やウェブサイトで調べても十分な答えが得られない。そこで "strace" を使ってプログラム実行をトレースすることした。使ったコマンドは次の通り。


  strace -s 10000 -vfo login.ben login ben



  strace -s 10000 -vfo login.root login root

root のログイン過程もトレースして比べてみる。これで違いがわかるはず。ログインの過程をトレースした結果目に付いたポイントはこれだ。

(300+ lines elided)

execve("/bin/bash", ["-bash"], ["TERM=linux", "HZ=100", "HOME=/home/ben", 

    "SHELL=/bin/bash", "PATH=/bin:/usr/bin", "USER=ben", "LOGNAME=ben", 

    "MAIL=/var/spool/mail/ben", "LANG=C", "HUSHLOGIN=FALSE"]) = -1 EACCES 

    (Permission denied)            

write(2, "Cannot execute /bin/bash: Permission denied\n", 44) = 44

この結果 "login" から起動されるライブラリに問題がありそうだと見当をつけ、/lib にある ld-2.0.7.so のパーミッションが 644 になっていることに気がついた。これは 755 でなければならないはず。そこで パーミッションを 755 に変更して問題は解決した。

問題が発生した場合に OS を再インストールして解決するのは簡単だがそれでは今後同じ問題が発生しても自力では解決できなくなってしまう。なるべく "System Administrator's Guide" や man や HOWTO を利用して問題の解決に努めるようにしよう。そうすれば Linux がもう少し楽しくなるはずだ。


Copyright © 2000, Ben Okopnik
Published in Issue 52 of Linux Gazette, April 2000

シェルスクリプトへの招待 (By Ben Okopnik)

シェルスクリプトは非常にシンプルなツールだが柔軟で強力な Linux のパワーを引き出すことができる。PC 上で DOS のバッチファイルを使っていたが、今考えると DOS は Unix のシェルスクリプトの貧弱な模倣でしかない。Linux は初心者にやさしいシステムではない。シェルスクリプトもプログラムの一部だ。が、プログラムそのものよりは簡単だ。再利用可能のスクリプトを書けばそれだけ後々楽になる。

筆者の好みのシェルは "bash" だ。気をつけなければならないことは、作業ディレクトリはホームディレクトリにする、シェルスクリプトファイルの名前はパスの通った実行可能ファイルと同じものは使わない。また決して "test" というファイル名を用いないこと。同名の実行可能ファイルが /bin ディレクトリに存在する。さらにファイルオペレーションやファイルシステムに関する若干の知識が必要で、エディタを利用できること。今回使用するエディタは mcedit だ。

実際に簡単なシェルスクリプトを書いてみよう。シェルスクリプトはコマンドラインで入力する一連のコマンドと同じだ。それをシェルにスクリプトであることを知らせればいい。最初の例は指定したファイルを指定したディレクトリへバックアップするスクリプトだ。まずファイルを作成しパーミッションを設定する。


  > bkup

  chmod +x bkup

1行目のコマンドはカレントディレクトリに "bkup" というファイルを作成する。
2行目のコマンドは実行可能属性を "bkup" に付加している。"+x" はすべてのユーザに実行を許可している。制限したければ "u+x" か "ug+x" のようにすればいい。それでは実際のスクリプトを書こう。まずスクリプトファイルをエディタで開く。

  mcedit bkup

スクリプトファイルの最初はいつもこれで始まる。なお、行頭の番号は分かりやすいように付けているだけなので無視すること。


1: #!/bin/bash
スクリプトファイルの中で#で始まる行はコメントとしてシェルから無視されるのだがこれだけは特別だ。スクリプトが開始するときに現在のシェルは別の bash プロセスを起動してスクリプトを実行する。スクリプトが終了すれば元のシェルにプロセスが戻る。

スクリプトを続けよう。



2:  # "bkup" - 指定されたファイルをファイル名の競合をチェックしてから 3:  # ~/Backup ディレクトリにコピーする
前述の通り、# で始まる行はコメントだ。シェルからは無視される。でもスクリプトに説明をつけておくことはいいことだ。

4: cp -i $1 ~/Backup
"cp" コマンドの "-i" オプションは "cp" コマンドをインタラクティブに動作させる。もし Backup ディレクトリに 同名のファイルが存在すると上書きするかどうか問い合わせる。$1 は特定の引数を表す。この場合は2つ目の引数だ。一つ目の引数 $0 はコマンド名、この場合は bkup になる。#@ は引数のリスト、$# は引数の数を表す。引数を操作する方法はその他にもあるが bash のマニュアルを参照して欲しい。

このままではあまり役に立つスクリプトではない。そこでバックアップの際にバージョンを付加するように変えてみよう。


4: a=$(date +%T-%d_%m_%Y) 5: cp -i $1 ~/Backup/$1.$a
&(コマンド)は括弧内のコマンドを実行して全体をその結果に置き換える。この例では日付時間を取得して変数 "a" に代入しそれをファイル名に付加している。変数 "a" を参照するには "$" を変数名の前に付ける。変数名は自由に使えるが予約語や予約された記号、シェルで使用される変数名は使用できない。

さてここまで作成したシェルスクリプトは次の通りだ。


#!/bin/bash
# "bkup" - 指定されたファイルをファイル名の競合をチェックしてから

# ~/Backup ディレクトリにコピーする


a=$(date +%T-%d_%m_%Y)

cp -i $1 ~/Backup/$1.$a


わずか2行のシェルスクリプトだがシェルスクリプトを学ぶにはいい材料だろう。ところでこのスクリプトを

  bkup

のように実行してみると

  bash: bkup: command not found

のようなメッセージが表示されるはずだ。これは DOS などと違い、カレントディレクトリにパスが通っていないためだ。このスクリプトを実行するには次のようにする。

./bkup file.txt

シェルスクリプトは Unix のパワーを引き出すツールだ。来月はエラーチェック、ループ、条件分岐、それに強力なツールにも触れる予定だ。


Copyright ゥ 2000, Ben Okopnik
Published in Issue 52 of Linux Gazette, April 2000

Python で構文解析、仮想マシン (By Pramode C E)

コンパイラやインタプリタを作成するというのは難しい。プログラムを書くことの他にもいろいろな知識を要求する。Python のユーザとして今学んでいるものを Python で試してみようと思う。でもオブジェクト指向やガベージコレクションなど高度な話題ではなく非常に初歩的なものだ。例えば次のようなコマンドを実行するようなものだ。


1+2*3-4

1/2+3-4/5

.....

最初はこのような式を読み込んで処理をし、次は構文解析木を使い、最後は仮想マシンへの命令を作成してディスクから必要に応じて動作させるようにしたい。


E ::= T { ADDOP T }

T ::= F { MULOP F }

F ::= 0 | 1 | 2 | 3 | .....

ADDOP ::= + | -

MULOP ::= * | /

まず数学の式を上のように表してみる。E は式、T は項、F は要素だ。{} の中は0個以上の繰り返しとなる。これを Python で実行するコードは次のようなものだ。

#--------------------単純な式の評価---------------#



import re, string

Inputbuf = []

	

# トークンは数字か演算子 

# プログラムの main はinput から1行ずつ読み込み

# Inputbuf という配列に保存する

# 関数 gettoken() はこの配列から個々のトークンを返す



def gettoken(): 

	global Inputbuf

	p = re.search('^\W*[\+\-\*/]|^\W*[0-9]+', Inputbuf)

	token = p.string[p.regs[0][0]:p.regs[0][1]]

	token = string.strip(token)

	if token not in ['+', '-', '*', '/']:

		token = int(token)

	Inputbuf = Inputbuf[p.regs[0][1]:]

	return token

	



# lookahead() はインプットストリームを調べ

# 次のインプットトークンを返す

	

def lookahead():

	global Inputbuf

	try:

		p = re.search('^\W*[\+\-\*/]|^\W*[0-9]+', Inputbuf)

		token = p.string[p.regs[0][0]:p.regs[0][1]]

		token = string.strip(token)

		if token not in ['+', '-', '*', '/']:

			token = int(token)

		return token

	except:

		return None



	

def factor():

	return gettoken()





def term():

	e1 = factor()

	tmp = lookahead()

	while (tmp in ['*', '/']):

		gettoken()

		if (tmp == '*'):

			e1 = e1 * factor()

		else:

			e1 = e1 / factor()

		tmp = lookahead()



	return e1



	

def expression():

	e1 = term()

	tmp = lookahead()

	while (tmp in ['+', '-']):

		gettoken()

		if (tmp == '+'):

			e1 = e1 + term()

		else: 

			e1 = e1 - term()

		tmp = lookahead()

	

	return e1



	

def main():

	global Inputbuf

	Inputbuf = raw_input()

	print expression()



	

if __name__=='__main__':

	main()



上の例は単純に数学の式を評価するだけのものだ。これを構文解析木を作成できるように修正する。式 1+2*3 の構文解析木は次のようになる。

			+

		       / \

		      /   \

		     1     *

		     	  / \

		         /   \

                         2   3	     

項分解析木はボトムズアップで作成される。関数 factor は数字を持ったノードを作成し、左右のノードを NULL ポインタで作成しノードを返す。関数 expression() は演算子のノードで "+" や "-" を格納し左右のノードには term() が返す数字へのポインタを保持する。term() の動作も同様だ。

#--------------------構文解析木の作成---------------------#



# gettoken() と lookahead() は最初の例と同じ



NULL = 0

import re, string

Inputbuf = []

	

class Tree:

	pass

	

def factor():

	newnode = Tree()

	newnode.number = gettoken()

	newnode.left = newnode.right = 0

	return newnode

	

def term():

	left = factor()

	tmp = lookahead()

	while (tmp in ['*', '/']):

		gettoken()

		right = factor()

		newnode = Tree()

		newnode.op = tmp

		newnode.left = left

		newnode.right = right

		left = newnode

		tmp = lookahead()



	return left

	

def expression():

	left = term()

	tmp = lookahead()

	while (tmp in ['+', '-']):

		gettoken()

		right = term()

		newnode = Tree()

		newnode.op = tmp

		newnode.left = left

		newnode.right = right

		left = newnode

		tmp = lookahead()

	

	return left

	

def treeprint(ptree):

	if (ptree):

		try:

			print ptree.op

		except:

			print ptree.number

		treeprint(ptree.left)

		treeprint(ptree.right)

		

def main():

	global Inputbuf

	Inputbuf = raw_input()

	ptree = expression()

	return ptree

	

if __name__=='__main__':

	ptree = main()

	treeprint(ptree)

上記の構文解析木は再帰関数により評価されるが今回はスタックマシンという仮想マシンを使って処理をしてみよう。このマシンの命令は単純だ。数字をスタックに積み、二つの数字を加算、乗算・・・するというものだ。式 1+2*3 は次のようなコードを生成する。


push 1 

push 2 

push 3

mul 

add

Push, mul, add などは配列に格納された命令だ。配列の命令は直接実行され、配列の要素に格納された関数やディスクにファイルとして保存されている関数が実行される。筆者の書いたコードはこのように動作する。引数なしでプログラムを実行するとキーボードから式を読み込み、仮想マシン用のコードを作成し実行する。コードは "code.out" というファイル名でディスクに保存されるので "code.out" を引数にプログラムを起動するとキーボードからの入力なしで実行される。



import re, string, sys, pickle

# プログラム中に存在しない関数は上記のプログラムからコピーする



NULL = 0

Inputbuf = []



NCODE = 100

NSTACK = 100

Code = [] 

Stack = [0] * NSTACK

Pc = 0

Stackp = 0



class Tree:

	pass

	

class CodeItem:

	pass

	

def initcode():

	global Code

	for i in range(0, NCODE):

		t = CodeItem()

		Code.append(t)



	

def pushop():

	global Stack, Stackp, Code, Pc

	

	Stack[Stackp] = Code[Pc].number

	Stackp = Stackp + 1

	Pc = Pc + 1

	

	

def addop():

	global Stack, Stackp, Code, Pc

	

	Stackp = Stackp - 1

	right = Stack[Stackp]

	Stackp = Stackp - 1

	left = Stack[Stackp]

	Stack[Stackp] = left + right

	Stackp = Stackp + 1



# subop, mulop, divopをここで宣言する

	

	

def generate(codep, ptree):

	try:

		# 'number' という項目が存在しないと

	        # 例外が発生する



		n = ptree.number 

		Code[codep].op = pushop

		codep = codep + 1

		Code[codep].number = n

		codep = codep + 1

		return codep

	except:

		if (ptree.op == '+'):

			codep = generate(codep, ptree.left)

			codep = generate(codep, ptree.right)

			Code[codep].op = addop

			codep = codep + 1

			return codep

			

		# elif (ptree.op == '-'): ここに '-', '*', '/' 等の

                # コードを書く

               

			

def eval(ptree): # 命令を作成して実行

	global Pc, Stackp, Code, Stack

	Pc = generate(0, ptree)

	Code[Pc].op = NULL

	

	Stackp = 0

	Pc = 0

	while Code[Pc].op != NULL:

		tmp = Pc

		Pc = Pc + 1

		Code[tmp].op()

	return Stack[0]

	

	

def eval2():    # 読み込まれたコードを直接実行

	global Pc, Stackp, Code, Stack

	

	Stackp = 0

	Pc = 0

	while Code[Pc].op != NULL:

		tmp = Pc

		Pc = Pc + 1

		Code[tmp].op()

	return Stack[0]

	

	

def main():

	global Inputbuf, Code

	

	try:

		f = open(sys.argv[1])

		Code = pickle.load(f)

		f.close()

		result = eval2()

		print 'result is:', result

		return result

	except:

		print 'Not opening code file, reading from k/b'

		initcode()

		Inputbuf = raw_input()

		ptree = expression()

		result = eval(ptree)

		f = open('code.out', 'w')

		pickle.dump(Code, f)

		print 'Code dumped in a file called dat'

		print 'result is:', result

		return result

		



if __name__=='__main__':

	result = main()





"generate()" と "eval()" は非常に重要な関数だ。"gererate()" は仮想マシン用のコードを作成し配列に格納する。"eval()" はスタックを使用して配列に格納された命令を実行する。

このコードを拡張して変数、アサインメント、goto や if などを組み込むことも可能だ。そうすると単純な Basic のような言語になる。


Copyright © 2000, Pramode C E
Published in Issue 52 of Linux Gazette, April 2000