Модераторы: LSD

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Попытка сравнить C/Java/C#/Python 
:(
    Опции темы
APM
Дата 21.1.2008, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 13.7.2007

Репутация: нет
Всего: 6



Вот решил попробовать сравнить эти языки. 
Сравнение проводилось на основе времени, которое требуется для сортировки 10000 случайных элементов методом пузырька.
С/С++ - 0,330 сек.
Python - 42 сек
Java - 0,515 сек (код для сортировки даже переписывать не пришлось)
С# - .NET 3.5 - 0,350 сек. 

Результаты довольно странные, получается что С# лишь немного хуже C, а Python отстает почти на два порядка.
Попробуем запустить эту же программу, но увеличим число элементов до 100000, Python естественно не участвует :(
С/С++ - 27,6 сек.
Java - 37,7 сек.
C# - 32, 5 сек.

Для меня такие результаты оказались неожиданность, уж никак не ожидал что на такой задаче С# будет таким шустрым, а Питон так провалится.

У кого какие мнения? =)
PM   Вверх
LSD
Дата 21.1.2008, 14:36 (ссылка) |    (голосов:5) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 9
Всего: 538



Цитата(APM @  21.1.2008,  14:28 Найти цитируемый пост)
У кого какие мнения? =)

1. Есть специальный раздел для тестов.
2. Без исходников, конфигурации и версий компиляторов это не тест, а баловство.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
mr.DUDA
Дата 21.1.2008, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 4
Всего: 232



Поддерживаю предыдущего оратора  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
APM
Дата 21.1.2008, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 13.7.2007

Репутация: нет
Всего: 6



C++ - компилятор из MSVS 2008 Express
C# - .NET 3.5
Java - Jre 1.6
Python - 2.5

Core 2 Duo T5500, 1Gb Ram
PM   Вверх
Ch0bits
Дата 21.1.2008, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 1
Всего: 62



Блин, сортировка пузырьком, не смешите мои подковы!  smile  smile 
PM WWW   Вверх
Lazin
Дата 21.1.2008, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 4
Всего: 154



Питоном что запускал .py или .pyc? И вообще нечего сравнивать по скорости питон и С++(или любой другой язык со статической типизацией), это всеравно что палец известно с чем сравнивать)). У питона другие задачи.

Это сообщение отредактировал(а) Lazin - 21.1.2008, 16:19
PM MAIL Skype GTalk   Вверх
MAKCim
Дата 21.1.2008, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 8
Всего: 207



APM, 
вот сортировка на Python
Код

sorted([randint(0, 0xFFFFFFFF) for x in xrange(0, 10000)])

0.04 секунд
Linux (x86-64, 2.6.18), CPU = C2D 1.86Ghz, PVM 2.5
 smile 

Это сообщение отредактировал(а) MAKCim - 21.1.2008, 17:51


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
APM
Дата 21.1.2008, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 13.7.2007

Репутация: нет
Всего: 6



Я не пытался выполнить сортировку как можно было быстрее, поэтому выбрал самый плохой для этого алгоритм. Затем код был одинаково написан для четырех языков. В итоге получились такие результаты. Я не пытался использовать "фишки", доступные для конкретного языка.
PM   Вверх
Void
Дата 21.1.2008, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 11
Всего: 173



Может мы хотя бы код увидим...


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Sardar
Дата 21.1.2008, 18:54 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 2
Всего: 317



