Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

Brainfuck на AppleScript

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

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

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

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

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

#!/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 комментариев
indeec17 2011

а, в общем-то, действительно... чем ещё себя развлечь в 4 часа ночи? =)

viy (v-i-y.livejournal.com) 2011

Женя, там что действительно в языке используются ≤ и ≠?
Ooo.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для v-i-y.livejournal.com:

Да, действительно :) Причём, можно набрать просто „<=“, AppleScript Editor сам поправит.

А ещё, например, используются кавычки-ёлочки :)

Евгений Степанищев (bolknote.ru) 2011

Комментарий для indeec17:

а, в общем-то, действительно... чем ещё себя развлечь в 4 часа ночи? =)

Ну, правда, чем? :))

viy (v-i-y.livejournal.com) 2011

Комментарий для Евгения Степанищева:

Мда, любит эпл отличаться, даже если это странно и неудобно.
Ведь правда же будет неудобно, если редактировать исходник не в их редакторе?

Евгений Степанищев (bolknote.ru) 2011

Комментарий для v-i-y.livejournal.com:

Ведь правда же будет неудобно, если редактировать исходник не в их редакторе?

Ну, мне неудобно не будет, у меня эти клавиши есть в раскладке Бирмана (рекламирую!). Кстати и на родной, Маковской раскладке они, возможно, как-то вводятся.

Но кому-то, наверное, будет неудобно. Правда, как пример, „≠“ можно записать как «is not», к примеру. Там масса альтернатив: http://developer.apple.com/library/mac/#documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_operators.html#//apple_ref/doc/uid/TP40000983-CH5g-124070

Евгений Степанищев (bolknote.ru) 2011

Комментарий для v-i-y.livejournal.com:

Ага, в доке по AppleScript написано:

≠ (Option-equal sign on U.S. keyboard)
≥ (Option-period on U.S. keyboard)
≤ (Option-comma on U.S. keyboard)

mixael 2011

Неужели ты теперь фанат AppleScript-а??? Нидоного ругательства я как-то не заметил) ;)

Евгений Степанищев (bolknote.ru) 2011

Комментарий для mixael:

Неужели ты теперь фанат AppleScript-а??? Нидоного ругательства я как-то не заметил) ;)

Не, ну что ты :) Я и на языке CMD/BAT-файлов что-то писал довольно длинное. Пример: http://bolknote.ru/all/3173/

AppleScript, наверное, неплох для непрограммистов, но для программиста он неудобен. Ведь не зря в языках используют сокращённые конструкции, скобочки там разные, доллары. Так быстрее и удобнее писать, но, да, это надо помнить.

В общем, AppleScript, вроде как, язык для того, чтобы иногда написать что-то короткое. «Вроде как» — потому что всё равно надо помнить массу вещей. Да, это почти английский, но, например, «set Var to Var plus one» не работает.

praeivis (praeivis.lt) 2011

Комментарий для Евгения Степанищева:

Ну, правда, чем? :))

Некоторые какбы намекает что можно было надеть униформу что на аватаре и раздудить жену =)

Евгений Степанищев (bolknote.ru) 2011

Комментарий для praeivis.lt:

Жене вставать в шесть, я же не эгоист. И будить надо, когда хочется чего-то определённого, а не когда скучно.