Assasin писал(а):
На этот счет я уже готовил фразу "нет, не допустим"А зачем условие ставил if cnt>0 then
Assasin писал(а):
После взгляда на такое я начинаю понимать смысл жизниДа ладно тебе...
Ну да, не шашкой махать.
НО, есть же главное - можно делать по частям....
Ну полсотни строк кода... Ну может чуть больше, ибо не все еще продуманно.
Ну да - не десять. Но ведь можно же сделать так, чтобы это на другие уровни не влияло.
Вот.......
А уровней нас вовсе не сто. И в шею особо никто не гонит.
Вполне себе... За конечное время, можно сделать результат, к которому потом не подходить десятилетиями. А он будет работать.
Лично мне - просто интересен сам факт: за конечное время... к которому потом не подходить
Типа - именно в этом и есть смысл жизни
Но это так - опять философия. Не бери в голову. Лучше всего - развеяться немного (типа на пляж сходить)
------------ Дoбавленo в 10.39:
Assasin писал(а):
Так что я лучше постараюсь оттестить тот код, что уже есть, и на этом закончуУ меня есть предложение -- сменить тональность на менее печальную.
Да, совершенно необходимо выложить боевой вариант, с указанными тобой характеристиками:
1) Подсчет длины MT-цепочки для передачи вверх на точку - тут относительно просто все.
2) Подсчет размера стека при компиляции - тут мне представляется, что без рекурсивного анализа не обойтись. Да хоть бы и открытое поле maxSP в TResult.
И у меня есть несколько дополнительных (к твоим) соображений:
3) Компилировать ТОЛЬКО по SetLine и SetDebug. А сообщения об ошибке выдавать только по doCalc. Или реально запускать, коль скоро нет ошибок. Не, ну сам подумай: пусть есть ошибка компиляции, и мы, как дураки, на каждый doCalc начинаем компилировать. Типа - а вдруг в прошлый раз СЛУЧАЙНО не откомпилировалось.
4) LPos у нас дурацкий какой-то... Вообще-то он указывает на начало следующей лексемы, после ошибочной. Думаю, его надо забуферизировать. Типа, в GetToken сохранять его (после скипа пробельных) в какой-нибудь OldPos. Который в последствии и использовать. А из их разница, кстати говоря - даст длину лексемы ошибки...
5) CalcErrPos - надо взять от nesco из MathParse.
6) Синтаксическую диаграмму надо переделать нафиг.
Соображения по п.3 - руки у меня шаловливые, и это почти у меня реализовано - я выложу для посмотреть, и подумать.
По п.6 - у меня нарисовано, но дома. Вечером выложу. Думаю, для тебя это не трудно будет.
Ибо здесь важна не скоропись, а понимание происходящего.
Зато правильно получится. Да и работают такие вещи, обычно - почти с первого раза.
Вот, и чего у нас получится...
А получится боевой вариант, про который уже смело можно будет сказать - "замахается пользователь почувствовать именно вычислительные задержки".
Это весьма достойный результат.
И, главное - он приспособлен (после внедрения TResult) к расширениям в сторону оптимизации.
Могут далее появиться Боевой+, Боевой++...
Если не зарекаться
------------ Дoбавленo в 20.44:
Соображения по п.3 - руки у меня шаловливые, и это почти у меня реализовано - я выложу для посмотреть, и подумать.
По п.6 - у меня нарисовано, но дома. Вечером выложу. Думаю, для тебя это не трудно будет.
По п.6 - у меня нарисовано, но дома. Вечером выложу. Думаю, для тебя это не трудно будет.
Вот код
А вот синтаксис:
Синтаксис
============= Синтаксис ================================================================================================
<Expression> := <Compare> { <TokLog> <Compare> }. // Логические операторы (and or xor)
<Compare> := [ 'not' ] <Addition> { <TokCmp> <Addition> }. // Логический NOT, и сравнение (< > <= >= = <>)
<Addition> := [ ('+'|'-') ] <Production> { ('+'|'-') <Production> }. // Сложение/Вычитание
<Production> := <Powers> { <TokMul> <Powers> }. // Умножение/Деление
<Powers> := <BinExp> { '^' <BinExp> }. // Возведение в степень
<BinExp> := <Binary> { <TokBin> <Binnary }. // Бинарные операторы (& | ! << >>)
<Binary> := [ '~' ] <Atoms>. // Бинарная инверсия (~)
<Atoms> := <TokArg> [ '[' <Expression> [ ',' <Expression> ] ']' // Просто Пин, или Массив, или Матрица
| '(' <Expression> { ',' <Expression> } ')' ] // или Пин-Функция
| <TokName> [ '(' <Expression> { ',' <Expression> } ')' ] // или Функции (встроенные, и пользовательские)
| '(' <Expression> ')' // или Просто скобочная рекурсия
| <TokNumber> | <TokHex> | <TokReal>. // или Тупо константа
============= Сканер ===================================================================================================
SKIP := ' ' | #9 | #10 | #13.
<TokLog> := 'and' | 'or' | 'xor'.
<TokCmp> := '<' | '<>' | '<=' | '>' | '>=' | '='.
<TokMul> := '*' | '/' | 'div' | 'mod'.
<TokBin> := '&' | '|' | '!' | '<<' | '>>'.
<TokArg> := '%' <TokNumber>.
<TokName> := <isLetter> { <isLetter> | <isDigit> }.
<TokNumber> := <isDigit> { <isDigit> }.
<TokHex> := ( '$' | '0x' ) <isHEX> { <isHEX> }.
<TokReal> := ( <isDigit> { <isDigit> } [ '.' { <isDigit> } ]
| '.' <isDigit> { <isDigit> } )
[ ('E'|'e') ['+'|'-'] <isDigit> { <isDigit> } ].
ERROR := <isANY>.
// <isXXX> - это один символ из соответствующего множества
// их всегда можно записать как <isXXX> := 'sym1' | 'sym2' | ... .
BTW:
В принципе, для операций сравнения уже существуют общепринятые суффиксы GT, LT, GE, LE, EQ, NE.
Так было бы лучше:
#pas
....
Cmd_GT = $14; // >
Cmd_LT = $15; // <
Cmd_GE = $16; // >=
Cmd_LE = $17; // <=
Cmd_EQ = $18; // =
Cmd_NE = $19; // <>
....
------------ Дoбавленo в 13.18:
Вот еще предложение...
А вот пускай множественный Compare (операции сравнения) будет У НАС обладать такой семантикой:
E0 <cmp1> E1 <cmp2> E2 <cmp3> E3 ... <cmpn> En ==> (E0 <cmp1> E1) and (E1 <cmp2> E2) and (E2 <cmp3> E3) ... and (En-1 <cmpn> En)
И при этом, всякие там арифметические выражения E1 ... En-1 мы будем считать только один раз.
Естественно.