LuaでBrainfuckインタープリターを作成する

Luaロゴ

彼の人生の各プログラマーは、多くの言語を学んで、いくつかの言語に特化し、長い間働き続け、残りは通過します。 さまざまな理由で。 仕事をする地域をすでに決めている場合、新しい言語の学習に時間を費やすことは価値がありますか? 個人的には、費用がいくらなのかは確かですが、コンピューターサイエンスの基礎知識は重要であり、どの言語でコードを記述することは重要ではないと多くの人が言うでしょう。 本質的にはそうです。 それでも、言語を学ぶことは興味深く有用です。



ルア。 言語の簡単な歴史。


言語Lua([lua]、port。「Moon」)は、1993年に比較的遠い場所で発生しました。 Roberto Jerusalem(Roberto Ierusalimschy)、Luiz Henrique de Figueiredo(Luiz Henrique de Figueiredo)、Waldemar Celes(Waldemar Celes)、リオデジャネイロ聖公会カトリック大学のコンピューターグラフィックス技術開発チーム(Tecgraf)のメンバーにより作成されましたリオデジャネイロ大学)ブラジル。 これは、命令型言語と関数型言語のプロパティを組み合わせ、オブジェクト指向のプロパティを持つスクリプト言語です。 Scheme、SNOBOL、JavaScript、C / C ++などの影響を受けます。 その結果、埋め込み可能な、拡張が容易な、シンプルな構文のスクリプト言語が完成しました。

長年にわたって、Luaは組み込み言語として正確に人気を博してきました。多くのプログラムが、さらに多くのゲームで使用されています。 たとえば、Vim(バージョン7.3以降)、World of Warcraft、Ragnarok Online など



言語について少し


これは、 www.lua.ru / doc (rus)およびwww.lua.org/manual/5.1(eng )に最適に記述されています。



Luaをインストールする


Luaはここからダウンロードできますluabinaries.sourceforge.net/download.html

Linuxの場合(ただし、Ubuntu 10.04リポジトリにはすでに3つのバージョンがあります)

sudo apt-get install lua5.1 sudo apt-get install lua50 sudo apt-get install lua40
      
      







または、ソースからビルドします(lua5.1パッケージの名前はまったく明らかではなかったため、ビルドする必要がありました)。

 cd /tmp wget http://www.lua.org/ftp/lua-5.1.4.tar.gz tar -xf lua-5.1.4.tar.gz cd lua-5.1.4 sudo apt-get install build-essential libreadline5-dev make linux test sudo checkinstall --fstrans=no --install=no --pkgname=lua --pkgversion "5.1.4" --default sudo dpkg -i lua_5.1.4-1_i386.deb lua -v >>> Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
      
      







素晴らしい、今、あなたは楽しんで始めることができます。



Hello World!


どこで言語学習を始めますか? Hello world! 面白くない。 インタプリタを書きましょう。 非常にシンプルで非常に興味深い、素晴らしいBrainfuck言語があります。 脳を伸ばすのに役立ちます。



タスクを設定します。





Brainfuckの説明


Urban Mullerによる「古典的な」Brainfuckでは、セルサイズは1バイト、セルの数は30,000、入力/出力はバイトごと、命令の数は8個です。 以下に簡単な説明を示します。







書く


小さく始めましょう:作業用のディレクトリ、brainfuck.luaファイルを作成し、実行可能にします



 #!/usr/bin/env lua -- Lua Brainfuck Interpreter Brainfuck = { -- validate source -- Return 1 if closing bracket(s) missing. -- Return 2 if opening bracket(s) missing. -- Return 0 otherwise. validate = function (self, source) return 0 end, -- debug function showError = function (self, errorCode) end, -- brainfuck function brainfuck = function (self, source) end, }
      
      







また、hello.bファイルを作成します(brainfuckのコード。HelloWorld!を画面に表示します。テストに必要です)

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.







さて、これですべての準備が整いました。



1.ファイルからBrainfuckコードを読み取ります。


インタープリターに、コマンドラインで名前が渡されたファイルからコードを実行させます

