Вверх ↑
Этот топик читают: Гость
Ответов: 9906
Рейтинг: 351
#31: 2007-06-26 13:54:36 ЛС | профиль | цитата
Dilma писал(а):
и именно такое использование данного элемента и подразумевается

Во-первых, далеко не только данного.
Во-вторых, не только элемента.

А дело-то в том, что вопрос inline/function имеет в данном случае отношение не к элементу, а ко всей алгоритмической ветке. Элементы как раз могут оказаться из серии AlreadyInline

И проблема не "может возникнуть", а именно возникнет. И не настолько она проста, чтобы ее решал пользователь.
Не отрицая конечно, что решение пользователем - гораздо лучше, чем никакого решения.

Что значит не так проста:
Ну к примеру - код метода элемента, это уже просто функциональный вызов. Автор (а может и CodeGen) принял решение AlreadyFunction
Или начало ветки - сразу уже функциональный вызов:
Add(Hub,16412592,350,112)
{
}
Add(Button,2557492,266,112)
{
link(onClick,12457600:doWork2,[])
}
Add(Button,4859552,266,161)
{
link(onClick,12457600:doWork3,[(326,167)])
}
Add(HubEx,12457600,322,105)
{
link(onEvent,16412592:doEvent1,[])
}
И в результате думаю, что правильнее будет эту проблему решать, а не полагаться на пользователя.
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#32: 2007-06-26 14:16:37 ЛС | профиль | цитата
nesco писал(а):
Это значит, что в группе примитивов совершенно необязательно заморачиваться насчет объявления переменных в приватных секциях, для этого должны быть отдельные примитивы. Я правильно понял?

не совсем. Просто компоненты примитивов должны проектироваться из расчета на более продвинутого пользователя. Особо лениться из-за этого не стоит.

[size=-2]------ Добавлено в 14:16
Galkov, да это все верно. Никто и не спорит. Однако верно так же и то, что производственные мощности у нас лимитированны и достаточно сильно ограничены. А раз так, то решение указанной проблемы(связанной только с оптимальностью кода между прочим) можно отложить на неопределенное время и забыть про нее на данный момент. Сейчас и без того хватает других задач, без решения которых вообще не возможно что-либо делать.
карма: 27
0
Ответов: 9906
Рейтинг: 351
#33: 2007-06-26 14:48:58 ЛС | профиль | цитата
Dilma писал(а):
Сейчас и без того хватает других задач, без решения которых вообще не возможно что-либо делать

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

А бросим - можем потом долго расхлебывать.
Ну скажем: помещение в контейнер - чисто интерфейсная вещь. Пользователь должен делать как ему понятней программировать, а не по консультациям с некими гуру

Нельзя категорически проблемы кодогенерации выносить на интерфейс.
Знаю что лимитированы. По этому пытаюсь не бежать (благо пока и работа не позволяет) в каком-то направлении, не убедившись, что не придется возвращаться...
А такое - запросто (ну и не факт, конечно же), если замкнуться на одном вопросе.
Все вопросы сразу - решить невозможно.
А вот хотя бы представить "схему" их решения - очень надо.
И именно всех...
Но только схему.
Надежность работы, после этого, должна возрасти многократно. ИМХО
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#34: 2007-06-26 15:00:09 ЛС | профиль | цитата
Galkov писал(а):
АвтоТипизация

что это?

Galkov писал(а):
что это многопроходность

ага, а перед этим нужно сделать промежуточное представление ввиде байт кода. А значит делать практически кодогенератор еще раз. И на отладку после этого еще времени уйдет сколько.
карма: 27
0
Ответов: 9906
Рейтинг: 351
#35: 2007-06-26 15:48:45 ЛС | профиль | цитата
Dilma писал(а):
что это?

Может точнее будет АвтоПриведениеТипов.
Потом можно вспомнить про ссылочные типы (PControl, PBitmap, PStream и иже с ними)
Для них, видимо, вспомнить нашу технологию Guid-ов.
А если вспомнить про необходмость определения наследования одного Guid-а другим, то и усложнить нашу технологию.
Естественно, все это в рассчете на исполнение в Design-Time

Dilma писал(а):
ага, а перед этим нужно сделать промежуточное представление ввиде байт кода

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

А что байт-код... Ну сэкономит работу lexer-а, конечно же.
Но быстрые компиляторы делаются вроде нерекурсивными, скажем LR-восходящими...
Содержательная часть: есть стек для токенов, и конечный автомат... Таблица переходов которого это просто константный массив.
Да пусть даже и большой - зато шустро....
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#36: 2007-06-26 17:16:31 ЛС | профиль | цитата
Galkov писал(а):
Естественно, все это в рассчете на исполнение в Design-Time

