JBForth2

+
-
edit
 

Balancer

Администратор
Ковырялся сегодня, наконец, на тему Java-байткода. Т.е. по поводу возможности компиляции JBForth в байткод JVM.

Пробные примеры получатся.

Огорчение - у каждого метода свой стек. Ограничиться им теоретически можно, но это не оставит от Форта ничего, кроме синтаксиса :) А оно нам нафиг не надо...

Похоже, придётся делать таки отдельный глобальный стек.

Таким образом от нативной производительности остаются опять рожки да ножки.

Хотя, естественно, будет возможность генерации нативных для JVM классов и методов. Так что критические куски кода можно будет писать на JVM-функционале.

...

В общем, перспективы интересные, но работы предстоит чудовищное количество :)
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  

Murkt

Pythoneer
Меня это давно интересует - генерация кода на лету, или же трансляция (форт -> джава). Дай ссылок, пожалуйста :)
[team Їжачки - сумні падлюки]  

Murkt

Pythoneer
Или сам расскажи :)
[team Їжачки - сумні падлюки]  
+
-
edit
 

Balancer

Администратор
Буду базироваться на http://asm.objectweb.org

Но проблем ожидается масса. Как технологических, так и идеологических.
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  

Balancer

Администратор
Murkt> Или сам расскажи :)

В двух словах там, действительно, всё просто. Есть байткод (типично Фортовский, кстати, стековый - DUP/SWAP/ADD и т.д.). Каждому методу при вызове формируется отдельный стек и область локальных переменных. И то и другое - заказанного размера. Аргументы метода - тоже локальные переменные. Соответственно, в байткоде есть операции чтения такой переменной. Или field'а какого-либо класса. Или вызова статического или виртуального метода. И т.п.

Проблемы в том, что нет общего стека на всю систему. JVM сама снимает для вызываемого метода со стека аргументы. Соответственно, и число аргументов всегда фиксированное. Возвращаться может только одно значение. Хотя прописаться может с любого места.

Сейчас вижу три (выше писал - два) выхода:

- Делать глобальный стек в виде отдельного класса, как сейчас в JBForth. Но тогда, во-первых, сильно снизится скорость (грубо говоря вместо байтоперации SWAP будем вызывать метод чужого класса, который будет работать с чужими данными). Во-вторых (впрочем, это тоже самое) пропадёт возможность использования массы байткода. Промежуточное решение - делать Форт не кодогенерирующий, а классический. А низкоуровневые слова определять через CODE, как в классическом Форт-ассемблере. Уже внутри этих слов использовать как глобальный, так и локальный стеки в зависимости от требуемой задачи.

- Делать 100% "Java-форт" со всеми ограничениями JVM. Т.е. для каждого слова будет определён фиксированный тип аргументов. Теряем капитально совместимость с классическим Фортом (скажем, слова, типа ?dup будут принципиально невозможны), но приобретаем скорость и "нативный" байткод.

- Делаем весь Форт со всеми словарями одним классом. Практически классическое решение, когда весь словарь лежит в одном кодофайле. Высокая скорость, совместимость с Фортом и... все ограничения одного класса. А их дофига. ЕМНИП, это только 256 локальных переменных, 65536 методов и ограничение на размер в байтах. Также теряется интересная фишка нынешнего JBForth, когда отдельное слово можно переопределять и удалять независимо от всей системы. Точные цифры следует, конечно ещё уточнить. Но ограничения мне не нравятся :)
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  

Murkt

Pythoneer
ИМХО, лучше медленнее, но с полными возможностями.

Насчёт входящих-выходящих параметров (точно заданное количество, один на выходе) - может есть смысл их просто заворачивать во что-то, как это в Питоне делается? Если хочешь, расскажу как заворачивается.
[team Їжачки - сумні падлюки]  
+
-
edit
 

Balancer

Администратор
Расскажи вкратце, но... Вариант с "внешним" стеком будет не сильно быстрее нынешнего, увы :-/ Разве что только бонус будет в написании именно полноценных .class и генерации .jar

...

В принципе, возможно, это будет самый компактный JDK :D Форт-система размером под несколько сот килобайт сможет генерировать полноценные .jar :)

...

А так - конечно, можно будет сделать дуальную систему. Когда можно будет определять два вида Форт-слов. С фиксированным числом аргументов в нативном коде и с внешним стеком.
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  

Murkt

