Состав компилятора Важная информация о структурах данных компилятора - в конце модуля НяФс.
НяЛексер - лексер, существует в единственном экземпляре
НяПарсер - парсер, то же
НяМ - Вычитывание_исходного_текста_модуля_из_отображения,
Чтение_простых_типов_из_символьного_файла
Запись_простых_типов_в_символьный_файл
Запись_объектного_файла
НяФк - порождение кодового файла
НяД - строит синтаксическое дерево, проводит контроль и неявное преобразование типов
НяФс - файлы символов: создание, импорт, поиск
НяГенКода486 - генератор кода
НяИспользование - UseCalls и UseReals, что делают - не знаю.
НяГ486Ву - генератор кода, высокий уровень (?)
НяГ486Ну - генератор кода, низкий уровень (?)
См. также http://obertone.ru/_media/bb/op2.paper.pdf :
См. также http://obertone.ru/blackbox/dev
Опции компилятора ищутся в документации ББ по словам «Особенности, зависящие от платформы».
DevCompiler
Пакет команд для компилятора Ня. Критичные для безопасности проверки времени выполнения проводятся всегда (охрана типов, проверки границ массивов, и т.п.), в то время как не критичные проверки не могут генерироваться вообще (SHORT, переполнение целых, проверка вхождения во множества). «Критичные» означает, что может быть повреждена нелокальная память, с неизвестными глобальными эффектами.
PROCEDURE Compile - Компилирует модуль Ня, исходный текст которого находится в фокусированном отображении.
PROCEDURE CompileAndUnload - компилирует модуль, исходный текст которого находится в фокусированном отображении. Если компиляция проходит успешно, то старая версия этого модуля выгружается. CompileAndUnload полезна при разработке модулей верхнего уровня, то есть таких, которые не импортируются другими модулями и поэтому могут быть отдельно выгружены.
PROCEDURE CompileModuleList - компилирует список модулей, имена которых выделены. Когда обнаруживается первая ошибка, содержащий ее исходный код открывается, показывая ошибку.
PROCEDURE CompileSelection - компилирует модуль, начало которого выделено.
PROCEDURE CompileThis - используется в тексте с DevCommanders.View. Эта команда берет текст, следующий за ним, и интерпретирует его как список модулей, которые следует откомпилировать. Похожа на CompileModuleList за исключением того, что не нужно выделение.
См. такжеПарсер. Проще всего идти по грамматике из определения языка. Каждый элемент грамматики переведён на русский. Функция разбора этого элемента называется «Разбери<ЭтотЭлемент>», например, «РазбериМодуль», но может содержать и уточнения. Отфильтровать все можно поиском по подстроке «PROCEDURE Разбери»
У нас нет инструментов рефакторинга, чтобы исключить дублирование блоков констант (а можно было бы их положить в отдельный модуль). Нужно реанимировать ПроверитьИнклюды и применить здесь, чтобы проверять их совпадение. Пока что каждая группа констант описывается в одноимённой статье данного документа с тегом ОПИСАНИЕ-ГРУППЫ-КОНСТАНТ . Если понимаем, переводим. Если нет - оставляем. При переводе не убираем комментарии, а добавляем к ним русские рядом - на случай, если мы пропустим часть английских, чтобы у нас оставалась смысловая связка.
Теги: ПРОЦЕСС-ДОКУМЕНТИРОВАНИЯEnglishName => РусскоеИмя_EnglishName предпочтительно Но иногда можно просто превратить в русское имя. Тогда английское надо упомянуть хотя бы в комментарии, в угловых скобках.
Теги: ПРОЦЕСС-ДОКУМЕНТИРОВАНИЯЛексер выдаёт лексемы, а не символы.
Assert = Убдеись
New = Яви (т.к. этот New вызывает тот, к кому мы сейчас обращаемся. Явись было бы, если бы обращались к самому объекту, который должен родиться)
Record = Структа
Процедура внутри другой процедуры - Подпроцедура
Case = Сита - состоит из нескольких вариантов, каждый из которых называется Сито.
forward declaration = Упреждающее объявление
Теги: ПРОЦЕСС-ДОКУМЕНТИРОВАНИЯMODULE ZZZ;
(**** Комментарий к модулю *)
(** Полный комментарий *)
Name = RECORD (* Краткий комментарий *)
(** Подробный комментарий к полю,
если надо *)
Field (* Здесь комментарий *)
(** Полный комментарий *)
PROCEDURE Имя(args); (* <OldName> Краткий комментарий *)
(* ? Информация в комментарии и имя объекта требуют уточнения *)
Теги: ПРОЦЕСС-ДОКУМЕНТИРОВАНИЯ (*** Название_раздела , см. также Название_другого_раздела *)
Теги: ПРОЦЕСС-ДОКУМЕНТИРОВАНИЯ Пытаемся взять одну функцию SYSTEM.VAL и отследить её историю по всему компилятору.
Функция регистрируется (становится известной компилятору)
в модуле НямФС: EnterProc("VAL", valfn);
Далее нужно искать valfn.
«Особенности, зависящие от платформы», Dev/Docu/P-S-I.odc
VAL(T, x), значение значение x
интерпретируется как имеющее тип T
НяД.StPar0 - обработка первого параметра стандартной функции. Обработки никакой не происходит, дело сводится к проверкам.
НяД.StPar1 - обработка второго параметра стандартной ф-ии (он обозначается x). Главное здесь - в конце. Тип результата (x.typ) назначается равным p.typ (типу первого параметра), а значение результата берётся из второго параметра (p := x) В итоге первый аргумент и сам вызов SYSTEM.VAL удаляются из дерева.
В простом случае обработка функции VAL сводится к тому, что её вызов выбрасывается, узел её второго аргумента получает другой тип времени компиляции, и его значение возвращается.
Цель - узнать, как вставить в код (funcall ,(intern имя модуль) ... ), где имя и модуль - константы, известные во время компиляции.
НяПарсер.GetParams НяПарсер.FormalParameters(proc.link, proc.typ, name) НяД.CheckParameters
Теги: СОСТОЯНИЕ-КОМПИЛЯТОРА СИМВОЛЬНАЯ-ИНФОРМАЦИЯсделать "case" по примитивному типу, известному во время компиляции. Как-то так:
if ч.тип == 'INTEGER' then
Обернуть ч в узел вызова функции NewItemFromInteger
elseif ч.тип = 'STRING' then
Обернуть ч в узел вызова функции NewItemFromString
...
endif
Как вставить вызов? Идём по процессу, как это делает компилятор.
РазбериМножитель
РазбериИдентификторВтчСКвалификатором
НяД.PrepCall(x, fpar);
IF (x.obj # NIL) & (x.obj.mode = TProc) THEN НяД.CheckBuffering(x.left, NIL, x.obj.link, pre, lastp)
END;
РазбериФактическиеПараметры(apar, fpar, pre, lastp);
НяД.Call(x, apar, fpar);
IF pre # NIL THEN НяД.Construct(Ncomp, pre, x);
И т.п. При этом, если идти по этим ф-ям, то видно, что можно задать модуль и пр-ру именами (например, 'Kernel' 'NewItemFromInt') и тем самым импортировать. Правда, нужно будет усовершенствовать сообщения об ошибках.
РазбериПостфиксныеДействияИдентификатора
НяФс.Import - импортирует модуль (объявление импорта одного файла в директиве IMPORT) Ищи комментарий «Импорт_модуля» . Общая идея: открывает символьный файл, всё читает из него, и вешает в виде графа связей в GlbMod.
Главный тип таблицы символов - это, похоже, НяФс.ObjDesc и указатель на него НяФс.Object
Теги: СОСТОЯНИЕ-КОМПИЛЯТОРА СИМВОЛЬНАЯ-ИНФОРМАЦИЯchar = 1; integer = 2; real = 4; int64 = 5; real32 = 6; real64 = 7;
Теги: ОПИСАНИЕ-ГРУППЫ-КОНСТАНТСимволы арифметических операций, включая сравнения, логических операций, а также is и in
Теги: ОПИСАНИЕ-ГРУППЫ-КОНСТАНТСимволы разделителей, ключевые слова языка
См. также Теги: ОПИСАНИЕ-ГРУППЫ-КОНСТАНТПохоже на подмножество symbol-values-17-76, но, как минимум, moudle (moduleSym) отличается написанием
Теги: ОПИСАНИЕ-ГРУППЫ-КОНСТАНТМожет находиться в поле ObjDesc.mode. Например, символьная информация модуля имеет ObjDesc.mode = 11 (Mod)
Теги: ОПИСАНИЕ-ГРУППЫ-КОНСТАНТStructure types Грубая классификация типов данных Перекликаются с тегами типов (см. Kernel DevHeapSpy.FormOf), но не полностью совпадают.
Теги: ОПИСАНИЕ-ГРУППЫ-КОНСТАНТMODULE Бережок; IMPORT StdLog, SYSTEM;
TYPE
zz = RECORD END;
VAR v : zz;
BEGIN
StdLog.Int(SYSTEM.TYP(v)); (* напечатает число *)
StdLog.Int(SYSTEM.TYP(zz)); (* напечатает то же число *)
END Бережок.
(* ^q "Kernel.LoadMod('Бережок')"
*)
MODULE Бережок; IMPORT SYSTEM; BEGIN
ASSERT(SYSTEM.VAL(INTEGER,"ж")=1078);
ASSERT(SYSTEM.VAL(INTEGER,"b")=98);
END Бережок.
(* ^Q "Kernel.LoadMod('Бережок')"
*)
По сути это - преобразование от void* к типу записи. Страшная вещь, т.к. принимает адрес в виде числа. Источник сведений: ОберонЦоре
Ищите применения в исходнике. Параметры - Int32 (или «младшие»)
MODULE Бережок; IMPORT SYSTEM;
TYPE ТипЮ = RECORD Поле:LONGINT END;
VAR У1 : ТипЮ;
VAR Адрес,ТегТипа:INTEGER;
ЗначениеПоля:LONGINT;
PROCEDURE ВерниПоле(IN З: ТипЮ):LONGINT;
BEGIN RETURN З.Поле; END ВерниПоле;
BEGIN
У1.Поле := 115773100500;
Адрес := SYSTEM.ADR(У1);
ТегТипа := SYSTEM.TYP(ТипЮ);
(* Почему-то нельзя присвоить переменной типа ТипЮ
возврат SYSTEM.THISRECORD - компилятор падает.
Но можно вызвать процедуру с параметром In *)
ЗначениеПоля := ВерниПоле(
SYSTEM.THISRECORD(Адрес,ТегТипа)
);
ASSERT(ЗначениеПоля = У1.Поле);
END Бережок.
(* "Kernel.LoadMod('Бережок')"
*)
(* Items:
mode | offset index scale reg obj
------------------------------------------------
1 Var | adr xreg scale obj (ea = FP + adr + xreg * scale)
2 VarPar| off xreg scale obj (ea = [FP + obj.adr] + off + xreg * scale)
3 Con | val (val2) NIL
Con | off obj (val = adr(obj) + off)
Con | id NIL (for predefined reals)
6 LProc | obj
7 XProc | obj
9 CProc | obj
10 IProc | obj
13 TProc | mthno 0/1 obj (0 = normal / 1 = super call)
14 Ind | off xreg scale Reg (ea = Reg + off + xreg * scale)
15 Abs | adr xreg scale NIL (ea = adr + xreg * scale)
Abs | off xreg scale obj (ea = adr(obj) + off + xreg * scale)
Abs | off len 0 obj (for constant strings and reals)
16 Stk | (ea = ESP)
17 Cond | CC
18 Reg | (Reg2) Reg
19 DInd | off xreg scale Reg (ea = [Reg + off + xreg * scale])
tmode | record tag array desc
-------------------------------------
VarPar | [FP + obj.adr + 4] [FP + obj.adr]
Ind | [Reg - 4] [Reg + 8]
Con | Adr(typ.strobj)
*)
Теги: СПРАВОЧНАЯ-ТАБЛИЦА Выдернуто из (Ня)Фс.kp
Objects:
mode | adr conval link scope leaf
------------------------------------------------
Undef | Not used
Var | vadr next regopt Glob or loc var or proc value parameter
VarPar| vadr next regopt Var parameter (vis = 0 | inPar | outPar)
Con | val Constant
Fld | off next Record field
Typ | Named type
LProc | entry sizes firstpar scope leaf Local procedure, entry adr set in back-end
XProc | entry sizes firstpar scope leaf External procedure, entry adr set in back-end
SProc | fno sizes Standard procedure
CProc | code firstpar scope Code procedure
IProc | entry sizes scope leaf Interrupt procedure, entry adr set in back-end
Mod | scope Module
Head | txtpos owner firstvar Scope anchor
TProc | entry sizes firstpar scope leaf Bound procedure, mthno = obj.num
Теги: СПРАВОЧНАЯ-ТАБЛИЦА Выдернуто из (Ня)Фс.kp
Structures:
form comp | n BaseTyp link mno txtpos sysflag
----------------------------------------------------------------------------------
Undef Basic |
Byte Basic |
Bool Basic |
Char8 Basic |
Int8 Basic |
Int16 Basic |
Int32 Basic |
Real32 Basic |
Real64 Basic |
Set Basic |
String8 Basic |
NilTyp Basic |
NoTyp Basic |
Pointer Basic | PBaseTyp mno txtpos sysflag
ProcTyp Basic | ResTyp params mno txtpos sysflag
Comp Array | nofel ElemTyp mno txtpos sysflag
Comp DynArr| dim ElemTyp mno txtpos sysflag
Comp Record| nofmth RBaseTyp fields mno txtpos sysflag
Char16 Basic |
String16Basic |
Int64 Basic |
Теги: СПРАВОЧНАЯ-ТАБЛИЦА Выдернуто из (Ня)Фс.kp
Здесь Ntype - видимо, литерал, указывающий тип, например, CHAR. Ncall - вызов процедуры.
Nodes:
design = Nvar|Nvarpar|Nfield|Nderef|Nindex|Nguard|Neguard|Ntype|Nproc.
expr = design|Nconst|Nupto|Nmop|Ndop|Ncall.
nextexpr = NIL|expr.
ifstat = NIL|Nif.
casestat = Ncaselse.
sglcase = NIL|Ncasedo.
stat = NIL|Ninittd|Nenter|Nassign|Ncall|Nifelse|Ncase|Nwhile|Nrepeat|
Nloop|Nexit|Nreturn|Nwith|Ntrap.
class subcl obj left right link
---------------------------------------------------------
design Nvar var nextexpr
Nvarpar varpar nextexpr
Nfield field design nextexpr
Nderef ptr/str design nextexpr
Nindex design expr nextexpr
Nguard design nextexpr (typ = guard type)
Neguard design nextexpr (typ = guard type)
Ntype type nextexpr
Nproc normal proc nextexpr
super proc nextexpr
expr design
Nconst const (val = node.conval)
Nupto expr expr nextexpr
Nmop not expr nextexpr
minus expr nextexpr
is tsttype expr nextexpr
conv expr nextexpr
abs expr nextexpr
cap expr nextexpr
odd expr nextexpr
bit expr nextexpr {x}
adr expr nextexpr SYSTEM.ADR
typ expr nextexpr SYSTEM.TYP
cc Nconst nextexpr SYSTEM.CC
val expr nextexpr SYSTEM.VAL
Ndop times expr expr nextexpr
slash expr expr nextexpr
div expr expr nextexpr
mod expr expr nextexpr
and expr expr nextexpr
plus expr expr nextexpr
minus expr expr nextexpr
or expr expr nextexpr
eql expr expr nextexpr
neq expr expr nextexpr
lss expr expr nextexpr
leq expr expr nextexpr
grt expr expr nextexpr
geq expr expr nextexpr
in expr expr nextexpr
ash expr expr nextexpr
msk expr Nconst nextexpr
len design Nconst nextexpr
min expr expr nextexpr MIN
max expr expr nextexpr MAX
bit expr expr nextexpr SYSTEM.BIT
lsh expr expr nextexpr SYSTEM.LSH
rot expr expr nextexpr SYSTEM.ROT
Ncall fpar design nextexpr nextexpr
Ncomp stat expr nextexpr
nextexpr NIL
expr
ifstat NIL
Nif expr stat ifstat
casestat Ncaselse sglcase stat (minmax = node.conval)
sglcase NIL
Ncasedo Nconst stat sglcase
stat NIL
Ninittd stat (of node.typ)
Nenter proc stat stat stat (proc=NIL for mod)
Nassign assign design expr stat
newfn design nextexp stat
incfn design expr stat
decfn design expr stat
inclfn design expr stat
exclfn design expr stat
copyfn design expr stat
getfn design expr stat SYSTEM.GET
putfn expr expr stat SYSTEM.PUT
getrfn design Nconst stat SYSTEM.GETREG
putrfn Nconst expr stat SYSTEM.PUTREG
sysnewfn design expr stat SYSTEM.NEW
movefn expr expr stat SYSTEM.MOVE
(right.link = 3rd par)
Ncall fpar design nextexpr stat
Nifelse ifstat stat stat
Ncase expr casestat stat
Nwhile expr stat stat
Nrepeat stat expr stat
Nloop stat stat
Nexit stat
Nreturn proc nextexpr stat (proc = NIL for mod)
Nwith ifstat stat stat
Ntrap expr stat
Ncomp stat stat stat
Теги: СПРАВОЧНАЯ-ТАБЛИЦА