вот это задача номер 1 на ближайшее время. Доработать кодогенератор так, чтобы в любой моент времени для любых данных скрипта можно было сказать какого они типа. Принцип Guid-ов останется, но конечно же только для Design-Time. В конечном приложение их уже не будет.

Galkov, решил таки тут задасться вопросом, а чего нам еще конкретно не хватает, чтобы сделать свой настоящий и полноценный элемент в пакете WEB из элементов низкого уровня? Оказалось что совсем чуть чуть:
code_1598.txt

Чтобы из этого получить полноценный элемент нужно memory заменить на некий компонент с двумя точками(верхняя Data и нижняя Result) и одним св-вом(Data), работающий так: если верхняя точка включена, то передавать данные с нее на точку Result, иначе если св-во Data задано, то передавать его и в противном случае считать точку Result не подключенной. Положим элемент сделать не сложно однако требуется то, о чем мы уже как-то говорили: нужно сделать интерфейс через который кодогенератор сможет у самого элемента спросить о подключенности его точек. Скажем, у описанного компонента этот интерфейс реализовывался бы так:

func isLinked(point)
  if(point = "Result")
return(isset(Data))
end
end

   Однако делать такой интерфейс сейчас не хочется. Вызов парсинга hws на каждый linked в скрипте это очень ресурсоемкая процедура. Испытывать на медленном варианте конечно можно, но слишком уж заметна эта медлительность получается. Да и хинты над точками начнут заметно тормозить.
   Впрочем не факт еще, что такой интерфейс является удачным. Может быть стоит боле общий:
func getState(cmd, object)
  switch(cmd)
case IS_POINT:
if(object = "Result")
return(isset(Data))
end
end
end

собственно тема для размышления

[size=-2]------ Добавлено в 17:16
PS: сделав такой элемент и вставив его в схему таким образом:
code_1599.txt
мы по идее получим конечный код при любых включениях вточности таким, каким он получается в элементе md5
карма: 27
0
файлы: 2code_1598.txt [527B] [655], code_1599.txt [632B] [627]
Администрация
Ответов: 15295
Рейтинг: 1519
#37: 2007-06-28 01:13:29 ЛС | профиль | цитата
nesco, решено сделать данный пакет некоторым испытательным полигоном для отладки основной ф-ности FTCG применительно к типизированным языкам. Всвязи с этим на SVN закоммичена некоторая версия, которая в том или ином виде может притепревать достаточно значительные изменения. Поэтому следут умеренно надстраивать к ней элементы.

В последнюю версию FTCG внесены правки, благодаря которым стала возможно автоматическая конвертация типов из числа в строку для данных полученных из потока. Добавлены операторы:
expof(<expression>)

возвращает подтип для типа data_code.

lang(<var name>:<int|str|real, [<var name>:<int|str|real>])

объявляет так называемую переменную целевого языка. Эта переменная обладает следующими св-вами:
- её typeof() = data_code - т.е. скрипт видит её как переменную типа code
- её expof() = dataint|data_str|data_real в зависимости от указанного в объявление типа
- значение данной переменной устанавливается равным var_mask из direct.inc с заменой соответствующих полей.

обновив пакет с SVN можно посмотреть какой код дает вот такое включение:
Add(Message,3261178,287,154)
{
}
Add(For,1644231,231,154)
{
End=5
link(onEvent,3261178:doMessage,[])
}
...
  for i4 := 0 to 5 do
  begin
MessageBox(frm2.Handle, PChar(int2str(i4)), PChar('hiasm msg'), MB_OK);
end;

т.е. CG сам заменил параметр Text компонента Message на int2str(Text). В дальнейшем такая замена будет производиться для всех типов, а так же и для данных, считанных через верхнюю точку. Для разработчика компонента эта фишка очевидно избавит от необходимости следить за типами вообще. исключение составляют ситуации, когда элемент понимает более одного типа входных данных(элемент Memory скажем)
карма: 27
0
Ответов: 9906
Рейтинг: 351
#38: 2007-06-28 12:07:01 ЛС | профиль | цитата
Dilma, вот чего я думаю...
Пока ты увлеченно улучшаешь CG, попробую я растолковать тебе, чего такое LR-восходящий алгоритм трансляции (или интерпретации) на конкретном примере.
Ну чтобы друг-другу не мешать сильно...
Все равно FastMathParse надо доводить до ума - вот и соберу я его в этой технике...
"Язык" там простой, и половина уже в букварях написана, поэтому можно и ручками будет...
А смысле - без злобных Аяксов всяких

