Serguey Zefirov ([info]thesz) wrote,
@ 2006-08-21 19:55:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:haskell, rsdn, ассемблер, языки

Дорвался до RSDN.

import qualified Data.Map as M

import Control.Monad.State

-- Типа, команда.
step = modify (\(a,is,labels,alllabels) -> (a+1,("s "++show a):is,labels,alllabels))

-- Типа, определить метку.
label name = modify (\(a,is,labels,alllabels) -> (a,is,upd a labels,alllabels))
    where
        upd addr labels = case M.lookup name labels of
            Just _ -> error $ "Label "++name++" redefined."
            _ -> M.insert name addr labels

-- Переход, типа. Вычисление дистанции до метки, будь то вперед или назад.
-- Ну, и симуляция инструкции.
jump name = modify (\(a,is,labels,alllabels) -> (a+1,d a alllabels:is,labels,alllabels))
    where
        d a alllabels = case M.lookup name alllabels of
            Nothing -> error $ "Undefined "++name
            Just la -> "j "++show a++" + "++show (la-a)

-- Как запустить вычисление ассемблерных команд:
prog p = let (_,is,alllabels,_) = execState p (0,[],M.empty,alllabels) in reverse is

-- Типа, программа на ассемблере:
p = do
    label "a"
    step
    step
    jump "b"
    jump "a"
    step
    step
    label "b"

-- Типа, проверка результатов вычислений смещений:
testp = prog p
Результат работы:
*Main> testp
["s 0","s 1","j 2 + 4","j 3 + -3","s 4","s 5"]
Вот меня интересует, сложно ли сделать похожий ассемблер с помощью любого императивного языка?

Товарищи с RSDN "проблем не видят." ;)


(Post a new comment)


[info]the_lazy_guy
2006-08-21 04:23 pm UTC (link)
А ы чём проблема? Реализация на C++ будет практически 1 в 1, хотя и чуть более многословна (но не больше, чем в полтора раза по строчкам). Пусть и без монад, благо состояния в C++ явные.

(Reply to this)(Thread)


[info]the_lazy_guy
2006-08-21 05:10 pm UTC (link)
Хотя let (_, _, allLabels, _) = execState p (_, _, _, allLabels) это красиво. Только сейчас просёк фишку. Тем не менее, в плюсах можно прекрасно обойтись без этого (как, впрочем и в хаскелле)

(Reply to this)(Parent)(Thread)


[info]thesz
2006-08-21 05:52 pm UTC (link)
Вот мне и интересно, можно ли. ;)

Я даже критерий введу - если код на Хаскеле разбухнет менее, чем в три раза - значит, можно. ;)

В плюсах такая конструкция просто-напросто нежизнеспособна. Можешь прикинуть. ;)

(Reply to this)(Parent)(Thread)


[info]the_lazy_guy
2006-08-21 06:37 pm UTC (link)
В плюсах нежизнеспособна (ибо не ленивы). Именно поэтому без неё все умеют прекрасно обходиться. А вот не хаскелле, вариант без подобных трюков%
import qualified Data.Map as M

import Control.Monad.State

step = modify (\(a,is,labels) -> (a+1,(\_ -> "s "++show a):is,labels))

label name = modify (\(a,is,labels) -> (a,is,upd a labels))
    where
        upd addr labels = case M.lookup name labels of
            Just _ -> error $ "Label "++name++" redefined."
            _ -> M.insert name addr labels

jump name = modify (\(a,is,labels) -> (a+1,d a:is,labels))
    where
        d a = \allLabels -> case M.lookup name allLabels of
            Nothing -> error $ "Undefined "++name
            Just la -> "j "++show a++" + "++show (la-a)

prog p = let (_,is,labels) = execState p (0,[],M.empty) in
	map (\x -> x labels) (reverse is)

p = do
    label "a"
    step
    step
    jump "b"
    jump "a"
    step
    step
    label "b"

testp = prog p


Вот теперь на C++ всё будет 1 в 1. Только состояние в p мы будем не неявно протягивать, а через специальный объект.

В принципе вариант на хаскелле будет несколько мощнее, потому что можно сделать нечто вроде.

a = do
    label "c"
    step
    jump "a"

b = do
    label "c"
    step
    jump "b"

p pieceOfCode = do
    step
    jump "c"
    step
    label "a"
    step
    label "b"
    step
    pieceOfCode

....
    let code = if (...) then p a else p b


То есть получившиесе программы являются first-calss citizens и их изначально легко комбинировать. В C++ придётся писать небольшую обёртку, чтобы один кусок можно было прозрачно вставить в другой. Тем не менее, этого не было в ТЗ.

(Reply to this)(Parent)(Thread)


[info]thesz
2006-08-21 06:48 pm UTC (link)
В общем, понятно.

Мне такая вещь в голову не пришла.

Что самое интересное, получается из моего кода тривиальной трансформацией. Что еще более интересно, в процессе поиска дурацкого бага я это преобразование почти провел. У меня была State Monad с дополнительным параметром future. ;)

Он оказался ненужным. ;)

(Reply to this)(Parent)


[info]_adept_
2006-08-22 06:33 am UTC (link)
А можно ссылочку на RSDN?

Тамошним товарищам указывалось на волшебную строчку? :)

(Reply to this)(Thread)


[info]thesz
2006-08-22 08:56 am UTC (link)
Один ее разглядел. А за ним - и остальные. ;)

http://rsdn.ru/Forum/Message.aspx?mid=2068993&only=1 - мой пост.
http://rsdn.ru/Forum/Message.aspx?mid=2069532&only=1 - вариант FR на Питоне (использовал лямбду;).
http://rsdn.ru/Forum/Message.aspx?mid=2069409&only=1 - вариант Vermicious Knid по следам FR.

(Reply to this)(Parent)


Create an Account
Forgot your login?
Login w/ OpenID
English • Español • Deutsch • Русский…