Brainfuck на AppleScript

Для развлечения написал интерпретатор языка Brainfuck на AppleScript.

Особенности: для ввода программы используется текстовое поле, которое выглядит как однострочное, но на деле понимает многострочный текст. Операция «,» у меня с буфером, это значит, что при запросе можно вводить сразу строку, при надобности интерпретатор сам будет брать оттуда значения. Если их не хватит, запросит ещё.

AppleScript медленный язык, следовательно и получившийся интерпретатор медленный (никаких оптимизаций я не делал), лучше всего на нём запускать небольшие программы. Например, «Hello, world»:

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

Не уверен, что нигде не ошибся (всё-таки время четвёртый час ночи), но даже вложенные циклы на программах, которые я прогонял, работают нормально.

Интерпретатор Brainfuck на AppleScript.

#!/usr/bin/osascript
-- AppleScript Brainfuck interpreter
-- Evgeny Stepanischev 1 Jul 2011 //bolknote.ru

set Cells to {}
repeat 30000 times
    set end of Cells to 0
end repeat

display dialog "Enter your BF program" default answer ""
set Bf to text items of text returned of result

set Pointer to 1
set CmdPointer to 1
set Output to ""
set Input to {}
set Stack to {}

repeat while CmdPointer ≤ (count of Bf)
    set Cmd to item (CmdPointer) of Bf
    
    if Cmd is equal to ">" then
        set Pointer to Pointer + 1
        if Pointer > 30000 then set Pointer to 1
        
    else if Cmd is equal to "<" then
        set Pointer to Pointer - 1
        if Pointer < 1 then set Pointer to 30000
        
    else if Cmd is equal to "+" then
        set Val to (item (Pointer) of Cells) + 1
        if Val is greater than 255 then set Val to 0
        copy Val to item (Pointer) of Cells
        
    else if Cmd is equal to "-" then
        set Val to (item (Pointer) of Cells) - 1
        if Val is less than 0 then set Val to 255
        copy Val to item (Pointer) of Cells
        
    else if Cmd is equal to "." then
        set Output to Output & (ASCII character item (Pointer) of Cells)
        
    else if Cmd is equal to "," then
        if Output ≠ "" then
            display alert Output
            set Output to ""
        end if
        
        if Input is {} then
            display dialog "Enter one or more characters" default answer ""
            set Res to text returned of result
            
            set item (Pointer) of Cells to ASCII number of character 1 of Res
            
            try
                set Input to rest of text items of Res
            end try
            
        else
            set item (Pointer) of Cells to ASCII number of item 1 of Input
            set Input to rest of Input
        end if
        
    else if Cmd is equal to "[" then
        if item (Pointer) of Cells = 0 then
            set CmdPointer to CmdPointer + 1
            set Deep to 1
            
            repeat while CmdPointer ≤ (count of Bf)
                set Cmd to item (CmdPointer) of Bf
                
                if Cmd is equal to "[" then
                    set Deep to Deep + 1
                else if Cmd is equal to "]" then
                    set Deep to Deep - 1
                    
                    if Deep is 0 then exit repeat
                end if
                
                set CmdPointer to CmdPointer + 1
                
            end repeat
        else
            set Stack to (CmdPointer - 1) & Stack
        end if
    else if Cmd is equal to "]" then
        if item (Pointer) of Cells ≠ 0 then
            copy item (1) of Stack to CmdPointer
        end if
        set Stack to rest of Stack
    end if
    
    set CmdPointer to CmdPointer + 1
end repeat

if Output ≠ "" then
    display alert Output
end if

11 комментариев

Как мне AppleScript

Миша, мой коллега, под постом, где я написал про интерпретатор Brainfuck на AppleScript с беспокойством осведомился, не подсел ли я на AppleScript.

Краткий ответ: нет.

Длинный ответ таков.

Мне непонятно текущее состояние AppleScript. Очевидно, что концепция «пользователь пишет программы на английском» вполне себе ничего. Для непрограммистов это был бы выход. А для программистов такой язык жутко неудобен. По понятными причинам. Программисты привыкли писать много, а на велиречивом AppleScript писать не каждому понравится (не пишу «никому», потому что существует же Objective C). Все эти сокращения в языке — «собачки», доллары и разные скобочки, их нужно помнить, но они здорово экономят время при написании программы и при её чтении. Потому что они короткие и их больше помещается на экране.

Текущее состояние непонятно, потому что цели своей авторы языка не достигли. До сих пор нужно писать «set Var to Var + 1» и нельзя «set Var to Var plus one», какой же это английский? При этом язык уже полтора года не развивается.

То есть проблема «иногда быстро писать мелкие программы» явно пока не решена. Так как для этого «иногда» надо иметь память робота, чтобы вспомнить через несколько месяцев как в этом языке что-то проверить или присвоить. Сам язык ещё ничего, запоминающийся. Но если хочется чего-то чуть более серьёзного, то приходится обращаться к специальному API.

Например, чтобы вызвать текстовый редактор и написать там «Hello», нужно сделать следующее:

tell application "TextEdit"
    activate
    tell application "System Events" to keystroke "hello"
end tell

Я открываю приложение TextEdit (так встроенный в MacOS текстовый редактор называется) и прошу System Events понажимать в редактор несколько клавиш. Выделенное наклонным — это как раз пример такого API. Причём, если написать в кавычки «³˚¹⁄₃¹⁄₂», то программа либо не сделает ничего, либо напечатает в редактор ерунду. Всё устроено так, как будто System Events действительно жмёт клавиши на клавиатуре. А вот эти символы система не знает как ввести. То же будет с китайскими иероглифами, например.

Ещё, когда я только начал знакомиться с AppleScript, у меня было заблуждение, что AppleScript — язык общего назначения, вроде PowerShell или Bash. Ничего подобного, вместо bash в Mac OS есть bash. AppleScript толком не умеет даже получить данные от пользователя, скажем перехватить нажатие клавиши (и нет ничего встроенного, что может ему в этом помочь), а уж о том, как мало он умеет самостоятельно выводить и говорить нечего.

Так что симпатии к языку у меня не появится, думаю. Не для меня он. Но писать я на нём иногда буду, я и на CMD много странного писал в своё время.

2 комментария

«Гонка версий»

Смешно, ей-богу, читать, что «Микрософт» включилась в «гонку номеров версий» браузеров. Мол, вместо того, чтобы выпустить какой-нибудь Internet Explorer 9.1, они выпускают 10. Мне повезло, я был уже в сознании, когда интернет только начинался. Поэтому я помню, что гонку номеров версий «Микрософт» начала!

Пока фирма Netscape выпускала свои бесконечные 1.00, 1.1, 1.22, 2.0, 2.01, 2.02, 3.0, 3.01, 3.02, 3.03, 3.04, 4.0, 4.01, 4.01a, 4.02, 4.03, 4.04, 4.05, 4.06, 4.07, 4.08, 4.5, 4.51, 4.6, 4.61, 4,7, 4.72, 4.73, 4.74, 4.75, 4.76, 4.77, 4.78, 4.79 и 4.8, «Микрософт» выпускала и продолжает выпускать IE 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 5.5, 6, 7, 8, 9 и 10. Причём, последние версии ещё и ноль в конце потеряли.

Версия 1.5 была явным заблуждением, а 4.5 я в список не включил — это отдельная ветка, её для «Мака» делали, так же как и другие, ещё менее известные подверсии для других систем.

23 комментария