Вы бы ещё сюда Haskell со строковыми и monadic I/O приписали  smile 
Простые истины (из пальца smile ):
  • пустая итерация в миллиард раз (к примеру инкремент целого) - быстрей на асме (при условии что итерация реально выполняется). 
  • фильтрация растровой картинки, представленной массивом пикселей быстрей на C
  • работа с массой строковых операций, юникод, без лимитов на размеры и беря во внимание лень программиста - вероятно PHP6/Java/C#. Да, на C можно быстро, но все тупо копируют байтовые массивы ;-)
  • собрать огромное DOM дерево с массой дополнительных интерфейсов, в итоге граф так на 10.000 нод - однозначно все со сборщиком мусора, т.е. Java/C#
  • IDE с массой взможностей, анализ кода на лету, плагины и т.д. (читаем NetBeans6) - однозначно Java/C#. Кто не уверен, запускайте NetBeans6 - штука реактивная.
  • парсеры, текстовы ввод (гибкость/скорость) - вероятно OCaml, Perl6
Всё упирается в лень программиста, если он робот, то и на ASM'е сможет шустрый Mozilla/FireFox написать (шанс нулевой, от лени будет пользоваться простейшими алгоритмами, в итоге будет тормозить). Сейчас лиса до жути задумчива, аргумент против C++ (за работу с памятью). Чем меньше оптимизированных решений в языке (алгоритмы), тем более отвратный софт в итоге. 


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Mayk
Дата 21.1.2008, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 2
Всего: 134



Цитата(Sardar @  21.1.2008,  22:54 Найти цитируемый пост)
# парсеры, текстовы ввод (гибкость/скорость) - вероятно OCaml, Perl6

Более разумно использовать генераторов этих самых парсеров[привет, antlr и yacc]. 
Менять ради одной подзадачи язык — не очень здравая идея имхо.

Тем более что генераторы парсеров есть почти для всех языков. Ну для c,c++,java точно есть.

Это сообщение отредактировал(а) Mayk - 21.1.2008, 19:14


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Void
Дата 21.1.2008, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 11
Всего: 173



Цитата(Sardar @  21.1.2008,  20:54 Найти цитируемый пост)
итерация в миллиард раз быстрей на асме (при условии что итерация реально выполняется). 

Неудачно предложение построил, я полминуты где-то пытался понять, откуда такое фантастическое быстродействие smile

Добавлено через 3 минуты и 29 секунд
Цитата(Mayk @  21.1.2008,  21:12 Найти цитируемый пост)
Менять ради одной подзадачи язык — не очень здравая идея имхо.

Подзадачи — да, если задача в целом связана с синтаксическим анализом, why бы и not.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Lazin
Дата 21.1.2008, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 4
Всего: 154



Невсегда важно быстродействие, иногда(почти всегда) важнее скорость разработки,масштабируемость, надежность. 
я этим посто кагбы открыл всем глаза на реальне положение дел в программировании 
PM MAIL Skype GTalk   Вверх
Sardar
Дата 21.1.2008, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 2
Всего: 317



Цитата(Void @  21.1.2008,  18:13 Найти цитируемый пост)
Неудачно предложение построил, я полминуты где-то пытался понять, откуда такое фантастическое быстродействие

Точно, изменил smile

Цитата(Mayk @  21.1.2008,  18:12 Найти цитируемый пост)
Более разумно использовать генераторов этих самых парсеров[привет, antlr и yacc].

Помимо самого анализа нужно ещё и представление AST/других структур, манипуляции с ними и т.д.  Да хотя бы имея алгебраические  типы уже проще строить деревья и т.п.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Mayk
Дата 21.1.2008, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 2
Всего: 134



Цитата(Sardar @  22.1.2008,  00:30 Найти цитируемый пост)

Помимо самого анализа нужно ещё и представление AST/других структур, манипуляции с ними и т.д.  Да хотя бы имея алгебраические  типы уже проще строить деревья и т.п. 

 smile 


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Sardar
Дата 21.1.2008, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 2
Всего: 317



Когда то тут было. По началу немного сумбурно, тема была вырезана из другого топа smile