И чего-то мне кажется, что компиляция (именно компиляция) должна убыстриться на порядок...

[size=-2]------ Добавлено в 12:07
Не сегодня конечно же
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#39: 2007-06-28 12:17:57 ЛС | профиль | цитата
Вообще прошлая практика написание трансляторов и языков скриптового типа(да тот же VBScript, встроенный в среду) показала, что простой поток команд полученный после разбора исходного кода и представляющий из себя массив эелементов вида:
LexemType - тип лексемы(оператор, переменная, ф-ция и т.д.)
LexemIndex - индекс в таблице лексем данного типа

дает достаточно приемленмое быстродействие на котором можно вполне остановиться. Кроме того появится возможность дампировать этот масив в файл и в дальнейшем уже парсингом не заниматься. А это значит, что схемы из пары сотен элементов будут собираться почти мгновенно...
карма: 27
0
Ответов: 9906
Рейтинг: 351
#40: 2007-06-28 12:39:58 ЛС | профиль | цитата
Одно другому не противоречит.
Конечно профайлинг нужен, чтобы определить кто сколько времени съедает
Думается, что без байт-кода - lexer, а с ним - parser.
А в парсере 11-кратные (это сегодня) рекурсии - не поверю что самая эффективная операция.

Я имею ввиду - нерекурсивные алгоритмы. И байт код - это экономия при повторном заходе на элемент, один-то раз lexer все равно сработает.
Грубо говоря, эксперимент с FMP должен получиться чистый - там же всего один проход по "исходнику"
карма: 9

0
Ответов: 2125
Рейтинг: 159
#41: 2007-06-28 12:58:27 ЛС | профиль | цитата
Dilma писал(а):
схемы из пары сотен элементов будут собираться почти мгновенно

Трансляцию надо делать один раз, а потом выполнять дерево программы, т.е. каждый узел дерева должен иметь виртуальную функцию Calc(context_list), выполняющую соответствующую узлу функцию, вызывая при необходимости аналогичную функцию под-узлов.

[size=-2]------ Добавлено в 12:53
Желательно также не делать "многофункциональных" узлов, чтобы избежать накладных расходов многофункциональности.

[size=-2]------ Добавлено в 12:58
Вобщем, должно быть похоже на интерпретатор схем, за исключением, что элементы такой схемы - это не готовые объекты, а построенные по скрипту деревья. Dilma, ты-ж на интерпретаторах схем "собаку съел", когда делал первые версии HiAsm!
карма: 1

0
Администрация
Ответов: 15295
Рейтинг: 1519
#42: 2007-06-28 13:10:26 ЛС | профиль | цитата
Galkov писал(а):
А в парсере 11-кратные (это сегодня) рекурсии - не поверю что самая эффективная операция.

есть такое дело. Последствия исполнения на лету...

tsdima писал(а):
ты-ж на интерпретаторах схем "собаку съел", когда делал первые версии HiAsm!

к сожалению схему интерпретировать проще. Это для пользователя она преставлена кубиками со свяязями. А внутри-то уже готовое полноценное дерево

tsdima писал(а):
т.е. каждый узел дерева должен иметь виртуальную функцию Calc(context_list)

в VB так и сделано. Только с учетом того, что программа не ввиде дерева, а ввиде цепочки лежит с польской формой записи выражений.

Очередное расширение CG
   Добавлен объект lng - изначально пустой объект, наполняемый разработчиком своими специфическими методами, заточенными только под данный пакет. В пакете Delphi2 приведен пример реализации кода скрипта в компоненте Button:
  ...
old = block.select(BLK_PRIV_VAR)
println(btn, ':PControl;')
block.select(old)
...
ввиде всего одного вызова метода объекта lng:
   lng.decl_priv_var(btn, 'PControl')[/code]
карма: 27
0
Ответов: 9906
Рейтинг: 351
#43: 2007-06-28 13:53:04 ЛС | профиль | цитата
Dilma писал(а):
есть такое дело. Последствия исполнения на лету...

Ну вот... Зря я что ли ДРАКОНА читал - посмотрим, проверим...
Не настолько там и не прозрачно все





