Rev 344 | Rev 2323 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download
для файлов с переменными можно сгенерить include в каждомно надо знать модель памяти (вдруг надо разделить команды и данные!)Now the _isaddr flag is set if another address was used in a calculation, and reset in multiplications (see _OPMUL in asmj.c). Maybe I must add rule: addr-addr is a number. For this, tempvalue and pushvalue stack must be typed.add(mul(px,px),add(mul(py,py),mul(pz,pz))) - ГЛЮК (первый add получает первый параметр уже затёртым), и при глубинных вызовах тожеглюк в выражениях с тайпкастом:struct zzz{BYTE ba;LONG lb;STRUCT zzz* pcc;}TYPEDEF STRUCT zzz* tpzzzCONST STRUCT zzz zuzu={0x03,5L,&zuzu}VAR STRUCT zzz* pzz1VAR tpzzz pzzzCONST UINT zzz_nnn = 0;VAR LONG l0 = &zuzu->lb;VAR LONG l1 = (STRUCT zzz*)((UINT)&zuzu+zzz_nnn)->lbвыдаёт;PUSHNUM zuzu ;Line=24;PUSHNUM zzz.lb ;Line=24;PUSHCONST zuzu ;Line=24LD HL,zuzu;OPERATION + ;Line=24;PUSHCONST zzz.lb ;Line=24LD DE,zzz.lbADD HL,DE;PEEK ;Line=24LD E,[HL]INC HLLD D,[HL]INC HLLD A,[HL]INC HLLD H,[HL]LD L,A;POPVAR l0 ;Line=24LD [l0],DELD [l0+2],HL;PUSHNUM zuzu ;Line=25;OPERATION cast 31>1 ;Line=25;PUSHNUM zzz_nnn ;Line=25;PUSHCONST zuzu ;Line=25LD HL,zuzu;OPERATION + ;Line=25;PUSHCONST zzz_nnn ;Line=25LD DE,zzz_nnnADD HL,DE;OPERATION cast 1>31 ;Line=25;PUSHNUM UINT.lb ;Line=25;OPERATION + ;Line=25;PUSHCONST UINT.lb ;Line=25LD DE,UINT.lb ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ADD HL,DE;PEEK ;Line=25LD E,[HL]INC HLLD D,[HL]INC HLLD A,[HL]INC HLLD H,[HL]LD L,A;POPVAR l1 ;Line=27let variable=l1 type=4, but expr type=47;_test.c line=27operation popvar bad type=47;_test.c line=27TODO ещё поддержать VAR LONG l1 = (&zuzu+zzz_nnn)->lb (но в Си так нельзя, он домножит zzz_nnn на размер)сделать вложенные скобки в дефайнах, иначе нельзя типизированные -(a/b)#include "name.h"должен выдавать:include "name.dec"incobj "name.bin","name.rel" или просто incobj "name"это может быть любое место исходника (в стартапе инклюды в конце)что если заголовочный файл включает другой заголовочный файл? ничего страшного, как будто подряд?как использовать один и тот же заголовочный файл для объявлений и использования? в gcc так нельзя?extern!=export (в си нет export)как передавать нумерацию модулей для обращений в объектнике?можно ли относительный номер перенумеровать в глобальный? (один и тот же модуль может быть включен в разные!!!)номер можно назначать по порядку компиляции (даже если перекомпилировать неизменённый не надо)надо перекомпилировать неизменённый модуль, если он использует изменённый модуль!!! (это потому что он привязывается к смещениям в декларациях используемого модуля)даже если привязываться не к смещениям, а к номерам символов, то вставка функции потребует перекомпилировать все модули, которые используют егоможно от первого изменившегося перекомпилировать все последующие модулиещё надо перекомпилировать всё при изменении структуры связей модулейесли это не сделать, то в линкере надо работать с символьными метками, то есть линкер не может стать лоадером (нужна память под метки)какой символ сделать для деклараций типа metka=<symbol><номермодуля>+<смещение>?или другой формат деклараций?ассемблерный файл должен знать свой номер модуля, чтобы правильно выгружать декларации!не страшно, если у ассемблера будет тот же список файлов, что у компилятора?или список файлов компилятора ни на что не влияет?не следует объединять .ast и .var в один файл (т.к. их надо компилировать в разные пространства)а инициализированные переменные - ещё одно пространство? сейчас явных нет, но есть константные массивы и структурыускорение сборки:- убрать токенизатор из главной цепочки, недоланг должен генерировать токенизированный асм без перелопачивания выражений, а недоасм должен уметь вычислять выражения нормально. nedodel и movedisk можно будет тоже убрать из главной сборки- асмоверсии работы с метками пусть используют страницы. не делить компилятор на 2 части- сделать однопроходный асм (с пост-метками)?- вклеить однопроходный асм прямо в недоланг?- убрать ещё какие-нибудь специфические процедуры в асмомодули (например, rdtword, genautonum)- добавить передачу параметров в регистрах? добавить REGISTER? токенизировать недоланг (ключевые слова и двойные символы)? генерировать обж прямо из недоланга (с патчами)(тогда нельзя асмовставки и асмопроцедуры - только асмомодули), сделать специальный линкер или лоадерпостроение проекта:в ассемблер попадает больше файлов, чем в компилятор, т.к. добавляются ещё стандартные процедуры умножения-деления и файлы с переменнымиили в ассемблер попадёт всего два файла - склеенный код (с приклеиванием стандартных процедур) и склеенные переменные, или только один склеенный кодесли просто вклеить токенизатор в компилятор, то он будет слишком жирным (особенно по меткам)можно убрать инлайн ассемблер и заставлять инклюдить токенизированные ассемблерные файлытогда компилятор просто будет выводить токенизированный асм вместо текстаreader будет общий у компилятора и токенизатора (и поддерживает комменты)тогда reader должен писать коммент в нетокенизированный ассемблерный текст и в токенизированный одинаковоили нетокенизированный ассемблерный текст не существуеттогда комментарии/ошибки тоже должны об этом знать! токенизировать комментарии/ошибки на уровне emitter?(компилятор может не выводить ошибки в ferr, а выводить прямо в асм)типность можно убрать в _istype (обнулять при старте и после тайпкаста)раньше не было зарезервированных словсейчас зарезервированы слова:- default (можно разрезервировать, но тогда 1. нельзя получить указатель на метку (в gcc особая команда &&labelname?), [2. пользовательские метки пересекутся с автометками (но можно добавить не одну точку, а две)])- TRUE, FALSE (если будет include, то можно определить, но сам тип BOOL лучше не определять - он нужен в if, while, repeat)- имена базовых типов - а они не соответствуют зарезервированным сишным именам!(ассемблерные команды вроде как не зарезервированы, т.к. имя метки проверяется в начале строки)чтобы заполнить константную структуру, надо где-то взять список полейили каждое поле будет выделяться по размеру написанного там значения (чревато багами)зато можно объединить с массивомно сейчас нельзя определить ширину типа по tword - она определяется по типу массиваtodo:в структуре поле типа массивпеределать &arr[] в &(arr[]) для упрощения?;для такого (call...=...define) не хватает двух проходов, и ошибка не пишетсяclosewrite=fclosewriteclosewrite.A.=fclosewrite.A.EXPORT closewriteEXPORT closewrite.A....EXPORT PROC fclosewrite(PBYTE file){fclose(file);}в асме добавить LIMIT addr, при достижении этого адреса выводить ошибку limittodo проверить знаковое сравнение (вроде в рейтрейсе работало?)todo проверить в токенизаторе, ставится ли LF перед ошибкой в начале строки (при отладке Thumb вылезло)в Си помечаются не int, а uint (1U)в Си помечается не export, а локальность (const - для функций, по крайней мере)указатели FAR, NEAR, HUGE - где взять образцы исходников в таком стиле?в C++ особый указатель на функцию-член класса, хранит также thisв Си limits.h содержит INT_MAX, CHAR_BIT итпa >> n, a << n, p + n (в Си) - не алгебраические операции, т.к. их операнды разного типа-a (в NedoLang), p - p (в Си), сравнения - не алгебраические операции, т.к. их результат другого типа15 nesting levels for #included files limit#include nestingCommentaryThis limit makes no distinction between system headers and developer-written header files. However, animplementation is required to support its own system headers whose contents are defined by the standard. Ifa particular implementation chooses to use nested #includes, then it is responsible for ensuring that thesedo not prevent a translator from meeting its obligations with regard to this limit.Use of nested #includes requires that the source file containing each of the #include directive be keptopen, while the included file is processed. Supporting 15 nesting levels invariably requires keeping at least17 (the top-level source file and the file holding the generated code also need to be counted) files opensimultaneously. Using the fsetpos library function to record the current file position, at the point the fsetposfunction#include occurs, and closing the current file before opening the nested include is possible; however, yourauthor has never heard of an implementation that uses it....C908 nesting levels for #included filescbook1_0bC90257 case labels for a switch statement (excluding those for any nested switch statements)The intent here was to support switch statements that included 256 unsigned character values plus EOF 1737 switchstatement(usually implemented as -1).cbook1_0bбаг:////////////CONST PBYTE tasks;PROC importtasks(PBYTE tasks){}PROC main(){importtasks(tasks);}///////////nolbl main.tasksнадо таблицу адресов коротких локальных метокTODO в асме локальные метки процедур .label (компилятся как title.label)новая метка заголовка определяется в команде PROC(можно по умолчанию, но это замедлит)TODO CY вместо CTODO проверить DB "string",'c',0x00для ООП нужно (даже без is-a, только с has-a):- как узнать размер объекта, даже если он точно имеет нужный интерфейс????отдельный интерфейс size или даже copyable? или даже listable?или все объекты списка одного размера (содержат только интерфейсы), а особая часть каждого класса будет в отдельном блоке памяти? (а как тогда клонировать объекты? через интерфейс copyable?)- как обратиться к нужному интерфейсу, если он в объекте может располагаться в разных местах? (а он может - интерфейсов может быть разное число). из списка мы получаем какой-то сферический объект, в котором надо только найти интерфейсы, а интерфейсы уже настроены в этом экземпляре на нужную реализацию (конструктором). как найти в объекте нужные интерфейсы по имени?пусть даже нельзя будет добавлять интерфейсы в объекты одного списка - у всех объектов списка будет один список интерфейсов. тогда надо, чтобы все интерфейсы (или ссылки на них) были включены в начало структуры.как это контролировать языком? можно сделать один интерфейс "распиновка", включающий все нужные интерфейсы? типаobj1->visualobject->viewable->View(obj1->visualobject->viewable)или(VisualObject)obj1->viewable->View(obj1) - как это на Недоланге???илиCALL (VisualObject)obj1->viewable->view(obj1) - так нельзя вернуть значение!илиresult = Viewable_View(obj1->visualobject->viewable) //Viewable - пространство имёнкак короче???а кроме этого в obj1 будет только obj1->data с произвольным структурным типом, чтобы не считать размер?как контролировать, что мы настроили все интерфейсы на нужную реализацию в конструкторе? (если они по указателю, то для этого надо ещё их создать! или не создавать, если конструктор с параметром-объектом) (С++ не контролирует, но вроде может сам вызвать все деструкторы, к тому же сам назначает виртуальные функции)- как вызвать конструктор и деструктор? их указатели тоже должны быть в фиксированном месте структуры, но не могут быть в obj1->data, т.к. data создаётся в конструкторе. они не могут быть и в obj1->visualobject по той же причине. но могут быть в obj1.visualobject (если вложенные структуры), но тогда все visualobject будут одинаковые, что мы не хотимвызывать конструктор как простую функцию, а не как метод класса?- как передать параметры в конструктор, если он по указателю?вызывать конструктор как простую функцию, а не как метод класса?типаtypedef <функция, возвращающая object*> Func;STRUCT IVisualObject{IViewable* viewable; //⠬ Proc ViewICopyable* copyable; //там size и Func CopyIListable* listable; //там Func Prev и Func Next???};STRUCT VisualObject{ //образец подкласса visualobject, используемый для хранения в списках и т.п.IVisualObject* visualobject;};STRUCT Button{IVisualObject* visualobject;... //data for Button};VAR [STRUCT] Button* btOK = CreateButton(10,10,100,100,"OK",&OnClickOK);//можно тип VisualObject* вместо Button*...destroyButton(btOK);надо вызывать из конструктора объекта конструктор "распиновки" с нужными параметрами - так можно проверить, что не пропустили ни одной инициализации интерфейсов (хотя пока Недоланг не проверяет число параметров). типа так:FUNC Button* createButton(...) //можно тип VisualObject* вместо Button*{VAR [STRUCT] Button* obj;obj = newStruct(+sizeof(Button));//obj->size = +sizeof(Button);obj->VisualObject = createVisualObject(..., obj/**для copyable*/, +sizeof(Button)/**для copyable*/, &ButtonView/**для viewable*/);obj->... = ... //data for ButtonRETURN obj;}- как передавать параметры в виртуальные методы?в Недоланге нет передачи по стекучитать из именованных параметров прообраза виртуальной функции? они недоступны из языка! а как их передать в прообраз, при этом вызвать виртуальную функцию? сам прообраз будет вызывать?Клонирование визуального объекта (в том числе клонирование данных по указателям??? в Qt так нельзя ради рефлексии и иерархии экземпляров):obj2 = obj1->visualobject->copyable->Copy(obj1)???obj должен быть приведён к типу VisualObject*!!! сразу всё хранить как VisualObject*, а не Button*?FUNC UINT Viewable_View(Viewable* viewable, UINT par1){_par1 = par1;CALL viewable->View(); //читает _par1, возвращает _resRETURN _res;}как бы сделать в Недоланге, чтобы вызывать функцию с результатом по указателю?в сишнике ад: ((<тип>(*)(void))(pfunc))()+call(pfunc) нельзя, если возвращаем указателькак в сишнике определить тип PROC? (это когда уберём слово PROC в процедурах)избавиться сразу от звёздочек в типах за счёт дополнительного typedef?как избавиться от вставки ->visualobject?можно наследовать структуру от "распиновки" IVisualObject (для этого надо будет скопировать все поля IVisualObject в нашу структуру), тогда "распиновка" будет лежать в началеможно тупо:STRUCT VisualObject{ //образец подкласса visualobject, используемый для хранения в списках и т.п.#include "visualobject.h" //начинка структуры "распиновки" без обёртки};STRUCT Button{#include "visualobject.h" //начинка структуры "распиновки" без обёртки... //data for Button};только Недоланг не умеет инклюды внутри структуры!!!и не умеет макросы дефайнами!!!???используем везде процедуры VisualObject_...(object), где объект имеет тип "образца наследника интерфейса", тогда мы не увидим таких вставок ->visualobject нигде ни в реализации Button, ни в использованиипроблема с распиновкой:у каждого визуального компонента своя распиновка!или можно добавить методы и данные вне распиновки? по распиновке обращается ось, а по отдельным методам - формаSTRUCT Button{IVisualObject* visualobject;//data for visibleBOOL visible;UINT left;UINT top;UINT width;UINT height;//data for listableList* head;Button* prev; //TODO как listable будет в них искать свои поля и свой интерфейс?Button* next;//data for ButtonPBYTE onclick; //todo PROCPCHAR text; //todo STRING};PROC VisualObject_View([STRUCT] VisualObject* object) //этот параметр - не интерфейс, а образец подкласса{_this = object;CALL object->visualobject->viewable->view;}FUNC [STRUCT] VisualObject* VisualObject_Copy([STRUCT] VisualObject* object) //этот параметр - не интерфейс, а образец подкласса{_this = object;CALL object->visualobject->copyable->copy;}PROC Button_View(){... _this->left, _this->top, _this->width, _this->height ...... _this->text}FUNC [STRUCT] VisualObject* Button_Copy(){ //кнопка ничего не создаёт, поэтому копируется легко//TODO вклиниться в цепочку prev,nextRETURN ([STRUCT] VisualObject*)getmem_copy(+sizeof(Button), _this);}//статическое создание//TODO нужны ли ...able? они сами по себе ничего не делают и не защищают//viewable и clickable явно относятся к visualobject//listable можно выделить, если там будут смещения до prev,next, а функции GetPrev, GetNext, GetHead, GetSize, IsEmpty, Add, Remove всегда одинаковые//copyable опасно, потому что семантика неясна (копировать ли вложенные объекты? по идее не попировать, и интерфейсы хранить как подструктуры, а не по ссылке!). чтобы класть в контейнер, достаточно наследовать интерфейс listable и т.п. можно даже неколько раз, если данные прошиты многими ссылкамиCONST [STRUCT] IViewable buttoniviewable{&Button_View};CONST [STRUCT] ICopyable buttoncopyable{&Button_Copy //должна знать +sizeof(Button) и что лишнего создавать (а надо ли когда-нибудь создавать лишнее?)};CONST [STRUCT] IListable buttonlistable{&Button_Prev, //должна знать, где лежит prev (тут нельзя, разве что смещение - т.к. для всех кнопок) //но смещение нельзя получить в константное выражение???&Button_Next //должна знать, где лежит next (тут нельзя, разве что смещение - т.к. для всех кнопок) //но смещение нельзя получить в константное выражение???};CONST [STRUCT] IClickable buttonclickable{&Button_Click};CONST [STRUCT] IVisualObject buttonvisualobject{&buttonviewable, //⠬ Proc View&buttoncopyable, //там Func Copy (она знает +sizeof(Button)) //а нужна ли?&buttonlistable, //там Func Prev и Func Next //или смещения до head,prev,next???&buttonclickable};CONST [STRUCT] Button btOK{&buttonvisualobject, //нельзя распиновку кнопки (она одинаковая для всех кнопок) включать в саму общую структуру&onClickOK, //onclick&listhead, //head (там size, ссылка на реальный head и ссылка на родителя произвольного типа?)&btOK, //prev&btOK, //next10, //left10, //top100, //width100, //height"OK" //text};//динамическое созданиеVAR [STRUCT] VisualObject* btOK = Button_Create(10,10,100,100,"OK",&vbutton,&onClickOK);//TODO вручную привязать prev, next, т.к. нельзя привязать их все друг к другу в конструкторе (next указывает на будущий объект!)...//VisualObject_View(btOK->ivisualobject, btOK); //во всех нужных интерфейсах уже стоят указатели на реализации, а в них нужны указатели на поля Button!//CALL btOK->visualobject->viewable->view(btOK); //не надо знать, что это кнопка, это просто образец подкласса visualobjectVisualObject_View(btOK);...//CALL btOK->visualobject->clickable->click(btOK);VisualObject_Click(btOK);...Button_Destroy(btOK);можно передавать параметры через байты перед заголовками функций(нерекурсивно, нереентерабельно, не для ПЗУ, несовместимо с iofast и др.)