Лаба из прошлого блока, читает и выполняет FEM - простейший абстрактный функциональный язык (всего три операции). На вкус отвратна (специально без оптимизаций, учили рекурсию и partial application функций), писалась после первых недель знакомства с Haskell, но принцип понять можно smile
Код
{---------------------------------------------
 - FEM language implementation
 - Sardar Yumatov (1679848) and others (1609874)
 -
 - Usage: showw (parseFEMProgram FEM_Code >>= eval)
 - Example: showw (parseFEMProgram "foo a bb = a, ((T foo S P)) 5 6 7" >>= eval)
 ---------------------------------------------}
module FEM where
import List
import Char


type FemGetal = Int                -- Fem deals with numbers only
type FemVariabele = String            -- Any identifier
type CodePosition = (Int,Int)            -- Term position in the source file, can be extended with file name later



-- собсно AST, без лишних классов
---------- Parsed program representation --------------
data FemTerm =
      S            -- increment, native function
    | P            -- decrement, native function
    | T            -- test (if-else), native function
    | N FemGetal        -- constant (integer) value
    | V FemVariabele    -- recall variable
    | L [FemParsedTerm]    -- execute (apply) variable (function)


type FemParsedTerm = (FemTerm, CodePosition)                -- term annotated with position in source code
type FemDeclaratie = (FemVariabele, (CodePosition, [FemVariabele], FemParsedTerm))    -- function declaration
type FemProg = ([FemDeclaratie], FemParsedTerm)                -- FEM program definition


---------- Token stream (tokenizer) ------------------
data Token = HOpen | HClose | Comma | Equal | Natural FemGetal | Variable String | PToken | TToken | SToken
type TokenStream = [(Token, CodePosition)]


---------- Runtime program representation ------------
data FemRuntimeTerm =
      NR FemGetal                                            -- primitive value
    | LR CodePosition [FemArgument] [FemParsedTerm]                            -- dellayed L term
    | FR String CodePosition [FemArgument] [FemVariabele] (Either FemParsedTerm FemSystemCallback)    -- partially applied function

-- Lookup must not be a stack, the context always consist of top-level functions and current arguments set
type ContextLookup = ([FemDeclaratie], [FemArgument])
type FemArgument = (FemVariabele, FemRuntimeTerm)

-- Native function callback.
type FemSystemCallback = [FemDeclaratie] -> [FemArgument] -> (Result FemRuntimeTerm)



----------------- Error handling -----------------------
-- Result of any evaluation (Maybe like type, extended with error messages)
data Result a = Error String | Success a

-- Allows chaining multiple (a -> Result a) together
instance Monad Result where
    Error  msg >>= f = Error msg
    Success rs >>= f = f rs
    Error  msg >> _  = Error msg
    _ >> Error msg   = Error msg
    Success a  >> Success b = Success b
    return          = Success
    fail msg        = Error msg

------------------- Pretty prints --------------------
class Source a where
    toSource :: a -> String

instance Show FemTerm where
    show a = toSource a

instance Source FemTerm where
    toSource S               = "S"
    toSource P               = "P"
    toSource T               = "T"
    toSource (N n)           = "N " ++ (show n)
    toSource (V str)         = "V " ++ str
    toSource (L trms)        = "(" ++ concat (intersperse " " (map (toSource.fst) trms)) ++ ")"

instance Show Token where
    show HOpen          = "_(_"
    show HClose         = "_)_"
    show Comma          = ", "
    show Equal          = " = "
    show PToken         = "p "
    show TToken         = "t "
    show SToken         = "s "
    show (Natural int)  = "@" ++ (show int)
    show (Variable str) = "$" ++ str

-- for debugging only
instance Show FemRuntimeTerm where
    show (NR n) = "NR " ++ (show n)
    show (LR p ctx trms) = "(" ++ concat (intersperse " " (map show trms)) ++ ")"
    show (FR nm p args ac func) = "Func: " ++ nm


-- Convert compiled FEM program to source
toSourceProgram :: FemProg -> String
toSourceProgram (xs, (term, q)) = ("(\n\t" ++ (concat (intersperse ",\n\t" (map toSourceDecl xs))) ++ "\n,\n\t" ++ (toSource term))
    where    toSourceDecl (name, (cp, xs, term)) = (name ++ " " ++ (concat (intersperse " " xs)))