Pythoneer
Я имел в виду, что ты в метод передаёшь вроде как ограниченное и чёткое количество аргументов, но на самом деле столько, сколько тебе надо. То есть, положить на стек вызываемой функции массив (это ведь не полноценный объект, по идее должно быть быстро) со стопкой параметров, а на выходе отдавать тоже массив, и его ты тоже можешь варьировать так как тебе надо - хочешь, без элементов вообще, хочешь - десяток.

Я себе слегка так представил - в принципе, сделать можно, и работать должно быстрее, чем с действително внешним стеком. Хоть это и будет небольшой rocket science.

Я бы посоветовал сначала сделать с полноценным внешним стеком, а потом попробовать сделать с фейковым (как я вот сказал), так как преждевременная оптимизация :)

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

def myfunc():
    return 1, 2, 'a'

first, second, third = myfunc()
code, type 'python'
[team Їжачки - сумні падлюки]  

Murkt

Pythoneer
Насчёт входных параметров:
def myfunc(a, b, c=5, *args, **kwargs):
    print (a, b, c, args, kwargs)
code, type 'python'


*<название кортежа> - это неименованные параметры, **<название словаря> - именованные.

# с - значение по умолчанию, "лишних" нет
>>> myfunc(1, 2)
(1, 2, 5, (), {})

# с - значение по умолчанию, d - "лишнее"
>>> myfunc(1, 2, d=3)
(1, 2, 5, (), {'d': 3})

>>> myfunc(1, 2, d=3, *(2,4))
(1, 2, 2, (4,), {'d': 3})

>>> myfunc(1, 2, 3, 4, 5, 6, d=7, e=8, f=9)
(1, 2, 3, (4, 5, 6), {'e': 8, 'd': 7, 'f': 9})

# аналогично предыдущему
>>> myfunc(*(1, 2, 3, 4, 5, 6), **{'d': 7, 'e': 8, 'f': 9})
(1, 2, 3, (4, 5, 6), {'e': 8, 'd': 7, 'f': 9})

# можно комбинировать
>>> myfunc(1, 2, 3, 4, x=10, y=11, *(5, 6), **{'d': 7, 'e': 8, 'f': 9})
(1, 2, 3, (4, 5, 6), {'y': 11, 'x': 10, 'e': 8, 'd': 7, 'f': 9})
code, type 'python'


Использование в повседневной жизни на каждом шагу, особенно **kwargs. Вот пример из рабочего проекта, можно сказать функция-прокси:
@login_required
@user_in_groups('Modellers')
def modeller_bundles(request, **kwargs):
    """ Show paginated list of bundles.
    """
    kwargs['template_name'] = 'modeller_bundles.html'
    kwargs['queryset'] = sort_query(Bundle.objects.filter(modeller=request.user.username), request)
    kwargs['extra_context'] = {'sorts': request.GET.getlist('sort')}
    kwargs['paginate_by'] = settings.PAGINATE_BY
    kwargs['template_object_name'] = 'bundle'
    return object_list(request, **kwargs)
code, type 'python'


Но и *args не остаётся незамеченным :)
def sort_query(base_query, request):
    """ Order base_query by parameters from request.GET['sort'].
    """
    if 'sort' in request.GET and request.GET['sort']:
        return base_query.order_by(*tuple(request.GET.getlist('sort')))
    return base_query
code, type 'python'
[team Їжачки - сумні падлюки]  
Это сообщение редактировалось 15.06.2007 в 19:49

Murkt

Pythoneer
статус
[team Їжачки - сумні падлюки]  
+
-
edit
 

Balancer

Администратор
fixed
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  
DE Кирилл #17.08.2007 09:37
+
-
edit
 

Кирилл

Втянувшийся
- Делать 100% "Java-форт" со всеми ограничениями JVM. Т.е. для каждого слова будет определён фиксированный тип аргументов. Теряем капитально совместимость с классическим Фортом (скажем, слова, типа ?dup будут принципиально невозможны), но приобретаем скорость и "нативный" байткод.

ИМХО самый интересный вариант.
Ибо не противоречит Форт-идеологии с одной стороны (меньше "умных" слов) и позволяет контроль стека при компиляции ("стековые комментарии" в середине слова помогут отловить ошибку ДО выполнения). И лаконичности не мешает - типы и количество аргументов высокоуровневого слова однозначно вычисляются по его определению.
Кстати, с точки зрения дисциплинирующих ограничений такой Форт будет ближе к массам, чем классический.
- Сами понимаете, вселенная-то на моей стороне.
- Вот это мне таким вульгарным и кажется.
 