[size=-2]------ Добавлено в 13:53
tsdima писал(а):
Трансляцию надо делать один раз, а потом выполнять дерево программы, т.е. каждый узел дерева должен иметь виртуальную функцию Calc(context_list), выполняющую соответствующую узлу функцию, вызывая при необходимости аналогичную функцию под-узлов.

А вот не все так просто, как ты рассказываешь

1) Вообще-то, у нас не совсем дерево. А в общем случае - совсем не дерево. Ex-ы и DPE-точки превращают дерево в граф (ДАГ - по научному).
А если еще и "кольцевания" есть, то в циклический граф. А ты, помнится, еще и примеры "неприводимых" выкладывал

2) Одной ф-ии Calc(context_list) не фига недостаточно для уважаемых всеми вариантов трансляции.
Букварь называет результат вызова аналогичной ф-ии - синтаксическим аттрибутом. Результирующий код - это такой аттрибут, и вроде бы кроме него нам ничего нафиг и не надо.
НО, беда в том, что такая ф-ия имеет, как правило, входные параметры.
Которые букварь (не я) называет уже наследуемыми аттрибутами.
Где его (входной параметр) взять ???
Выполнить какую-то другую ф-ию, для которой он уже будет синтаксическим. А у ней в свою очередь могут оказаться наследуемые...
И т.д., в общем

В скриптовых языках все эти необходимые ф-ии, и порядок их вызова определяются на этапе конструирования компилятора, и закладываются в некие правила раскрытия "нетерминала"
На узле дерева - грубо говоря...

Более приземленно: чтобы сконструировать код элемента Memory (к примеру) нам же надо знать тип данных, которые он (Memory) будет хранить. Этот тип должен пойти на вход той самой ф-ии, которая сделает код (у нас это скрипт метода элемента). А чтобы разумно (а не с потолка) сказать какой тип нужен, не плохо бы знать кто и чего просит от этого элемента.
В "классике" это означало бы необходимость ф-ии, которая не код возвращает, а этот тип...

Вот я вчера примерчик приводил...
Add(Button,2600237,161,56)
{
Left=20
Top=20
Caption="2"
Data=String(ФФФ)
link(onClick,6056868:doEvent1,[])
}
Add(Button,16372707,161,126)
{
Left=20
Top=55
Caption="1"
Data=Integer(111)
link(onClick,72255:doEvent1,[])
}
Add(Memory,12744181,364,63)
{
}
Add(HubEx,7214230,322,56)
{
link(onEvent,12744181:doValue,[])
}
Add(Hub,6056868,231,56)
{
link(onEvent1,2361893:doStrCat,[(334,62)(334,139)])
link(onEvent2,7214230:doWork2,[])
}
Add(Hub,72255,231,126)
{
link(onEvent1,10819280:doStrCat,[])
link(onEvent2,7214230:doWork3,[(326,139)])
}
Add(StrCat,10819280,357,126)
{
Str1="Перед первым: "
link(onStrCat,9836160:doWork2,[])
link(Str2,12769590:Var2,[])
}
Add(HubEx,9836160,455,119)
{
link(onEvent,15475207:doText,[])
}
Add(GetDataEx,12769590,357,105)
{
link(Data,12744181:Value,[])
}
Add(Label,15475207,497,126)
{
Left=20
Top=95
Width=255
Height=20
Color=12632256
AutoSize=1
Alignment=2
}
Add(StrCat,2361893,399,133)
{
Str1="Перед вторым: "
link(onStrCat,9836160:doWork3,[(459,139)])
link(Str2,12769590:Var3,[(412,114)])
}
Так в ём, тип данных у элемента Memory вроде string быть должен
Как догадался рассуждал "с конца"
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#44: 2007-06-28 14:13:09 ЛС | профиль | цитата
FTCG

ручной запуск механизма конвертации типов производится операторами e_XXX. Сейчас таких операторов три: e_int, e_str, e_real. В качестве примера можно помотреть метод doCaption элемента Label
карма: 27
0
Ответов: 2125
Рейтинг: 159
#45: 2007-06-28 14:23:20 ЛС | профиль | цитата
Galkov писал(а):
тип данных у элемента Memory вроде string быть должен

На самом деле, тип данных у элемента Memory в данном случае должен быть variant. Ясно, что число можно и строкой представить, и в этом смысле string в данном случае выполняет роль хранилища для разных типов данных. А если бы это было число и bitmap, например?

[size=-2]------ Добавлено в 14:23
"Ключевым" в данном примере является HubEx: он получает на входах разные типы данных, а выдаёт через один выход. Вот он и должен выдавать variant, по которому определяется тип переменной Memory.
карма: 1

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)