-- Retrive from Result monad
showw :: (Show a) => (Result a) -> String
showw (Success foo) = (show foo)
showw (Error foo) = (show foo)

-- Print term position. Used in error messages.
showPosition (a, b) = "L" ++ (show a) ++ ":C" ++ (show b)





--------------------------- Parser -----------------------------
-- Parse FEM program into an exutable
parseFEMProgram :: String -> Result FemProg
parseFEMProgram code = tokenize code >>= trimBrackets >>= shredTokens >>= parseParts
    where    parseParts (decl, term) = parseDeclarations ([], decl) >>= parseTerm term
        parseTerm term (decls, []) = parseTermStream term >>= assembleProgram decls
        assembleProgram decls (term, []) = return (decls, term)
        assembleProgram decls (term, (x:strm)) = fail ("Unexpected input after closing ')' at the end of the program: " ++ (show x))
        trimBrackets ((HOpen, p):ts) =
                       case reverse ts of
                               ((HClose,p):tts) -> return (reverse tts)
                               (tts)            -> fail "Global ) at the end of the code is required!"
        trimBrackets ts = return ts


-- Split FEM source code to tokens.
-- This function will parse the whole string at once (no lazy evaluation), in return
-- the function will fail correctly if given FEM code contains syntax errors.
tokenize :: String -> Result TokenStream
tokenize src = tryNextToken ([], (0,0), src) >>= returnStream
    where    returnStream (toks, p, rest) = return toks
        tryNextToken (toks, p, []) = return (toks, p, [])
        tryNextToken (toks, p, xs) = (nextToken p xs >>= addTok) >>= tryNextToken
            where    addTok (tok, pp, pn, rest) = return (toks ++ [(tok, pp)], pn, rest)

-- Read next token
nextToken :: CodePosition -> String -> Result (Token, CodePosition, CodePosition, String)
nextToken p@(r,c) (x:xs)
    | x == '='               = return (Equal, p, (r, c+1), xs)
    | x == '('               = return (HOpen, p, (r, c+1), xs)
    | x == ')'               = return (HClose, p, (r, c+1), xs)
    | x == ','               = return (Comma, p, (r, c+1), xs)
    | x == '\n'              = nextToken (r+1, 0) xs
    | elem x "\t \r"           = nextToken (r, c+1) xs
    | isAlpha x || isDigit x = tryToken p (break (not.isAlphaNum) (x:xs))
    | otherwise            = fail ("Not a valid FEM token. Unexpected: " ++ [x])


-- Try to parse a Variable, Natural, P, S or T Token from a String.
tryToken :: CodePosition -> (String, String) -> Result (Token, CodePosition, CodePosition, String)
tryToken p@(r,c) (term, rest)
    | term == "p" || term == "P" = return (PToken, p, (r, c+1), rest)
    | term == "s" || term == "S" = return (SToken, p, (r, c+1), rest)
    | term == "t" || term == "T" = return (TToken, p, (r, c+1), rest)
    | all isDigit term           = return (Natural (read term), p, (r, c+(length term)), rest)
    | isAlpha (head term)        = return (Variable term, p, (r, c+(length term)), rest)
    | otherwise                  = fail ("Not a valid number: " ++ term)



-- Split token stream to program declarations and the main term.
shredTokens :: TokenStream -> Result ([TokenStream], TokenStream)
shredTokens (x:xs) = return (decl, term)
    where    (term:decl) = map reverse (shred (reverse (x:xs)))
        shred [] = []
        shred ((Comma, p):ts) = shred ts    -- so (decl, , , term) is allowed, commas are ignored
        shred ts = y : shred ys
            where    (y, ys) = break isComma ts
                isComma (Comma, p) = True
                isComma _          = False