RU Balancer #17.08.2007 10:21 @Кирилл#17.08.2007 09:37
+
-
edit
 

Balancer

Администратор
Кирилл> Кстати, с точки зрения дисциплинирующих ограничений такой Форт будет ближе к массам, чем классический.

Да, массам нужна жёсткость :)

...

Кстати, ещё мысль. Нормальную работу со стеком внутри определений можно реализовать в CODE-словах, которые будут просто инлайниться в компилируемое слово. Вернее, CODE-слова надо оставить как есть, а реализовать, скажем, INLINE.

: word1 ( arg1:type1 arg2:type -- result:type3 )
\ код высокоуровневого слова
;

CODE word2 ( arg:type -- result:type )
   \ низкоуровневый код JVM
   NEXT
END-CODE

INLINE word3
   \ низкоуровневый код JVM
END-INLINE

: word4 ( -- )
\ ...
    word1 \ тут вызывается внешний метод со всей бодягой в виде передачи аргументов и возврата значения

    word2 \ тут - тоже самое, с точки зрения Форт-системы разницы в вызове word1 и word2 нет.

    word3 \ а тут - будет заинлайнен код, работающий внутри текущего слова. Соответственно, использует текущее состояние стека.
;
code, type 'forth'


Правда, надо придумать ещё механизмы обращения к переменным метода из INLINE-слов. Обращаться по их номерам - это как-то старО :)
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  
DE Кирилл #26.08.2007 17:05
+
-
edit
 

Кирилл

Втянувшийся
А как насчет решения проблемы дороговизны вызовов через макрооптимизацию, как в SPF?
Заодно и специальных INLINE-слов не понадобится...

Еще в Ява-форте можно ввести модули, эквивалентные Ява-классам. Тогда вызовы внутри модуля будут быстрыми, а "наружу" - гибкими.
- Сами понимаете, вселенная-то на моей стороне.
- Вот это мне таким вульгарным и кажется.
 
RU Balancer #27.08.2007 10:25 @Кирилл#26.08.2007 17:05
+
-
edit
 

Balancer

Администратор
Кирилл> А как насчет решения проблемы дороговизны вызовов через макрооптимизацию, как в SPF?

Это уже на практике можно будет подумать. Ибо там это не так гладко будет, как в SPF. У JVM свои ограничения.

Кирилл> Еще в Ява-форте можно ввести модули, эквивалентные Ява-классам. Тогда вызовы внутри модуля будут быстрыми, а "наружу" - гибкими.

Да, где-то так и задумывается.
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  
DE Кирилл #04.09.2007 07:57
+
-
edit
 

Кирилл

Втянувшийся
Еще один довод в пользу Форта со статической типизацией: большинство слов с переменным числом аргументов на стеке (тот же ?DUP) делают двойную работу по принятию решения и ухудшают читабельность текстов программ.
Слова же, возвращающие флаг - бледное подобие исключений... костыль неполной реализации конструкций структурного программирования.
А если замечтаться, в воображении появляется Форт с системой типов Хиндли-Милнера ;)
- Сами понимаете, вселенная-то на моей стороне.
- Вот это мне таким вульгарным и кажется.
 
RU Balancer #04.09.2007 11:01 @Кирилл#04.09.2007 07:57
+
-
edit
 

Balancer

Администратор
Кирилл> с системой типов Хиндли-Милнера ;)

Вкратце распиши, а то гуглить некогда :)

...

А на счёт исключений - их реализовывать придётся, полагаю, в любом случае.

И надо думать над красивым синтаксисом аргументов слов. Первое, что в голову приходит - это использовать комментарий с параметрам, заданный де факто, но теперь сделать его обязательным по стандарту:
public static : str_repeat ( String:arg1 Integer:arg2 -- String )
\ ...
;
code, type 'forth'


Нужен набор модификаторов - public, private, static, final. По умолчанию, полагаю, нужно делать просто private.

Непонятно, что делать с режимом исполнения. Ибо делать два набора слов, для режима компиляции и для режима исполнения, ИМХО, бред. Как вариант - комиплировать введёную строку в анонимное слово и исполнять потом. Какие могут быть подводные камни?

