мои предложения по поводу оформления исходных текстов:
( то есть собственно соглашения меня со мной, которым я стараюсь следовать )
Код:
\. 07-01-2007 V1.1 ~mOleg
\. пример оформления библиотеки = ответ на вопрос что
\ написано по просьбе Profit-а = для чего предназначено
\ мне кажется что в заголовке более 5-и строк коментария быть не должно.
\. это слово выводит строку коментария на экран
\ удобно, когда нужно отобразить какие либы грузятся во время сборки
\ ну и в других случаях тоже бывает полезно. Код можно найти у меня
\ в ~moleg\util\useful.f
\ --------------------------------------------------------------------------
S" либа.f" INCLUDED \ подключаем первую либу
S" очень длинный путь\еще.f" INCLUDED \ два-три пробела до S"
S" и так далее и тому подобно" INCLUDED \ коментарий того, что подключаем
\ --------------------------------------------------------------------------
HEX
\ переход на другую систему исчисления выравниваем по середине строки -
\ так получается виднее. И лучше основание систем часто не менять.
VOCABULARY WORKVOC \ перед vocabulary табуляция
ALSO WORKVOC DEFINITIONS \ так мне кажется нагляднее
\ все слова, которые не относятся к интерфейсу помещаем в наш словарь.
\ код в словаре может перепроектироваться всегда и как угодно,
\ а вот интерфейсные слова меняться должны лишь в крайнем случае
\ при таком подходе будет более быстрый поиск и компиляция
\ так как в маленьком словаре быстрее ищутся слова. И в то же время
\ главный словарь не засоряется.
VARIABLE ABC \ выделяем одной табуляцией
0x345 VALUE BCDE \ значение выходит вперед
USER CDE \ впереди одна табуляция
\ все переменные и константы обычно выносятся в самое начало текста
\ да, не смотря на то, что Форт очень любит постфикс, коментарии
\ должны располагаться раньше самого кода, либо же на той же строчке.
\ на которой находится код, но не в коем случае не после нее.
0x100 CONSTANT #elem
\ перед CREATE обычно пара пробелов.
CREATE massive #elem CELLS ALLOT
\ что делает слово
\ какие особенности его работы
\ исключения
\ коментарий не должен отделять код слова от его имени!
\ иначе тяжело бывает найти начало слова - ведь не каждый раз мы
\ читаем коментарии.
: SYSTEM-WORD ( --> )
\ если слово ничего не берет и не возвращает обязательно
\ отобразить
системно зависимые слова пишем, так уж сложилось,
с большой буквы
;
\ теперь насчет коментариев внутри ( ) - я вообще считаю, что круглые
\ скобки стоит оставить только!!! для коментариев стековых диаграм!!
\ ТОЛЬКО - вне зависимости от того, где этот коментарий распологается.
\ разделитель состояния стека до и после у меня обычно -->
\ мне так больше нравится и, например, в smal32 так же выглядит
\ к тому же есть еще один момент - в СПФ -- "два минуса" зарезервировано
\ если слово принимает параметры из входящего потока, то пишем так:
: SWORD ( a b c / text --> asc # )
ОТСЮДА начинаем писать код
никаких коментариев после скобок не нужно!
так как они загромождают текст, особенно актуально,
когда текст и коментарии на одном языке!
если нужно прокоментировать строчку, то такое место
лучше вынести в отдельное слово!!! Иногда без этого
можно обойтись \ тогда коментарий именно после кода
в случае, если нужно прокоментировать стековую диаграму
опять же делаем отдельное слово, так как попытка
коментировать стековую диаграму внутри слова признак
того, что мы уже не понимаем что у нас на стеке происходит,
а значит нужен рефакторинг
но в крайнем случае делаем так \ ( --> стек после )
; IMMEDIATE
\ ; - не должна совпадать с позицией :
\ но должна выделяться относительно кода
\ ---------------------------------------------------------------------------
\ мне нравится отделять смысловые секции длинной строкой
\ опять же о том, что делает слово написать надо
\ иногда даже стоит привести короткий пример использования
CODE asmWord ( a --> c ) \ начинаем код под левой скобкой
MOV EAX, EBX
@@1: ROL EAX, # 1 \ метки выносим вперед
XOR EAX, EBX
DEC EBX
JNZ @@1 \ переходы внутри слова выносим чуть вперед
NOP
RET \ выходы выделяем еще сильнее чем переходы
END-CODE \ мне так отступы больше нравятся
\ теперь насчет данных на различных стеках
: R> ( r: n --> d: n )
если переносим данные с одного стека на другой, стоит указывать
тип каждого из стеков. По крайней мере я так стараюсь делать
в СПФ обычно встречается немного другой вариант:
( --> n ) ( r: n --> )
то есть отдельно для каждого стека свой коментарий
;
\ насчет вариантов
: FIND ( #asc --> #asc false | xt -1 | xt 1 )
варианты отделяются вертикальной чертой друг от друга.
в СПФ вроде тоже так
;
\ если на входе и на выходе всего один параметр одного типа
\ в СПФ есть такой вариант:
: CELLS ( n1 --> n2 ) ;
\ а я обычно стараюсь передать что же произошло
\ но тут я не уверен, как лучше. Такие слова достаточно большая редкость.
: CELLS ( n --> n*cell ) ;
\ если возвращаем произвольное число параметров
: GET-ORDER ( --> [ vidn .. vid1 ] # )
либо
: GET-ORDER ( --> vidn .. vid1 # )
первый вариант мне нравится больше, поэтому в частности у меня есть
и такой вариат:
\ удалить указанное число элементов с вершины стека данных
: nDROP ( [ .. ] # --> )
скобки пустые, так как на самом деле не известно, что же лежит
на вершине стека.
;
да, vid - voc-id
, а wid - word-id
\ c create does> словами все понятно
: aaaa ( n --> )
CREATE ,
( --> addr )
DOES> @ + ;
\ для слов, стековая диаграмма которых зависит от состояние переменной STATE
\ в СПФ принято писать отдельные диаграмы для каждого случая. Я с таким
\ подходом согласен, но его я бы и оставил для такого случая.
\ Компиляция: ( "ccc<quote>" --> )
\ Время выполнения: ( --> )
: ."
...
; IMMEDIATE
\ ---------------------------------------------------------------------------
VECT SOMETHING \ для следующего пояснения
\ в скобках пишутся слова, которые непосредственно не вызываются, а
\ являются значениями для VECT переменных.
: (something) ( --> )
;
' (something) IS SOMETHING \ обычно отсупаю на одну табуляцию
Да, мне ужастно не нравится что в СПФ есть только "TO",
для работы с векторами стоило бы оставить "IS".
\ об условных операторах
\ если между IF ELSE и\или ELSE THEN мало текста - пишу в одну строку
\ иначе отступы по одному пробелу на ELSE
: select ( n --> )
IF ." hello!"
ELSE ." ~BYE"
THEN ;
\ для вложенных условий.
\ вложенный IF находится под первым словом внутри внешнего IF-a
: complex ( n --> )
DUP IF 1+
IF ." immediate"
ELSE ." standart"
THEN
ELSE
THEN
\ так я оформляю циклы
: cycles ( n --> )
BEGIN DUP WHILE \ WHILE я пишу на одной строке условием
1- DUP WHILE \ если только условие влазит в ширину строки
DUP .
REPEAT \ если есть вложенные WHILE - то на один пробел дальше
THEN \ завершающее слово всегда в ровень с открывающим
;
\ ---------------------------------------------------------------------------
насчет стековых диаграм:
в первую очередь строки для меня привычнее писать так:
#asc - для строки со счетчиком
ascz - для строк, заканчивающихся нулем
asc # - говорит о том, что на стеке строка asc и ее длинна отдельно #
взято это не с потолка, а из InfoForth & SMAL32 систем то есть исторически
так сложилось.
\EOF отсюда обычно идет тестовый пример, прилагаемый к либе
я набросал другой вариант для добавления тестов в код, его
можно посмотреть в ~mOleg\lib\testing\testing.f
: test ( --> )
SOMETHING ... ;
test .( must be XXXXXX ) CR \ или что-то вроде этого.
\EOF
А вот отсюда описание идеи или любые другие множественные коментарии
в любом колличестве.
Мои сокращения( то есть, если слово содержит символ "x" то это значит что)
. - print слово что-то печатает
~ - show, say слово что-то отображает - помахать ручкой 8) ~BYE
! - store сохранить
@ - fetch извлечь
, - compile компилировать ," строка"
" - string что-то связанное со строкой Error" ощибка"
# - counter длинна чего-то, либо кол-во параметров #TIB - размер TIB
$ - reminder остаток от деления
' - address адрес чего-то, обычно wid
> - to, from если не проверка, то перемещение, например, >R R>
< - back ссылка назад, например <link
\ ---------------------------------------------------------------------------
да, насчет обозначений типов.
следующее соглашение взято из InfoForth
( отличная 16-битная ДОС форт-система )
n 16-paзpяднoe чиcлo co знaкoм;
u 16-paзpяднoe чиcлo бeз знaкa;
a aдpec в пaмяти;
# cчeтчик чиcлa бaйтов;
? лoгичecкий (бyлeвcкий) флaжoк;
d 32-paзpяднoe чиcлo co знaкoм;
ud 32-paзpяднoe чиcлo бeз знaкa;
b 8-paзpяднoe знaчeниe (бaйт);
c кoд cимвoлa.
а это из смал32
asc - Строка в формате ASCIIz, завершающаяся нулевым символом
xt - Адрес поля кода
c-addr - Адрес символа (невыровненный адрес)
w-addr - Адрес 2-байтового числа (выровненный на границу 2 байт)
a-addr - Адрес 4-байтового числа (выровненный на границу 4 байт)
addr - Любой действительный адрес
char - Символ или байт (играют роль только младшие 8 бит)
word - 2-байтовое число (играют роль только младшие 16 бит)
x - Любой элемент на стеке, занимающий одну ячейку (4 байта)
n - 4-байтовое число на стеке
+n - Неотрицательное 4-байтовое число
u - Беззнаковое 4-байтовое число
d - 8-байтовое число на стеке (занимает 2 4-байтовых эл-та)
+d - Неотрицательное 8-байтовое число
xd - Любой 8-байтовый элемент (занимает 2 4-байтовых эл-та)
ud - Беззнаковое 8-байтовое число
h - HANDLE - описатель блока динамической памяти
fh - FILE-HANDLE - описатель файла в DOS
port - Адрес порта ввода-вывода (важны только младшие 16 бит)
wid - Идентификатор словаря (адрес PFA слова-словаря)
flag - Логическое значение (=0 - FALSE, <>0 - TRUE)
true - Логическое значение TRUE (обычно -1)
false - Логическое значение FALSE (0)
tid - Идентификатор задачи (номер задачи; 0 - для главной)
почему-то не нашел # хотя в смал32 этот символ используется как и в InfoForth
это из EFORTH ( тоже очень интересная и распространенная форт-система )
a aligned address
b byte address
c character
ca code address
cy carry
d signed double integer
F logical false
f flag 0 or non-zero
la link address
n signed integer
na name address
T logical true
t flag T or F
u unsigned integer
ud unsigned double integer
va vocabulary address
w unspecified weighted value
а это 94 стандарт
flag flag 1 cell
true true flag 1 cell
false false flag 1 cell
char character 1 cell
n signed number 1 cell
+n non-negative number 1 cell
u unsigned number 1 cell
n|u (1) number 1 cell
x unspecified cell 1 cell
xt execution token 1 cell
addr address 1 cell
a-addr aligned address 1 cell
c-addr character-aligned address 1 cell
d double-cell signed number 2 cells
+d double-cell non-negative number 2 cells
ud double-cell unsigned number 2 cells
d|ud (2) double-cell number 2 cells
xd unspecified cell pair 2 cells
colon-sys definition compilation implementation dependent
do-sys do-loop structures implementation dependent
case-sys CASE structures implementation dependent
of-sys OF structures implementation dependent
orig control-flow origins implementation dependent
dest control-flow destinations implementation dependent
loop-sys loop-control parameters implementation dependent
nest-sys definition calls implementation dependent
i*x, j*x, k*x (3) any data type 0 or more cells