Народ, киньте ссылку по Форту. Когда-то им занимался (давным-давно), но сейчас ощутил что подзабыл. Хочется вспомнить все. И еще неплохо бы узнать не используется ли он сейчас. Действительно, штука была гениальной.
Последний раз вспоминал о Форте, только когда надо было просмотреть MSIL. Очень уж работа со стеком напомнило Форт.
Здравствуйте, GlebZ, Вы писали:
GZ>Может фиг, с ним, с Обероном. Все OS можно на форте накатать. И детишек форту учить. Пускай знают зачем мозги нужны.
Тем более что, программируя на Форте, приходится постоянно упражнять ум и память (а что у нас будет на стеке? а вот сейчас? а как это значение выцарапать?)
И кстати о Форте. Постскрипт — это тоже Форт, только специально заточенный. (насколько я знаю)
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, GlebZ, Вы писали:
GZ>>Может фиг, с ним, с Обероном. Все OS можно на форте накатать. И детишек форту учить. Пускай знают зачем мозги нужны.
С Обероном фиг.
RetroForth, кстати первый Форт, который я по-настоящему заценил.
Это не то уродство типа Forth ANS-83(94) с заглавными буквами, кривым режимом IMMEDIATE и интерпретирующей природой _компилятора_.
RetroForth — это самостроящийся NATIVE-компилятор, т.е. генерирующий в реальном времени native-код процессора. Хотя можно и байт-код прикрутить без проблем.
Ядро лишь позволяет определять новые слова и весит около килобайта.
Всё определяется уже в исходниках.
Т.е. все операции типа "+", "-", "*" и т.д. идут в исходниках в машкоде.
Вот, кстати, исходничек Retroforth(v7.5) на нём же самом (линкуется в чистом виде в ядрышко на асме),
пожатый UPX-ом весь этот RetroForth весит 4кб(>150 уже готовых слов):
forth
: rot >r swap r> swap ;
: -rot rot rot ;
: over swap dup -rot ;
: tuck swap over ;
: 2dup over over ;
: 2drop drop drop ;
: +! over @ + swap ! ;
: hex 16 base ! ;
: decimal 10 base ! ;
: binary 2 base ! ;
: octal 8 base ! ;
: /mod over over / -rot mod ;
: */ >r * r> / ;
: pad here 1024 + ;
: allot here + h0 ! ;
: align 0 here 4 mod allot ;
: cell+ 4 + ;
: cells 4 * ;
: char+ 1 + ;
: chars 1 * ;
: 2over >r >r 2dup r> -rot r> -rot ;
: 2swap rot >r rot r> ; forth
25 variable, lines
80 variable, columns
: ' 32 parse find ;
: alias create , does> @ >r ;
: fill swap repeat >r swap 2dup c! 1+ swap r> until ;
: 0; dup 0 =if r> 2drop ;; then ;
: << repeat >r dup + r> until ;
: cr 10 emit ;
: space 32 emit ;
: tab 9 emit ;
: del 8 emit ;
: clear lines @ repeat cr until ;
: >pad dup >r pad swap cmove pad r> ;
: " '" parse >pad ;
: ." " >pad type ;
: words last @ repeat @ 0; dup 8 + dup 1+ swap c@ type space again ;
: zt-make here over 4 / 1+ cells dup allot >r
2dup + >r dup >r
swap cmove r> 0 r> c! r> ;
: zt-free negate allot ;
: | 10 parse 2drop ;
here s0 ! 4096 allot
: .version s" RetroForth 7.5" type cr ;
Кстати, по моей (Alexey Abramov) наводке, автор (Chris Childers) взялся делать новый проект TetraForth (хе-хе, я придумал бренд ), более комплексный, чем RetroForth.
Retroforth неплох как скриптовая система для игр.
Это круче, чем CLR в NET.
За счёт того, что нет пролога/эпилога функций, многие функции работают быстрее, чем на том же асме/с++/delphi.
Внешние инклюды тоже цепляются. Пишется система инклюдов также на самом же форте. Там, кстати, в CodeLibrary есть блок, где я написал реализацию слова include для цепляния в рантайме исходников.
Также я писал систему пространств имён:
: namespace ( xt -- )
create last @ @ , does>
last @ @ swap
dup @ last @ !
;
: ns; ( n n -- )
last @ @ swap !
last @ !
;
Это вложенные пространства имён, как в .NET.
Ха-ха.
Вот асм на форте:
namespace asm
asm
| RetroForth Assembler
| ------------------------------------------------------------
| We aren't supporting a full-blown assembler yet; this is a
| small, carefully selected subset of x86 assembly.
| ------------------------------------------------------------
here sp ! 1024 4 * chars allot | Reserve 4k for strings
: error s" An error has been detected" type cr ;
variable state |
: m/r 0 state ! ; | memory->register
: r/m 1 state ! ; | register->memory
: i/r 2 state ! ; | immediate->register
: i/m 3 state ! ; | immediate->memory
: r/r 4 state ! ; | register->register
: m 5 state ! ; | memory address
0 constant eax 1 constant ebx |
2 constant ecx 3 constant edx |
4 constant esi 5 constant edi |
| ------------------------------------------------------------
: mov-i/r dup 0 = if drop $b8 1, , ;; then
dup 1 = if drop $bb 1, , ;; then
dup 2 = if drop $b9 1, , ;; then
dup 3 = if drop $ba 1, , ;; then
dup 4 = if drop $be 1, , ;; then
dup 5 = if drop $bf 1, , ;; then
error ;
: mov-m/r dup 0 = if drop $b8 1, , ;; then
dup 1 = if drop $bb 1, , ;; then
dup 2 = if drop $b9 1, , ;; then
dup 3 = if drop $ba 1, , ;; then
dup 4 = if drop $be 1, , ;; then
dup 5 = if drop $bf 1, , ;; then
error ;
: mov, state @ dup 0 = if drop s" m/r" type cr ;; then
dup 1 = if drop s" r/m" type cr ;; then
dup 2 = if drop mov-i/r ;; then
dup 3 = if drop s" i/m" type cr ;; then
dup 4 = if drop s" r/r" type cr ;; then
error ;
: push-r/m dup 0 = if drop $50 1, ;; then
dup 1 = if drop $53 1, ;; then
dup 2 = if drop $51 1, ;; then
dup 3 = if drop $52 1, ;; then
dup 4 = if drop $56 1, ;; then
dup 5 = if drop $57 1, ;; then
error ;
: push, state @ dup 1 = if drop push-r/m ;; then
dup 3 = if drop $68 1, , ;; then
error ;
: pop, dup 0 = if drop $58 1, ;; then
dup 1 = if drop $5B 1, ;; then
dup 2 = if drop $59 1, ;; then
dup 3 = if drop $5A 1, ;; then
dup 4 = if drop $5E 1, ;; then
dup 5 = if drop $5F 1, ;; then
error ;
asm
| ------------------------------------------------------------
| This is a test program:
label a 100 i/m push, eax pop, ret,
| If it works, it'll change the value on TOS to 100
200 a .
ns;
: testa
[ asm ]
300 a .
[ ns; ]
;
---
Жаль, что с плавающей точкой траблы.
Но ничего, пишешь на дельфях dll-ку на 10 к-байт, цепляешь её и юзаешь себе плавающую точку.
Это для винды.
Под линухом, юнихом и беосом на дельяфях не попишешь уже. Только ся. Или на том же асме набить. Тока хрен наёдёшь корректные float to string и vice versa сырцы.
А. Ещё ретрофорт юзается как мультиплатформенный веб-сервер (forth-wiki)
Нехилая штучка, сервер в 8 кб, да притом, что в standalone exe-шнике (или dll-ке) видны его же исходники.
К> Тем более что, программируя на Форте, приходится постоянно упражнять ум и память (а что у нас будет на стеке? а вот сейчас? а как это значение выцарапать?)
А то на сях ты не упражняешься, будет ли Aceess Violation или не будет?
К>И кстати о Форте. Постскрипт — это тоже Форт, только специально заточенный. (насколько я знаю)
Постскрипт — это та ещё гадость.
Кто на нём вручную ришет?
А никто!
Только принтеры и печатают.
Да PDF-ридеры рендерят месиво псевдо-фортовых слов.
Маразм кривой, одни словом.
Но ведь работает!
Заходите на форум (инглиш) http://retroforth.org/board/
я там бываю иногда (Alexey Abramov).
Мож слонов новых вместе изобретём
Там есть архив с последней выложенной версией djkaries_giref_test5.zip
Прога запускается без консоли.
Чтобы включить консоль, в модуле system.f вставьте первую строчку "console" — слово без кавычек.
exe-шник весит 3584 байта в несжатом виде (rar-ом ужимается до 1922 байт).
Он при запуске компилит исходники, лежащие рядом с ним.
Юзается glfw для инициализации OpenGL, fmod для музыки и звука.
Проекты не требуют компиляции. Просто меняется текст исходников и запускается exe-шник (djkaries_giref_test5.zip\ref\bin\ref.exe).
Содержимое файлика game.f:
uses rtl/math.f
uses rtl/string.f
uses giref/sound.f
uses giref/opengl.f
uses giref/glfw.f
uses giref/colors.f
uses giref/utils.f
var FullScreen
uses ini.f
Sound.Ini
" game.xm" Sound.PlaySong
3 vars: Running Width Height
2 vars: MouseX MouseY
3 vars: txFont txGui txWalls
var PressedQ
uses camera.f
uses levels.f
uses objects.f
uses levels/1.f
: LoadTextures
EnableTexture
s" Textures/Font.tga" LoadTexture to txFont texMipmapLinear
s" Textures/Gui.tga" LoadTexture to txGui texNearest
s" Textures/Walls.tga" LoadTexture to txWalls texNearest
;
: DeleteTextures
;
0 var, CurX
-256 var, CurY
16 var, CurSize
5 vars: x x2 y z i
3 vars: red green blue
: Render2D
GL_TEXTURE glMatrixMode
glLoadIdentity
float 0 float 1 float 0 glTranslatef
[ float 1 float 256 f/ ] literal [ float -1 float 256 f/ ] literal float 1 glScalef
GL_MODELVIEW glMatrixMode
EnableTexture
EnableBlend
texBlend
txWalls SetTexture
level.test
DisableTexture
texBlend
EnableBlend
| Header
224 224 255 128 glColor4ub
rects:
0 8 640 64 rectangle
0 448 640 24 rectangle
draw;
EnableTexture
texBlend
txFont SetTexture
16 to FontSize
-4 to FontStep
220 255 189 glColor3ub
s" giref Test v6 :)" 16 16 TextOut
150 210 255 glColor3ub
s" Press keys: Arrows, PGUp, PGDown, Esc" 16 32 TextOut
s" 'F'-FullScreen; 'Q'-Test" 16 48 TextOut
-2 to FontStep
8 to FontSize
128 224 255 224 glColor4ub
s" (c)2005 Alexey Abramov. e-mail: djkaries at list.ru" 16 456 TextOut
0 255 0 224 glColor4ub
PressedQ if
8 to FontSize
s" You pressed 'q'. Command Line: " 16 100 TextOut
GetCommandLine z>str 16 116 TextOut
then
| Render mouse cursor
txGui SetTexture
rects:
clWhite glColor3ub
MouseX MouseY 32 64 16 16 texRectangle
draw;
;
: reopenWindow
DeleteTextures
glfwCloseWindow
640 480 0 0 0 0 0 0
FullScreen if
s" FullScreen mode" type cr
GLFW_FULLSCREEN
else
s" Windowed mode" type cr
GLFW_WINDOW
then
glfwOpenWindow
s" giref: forth game sdk" drop glfwSetWindowTitle
1 glfwSwapInterval
LoadTextures
;
: ProcessControls
GLFW_KEY_RIGHT key: CurX 1+ to CurX key;
GLFW_KEY_LEFT key: CurX 1- to CurX key;
GLFW_KEY_DOWN key: CurY 1+ to CurY key;
GLFW_KEY_UP key: CurY 1- to CurY key;
GLFW_KEY_PAGEUP key: CurSize 1+ to CurSize key;
GLFW_KEY_PAGEDOWN key: CurSize 1- to CurSize key;
'F key:
FullScreen not to FullScreen
reopenWindow
key;
false to PressedQ
'Q key: true to PressedQ key;
addr MouseX addr MouseY glfwGetMousePos
CurX to camera.x
CurY to camera.y
;
: RenderLoop
repeat
GLFW_KEY_ESC key: ;; key;
GLFW_OPENED glfwGetWindowParam 0; drop
addr Width addr Height glfwGetWindowSize
ProcessControls
0 0 Width Height glViewport
float 0.25 float 0.25 float 0.75 float 1 glClearColor
GL_COLOR_BUFFER_BIT glClear
glLoadIdentity
float -1 float 1 float 0 glTranslatef
[ float 1 float 320 f/ ] literal [ float -1 float 240 f/ ] literal float 1 glScalef
GLFW_ACTIVE glfwGetWindowParam 0 =if
0 0 glfwSleep
then
Render2D
glfwSwapBuffers
again
;
: StartUp
glfwInit drop
reopenWindow
RenderLoop
glfwTerminate
;
!!!!
У меня ряд вопросов.
1) Его легко встроить в плюсовую программу?
2) Он генерит машинный код на лету и выполняет его, не создавая нового процесса?
Если все — "да", то это похоже идеальная штука для реализации своих скриптовых языков. Надо брать.
DK>--- DK>Жаль, что с плавающей точкой траблы. DK>Но ничего, пишешь на дельфях dll-ку на 10 к-байт, цепляешь её и юзаешь себе плавающую точку. DK>Это для винды. DK>Под линухом, юнихом и беосом на дельяфях не попишешь уже. Только ся. Или на том же асме набить. Тока хрен наёдёшь корректные float to string и vice versa сырцы.
Странно это как-то... А нельзя просто определить несколько новых слов, которые будут использовать сопроцессор? Это же элементарно должно быть.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, DJ KARIES, Вы писали:
DK>>Здравствуйте, GlebZ, Вы писали:
GZ>>>Народ, киньте ссылку по Форту. DK>>http://www.retroforth.org DK>>Оч маленький и оч шустрый. DK>>Полностью native. DK>>Мультиплатформенный, компилер fasm/nasm/etc. DK>>Исходник весит считанные килобайты. DK>>Развивается. GZ>Интересная штука. Особенно понравилось:
GZ>
GZ>Eventually we plan to release a ForthOS called RUNE that is built RetroForth/Native, but that's still in the planning stages.
GZ>Может фиг, с ним, с Обероном. Все OS можно на форте накатать. И детишек форту учить. Пускай знают зачем мозги нужны.
Форту не нужна оперсистема, вообще-то. Он спокойно может работать без нее. Например, загрузчик в рабочих станциях Sun был раньше написан на Forth (может и сейчас так, не знаю). При желании можно было включить машину и попасть в Forth-консоль.
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, DJ KARIES, Вы писали:
G> !!!! G>У меня ряд вопросов. G>1) Его легко встроить в плюсовую программу?
Да, хоть в delphi, хоть в асме, хоть в самом же форте.
Юзай retroforth.dll.
Там есть функция rfEval для интепретации переданной строки.
Вообще, достаточно передать через rfEval адрес одной своей сишной функции, а через которую биндить все остальные.
Т.е. типа GetProcAddress, как в винде организовать.
G>2) Он генерит машинный код на лету и выполняет его, не создавая нового процесса?
Да.
G>Если все — "да", то это похоже идеальная штука для реализации своих скриптовых языков. Надо брать.
Я с августа 2004, как узнал о Retroforth 7.2 просто без ума от него.
В той версии не было циклов. Так вот, я сваял слово "until" и циклы появились в v7.3.
Т.е. можно определить любую конструкцию, т.к. Forth — МЕТАКОМПИЛЯТОР.
DK>>--- DK>>Жаль, что с плавающей точкой траблы. DK>>Но ничего, пишешь на дельфях dll-ку на 10 к-байт, цепляешь её и юзаешь себе плавающую точку. DK>>Это для винды. DK>>Под линухом, юнихом и беосом на дельяфях не попишешь уже. Только ся. Или на том же асме набить. Тока хрен наёдёшь корректные float to string и vice versa сырцы.
G>Странно это как-то... А нельзя просто определить несколько новых слов, которые будут использовать сопроцессор? Это же элементарно должно быть.
Без проблем.
Там, вроде, даже уже есть в Code Library.
Можно хоть в asm-файлике приаттачить float-арифметику, хоть машкодами на самом форте. Траблик в переводе строки в float и наоборот.
Мне б алгоритм таких переводов, я б оформил это на форте.
Приходится юзать свою dll-ку на дельфях refmath.dll в 20кб для этого.
Раньше пробовал реализовать перевод строки во float на дельфях, чтоб потом алгоритм перенести на форт или асм, но вышло криво и я забил.
Кстати, вот интерфейс на дельфях к retroforth.dll, который я наваял:
unit rf;
interface
const
rfdll = 'rf.dll';
procedure rfAttach; stdcall external rfdll name 'retroforth_attach';
procedure rfInit; stdcall external rfdll name 'retroforth_init';
procedure rfEval; assembler; external rfdll name 'retroforth_eval';
procedure rfInterpreter; stdcall external rfdll name 'retroforth_interpreter';
procedure dup;
procedure drop;
procedure upsh(a: Integer); stdcall;
function upop: Integer;
procedure Eval(const Value: string);
implementation
procedure dup;
asm
sub esi,4
mov [esi],eax
end;
procedure drop;
asm
lodsd
end;
procedure upsh(a: Integer);
begin
asm
sub esi,4
mov [esi],eax
mov eax, a
end;
end;
function upop: Integer;
asm
lodsd
end;
procedure Eval(const Value: string);
var
i, n: Integer;
begin
upsh(Integer(PChar(Value)));
dup;
Length(Value);
rfEval;
end;
end.
Здравствуйте, DJ KARIES, Вы писали:
DK>Здравствуйте, Gaperton, Вы писали:
G>>Здравствуйте, DJ KARIES, Вы писали:
G>> !!!! G>>У меня ряд вопросов. G>>1) Его легко встроить в плюсовую программу? DK>Да, хоть в delphi, хоть в асме, хоть в самом же форте. DK>Юзай retroforth.dll. DK>Там есть функция rfEval для интепретации переданной строки. DK>Вообще, достаточно передать через rfEval адрес одной своей сишной функции, а через которую биндить все остальные. DK>Т.е. типа GetProcAddress, как в винде организовать.
G>>2) Он генерит машинный код на лету и выполняет его, не создавая нового процесса? DK>Да.
G>>Если все — "да", то это похоже идеальная штука для реализации своих скриптовых языков. Надо брать. DK>Я с августа 2004, как узнал о Retroforth 7.2 просто без ума от него. DK>В той версии не было циклов. Так вот, я сваял слово "until" и циклы появились в v7.3. DK>Т.е. можно определить любую конструкцию, т.к. Forth — МЕТАКОМПИЛЯТОР.
Я в курсах, я знаю форт хорошо. Писал несколько форт-машин сам в разное время. Последнее время я его использую в качестве движка выполнения для разнообразных кастомных скриптовых языков (считаю это самым простым способом из известных организовать рантайм). Но мне не хватало производительности шитого кода — а здесь — компиляция. Огромное спасибо, это мега-тулза. Кстати, какая на нее лицензия?
Здравствуйте, Gaperton, Вы писали:
G>Я в курсах, я знаю форт хорошо. Писал несколько форт-машин сам в разное время. Последнее время я его использую в качестве движка выполнения для разнообразных кастомных скриптовых языков (считаю это самым простым способом из известных организовать рантайм).
Можно ссылочки на такие проекты?
Интересно увидеть подобные реализации.
G>Но мне не хватало производительности шитого кода — а здесь — компиляция. Огромное спасибо, это мега-тулза.
Тут ещё такой прикол: т.к. компиляция в машкод, можно отвлечься от чисто стековой архитектуры и приплести использование других регистров процессора, включая все РОН, регистры MMX, SSE, FPU.
Насчёт скорости.
Т.к. компиляция происходит на лету, указатели можно прошивать в код, ускоряя этим работу.
В Retroforth есть 2 словаря: forth и macro.
При компиляции слова, если оно найдено в словаре macro, оно сразу же исполняется.
Это аналог IMMEDIATE в других фортах.
И фишка в том, что в тех фортах СЛОВО либо IMMEDIATE, либо нет, а в Retroforth могут присутствовать сразу обе версии слова, позволяя одному слову исполняться в диалоговом режиме и инлайниться в код при компиляции.
Регистровая модель взята из ColorForth. Т.е. код ничем не отличается от любого бинарника, кроме соглашения о стековой архитектуре, где используются только лишь регистры eax, esi и esp.
см. TheRetroBook.txt.
Register Use
-------------------------------
EAX Top of Stack
ESI Data Stack
[ESI] Second item on Stack
ESP Return Stack
-------------------------------
G>Кстати, какая на нее лицензия?
Абсолютно свободная. Тип лицензии — public domain. Т.е. делаешь всё, что хочешь.
см. на том сайте www.retroforth.org раздел про лицензию.
Моя версия ref и giref также абсолютно свободна.
Единственное требование — не убирать информацию об авторе.
И ещё.
Разрабатываемая сейчас версия RetroForth 8 более лажовая, чем 7.6.
ИМХО, лучше за отправную точку взять v7.6, к ней приплюсовать модули из ref.
Или юзать ref, где также можно поместить все модули в один exe/dll.
Здравствуйте, DJ KARIES, Вы писали:
DK>Здравствуйте, Gaperton, Вы писали:
G>>Я в курсах, я знаю форт хорошо. Писал несколько форт-машин сам в разное время. Последнее время я его использую в качестве движка выполнения для разнообразных кастомных скриптовых языков (считаю это самым простым способом из известных организовать рантайм). DK>Можно ссылочки на такие проекты? DK>Интересно увидеть подобные реализации.
1-я реализация, которую я делал, была для ZX Spectrum . Ничего особенного — применив непосредственный шитый код (команда — прямая ссылка на ассемблер) я порвал FigForth на 30% (там классика — косвенный шитый код). Просто было любопытно — проект для себя. Не сохранился.
2-я реализация — если так можно назвать — курсовая в универе сделаная за пару дней — SQL Server (спокойно!) реализующий подмножество SQL. Времени было мало (по разгильдяйству), и в качестве рантайма для выполения запросов была за несколько часов (рука уже набита — почти по памяти) реализована простая минимально необходимая форт-машина на С. Подход себя оправдал — дешево, и очень быстро. Проект не сохранился — учебная задача на выброс.
3-я реализация — подсистема выполнения встроенного языка системы CQG (простой язык обработки временных рядов). Старая зело тормозила, была разработана схема компиляции языка в фортовый байт-код (опять же, была написана своя машинка на С++ с соблюдением духа и идеологии Форт). Еще раз подтвердилось, что форт-машина — самый дешевый способ писать рантайм для скриптовых языков. Код дать не могу — non-disclosure agreement. Да и машинка там была проста и классична — абсолютно ничего интересного, все стандартно.
G>>Но мне не хватало производительности шитого кода — а здесь — компиляция. Огромное спасибо, это мега-тулза. DK>Тут ещё такой прикол: т.к. компиляция в машкод, можно отвлечься от чисто стековой архитектуры и приплести использование других регистров процессора, включая все РОН, регистры MMX, SSE, FPU.
Вот этого не надо. Весь бонус для меня в том, что я не использую явно регистры, а генерирую код для стековой машины (это сильно проще). А уж дальше пусть само разрешится.
DK>Насчёт скорости. DK>Т.к. компиляция происходит на лету, указатели можно прошивать в код, ускоряя этим работу.
Кстати, а что именно подразумевается под компиляцией в native код? Инлайн слов, определенных на ассемблере, + "прямой" шитый код (вызовы JMP word_address)? А как насчет стека — делает ли он честную раскладку по регистрам для арифметики?
DK>В Retroforth есть 2 словаря: forth и macro. DK>При компиляции слова, если оно найдено в словаре macro, оно сразу же исполняется. DK>Это аналог IMMEDIATE в других фортах.
Разница несущественна, ИМХО. Будет слово лежать в отдельном словаре, или ему будет выставлен признак IMMEDIATE — не суть. Хотя словарь дает дополнительную возможность контроля, так наверно лучше.
DK>И фишка в том, что в тех фортах СЛОВО либо IMMEDIATE, либо нет, а в Retroforth могут присутствовать сразу обе
версии слова, позволяя одному слову исполняться в диалоговом режиме и инлайниться в код при компиляции.
Да, так точно лучше. Похоже, автор глубоко понимает идеологию Форт.
DK>Регистровая модель взята из ColorForth. Т.е. код ничем не отличается от любого бинарника, кроме соглашения о стековой архитектуре, где используются только лишь регистры eax, esi и esp. DK>см. TheRetroBook.txt. DK>
Register Use
DK> -------------------------------
DK> EAX Top of Stack
DK> ESI Data Stack
DK> [ESI] Second item on Stack
DK> ESP Return Stack
DK> -------------------------------
G>>Кстати, какая на нее лицензия? DK>Абсолютно свободная. Тип лицензии — public domain. Т.е. делаешь всё, что хочешь. DK>см. на том сайте www.retroforth.org раздел про лицензию.
DK>Моя версия ref и giref также абсолютно свободна. DK>Единственное требование — не убирать информацию об авторе.
Нивапрос . Надо будет — еще и бабок отстегнем. Впрочем, пока такого проекта не планируется, так что на бабки рассчитывать не надо.
DK>И ещё. DK>Разрабатываемая сейчас версия RetroForth 8 более лажовая, чем 7.6. DK>ИМХО, лучше за отправную точку взять v7.6, к ней приплюсовать модули из ref. DK>Или юзать ref, где также можно поместить все модули в один exe/dll.
Спасибо. Буду иметь этот замечательный проект в виду.
Здравствуйте, Gaperton, Вы писали:
G> Форту не нужна оперсистема, вообще-то. Он спокойно может работать без нее. Например, загрузчик в рабочих станциях Sun был раньше написан на Forth (может и сейчас так, не знаю). При желании можно было включить машину и попасть в Forth-консоль.
Как писал Лео Броуди, "ФОРТ — это не язык, ФОРТ — это способ мышления.".
За дословность не ручаюсь, но с этим утверждением я согласен.
В том и красота ФОРТа, что это, в принципе и не язык.
Ну какой же это "язык", если весь синтаксис его состоит из слов и пробелов?
Стековая архитектура также упрощает создание машины.
Но в этом есть проблема — каждый норовит сделать СВОЮ Форт-машину, убивая совместимость.
Хотя, Форт — язык для создания прикладных языков...
Здравствуйте, Gaperton, Вы писали:
G>1-я реализация, которую я делал, была для ZX Spectrum . Ничего особенного — применив непосредственный шитый код (команда — прямая ссылка на ассемблер) я порвал FigForth на 30% (там классика — косвенный шитый код). Просто было любопытно — проект для себя. Не сохранился.
Да, ностальгия...
G>2-я реализация — если так можно назвать — курсовая в универе сделаная за пару дней — SQL Server (спокойно!) реализующий подмножество SQL. Времени было мало (по разгильдяйству), и в качестве рантайма для выполения запросов была за несколько часов (рука уже набита — почти по памяти) реализована простая минимально необходимая форт-машина на С. Подход себя оправдал — дешево, и очень быстро. Проект не сохранился — учебная задача на выброс.
Зато какой опыт!
G>3-я реализация — подсистема выполнения встроенного языка системы CQG (простой язык обработки временных рядов).
Что за язык обработки временных рядов.
DK>>Тут ещё такой прикол: т.к. компиляция в машкод, можно отвлечься от чисто стековой архитектуры и приплести использование других регистров процессора, включая все РОН, регистры MMX, SSE, FPU. G>Вот этого не надо. Весь бонус для меня в том, что я не использую явно регистры, а генерирую код для стековой машины (это сильно проще). А уж дальше пусть само разрешится.
Я о том, что регистры надо использовать не на уровне задачи, а на уровне подсистемы компиляции. Т.е. те же циклы можно реализовать без стека через регистры, ускорить ООП через использование регистров типа EBX, и т.д.
Естественно, использование регистров не должно накладывать след на прикладную часть.
DK>>Насчёт скорости. DK>>Т.к. компиляция происходит на лету, указатели можно прошивать в код, ускоряя этим работу. G>Кстати, а что именно подразумевается под компиляцией в native код? Инлайн слов, определенных на ассемблере, + "прямой" шитый код (вызовы JMP word_address)?
Текст программы компилируется в обычный бинарный код процессора, и не важно, где определено слово, на ассемблере, машкодом в форте или макросами форта.
Т.е. нет каких-то извратных шлюзов как в .NET при использовании pInvoke.
За счёт этого достигается максимально возможная скорость и отпадает нужда в конструировании системы команд вымышленного процессора с последующей его эмуляцией, т.к. реальный процессор и есть наш целевой интерпретатор байт-кода.
G>А как насчет стека — делает ли он честную раскладку по регистрам для арифметики?
Вершина стека в регистре EAX, второй элемент в [ESI].
Т.е. например для сложения мы делаем вот что:
add eax,[esi]
sub esi,4
Либо инлайним 3 байта макросом на Форте:
: + $ad0601 3, ;
DK>>В Retroforth есть 2 словаря: forth и macro. DK>>При компиляции слова, если оно найдено в словаре macro, оно сразу же исполняется. DK>>Это аналог IMMEDIATE в других фортах. G>Разница несущественна, ИМХО. Будет слово лежать в отдельном словаре, или ему будет выставлен признак IMMEDIATE — не суть. Хотя словарь дает дополнительную возможность контроля, так наверно лучше.
Нет. Насколько мне известно в этом есть гемор, т.к. на каждом шагу надо сравнивать STATE.
DK>>И фишка в том, что в тех фортах СЛОВО либо IMMEDIATE, либо нет, а в Retroforth могут присутствовать сразу обе G>версии слова, позволяя одному слову исполняться в диалоговом режиме и инлайниться в код при компиляции. G>Да, так точно лучше. Похоже, автор глубоко понимает идеологию Форт.
Согласен.
DK>>Моя версия ref и giref также абсолютно свободна. DK>>Единственное требование — не убирать информацию об авторе. G>Нивапрос . Надо будет — еще и бабок отстегнем. Впрочем, пока такого проекта не планируется, так что на бабки рассчитывать не надо.
Интересно развитие идей, заложенных в Retroforth и ref в частности.
Здравствуйте, DJ KARIES, Вы писали: G>>2-я реализация — если так можно назвать — курсовая в универе сделаная за пару дней — SQL Server (спокойно!) реализующий подмножество SQL. Времени было мало (по разгильдяйству), и в качестве рантайма для выполения запросов была за несколько часов (рука уже набита — почти по памяти) реализована простая минимально необходимая форт-машина на С. Подход себя оправдал — дешево, и очень быстро. Проект не сохранился — учебная задача на выброс. DK>Зато какой опыт!
Да, я был страшно горд — уж очень просто и красиво получилось .
G>>3-я реализация — подсистема выполнения встроенного языка системы CQG (простой язык обработки временных рядов). DK>Что за язык обработки временных рядов.
Очень простой декларативный язык. Основа грамматики — язык арифметических выражений с присваиваниями и вызовами функций/макросов. Задача, в том, чтобы определяеть функции для трансформации (типа бесконечных) последовательностей чисел. Каждая функция является "чистой" (без побочных эффектов) в пределах рассчета одного значения последовательности.
Довольно интересно писать к нему рантайм, в частности, возникают интересные моменты при попытке ввести теорию типа для этого языка, ввести императивные конструкции (надо преобразовывать программу для сохранения функциональной чистоты, вынося побочный эффект наверх, иначе работать не будет), и прочее. В общем, довольно интересно все получается. Это отдельная и большая тема, я сам в нюансы очень долго вникал.
G>>А как насчет стека — делает ли он честную раскладку по регистрам для арифметики? DK>Вершина стека в регистре EAX, второй элемент в [ESI]. DK>Т.е. например для сложения мы делаем вот что: DK>
add eax,[esi]
DK> sub esi,4
DK>
DK>Либо инлайним 3 байта макросом на Форте: DK>
: + $ad0601 3, ;
Понятно. Я имел в виду несколько другое. "Взрослые" компиляторы делают для сложных арифметических выражений раскладку на все доступные регистры, минимизируя обращение к памяти, есть специальный алгоритм для этого. Для того, чтобы это сделать, необходимо все выражение компилировать целиком.
В сети я встречал статью (в контексте Форт), где предлагался подобный алгоритм определения раскладки регистров для стековой арифметики — работает как оптимизация на байт-коде отдельным проходом (т. е. при кодогенерации опять рассматривается группа операций одновременно). В retroforth применяются подобные оптимизации?
Здравствуйте, Gaperton, Вы писали:
G>Понятно. Я имел в виду несколько другое.
Я показал то, что есть. Некоторые асмовые функции используют естественно, кроме eax, esi, esp другие регистры.
Не проблема их использовать.
G>"Взрослые" компиляторы делают для сложных арифметических выражений раскладку на все доступные регистры, минимизируя обращение к памяти, есть специальный алгоритм для этого. Для того, чтобы это сделать, необходимо все выражение компилировать целиком.
Это всё понятно.
Но, по-моему, Форты никогда не были "взрослыми" компиляторами. Они оригинальны, мощны, но ПРИМИТИВНЫ.
И в этом их сила. Всё даётся с трудом, никто за тебя ничего не сделает и не соптимизирует, т.е. так-сказать "НЕ НРАВИТСЯ — НЕ ЮЗАЙ!".
G>В сети я встречал статью (в контексте Форт), где предлагался подобный алгоритм определения раскладки регистров для стековой арифметики — работает как оптимизация на байт-коде отдельным проходом (т. е. при кодогенерации опять рассматривается группа операций одновременно). В retroforth применяются подобные оптимизации?
Подобной оптимизации в ядре и стандартной реализации Retroforth НЕТ.
Ибо данная форт-система не является оптимизирующей.
Это одна из простейших, но при этом мощных и расширяемых систем.
Если есть желание, можно как-то продумать оптимизацию, взять идеи по оптимизации из существующих фортов, например из того же SP-FORTH'а, и внедрить в своей работе.
Здравствуйте, DJ KARIES, Вы писали:
G>>"Взрослые" компиляторы делают для сложных арифметических выражений раскладку на все доступные регистры, минимизируя обращение к памяти, есть специальный алгоритм для этого. Для того, чтобы это сделать, необходимо все выражение компилировать целиком. DK>Это всё понятно. DK>Но, по-моему, Форты никогда не были "взрослыми" компиляторами. Они оригинальны, мощны, но ПРИМИТИВНЫ. DK>И в этом их сила. Всё даётся с трудом, никто за тебя ничего не сделает и не соптимизирует, т.е. так-сказать "НЕ НРАВИТСЯ — НЕ ЮЗАЙ!".
Это так... Но хочется-то чуда
Здравствуйте, Gaperton, Вы писали:
G>Здравствуйте, DJ KARIES, Вы писали:
DK>>Но, по-моему, Форты никогда не были "взрослыми" компиляторами. Они оригинальны, мощны, но ПРИМИТИВНЫ. DK>>И в этом их сила. Всё даётся с трудом, никто за тебя ничего не сделает и не соптимизирует, т.е. так-сказать "НЕ НРАВИТСЯ — НЕ ЮЗАЙ!". G>Это так... Но хочется-то чуда
Хочется чуда — используй MSIL. Тот же форт, но вид с попы.
Сегодня немного ознакомился с сим творением рук мелкомягких, стековая машина форева.
Толького нафига каждый год лепить новые версии по 25 метров?
Никакого диалапа на них не напасёшься.
Мне моих 3.5 кб. на компилер хватает
Даже пространства имён как в .NETе прикручиваются за 2 строчки