Кстати, от Форта не так уж много остаётся... Например, мы не можем оперировать стеком вызывающего слова. Что, с одной стороны, нам больше не нужно, так как число аргументов фиксированное и в слово передаётся всё, что ему надо, с другой - это уже не совсем Форт :)

Даже синтаксис. В приведёном примере двоеточие выглядит уже не в тему... Так и напрашивается "static function str_repeat ..." :)
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  
DE Кирилл #04.09.2007 11:58
+
-
edit
 

Кирилл

Втянувшийся
Вкратце распиши, а то гуглить некогда

Вкратце - типы переменных выводятся из выражения, а значит "стековая нотация" в большинстве случаев необязательна! В ОСАML, Haskell и т.д. именно так ;)
Например : AVERAGE + 2 / ; автоматически протипируется как ( int int -- int)
просто исходя из типов + и /
Если не баловаться с полиморфизмом на нижнем уровне (а Форт-идеология как раз такая!) - то все просто.
Потом можно и побаловаться - будет куда сложнее (или эквивалент шаблонов или передача неявного аргумента с указателем таблицы операций), зато получится выразительность типизированных функциональных языков реализованная в компактном императивном.
"Стековая нотация" однако полезна - для самодокументирования, усиления контроля компиляции, а также определения локальных переменных.
А ведь мы так даже Хаскель кое в чем уделаем - необязательным окажется указание не только типа, но и имен и даже количества аргументов: все выводится при компиляции.
А на счёт исключений - их реализовывать придётся, полагаю, в любом случае.

При наличии в языке исключений стеко-статичность слов сама по себе не является недостатком, а значит с ней можно спокойно смириться.
Нужен набор модификаторов - public, private, static, final. По умолчанию, полагаю, нужно делать просто private.

С точки зрения отделения интерфейса от реализации а также Форт-идеологии лучше будут словари public, static, final.
Кстати, static можно выкинуть - в Форте между явным и неявным self особой разницы нет.
Как вариант - комиплировать введёную строку в анонимное слово и исполнять потом. Какие могут быть подводные камни?

Куски между определениями компилируются в безымянные слова, которые потом выбрасываются. JIT однако... ;) На SPF кто-то так получил возможность использовать IF, THEN и т.п. в режиме исполнения.
Даже синтаксис. В приведёном примере двоеточие выглядит уже не в тему... Так и напрашивается "static function str_repeat ..."

А не надо из Форта Яву делать ;)
- Сами понимаете, вселенная-то на моей стороне.
- Вот это мне таким вульгарным и кажется.
 
RU Balancer #04.09.2007 12:31 @Кирилл#04.09.2007 11:58
+
-
edit
 

Balancer

Администратор
Кирилл> С точки зрения отделения интерфейса от реализации а также Форт-идеологии лучше будут словари public, static, final.

Не покатит. Это модификаторы Java-методов :)

Кирилл> Кстати, static можно выкинуть - в Форте между явным и неявным self особой разницы нет.

Опять же, это принципиальный для Java вопрос.

Мы же собираемся генерировать нативные Java-классы.

Кирилл> А не надо из Форта Яву делать ;)

А тогда у нас уже есть JBForth-1 :) Он форт как форт, совершенно типичный, хотя и не очень стандартный.
... чтобы понять рекурсию, нужно сперва понять рекурсию ...  
DE Кирилл #04.09.2007 13:34
+
-
edit
 

Кирилл

Втянувшийся
Не покатит. Это модификаторы Java-методов

Почему же? Если главное, чтобы для JVM генерились корректные методы и классы, то это возможно при любом синтаксисе, необязательно Явовском. Т.е. при помещении слова в словарь final - оно может быть точно так же скомпилировано в байт-код как final-метод, как и при указании java-модификатора.
Опять же, это принципиальный для Java вопрос.
Мы же собираемся генерировать нативные Java-классы.

Собственно генерировать ничто не мешает :) А static или нет - видно по первому же параметру слова.
Он форт как форт, совершенно типичный, хотя и не очень стандартный.

А хочется Форт быстрый и на JVM ;)
- Сами понимаете, вселенная-то на моей стороне.
- Вот это мне таким вульгарным и кажется.
 

Поиск
Поддержка
Поддержи Авиабазу!
ЯндексЯндекс. ДеньгиХочу такую же кнопку
Настройки
Персональное
Новости сайта
Популярные темы
На Facebook
География форума




АвиаТОП


 
Сайт работает на сервере ETegro Technologies