Ты знаешь Rel может быть да может быть и нет всё конечно может быть ещё раз повторюсь я занимаюсь этим просто ради интереса и не более того через год на пенсию философски можно так сказать впереди вечность чем ещё заниматься если не интересным делом а нужно оно кому нибудь или нет мне всё равно главное что это нужно мне по сути просто для самоудовлетворения А на счёт интерпретатора я уже писал выше он реально работает естественно нужно соблюдать определённый синтаксис без этого никуда но как ты понимаешь правила этого синтаксиса устанавливаю именно я а не кто то другой алгоритм интерпретатора сам понимаешь в двух словах не объяснить но ещё раз повторюсь он не просто работает он прекрасно работает моя задача на данный момент заменить некоторые алгоритмы ну и естественно я могу просто дописывать алгоритмы интерпретатора что бы он мог делать ещё что нибудь стоящее сам понимаешь по сути эта целая философия кода конечно мощный анализатор языка Си под капотом выстроит более эфективный код в плане быстродействия я далёк от мысли что инженерам программистам Майкрософта платят не заслуженную зарплату по этому анализаторы кода они стараются держать на уровне и мой простой анализатор и в подмётки не годится ему но работоспособность кода он обеспечивает и это пока что для меня самое главное не считая того что в критических секциях кода я могу просто прописать код на чистом ассемблере мой интерпретатор это вполне позволяет по сути чистый код ассемблера или синтаксис masm32 он просто проигнорирует то есть оставит всё как есть он обратит внимание только на то на что я ему укажу и соответственно под капотом в этом месте нарисует нужный мне код ты просто не догадываешься что на самом деле всё очень просто нужно только придерживаться определённому синтаксису то есть определённым правилам которые ещё раз повторюсь устанавливаю я
Да ради Бога, мне не принципиально, как ты там и что делаешь, я о том, что использовать форто-подобный язык для интерпретации в твоем случае имеет смысл, если прям мастурбировать на скорость и наносекунды исполнения. В других случаях, если хочешь получить что-то практичное, которое смогут использовать "не только лишь ты", то лучше брать что-то другое в качестве синтаксиса.
Конечно я старался чтобы некоторый скажем так новый синтаксис был интуитивно понятным и был чем то похож а в определённых случаях повторял синтаксис например Си а в условном цикле (for) в одной из его интерпретаций я применил оператор Паскаля ( to ) короче с миру по нитке Сейчас уже поздно а завтра я выложу здесь свою статью про условные операторы моего интерпретатора которую я писал просто для себя что бы не забыть а то бывает доходит до смешного сам уже начинаю путаться в синтаксисе своих же команд и операторов
Интуиция мне подсказывает, что это будет что-то очень интересное, по крайней мере для меня. Буду ждать. P.S. По вашим постам складывается впечатление, что вы очень светлый, позитивный и отзывчивый человек. Не то что некоторые на ВАСМе, не будем показывать пальцем, а лишь слегка намекнем... Даже в этом треде такие "пассажиры" присутствуют. Поэтому, хочется пожелать вам долгой и интересной пенсии, за время которой ВАСМ бы пополнился не менее интересными статьями.
Спасибо GRAFik за позитивный отзыв если это интересно то вот сама статья которую я писал для себя чтобы просто не забыть поведение своих операторов эта статья я надеюсь хоть немного объяснит поведение моего интерпретатора при обработки условных конструкций как я и предполагал в один пост статья не помещается по объективным ограничительным мерам форума по этому она разбита на две части Часть первая: --------------------------------------------------------------------- интерпретатор обрабатывает пять видов конструкций условий: --------------------------------------------------------------------- 1 - конструкция группы - if --------------------------------------------------------------------- if ... // если условие верно выполняется код ... // код elseif ... // если условие верно выполняется код ... // код else // без условий выполняется код ... // код endif // конец тела условия --------------------------------------------------------------------- 2 - конструкция группы - switch --------------------------------------------------------------------- switch ... // значение с которым будет сравнение case ... // значение которое сравнивается ... // код endsw // конец тела сравнений --------------------------------------------------------------------- 3 - конструкция цикла группы - while --------------------------------------------------------------------- while ... // если условие верно то выполняется код цикла ... // код endw // конец тела цикла --------------------------------------------------------------------- 4 - конструкция цикла группы - repeat --------------------------------------------------------------------- repeat // начало цикла ... // код until ... // если условие верно то выход из цикла --------------------------------------------------------------------- 5 - конструкция цикла группы - for --------------------------------------------------------------------- for ... // если условие верно то выполняется код цикла ... // код endf // конец тела цикла --------------------------------------------------------------------- допускаются вложенные друг в друга конструкции --------------------------------------------------------------------- запись утрированных одинарных условий: --------------------------------------------------------------------- x // если (x) - не ноль !x // если (x) - ноль x == 1 // если (x) - равен (1) x != 1 // если (x) - не равен (1) x <> 1 // если (x) - не равен (1) x < 1 // если (x) - меньше (1) x > 1 // если (x) - больше (1) x <= 1 // если (x) - меньше или равен (1) x >= 1 // если (x) - больше или равен (1) --------------------------------------------------------------------- так же применяя логические операторы (&&) и (||) --------------------------------------------------------------------- && понимается как (и) || понимается как (или) --------------------------------------------------------------------- можно записывать не одинарные условия: --------------------------------------------------------------------- x == 1 || x == 2 && y < 3 --------------------------------------------------------------------- эти операторы отличаются от некоторых (не всех) операторов - masm32 отсутствием префикса точки этот акцент делается для интерпретатора если интерпретатор увидит префикс точки (синтаксис - masm32) то он не будет заниматся этой конструкцией и оставит его - ml.exe --------------------------------------------------------------------- .if eax == 0 ... .endif --------------------------------------------------------------------- запись условия или условий в операторах без префикса точки почти такая же как и на основной платформе - masm32 исключение составляет условие типа (x <> 1) что означает что первый параметр не равен второму параметру по сути это одно и тоже что и (x != 1) --------------------------------------------------------------------- так же если пишется просто условие то по умолчанию интерпретатор формирует код для беззнакового условия потому что на практике это бывает чаще всего применительно к - dword значения от (0) до (FFFFFFFFh) это беззнаковые значения но если условие нужно построить для знакового значения применительно к - dword значения от (0) до (7FFFFFFFh) это плюсовые значения а значения больше (7FFFFFFFh) до (FFFFFFFFh) это минусовые значения то вначале условия нужно обязательно прописать спецификатор - # не после оператора условия а именно перед конкретным условием спецификатор не является префиксом в чистом виде по этому после спецификатора писать пробелы или нет это дело вкуса для интерпретатора это не имеет ни какого значения например: --------------------------------------------------------------------- x == 1 || #x < 0 && y < 3 --------------------------------------------------------------------- в этом случае интерпретатор для первого и третьего условия сформирует под капотом код для беззнакового значения а для второго условия для знакового значения чтобы понять смысл: --------------------------------------------------------------------- например переменная (x) имеет значение (-1) то есть меньше нуля и если перед вторым условием не прописать спецификатор - # то это условие не сработает потому что для программы значение (-1) это будет беззнаковое значение (FFFFFFFFh) больше нуля а если прописать впереди условия спецификатор - # то для программы (-1) это будет знаковое значение меньше нуля и соответственно условие отработает правильно --------------------------------------------------------------------- для примера попробуйте прописать это условие на синтаксисе - masm32 то есть с операторами с префиксом точки --------------------------------------------------------------------- .if x < 0 ... .endif --------------------------------------------------------------------- это условие не сработает так как по умолчанию на - masm32 подобная запись в лоб будет расматриватся как действие с беззнаковыми значениями чтобы это условие сработало могу ошибатся но кажется на платформе - masm32 нужно задействовать оператор флага - SIGN? что мягко говоря не совсем удобно по этому на новых операторах это сделать гораздо легче но всё равно нужно не забывать что по умолчанию условия расматриваются как беззнаковые и если нужно условие именно со знаковым значением на практике эта потребность возникает гораздо реже но всё же бывает по этому нужно просто знать что для этого достаточно перед условием прописать спецификатор - # и интерпретатор сформирует условие для знаковых значений --------------------------------------------------------------------- если нужно условие для вещественных значений типа - float перед условием нужно прописать двойной спецификатор - ## если нужно условие для вещественных значений типа - double перед условием нужно прописать тройной спецификатор - ### --------------------------------------------------------------------- в примерах будут показаны утрированные записи одинарных условий без применения спецификатора - # --------------------------------------------------------------------- --------------------------------------------------------------------- --------------------------------------------------------------------- конструкция группы - if --------------------------------------------------------------------- оператор - if обязательный оператор конструкции с одним параметром в конструкции записывается первым в параметре должно быть прописано условие или условия под капотом в этом месте интерпретатор пишет синтаксис условия и если условие верно то выполняется код в теле оператора - if --------------------------------------------------------------------- оператор - elseif не обязательный оператор конструкции с одним параметром в теле конструкции может прописыватся один или более раз в параметре должно быть прописано условие или условия под капотом в этом месте интерпретатор пишет синтаксис условия и если условие верно то выполняется код в теле оператора - elseif --------------------------------------------------------------------- оператор - else не обязательный оператор конструкции без параметра в теле может прописыватся в конце конструкции только один раз под капотом в этом месте интерпретатор пишет метку на которую осуществляется переход если предыдущее условие или условия операторов (if) или (elseif) не были верны и тогда выполняется код в теле оператора - else --------------------------------------------------------------------- оператор - endif условно не обязательный оператор конструкции без параметра в зависимости от реализации в конструкции прописывается последним под капотом в этом месте интерпретатор пишет метку или метки --------------------------------------------------------------------- пример полной конструкции со всеми операторами: --------------------------------------------------------------------- if x == 1 ... elseif x == 2 ... else ... endif --------------------------------------------------------------------- пояснения к тому что оператор - endif это условно не обязательный оператор --------------------------------------------------------------------- применительно к любой записи кода проекта интерпретатор разрешает записывать несколько строк на одной строке для этого применяется спецификатор наклонного слеша пробелы роли не играют утрированный пример: --------------------------------------------------------------------- mov x,1 \ mov x,2\mov x,3 --------------------------------------------------------------------- этот спецификатор в данном случае выполняет роль разделителя и должен быть именно промежуточным а не последним интерпретатор под капотом запишет эту строчку вот так: --------------------------------------------------------------------- mov x,1 mov x,2 mov x,3 --------------------------------------------------------------------- если применить этот спецификатор после условия оператора - if --------------------------------------------------------------------- if x == 1 \ mov x,0 --------------------------------------------------------------------- то интерпретатор будет считать что применена однострочная схема конструкции - if и для интерпретатора эта запись будет как --------------------------------------------------------------------- if x == 1 mov x,0 endif --------------------------------------------------------------------- если прописать не один спецификатор с последующими за ними данными --------------------------------------------------------------------- if x == 1 \ mov x,0 \ mov y,1 \ mov z,2 --------------------------------------------------------------------- для интерпретатора эта запись будет как --------------------------------------------------------------------- if x == 1 mov x,0 mov y,1 mov z,2 endif --------------------------------------------------------------------- этот подход однострочной записи разрешается только в этой конструкции и только с оператором - if при попытке прописать другие операторы этой конструкции например вот так: --------------------------------------------------------------------- if x == 1 \ mov x,1 ... endif --------------------------------------------------------------------- интерпретатор вызовет ошибку так как он уже сам оформил закрывающий оператор - endif то есть под капотом сам пропишет метку конца условия при открытии любого условия интерпретатор записывает это условие в определённую структуру а при закрытии условия уничтожает данные этого условия в этой структуре не сложно догадатся что оператор - endif как раз и даёт команду интерпретатору о закрытии и соответственно когда интерпретатор увидит этот оператор - endif он не сможет найти о нём данные в так называемом реестре и по этому вызовет ошибку --------------------------------------------------------------------- если в этой конструкции применить операторы цикла: --------------------------------------------------------------------- break // безусловный переход на метку выхода из цикла break if ... // переход на метку выхода из цикла с условием continue // безусловный переход на метку входа цикла continue if ... // переход на метку входа цикла с условием --------------------------------------------------------------------- то они сработают только в том случае если конструкция - if сама находится в теле конструкции какого нибудь цикла например в конструкции циклов (while) или (repeat) или (for) если нет то интерпретатор вызовет ошибку --------------------------------------------------------------------- --------------------------------------------------------------------- --------------------------------------------------------------------- конструкция группы - switch --------------------------------------------------------------------- оператор - switch условно не обязательный оператор конструкции с одним параметром в зависимости от реализации в конструкции записывается первым параметром должен быть или объект памяти или регистр явное числовое значение или константа не допускаются под капотом интерпретатор просто запопинает параметр оператора --------------------------------------------------------------------- оператор - case условно обязательный оператор конструкции с одним параметром параметром может быть любое значение в теле конструкции может прописыватся один или более раз если в теле конструкции не прописать ни одного оператора - case ошибки не будет и конструкция будет просто пустой под капотом в этом месте идёт сравнение значения параметра - switch с параметром оператора - case и если значения одинаковые выполняется код в теле оператора - case --------------------------------------------------------------------- оператор - endsw условно не обязательный оператор конструкции без параметра в зависимости от реализации в конструкции прописывается последним под капотом в этом месте прописывается метка выхода --------------------------------------------------------------------- пример конструкции: --------------------------------------------------------------------- switch Tmp case 1 ... case 2 ... case 3 ... endsw --------------------------------------------------------------------- для интерпретатора это выглядит по сути вот так: --------------------------------------------------------------------- if Tmp == 1 ... elseif Tmp == 2 ... elseif Tmp == 3 ... endif --------------------------------------------------------------------- если в этой конструкции - switch применить операторы цикла: --------------------------------------------------------------------- break // безусловный переход на метку выхода из цикла break if ... // переход на метку выхода из цикла с условием continue // безусловный переход на метку входа цикла continue if ... // переход на метку входа цикла с условием --------------------------------------------------------------------- то они сработают только в том случае если конструкция - switch сама находится в теле конструкции какого нибудь цикла например в конструкции циклов (while) или (repeat) или (for) если нет то интерпретатор вызовет ошибку --------------------------------------------------------------------- пояснение к тому что операторы (switch) и (endsw) были объявленны как условно обязательными: --------------------------------------------------------------------- если в коде проекта прописывается процедура окна - proc то интерпретатор всегда по умолчанию под капотом в этой процедуре окна сам в начале имитирует конструкцию - switch а перед функцией обработки сообщений которую тоже под капотом прописывает сам имитирует конструкцию - endsw по сути интерпретатор под капотом заряжает пустую конструкцию - switch по этому в процедуре окна для обработки сообщений можно использовать только оператор - case утрированный пример: --------------------------------------------------------------------- proc hWnd case WM_CREATE ... case WM_PAINT ... case WM_LBUTTONDOWN ... end --------------------------------------------------------------------- если оператор - case принадлежит именно этой имитационной конструкции - switch то в теле оператора под капотом в конце прописывается безусловный переход на выход из процедуры окна то есть мимо функции обработки сообщений по мимо упрощённой записи обработки сообщений окна если обработка сообщения в теле оператора не достаточна то в виде исключения интерпретатор разрешит применить операторы -------------------------------------------------------------- break // безусловный выход break if // выход с условием -------------------------------------------------------------- которые направят код на выход из этой конструкции то есть на функцию сообщений окна но это возможно только в имитационной конструкции - switch процедуры окна - proc --------------------------------------------------------------------- можно конечно для обработки сообщений окна прописать и полноценную конструкцию - switch --------------------------------------------------------------------- proc hWnd switch uMsg case WM_CREATE ... return case WM_PAINT ... return case WM_LBUTTONDOWN ... return endsw end --------------------------------------------------------------------- только для этого придётся прописать определённые дополнения это просто альтернатива но имитационная конструкция на много лучше --------------------------------------------------------------------- --------------------------------------------------------------------- --------------------------------------------------------------------- конструкция цикла группы - while --------------------------------------------------------------------- оператор - while обязательный оператор конструкции с одним параметром в конструкции записывается первым в параметре должно быть прописано условие или условия под капотом в этом месте интерпретатор пишет метку входа в цикл и синтаксис условия и если условие верно то выполняется код в теле оператора - while --------------------------------------------------------------------- оператор - endw обязательный завершающий оператор конструкции без параметра под капотом в этом месте интерпретатор пишет безусловный переход на метку входа и пишет метку выхода --------------------------------------------------------------------- утрированный пример: --------------------------------------------------------------------- while x > 8 ... endw --------------------------------------------------------------------- так же в теле конструкции цикла можно использовать операторы: --------------------------------------------------------------------- break // безусловный переход на метку выхода из цикла break if ... // переход на метку выхода из цикла с условием continue // безусловный переход на метку входа цикла continue if ... // переход на метку входа цикла с условием --------------------------------------------------------------------- --------------------------------------------------------------------- --------------------------------------------------------------------- конструкция цикла группы - repeat --------------------------------------------------------------------- оператор - repeat обязательный оператор конструкции без параметра в конструкции записывается первым под капотом в этом месте интерпретатор пишет метку входа в цикл --------------------------------------------------------------------- оператор - until обязательный оператор конструкции с одним параметром в параметре должно быть прописано условие или условия под капотом в этом месте интерпретатор пишет безусловный переход на метку входа если условие не выполнено смысл конструкции цикла заключается в том что если условие будет верным то тогда выход из цикла то есть на метку прописанную под капотом срузу же после прописанного безусловного перехода на метку входа --------------------------------------------------------------------- утрированный пример: --------------------------------------------------------------------- repeat ... until x > 8 --------------------------------------------------------------------- так же в теле конструкции цикла можно использовать операторы: --------------------------------------------------------------------- break // безусловный переход на метку выхода из цикла break if ... // переход на метку выхода из цикла с условием continue // безусловный переход на метку входа цикла continue if ... // переход на метку входа цикла с условием --------------------------------------------------------------------- --------------------------------------------------------------------- ---------------------------------------------------------------------
Часть вторая: --------------------------------------------------------------------- --------------------------------------------------------------------- --------------------------------------------------------------------- конструкция цикла группы - for --------------------------------------------------------------------- оператор - for обязательный оператор конструкции в зависимости от реализации может иметь от одного до трёх параметров которые записываются через запятую синтаксис записи параметров примерно похож на синтаксис языка программирования (Си) под капотом в этом месте интерпретатор пишет: необходимые данные если они указаны в первом параметре оператора метку входа в цикл а так же синтаксис условия или условий этого цикла и если условие верно то выполняется код в теле цикла --------------------------------------------------------------------- оператор - endf обязательный завершающий оператор конструкции без параметра под капотом в этом месте интерпретатор пишет действие или действия если они были указаны и пишет безусловный переход на метку входа а так же записывает метку выхода из цикла --------------------------------------------------------------------- если у оператора (for) прописано три параметра то это классический вариант использования этого оператора: --------------------------------------------------------------------- 1 параметр - (инициализация) объектов цикла 2 параметр - (условие или условия) для выполнения цикла 3 параметр - (модификация) действия перед выходом на начало цикла --------------------------------------------------------------------- если у оператора - for заполнены все три параметра по классическому варианту то интерпретатор будет ожидать что: --------------------------------------------------------------------- в первом параметре будет прописан объект памяти или регистр который будет инициализирован через обязательный одиночный символ (=) иначе интерпретатор вызовет ошибку синтаксически это будет эапись типа: --------------------------------------------------------------------- i=0 --------------------------------------------------------------------- и под капотом перед меткой входа в цикл будет записан код --------------------------------------------------------------------- mov i,0 --------------------------------------------------------------------- но если нужно например перед началом цикла обьявить ещё какие нибудь объекты памяти или регистры с нужным значением то это можно сделать при помощи спецификатора прямого слеша (|) который по сути выполнит роль разделителя данных синтаксически это будет эапись типа: --------------------------------------------------------------------- i=0|x=7|ebx=8 --------------------------------------------------------------------- под капотом перед меткой входа в цикл будет записан код --------------------------------------------------------------------- mov i,0 mov x,7 mov ebx,8 --------------------------------------------------------------------- во втором параметре интерпретатор будет ожидать что прописано условие или ряд условий утрированно что то типа: --------------------------------------------------------------------- i <= 8 --------------------------------------------------------------------- в третьем параметре интерпретатор будет ожидать что прописано действие или действия которые под капотом завершающего оператора - endf будут прописаны перед безусловным переходом на начало цикла --------------------------------------------------------------------- в параметре должен быть прописан объект и действие с ним действиями должны быть только эти символы --------------------------------------------------------------------- ++ // увеличение значения объекта на единицу -- // уменьшение значения объекта на единицу + // прибавление к значению объекта - // отнимание от значения объекта --------------------------------------------------------------------- с символами умножения и деления оператор не работает и соответственно это вызовет ошибку --------------------------------------------------------------------- если нужно объект памяти или регистра увеличить на единицу или уменьшить на единицу синтаксически это будут запись типа: --------------------------------------------------------------------- i++ i-- eax++ eax-- --------------------------------------------------------------------- символы плюсов или минусов прописываются именно постфиксно --------------------------------------------------------------------- если к объекту нужно что то прибавить больше единицы или от объекта нужно что то отнять больше единицы то в данном случае нужно применить выражение но в выражении нельзя прописывать два объекта памяти можно только если в выражении есть регистр или явное числовое значение или константа числового значения например вот так: --------------------------------------------------------------------- i+2 i-2 eax+2 eax-2 i+eax i-eax eax+i eax-i --------------------------------------------------------------------- так же как и в первом параметре здесь можно через разделительный спецификатор прямого слеша (|) прописать дополнительные действия что то типа: --------------------------------------------------------------------- i++|x+3|y-2 --------------------------------------------------------------------- все эти действия под капотом оператора - endf пропишутся перед безусловным переходом на начало цикла --------------------------------------------------------------------- inc i add x,3 sub y,2 --------------------------------------------------------------------- с полностью заполненными тремя параметрами и без всяких дополнительных объектов это классически будет выглядеть примерно так: --------------------------------------------------------------------- for i=0, i <= 8, i++ ... endf --------------------------------------------------------------------- под капотом сначала инициализируется нулём переменная (i) потом пропишется метка входа в цикл а под капотом оператора - endf пропишутся действия указанные в третьем параметре то есть увеличение на единицу переменной (i) после пропишется безусловный переход на начало цикла --------------------------------------------------------------------- если у оператора - for будут заполнены только два параметра это будет означать что или в первом параметре присутствует оператор - to или это будет означать что один из параметров заполняемых при классической схеме не нужен --------------------------------------------------------------------- чтобы это выяснить интерпретатор проведёт анализ первого параметра и если она обнаружит в первом параметре оператор - to это будет означать что первый и второй параметр класической схемы объеденены и имеют немного другой смысл --------------------------------------------------------------------- в первом параметре сначала прописывается инициализация или множественная инициализация потом следует оператор - to а за ним указывается или явное число или объект памяти или регистр --------------------------------------------------------------------- во втором параметре указывается действие или действия синтаксически без дополнительных инициализаций и действий это будет выглядеть примерно так: --------------------------------------------------------------------- for i=3 to 5,i++ ... endf --------------------------------------------------------------------- по сути оператор (to) в переводе (до) означает что нужно основной параметр цикла (i) в данном примере довести до значения (5) и как только значение будет больше проиэойдёт выход из цикла так же это можно применить и на минусовых значениях пример без дополнений: --------------------------------------------------------------------- for i=10 to 4,i-2 ... endf --------------------------------------------------------------------- применение такой схемы с оператором - to в первом параметре должна быть интуитивно понятной она немного напоминает синтаксис языка паскаль по сути исходя из примера нужно переменную цикла (i) довести до значения указаного после оператора - to в конце первого параметра шагами прописанными во втором параметре --------------------------------------------------------------------- здесь в первом параметре до оператора - to тоже можно применить множественную инициализацию и во втором параметре так же можно прописать множество действий но в любом случае оператором цикла будет только первый по ходу объявленный объект из первого параметра а формироватся условие под капотом будет только по первому прописанному действию второго параметра если взять предыдущий пример и дополнить его: --------------------------------------------------------------------- for i=10|x=5 to 4,i-2|x++ ... endf --------------------------------------------------------------------- то оператором цикла будет переменная (i) так как она прописана первой в первом параметре (i=10) а формироватся условие будет на основе минуса (-) так как первая запись второго параметра минусовое (i-2) если объект цикла в первом и во втором параметре это будут разные объекты интерпретатор вызовет ошибку так же можно у переменной цикла и только у неё в первом параметре не указывать инициализацию: --------------------------------------------------------------------- for i to 0,i-- ... endf --------------------------------------------------------------------- в этом случае переменная цикла в данном случае (i) просто не будет прописыватся с присвоением перед входом в цикл как бы подразумевая что нужное значение уже в ней есть а в теле цикла в конце перед безусловным переходом на начало цикла будет уменьшатся на единицу пока не обнулится но в первой переменной второго параметра нужно обязательно указать действие иначе интерпретатор вызовет ошибку --------------------------------------------------------------------- но если интерпретатор не обнаружит в первом параметре оператор - to значит или первый или третий параметр из классической схемы просто не нужны при выполнении цикла но параметр условия должен быть обязательно чтобы понять какой из этих параметров лишний интерпретатор проведёт предварительный анализ для этого он проверит первый заполненный параметр на предмет нахождения в нём символа (=) и если он не найдёт в этом параметре этот символ значит в первом параметре точно условие но если интерпретатор найдёт этот символ в первом параметре нужно будет выяснить это символ для инициализации или от условия для этого интерпретатор проверит символ перед этим символом и если этим символом будет или (=) или (<) или (>) то интерпретатор будет предпологать что лишний параметр класической схемы это параметр инициализации объектов то есть первый параметр в класической схеме и соответсвенно запись будет примерно такая: --------------------------------------------------------------------- for i >= 3, i-- ... endf --------------------------------------------------------------------- в этом случае интерпретатор просто не будет прописывать предварительную инициализацию перед входом в цикл подобное применение может понадобится если объект уже заранее имеет нужное значение для цикла --------------------------------------------------------------------- но если лишний это третий параметр класической схемы то соответсвенно запись будет примерно такая: --------------------------------------------------------------------- for i=0, i <= 3 ... endf --------------------------------------------------------------------- в этом случае интерпретатор пропишет инициализацию перед циклом но оператор (endf) не будет прописывать ни каких действий перед бузусловным переходом на начало цикла подобное применение может понадобится например если действия будут расписаны в теле цикла самостоятельно --------------------------------------------------------------------- если у оператора - for будет заполнен только один параметр это будет означать что цикл будет использован по упрощённой схеме в параметре должен быть прописан объект с явным или не явным количеством циклов но этот объект не должен быть явным числовым значением а обязательно объектом памяти или регистром под капотом интерпретатор применит только декримент то есть уменьшение значения объекта на единицу перед безусловным переходом на начало цикла фактически цикл будет идти пока объект не обнулится допускается два варианта записи --------------------------------------------------------------------- это указание объекта без инициализации подразумевая что объект уже имеет нужное значение в этом случае количество циклов будет зависить от значения указанного объекта --------------------------------------------------------------------- for i ... endf --------------------------------------------------------------------- и указание объекта с инициализацией --------------------------------------------------------------------- for i=3 ... endf --------------------------------------------------------------------- в этом случае будет только (3) цикла --------------------------------------------------------------------- здесь тоже допускается множественная инициализация спецификатором прямого слеша (|) --------------------------------------------------------------------- for i=3|x=1|y=2 ... endf --------------------------------------------------------------------- но основным объектом будет только первый прописанный объект так как он будет являтся параметром цикла и соответственно именно он будет уменьшатся на единицу перед выходом на начало цикла --------------------------------------------------------------------- в принципи это может сделать оператор - while --------------------------------------------------------------------- while ebx ... dec ebx endw --------------------------------------------------------------------- просто с оператором (for) это будет сделать не много проще --------------------------------------------------------------------- for ebx ... endf --------------------------------------------------------------------- не говоря уже о том что можно в первом параметре прописать упрощённую множественную инициализацию перед началом цикла --------------------------------------------------------------------- for ebx=3|esi=2|edi=1 ... endf --------------------------------------------------------------------- оператор - for это оператор с немного расширенными возможностями но в любом случае выбор за программистом --------------------------------------------------------------------- так же в теле конструкции цикла можно использовать операторы: --------------------------------------------------------------------- break // безусловный переход на метку выхода из цикла break if ... // переход на метку выхода из цикла с условием continue // безусловный переход на метку входа цикла continue if ... // переход на метку входа цикла с условием --------------------------------------------------------------------- --------------------------------------------------------------------- ---------------------------------------------------------------------
Прикольно! Давно нечто подобное хотел сделать. А именно макросы типа LET или EXPR, где как раз разбираются выражения. А ещё можно делать так: переменная := выражения. Это всё частично сделано в UASM, AsmC форки WASM. Получится промежуточный ЯП между С/С++ и ассемблером, да некоторые фичи можно из С++ добавить, упрощенный ООП и тп. ЗЫ Кстати можно взять тот же UASM и форкнуть его, исходники на С. Так что это просто, а вот форнуть FASM очень сложно.
В качестве имхО. Натянуть какие-то элементы высокоуровневого ЯП на ассемблер хотя бы раз жизни приходит в голову каждому второму, кто по какой-то непонятной причине однажды связывается с ассемблером. Если дело доходит до практической реализации, то первый сюрприз, который его ждет - ограниченные возможности макроязыка выбранного ассемблера. Если это их не останавливает, следующий сюрприз - лимит памяти. И самая страшная фрустрация ждет их в конце, когда при переходе к практическому программированию выяснится, что все эти технологии реальную пользу несут в редких частных случаях. А кое-в-чем даже откровенно вредят. Ну вот например это же самое преобразование infix в postfix, в котором буквально читается переложение формулы в последовательность инструкций. Мало того, что эта абстракция должна безбожно хоронить значения eax/edx при делении и умножении (если будут применяться mul/div), едва ли она будет применять например lea reg,[scale*index+base] там, где это применимо. В итоге получится ограниченное применение регистров вручную (либо придется учитывать особенность этих макросов, что не делает их аналогом высокоуровневых ЯП) и дельфи в самом худшем смысле (когда компилятор туп настолько, что по бреду, который он генерирует, его можно безошибочно узнать в листинге). Если чьему-то сердцу так милы высокоуровневые ЯП, может быть не стоит их заменять суррогатами?
Код а точнее коды интерпретатора на данный момент давать бесполезно потому что они написаны на моих старых макросах да и дело даже не в этом просто нужно знать смысловую концепцию интерпретатора а точнее алгоритм его работы а это сами понимаете в двух словах не объяснить посмотрите сначала примеры его работы кому интересно я выкладываю ссылку на файл который я положил на - Облако https://cloud.mail.ru/public/MWj9/CgASzkLD9 кто не боиться скачайте этот архивный файл архив запоролен моим ником - assch что бы не создалась лишняя папка лучше нажимать - извлечь в текущую папку саму папку - masm32++ нужно положить в корень диска открыть папку и запустить ярлык - EmEditor1 если ярлык не сработает нужно открыть папку - editor и в этой папке запустить файл - EmEditor1.exe должен открыться редактор - EmEditor откройте папку - Проекты выбирите какой нибудь проект в папке примера будет обязательная папка проекта с обязательным уникальным названием - $ и главный файл проекта с обязательным названием - $.asm уникальность имён должно быть соблюдено потому что интерпретатор заточен именно на них перетащите мышкой файл - $.asm в окно редактора и там вы увидите философию моего синтаксиса в верхнем левом углу редактора будет зелёная кнопка со стрелкой если вы подведёте к ней мышку покажется подсказка - Run нажмите эту кнопку должен запустится процесс: интерпретации компиляции запуск исполняемого файла - #.exe если вы сделали какие то изменения в коде необязательно нажимать на кнопку - Сохранить так как при нажатии на зелёную стрелку файл сохранится автоматически если что то не получилось то увы значит что то пошло не так если получилось то в папке проекта - $ должно появиться два файла это файл - #.asm в нём будет интерпретированный код который и обрабатывает - ml.exe а в бинарном файле - #Error находится информация о выстроенном коде проекта она понадобится для того чтобы при ошибках правильно определялось место ошибки я еще не занимался этим вторая кнопка после стрелки - чистит папку проекта третья кнопка - уничтожает процесс исполняемого файла четвёртая кнопка - открывает папку платформы - masm32++ пятая кнопка - запускает вторую копию - EmEditor шестая кнопка - запускает третью копию - EmEditor седьмая кнопка - запускает четвёртую копию - EmEditor если повезёт и вас всё запустится просто посмотрите примеры а точнее синтаксис примеров правда большинство примеров не стоят и внимания но некоторые можно посмотреть если что спрашивайте
assch, спасибо. Скачал, посмотрел. У меня только больше половины файлов не компилируются - выдают ошибку, что не удается найти ("masm32++/exe/Error.exe"), а некоторые нормально компилируются. Но принцип я уловил - все файлы ($.asm) можно открыть, просмотреть. По сути, да, это как бы подобие своего компилятора-интерпретатора получается. Как, собственно, вы и писали выше. А с FASM вы никогда дела не имели? У него говорят макросы более гибкие и можно всякие хитрые фишки проворачивать. Интересно бы было узнать у того кто с этим имел дело. f13nd-то наверняка знает, но он мне не скажет. В обиде за что-то на меня. Я правда, не знаю за что.
GRAFik, возьмите какой нибудь пример который выдаёт ошибку только сначала почистите папку проекта - $ второй кнопкой на верху при ошибке в папке проекта должны появится файлы Rc.txt Cvtres.txt Ml.txt Link.txt в одном из них будет описана ошибка скопируйте её в пост с указанием файла ошибки и не забудьте указать какой вы взяли пример
assch, Пример - Шаговый прогресс Файл - Link.txt Microsoft (R) Incremental Linker Version 14.10.25017.0 Copyright (C) Microsoft Corporation. All rights reserved. LINK : fatal error LNK1104: cannot open file '\masm32+\lib\User32.lib'
эта путаница из за того что я делал два проекта и у меня в корне диска лежит такая же папка только без одного плюса в конце попробуй просто скопировать папку в корне диска - masm32++ и положить её рядом только назови её - masm32+ то есть без одного плюса в конце в итоге просто будет две папки должно впринципи получится не исключено даже что именно в этой папке нужно оставить только папку - lib
Теперь полный порядок - все файлы компилируются без ошибок. assch, у меня к вам просьба, если вам не трудно, не могли бы вы чуть более подробно прокомментировать ваш последний файл парсинга обратной польской записи. Можно даже к нему какую-нибудь блок-схему приложить. Пока вы ее еще не успели забыть. А то мне, если что, то придется с отладчиком разбиратся, а это будет дольше по времени. Комментировать там можно по принципу: сюда пришло, отработало цикл, скакнуло туда ну и т.д. А если бы еще точно такой-же пример на СИ или СИ++, то было бы вообще классно. Ну тут, я думаю, вы скажете, что что-то ты товарищь слишком губу раскатал и будете правы. Там, кстати, присутствуют участки, которые никогда не выполняются. Это, вроде, называется - мертвый код. Но это в принципе не важно, можно это поправить. Это я, просто чтобы вы были в курсе. На скрине, это где шесть серых прямоугольников в один ряд и к ним нет входящих стрелок. https://hostingkartinok.com/show-image.php?id=3dc7f5bfe1a96bee4b2addd0a3262326
GRAFik, конечно всё бывает скопируй в пост тот участок который ни когда не выполняется а я ради интереса посмотрю чтобы как говорится в следующий раз это учитывать
assch, я все понял по вашему ироническому тону. Вот вляпался - доверился Иде и забыл, что она очень часто косячит. Сам-то я код еще внимательно не изучал. Просто я подумал, что код не очень большого объема и почему бы не довериться Иде. Все, напишу Ильфаку, что он редиска, а его Ида и того хуже. Ну кого-то же нужно сделать крайним, не себя же в конце концов.
чтобы чуть чуть упростить код надо вместо кода на строке - 59 Код (ASM): .elseif ax == 282Bh && edx == 0 ; "+(" inc esi push 28h ; "(" jmp Loc__inc прописать Код (ASM): .elseif ax == 282Bh && edx == 0 ; "+(" inc esi jmp Loc__met а в место кода на стоке - 117 Код (ASM): .elseif al == 28h ; "(" xor edx,edx movzx eax,al push eax jmp Loc__inc прописать Код (ASM): .elseif al == 28h ; "(" Loc__met: xor edx,edx push 28h ; "(" jmp Loc__inc хотя я не уверен что регистр edx нужно обнулять (xor edx,edx) не исключено что он уже в этот момент имеет нулевой размер хотя вродебы работает если какой то участок будет не понятным спрашивай не стесняйся
Не! Лучше просто отказаться от масм32 и масм64, и делать на UASM! Просто добавляем оператор :=, а так же +=,-+ и т.д из Си. Ещё надо сделать поддержку типов указателей, что позволит делать код более безопасный и контролируемый. Говорю же, надо создать промежуточный ЯП, высокоуровневый ассемблер на привычном МАСМ'ком синтаксе. FASM мне что-то не нравится, и UASM так же может создавать бинарники, elf'ы и так далее. ЗЫ Кстати, UASM компилирует в 30 раз быстрей чем MASM!
Лет 10 назад потребовалось в одну программу встроить поддержку написания скриптов. Сделал С подобный язык. При помощи алгоритма сортировочной станции Дейкстры переводится в польскую нотацию а затем интерпретируется через стек. Работает и до сих пор люди используют. Одна из проблем которая не решена. Допустим функция возвращает значение. Оно кладется вверх стека. А если оно не используется то так и остается. При применениии в цикле стек разрастается. Надо как то отслеживать что возвращаемое значение из функции не присваивается дальше.