Главная | Регистрация | Вход | RSSВоскресенье, 15.06.2025, 21:36

НеПотеряйка

Меню сайта
Наш опрос
Что для Вас "МОДЕРНИЗАЦИЯ ОБРАЗОВАНИЯ"?
Всего ответов: 210
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Дневник

Главная » 2012 » Март » 02 » Пишем интерпретатор Brainfuck на Lua
Пишем интерпретатор Brainfuck на Lua
22:33

Пишем интерпретатор Brainfuck на Lua

http://habrahabr.ru/blogs/crazydev/112919/#habracut

Каждый программист за свою жизнь успевает изучить множество языков, в нескольких из них специализируется и продолжает работать продолжительное время, а остальные проходят мимо. По разным причинам. Стоит ли тратить время на изучение новых языков, когда уже определился с областью в которой будешь работать? Лично я уверен что стоит, хотя, быть может, многие скажут что важны фундаментальные знания в computer science, а на каком языке писать код не критично. В сущности так и есть. И тем не менее изучать языки интересно и полезно.

Lua. Краткая история языка.

Своё начало язык Lua ([луа], порт. «луна») берёт в относительно далёком 1993 году. Его создали Роберто Иерусалимши (Roberto Ierusalimschy), Луис Энрике де Фигуэйредо (Luiz Henrique de Figueiredo) и Вальдемар Селес (Waldemar Celes), в то время члены группы разработки технологии компьютерной графики (Tecgraf) Епископального католического университета Рио-де-Жанейро (Pontifical Catholic University of Rio de Janeiro) в Бразилии. Это скриптовый язык, сочетающий свойства императивных и функциональных языков и обладающий объектно-ориентированными свойствами. Испытал влияние 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 есть аж три версии)
sudo apt-get install lua5.1
sudo apt-get install lua50
sudo apt-get install lua40

Либо собрать из исходников (название пакета lua5.1 было совсем не очевидно, поэтому пришлось собрать)
cd /tmp
wget 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 © 1994-2008 Lua.org, PUC-Rio

Замечательно, теперь можно начинать развлекаться.

Hello World!

С чего начать изучение языка? С Hello world! не интересно. Давайте напишем интерпретатор. Есть такой замечательный язык Brainfuck, очень простой и очень интересный. Помогает размять мозг.

Ставим задачу:
  • Чтение brainfuck кода из файла
  • Базовая валидация кода
  • Исполнение Brainfuck кода


Описание Brainfuck