-- Parse list of variable declarations
parseDeclarations :: ([FemDeclaratie], [TokenStream]) -> Result ([FemDeclaratie], [TokenStream])
parseDeclarations (dcl, []) = return (dcl, [])
parseDeclarations (dcl, (s:sms)) = parseDeclaration s >>= addDeclaration
       where   addDeclaration decl = (return (decl:dcl, sms)) >>= parseDeclarations



-- Parse FEM declaration (variable)
parseDeclaration :: TokenStream -> Result FemDeclaratie
parseDeclaration []  = fail "Software bug detected: empty variable declaration. Probably parser's (shredTokens) error!"
parseDeclaration str = possibleBrakets str >>= combineResults
    where    combineResults ((nm,p), arg, term, []) = return (nm, (p, arg, term))
        combineResults ((nm,pp), arg, term, ((t,p):ts)) = fail ((showPosition p) ++ " - Unexpected token after closing ')' of variable declaration: " ++ nm)

        possibleBrakets ((HOpen, p):ts) = (parseDecl p ts) >>= expectClose    -- consume (
        possibleBrakets ((t,p):ts) = parseDecl p ((t,p):ts)                -- no brakets variant

        expectClose (n,a,t,[(HClose,p)]) = return (n,a,t,[])        -- consume )
        expectClose ((n,p),a,t,[]) = fail ((showPosition p) ++ " - Expecting ')' at the end of variable declaration: " ++ n)
        expectClose ((n,pp),a,t,((o,p):ts)) = fail ((showPosition p) ++ " - Expecting only ')' at the end of variable declaration: " ++ n)

        parseDecl p [] = fail ((showPosition p) ++ " - Expecting variable declaration, but there is no more terms.")
        parseDecl p ts = parseName ts >>= parseArguments >>= parseBody

        parseName (((Variable nm), p):str) = return ((nm,p), str)
        parseName ((t,p):xs) = fail ((showPosition p) ++ " - fuck Expecting variable name, got: " ++ (show t))

        parseArguments ((n, p), str) = nextArgument ([], str) >>= combineArg
            where    combineArg (arg, ts) = return ((n,p), arg, ts)
                nextArgument (arg, []) = fail ((showPosition p) ++ " - Expecting body for variable: " ++ n)
                nextArgument (arg, (((Variable nm), p):ts)) = (return (arg ++ [nm], ts)) >>= nextArgument
                nextArgument (arg, ((Equal, p):ts)) = return (arg, ts)
                nextArgument (arg, ((t, pt):ts)) = fail ((showPosition pt) ++ " - Expecting variable name or '=', got: " ++ (show t))

        parseBody ((n,p), a, []) = fail ((showPosition p) ++ " - Expecting body (code) for variable: " ++ n)
        parseBody (n, a, str) = parseTermStream str >>= returnBody
            where    returnBody (term, rest) = return (n, a, term, rest)