./brainfuck.lua hello.b





ドキュメントは、Luaがパラメーターをarg配列に入れることを教えてくれます



 -- start here if arg[1] then -- read source from file in arg[1] source = io.input(arg[1]):read("*a") -- get error code (0 == no error) errorCode = Brainfuck:validate(source) -- if no error run source else show error if errorCode == 0 then Brainfuck:brainfuck(source) else Brainfuck:showError(errorCode) end else print("Usage: ./brainfuck.lua script") Brainfuck:showError(3) end
      
      







2.基本的なコード検証




 -- validate source -- Return 1 if closing bracket(s) missing. -- Return 2 if opening bracket(s) missing. -- Return 0 otherwise. validate = function (self, source) local i, errorCode, l = 0, 0, 0 for i = 1, string.len(source), 1 do -- [ 91 if string.byte(source, i) == 91 then l = l + 1 -- ] 93 elseif string.byte(source, i) == 93 then l = l - 1 if l < 0 then return 2 end end end if l > 0 then return 1 elseif l < 0 then return 2 else return 0 end end, -- debug function showError = function (self, errorCode) if errorCode == 1 then print("Error: Closing bracket(s) missing.") elseif errorCode == 2 then print("Error: Opening bracket(s) missing.") elseif errorCode == 3 then print("Error: No source file.") else print("Error: Unknown error code.") end end,
      
      







3. Brainfuckコードの実行




 -- brainfuck function brainfuck = function (self, source) -- memSize: Brainfuck memory size (30k) -- maxVal: Max memory value (255) byte -- mem: Memory table (array) -- pointer: default 0 -- l: default 0. braket level counter local memSize, maxVal, mem, pointer, l = 30000, 255, {}, 0, 0 -- clear memory for i = 0, memSize, 1 do mem[i] = 0 end -- execute program i = 0 while i <= string.len(source) do i = i + 1 -- + 43 C eqv ++(*p); if string.byte(source, i) == 43 then if mem[pointer] < maxVal then mem[pointer] = mem[pointer] + 1 end -- - 45 C eqv --(*p); elseif string.byte(source, i) == 45 then if mem[pointer] > 0 then mem[pointer] = mem[pointer] - 1 end -- , 44 C eqv *p = getchar(); elseif string.byte(source, i) == 44 then mem[pointer] = string.byte(io.stdin:read('*l'), 1) -- . 46 C eqv putchar(*p); elseif string.byte(source, i) == 46 then io.write(string.char(mem[pointer])) -- < 60 C eqv --p; elseif string.byte(source, i) == 60 then pointer = pointer - 1 if pointer < 0 then pointer = 0 end -- > 62 C eqv ++p; elseif string.byte(source, i) == 62 then pointer = pointer + 1 if pointer > memSize then pointer = memSize end -- [ 91 C eqv while (*p) { elseif string.byte(source, i) == 91 then if mem[pointer] == 0 then while (string.byte(source, i) ~= 93) or (l > 0) do i = i + 1 if string.byte(source, i) == 91 then l = l + 1 end if string.byte(source, i) == 93 then l = l - 1 end end end -- ] 93 C eqv } elseif string.byte(source, i) == 93 then if mem[pointer] ~= 0 then while (string.byte(source, i) ~= 91) or (l > 0) do i = i - 1 if string.byte(source, i) == 91 then l = l - 1 end if string.byte(source, i) == 93 then l = l + 1 end end end else -- print("Unknown symbol") -- return end -- print("Debug: l="..l.." cmd="..string.char(string.byte(source, i))) end end,
      
      







完成版



できた これで例を実行して、すべてが機能することを確認できます。 ご覧のとおり、Luaはスタンドアロンでの使用に非常に適しています)



字下げができないことをおaびします。 強調表示で失われました。

Luaに関するブログを見つけられなかったため、Abnormal programmingに投稿します。

Luaに関する記事がコミュニティにとって興味深いものである場合、私はもっと書くことができます



有用な文献





All Articles