В «классическом» Brainfuck, описанном Урбаном Мюллером, размер ячейки — один байт, количество ячеек 30 000, ввод/вывод происходит побайтово, количество инструкций 8 шт. ниже краткое описание:
> перейти к следующей ячейке
< перейти к предыдущей ячейке
+ увеличить значение в текущей ячейке на 1
— уменьшить значение в текущей ячейке на 1
. напечатать значение из текущей ячейки
, ввести извне значение и сохранить в текущей ячейке
[ если значение текущей ячейки нуль, перейти вперёд по тексту программы на ячейку, следующую за соответствующей ] (с учётом вложенности)
] если значение текущей ячейки не нуль, перейти назад по тексту программы на символ [ (с учётом вложенности)

Пишем

Начнём с малого: создадим каталог для работы, файл brainfuck.lua в нём, сделаем его исполняемым

  1. #!/usr/bin/env lua
  2. -- Lua Brainfuck Interpreter
  3.  
  4. Brainfuck =
  5. {
  6. -- validate source
  7. -- Return 1 if closing bracket(s) missing.
  8. -- Return 2 if opening bracket(s) missing.
  9. -- Return 0 otherwise.
  10. validate = function (self, source)
  11. return 0
  12. end,
  13.  
  14. -- debug function
  15. showError = function (self, errorCode)
  16.  
  17. end,
  18.  
  19. -- brainfuck function
  20. brainfuck = function (self, source)
  21.  
  22. end,
  23. }


Также создадим файл hello.b (код на brainfuck. выводит Hello World! на экран. нужен для тестов)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

Ну, теперь всё готово.

1. Чтение brainfuck кода из файла.

Пусть наш интерпретатор выполняет код из файла имя которого передано в командной строке
./brainfuck.lua hello.b
Документация скажет нам что Lua помещает параметры в массив arg

  1. -- start here
  2. if arg[1] then
  3. -- read source from file in arg[1]
  4. source = io.input(arg[1]):read("*a")
  5. -- get error code (0 == no error)
  6. errorCode = Brainfuck:validate(source)
  7. -- if no error run source else show error
  8. if errorCode == 0 then
  9. Brainfuck:brainfuck(source)
  10. else
  11. Brainfuck:showError(errorCode)
  12. end
  13. else
  14. print("Usage: ./brainfuck.lua script")
  15. Brainfuck:showError(3)
  16. end
  17.  


2. Базовая валидация кода


  1. -- validate source
  2. -- Return 1 if closing bracket(s) missing.
  3. -- Return 2 if opening bracket(s) missing.
  4. -- Return 0 otherwise.
  5. validate = function (self, source)
  6. local i, errorCode, l = 000
  7.  
  8. for i = 1string.len(source)1 do
  9. -- [ 91
  10. if string.byte(source, i) == 91 then
  11. = l + 1
  12. -- ] 93
  13. elseif string.byte(source, i) == 93 then
  14. = l - 1
  15. if l < 0 then return 2 end
  16. end
  17. end
  18.  
  19. if l > 0 then
  20. return 1
  21. elseif l < 0 then
  22. return 2
  23. else
  24. return 0
  25. end
  26. end,
  27.  
  28. -- debug function
  29. showError = function (self, errorCode)
  30. if errorCode == 1 then
  31. print("Error: Closing bracket(s) missing.")
  32. elseif errorCode == 2 then
  33. print("Error: Opening bracket(s) missing.")
  34. elseif errorCode == 3 then
  35. print("Error: No source file.")
  36. else
  37. print("Error: Unknown error code.")
  38. end
  39. end,


3. Исполнение Brainfuck кода


  1. -- brainfuck function
  2. brainfuck = function (self, source)
  3. -- memSize: Brainfuck memory size (30k)
  4. -- maxVal: Max memory value (255) byte
  5. -- mem: Memory table (array)
  6. -- pointer: default 0
  7. -- l: default 0. braket level counter
  8. local memSize, maxVal, mem, pointer, l = 30000255{}00
  9.  
  10. -- clear memory
  11. for i = 0, memSize, 1 do mem[i] = 0 end
  12.  
  13. -- execute program
  14. = 0
  15. while i <= string.len(source) do
  16. = i + 1
  17. -- + 43 C eqv ++(*p);
  18. if string.byte(source, i) == 43 then
  19. if mem[pointer] < maxVal then
  20. mem[pointer] = mem[pointer] + 1
  21. end
  22.  
  23. -- - 45 C eqv --(*p);
  24. elseif string.byte(source, i) == 45 then
  25. if mem[pointer] > 0 then
  26. mem[pointer] = mem[pointer] - 1
  27. end
  28.  
  29. -- , 44 C eqv *p = getchar();
  30. elseif string.byte(source, i) == 44 then
  31. mem[pointer] = string.byte(io.stdin:read('*l')1)
  32.  
  33. -- . 46 C eqv putchar(*p);
  34. elseif string.byte(source, i) == 46 then
  35. io.write(string.char(mem[pointer]))
  36.  
  37. -- < 60 C eqv --p;
  38. elseif string.byte(source, i) == 60 then
  39. pointer = pointer - 1
  40. if pointer < 0 then pointer = 0 end
  41.  
  42. -- > 62 C eqv ++p;
  43. elseif string.byte(source, i) == 62 then
  44. pointer = pointer + 1
  45. if pointer > memSize then pointer = memSize end
  46.  
  47. -- [ 91 C eqv while (*p) {
  48. elseif string.byte(source, i) == 91 then
  49. if mem[pointer] == 0 then
  50. while (string.byte(source, i) ~= 93) or (> 0) do
  51. = i + 1
  52. if string.byte(source, i) == 91 then l = l + 1 end
  53. if string.byte(source, i) == 93 then l = l - 1 end
  54. end
  55. end
  56.  
  57. -- ] 93 C eqv }
  58. elseif string.byte(source, i) == 93 then
  59. if mem[pointer] ~= 0 then
  60. while (string.byte(source, i) ~= 91) or (> 0) do
  61. = i - 1
  62. if string.byte(source, i) == 91 then l = l - 1 end
  63. if string.byte(source, i) == 93 then l = l + 1 end
  64. end
  65. end
  66. else
  67. -- print("Unknown symbol")
  68. -- return
  69. end
  70. — print("Debug: l="..l.." cmd="..string.char(string.byte(source, i)))
  71. end
  72.  
  73. end,


Готовая версия

Готово. Теперь можно запустить пример и убедиться что всё работает. Как видите Lua вполне пригоден для standalone использования)

Прошу прощения за отсутствие отступов. Утеряны при подстветке.
Блога о Lua не нашел, поэтому размещу в Ненормальное программирование.
Если статьи о Lua интересны сообществу могу написать ещё

Полезная литература

Просмотров: 1623 | Добавил: i_elf | Рейтинг: 0.0/0 |
Всего комментариев: 2
2 GenwewofTotk  
0
windows 7 key viewer windows 7 student product key
windows 7 professional 32 bit key

1 GenwewofTotk  
0
windows 7 product key sticker windows 7 professional genuine key
window 7 cd key

Имя *:
Email *:
Код *:
Форма входа
Поиск по сайту
Google Scholar

Мои сайты
  • Создать сайт
  • Творческий учитель
  • Сайт ООАКМР
  • Школьный сайт
  • Информатика учебник (будет)
  • Математические основы информатики
  • РоЖдЕнИе ИдЕи
  • ВиРтУаЛьНыЙ мУзЕй
  • О тебе и обо мне

  • Copyright MyCorp © 2025
    Бесплатный хостинг uCoz