-- Parse FEM term (program body)
parseTermStream :: TokenStream -> Result (FemParsedTerm, TokenStream)
parseTermStream [] = fail "Software bug detected: no input for parseTermStream!"
parseTermStream str = parseSingleTerm ([], str) >>= optimizeNesting
    where    optimizeNesting (tt@((t, p):trs), ts) = return (optimizeList (L tt, p), ts)
        parseSingleTerm (trms, [])                   = return (trms, [])
        parseSingleTerm (trms, ((Natural n, p):ts))  = return (trms ++ [(N n,p)], ts) >>= parseSingleTerm
        parseSingleTerm (trms, ((Variable n, p):ts)) = return (trms ++ [(V n,p)], ts) >>= parseSingleTerm
        parseSingleTerm (trms, ((PToken, p):ts))     = return (trms ++ [(P,p)], ts)   >>= parseSingleTerm
        parseSingleTerm (trms, ((TToken, p):ts))     = return (trms ++ [(T,p)], ts)   >>= parseSingleTerm
        parseSingleTerm (trms, ((SToken, p):ts))     = return (trms ++ [(S,p)], ts)   >>= parseSingleTerm
        parseSingleTerm (trms, ((Equal, p):ts))      = fail ((showPosition p) ++ " - Unexpected '=', probably ',' is missing.")
        parseSingleTerm (trms, ((HClose, p):ts)) = return (trms, ts)
        parseSingleTerm (trms, ((HOpen, p):ts)) = parseSingleTerm ([], ts) >>= addTermList >>= parseSingleTerm
            where    addTermList (trs, rest) = return (trms ++ [(L trs, p)], rest)

        --parseSingleTerm (trms, ((t,p):ts)) = fail ((showPosition p) ++ " - Software bug detected. Unexpected token: " ++ (show t))

        optimizeList ((L [x]), q)                = (optimizeList x)
        optimizeList ((L xs ), q)                = ((L (map optimizeList xs)), q)
        optimizeList (x, q)                      = (x, q)




------------------------------------ FEM Runtime --------------------------------------------
-- Evaluate program. The result will be an number or error message.
eval :: FemProg -> Result FemGetal
eval (decl, term) = evaluableTerm (decl, []) term >>= execTerm decl >>= evalTerm
    where    evalTerm (NR n) = return n
        evalTerm (FR n p a ac f) = fail ("Can't execute partially applied function: " ++ n ++ ", expecting arguments: " ++ (concat $intersperse ", " ac))
        evalTerm d = fail "Software bug detected: not number nor partial function in evalTerm!"


-- Convert an expression to evaluable object (lazy evaluation).
evaluableTerm::ContextLookup->FemParsedTerm->Result FemRuntimeTerm
evaluableTerm _  (S,p)               = return (FR "S" p [] ["arg"] (Right femNative_S))    -- introduce natives
evaluableTerm _  (P,p)               = return (FR "P" p [] ["arg"] (Right femNative_P))
evaluableTerm _  (T,p)               = return (FR "T" p [] ["arg","true","false"] (Right femNative_T))
evaluableTerm _  ((N n), p)          = return (NR n)        -- introduce primitive constant
evaluableTerm _  ((L []), p)         = fail ((showPosition p) ++ " - Empty group ()")
evaluableTerm (f,a) ((L (t:trms)),p) = return (LR p a (t:trms))
evaluableTerm (f,a) ((V name), p)    =
    case (lookup name a) of
        Just term    -> return term                            -- inject partially applied function
        Nothing    -> case lookup name f of
            (Just (pf, arg, term))    -> return (FR name pf [] arg (Left term))    -- introduce top level function
            Nothing            -> fail ((showPosition p) ++ " - Variable not found: " ++ name)


{- Execute delayed/lazy term
 - Function will terminate with either primitive value or partially applied FEM variable. -}
execTerm::[FemDeclaratie]->FemRuntimeTerm->Result FemRuntimeTerm
execTerm _ d@(NR n) = return d                    -- primitive value
execTerm flc (LR p alc (lamfunc:args)) = evaluableTerm (flc,alc) lamfunc >>= evaluableLambda args >>= execTerm flc
    where    evaluableLambda [] r = return r    -- L [ single term ] => single term
        evaluableLambda (t:ts) (NR n) = fail ((showPosition p) ++ " - Variable with at least one parameter expected, but got primitive: " ++ (show n))
        evaluableLambda (t:ts) (FR nm p arg (a:ags) f) = evaluableTerm (flc,alc) t >>= addArgument >>= evaluableLambda ts    -- fill in arguments. for partial application the function runs in own context, while arguments are from current context
            where    addArgument rt = return (FR nm p ((a,rt):arg) ags f)
        evaluableLambda (t:ts) trm = execTerm flc trm >>= evaluableLambda (t:ts)    -- full FR or L term, evaluate and apply the rest of arguments

execTerm _ d@(FR nm p ctx (a:as) func) = return d    -- partially applied function
execTerm flc (FR nm p ctx [] func) = applyFunc func    -- until either primitive val or partially applied func
    where    applyFunc (Left term) =
            case evaluableTerm (flc,ctx) term of
                Success term    -> execTerm flc term
                Error msg    -> Error (msg ++ "\n" ++ (showPosition p) ++ " - Failed to execute: " ++ nm)

        applyFunc (Right term) = 
            case term flc ctx of
                Error msg -> Error (msg ++ "\n       - Executed at: " ++ (showPosition p))
                Success val -> execTerm flc val    -- usually NR n






----------------------- Native bindings -------------------------
-- Increment
femNative_S :: FemSystemCallback
femNative_S lk [(a,t)] = execTerm lk t >>= updateWaarde
    where    updateWaarde (NR n) = return (NR (n+1))        -- direct execute
        updateWaarde d@(FR n p a ac f) = return (FR "<anonymous>" (-1,-1) [] ac (Right (femLambda [] (femNative_S lk) d)))

-- Decrement
femNative_P :: FemSystemCallback
femNative_P lk [(a,t)] = execTerm lk t >>= updateWaarde
    where    updateWaarde (NR 0) = return (NR 0)        -- direct execute
        updateWaarde (NR n) = return (NR (n-1))
        updateWaarde d@(FR n p a ac f) = return (FR "<anonymous>" (-1,-1) [] ac (Right (femLambda [] (femNative_P lk) d)))

-- Test (not)
femNative_T :: FemSystemCallback
femNative_T lk args = execTerm lk (takejust (lookup "arg" args)) >>= executeT -- executeT (takejust (lookup "arg" args)) -- 
    where    executeT (NR 0) = return taakTrue
        executeT (NR n) = return taakFalse
        executeT d@(FR n p a ac f) = return (FR "<anonymous>" (-1,-1) [] ac (Right (femLambda args (femNative_T lk) d)))
        taakTrue = takejust (lookup "true" args)
        taakFalse = takejust (lookup "false" args)
        takejust (Just n) = n


-- Native lambda, used to wrap native (black-box) functions
femLambda oargs nat (FR n p a ac f) lk args = (return (FR n p (a++args) [] f)) >>= execTerm lk >>= execNative >>= nat
    where    execNative rt = return ([("arg", rt)] ++ oargs)



Это простейший LL(1) парсер-интерпретатор + пара debug функций.  Коррктно выводит контекст ошибки (parsing, runtime) и т.п. отсюда много кода. Просто парсер укладывается в пару десятков строк. Кстати пример как реализуются не типичные для чистых декларативных языков последовательные операции посредством монад.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
mr.DUDA
Дата 21.1.2008, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 4
Всего: 232



Какой кошмарный язык. Напомнило мне времена когда не зная ничего кроме бейсика пытался вникнуть в примеры из книги Страуструпа...


--------------------
user posted image
PM MAIL WWW   Вверх
Real
Дата 18.4.2008, 20:41 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 507
Регистрация: 9.11.2007

Репутация: -3
Всего: -1



Цитата(LSD @ 21.1.2008,  14:36)
Цитата(APM @  21.1.2008,  14:28 Найти цитируемый пост)
У кого какие мнения? =)

1. Есть специальный раздел для тестов.
2. Без исходников, конфигурации и версий компиляторов это не тест, а баловство.

Где этот раздел?
PM   Вверх
Ch0bits
Дата 18.4.2008, 21:23 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 1
Всего: 62



PM WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила ведения Религиозных войн
Smartov
1. Уважайте собеседника
2. Собеседник != враг
3. Старайтесь воздерживаться от тем вида "Windows Rulez" или "Linux Rulez"

С уважением, Smartov.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Религиозные войны | Следующая тема »


 




[ Время генерации скрипта: 0.0871 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.