Robby - расширение языка Robot Warfare 1 (RW1)
Moderator: Shaos
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Robby - расширение языка Robot Warfare 1 (RW1)
Пришло время с нуля писать новую быструю виртуальную машину RW0 на голом C...
P.S. Это в том числе и для RW3D будет использовано
P.P.S. Использование слова "Robby" в качестве нового варианта названия языка RW1 началось с мая 2016,
соответственно теперь виртуальную машину можно обозвать RobbyVM
P.P.P.S. Исходники старых виртуальные машин RW0 можно посмотреть вот в этих репах:
https://gitlab.com/shaos/rw1o (версия байткода 1.99)
https://gitlab.com/shaos/rw2d (версия байткода 2.0)
И ещё был простой интерпретатор на PocketC
P.S. Это в том числе и для RW3D будет использовано
P.P.S. Использование слова "Robby" в качестве нового варианта названия языка RW1 началось с мая 2016,
соответственно теперь виртуальную машину можно обозвать RobbyVM
P.P.P.S. Исходники старых виртуальные машин RW0 можно посмотреть вот в этих репах:
https://gitlab.com/shaos/rw1o (версия байткода 1.99)
https://gitlab.com/shaos/rw2d (версия байткода 2.0)
И ещё был простой интерпретатор на PocketC
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Придётся поддержать в том числе и старую систему команд (см. про версию 1.99 тут):
Code: Select all
Robot Warfare 1
RW0 bytecode description
Version 1.99
Alexander A. Shabarshin (shaos@mail.ru)
http://robots.ural.net
November 1998 - January 2000
Header:
-------
0x0000: 0x00..0x02 // Version (0x00 for 1.*, 0x01 for 1.99)
0x0001: 2 bytes // CheckSum (simple adding of the bytes starting from 0x0005)
0x0003: 2 bytes // Offset to bytecode start point (in bytes)
0x0005: 1 byte // Length of the robot name (strlen)
0x0006: N bytes // Robot name
0x????: 0x00 // Terminal character for robot name
0x????: 2 bytes // Number of variables (plus arrays length)
0x????: 2 bytes // Code length in bytes (beginning from start point)
0x????: 3 bytes // Robot color (R,G,B)
0x????: 4 bytes // Equipments on the FRONT,RIGHT,BACK,LEFT (0-empty,1-eye,2-gun)
0x????: 1 byte // Image flag (0x00-image is absent, 0x20-image is present)
// if image present, then next 32 bytes describe the robot image (2pix/byte)
// after that follows bytecode (after start point)
0x????: N bytes // Author nickname
0x????: 0x00 // Terminal character for author nickname
0x????: ?? ... // reserved for additional data
START:
-----------------------------------------------------------------
B - byte (1 byte)
W - word (2 bytes - low byte + high byte)
M - variable or constant (3-5 bytes):
0x00 W - signed integer (-32K..+32K)
0x01 W - variable in W cell (array[constant] is compiled to it too)
0x02 W1 W2 - array element (W1-begin of array, W2-variables with offset)
Registers are variables (0x01 0x?? 0xFF) with the addresses:
0xFF00 - X // register for relative X value
0xFF01 - Y // register for relative Y value
0xFF02 - D // register for distance value
0xFF03 - N // register for object value
0xFF04 - K // register for additional value
0xFF05 - R // register for random value
0xFF06 - T // register for timer value
0xFF07 - E // register for our energy value
0xFF08 - M // register for our missiles number
0xFF09 - I // register for order number of robot
0xFF0F - S // register for stack length
labW - label with address W
-----------------------------------------------------------------
DEF commands - array definition (minimal length is 5 bytes)
------------
0x01 W1 W2 // DEF arr[len] (W1-offset to array start, W2-len)
0x02 W1 W2 W3 ... // DEF arr[len]={list} (W3-number of words)
IF commands - maximal length is 13 bytes
-----------
0x10 W M1 M2 // IF M1<M2 : labW
0x11 W M1 M2 // IF M1>M2 : labW
0x12 W M1 M2 // IF M1<=M2 : labW
0x13 W M1 M2 // IF M1>=M2 : labW
0x14 W M1 M2 // IF M1==M2 : labW
0x15 W M1 M2 // IF M1!=M2 : labW
// or IF M1<>M2 : labW
Expressions - maximal length is 11-16 bytes
-----------
0x20 M1 M2 // M1=M2
0x21 M1 M2 // M1=-M2
0x22 M1 M2 M3 // M1=M2+M3
0x23 M1 M2 M3 // M1=M2-M3
0x24 M1 M2 M3 // M1=M2/M3
0x25 M1 M2 M3 // M1=M2*M3
0x26 M1 M2 M3 // M1=M2%M3
0x27 M1 M2 M3 // M1=M2&M3 - binary AND
0x28 M1 M2 M3 // M1=M2|M3 - binary OR
0x29 M1 M2 M3 // M1=M2^M3 - binary XOR
0x2A M1 M2 // M1=~M2 - binary NOT
Simple commands - 1-5 bytes
---------------
0x30 W // GOTO labW
0x31 W // CALL labW
0x33 // RET
0x34 // STEP
0x35 // LEFT
0x36 // RIGHT
0x37 string 0x00 // SAY "string"
0x38 M // print M
0x3A M // ACT M (FRONT=0,RIGHT=1,BACK=2,LEFT=3)
0x3B // SPY
0x3C M // RADAR M
0x3F 0x00 B // DUMP variables in the B columns (3 bytes)
0x51 W wildcard-string 0x00 // TEST "wildcard" : label
0x60 M // SHOT var
0x61 M1 M2 // SEND var1 var2 - send code var1 to robot var2
0x62 M // RECV var - receive code and save it to var
0x63 // POP
0xFF // END - end of bytecode
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Предполагается, что код виртуальной машины будет собираться в большинстве существующих компиляторов C, как 32-битных:
- GCC 4
- DJGPP (GCC 2.81)
- Open Watcom C/C++ 1.9
- Borland C++Builder 5.5
- Visual C++ ?
- LCC 4.2 ?
- TCC 0.9.25 ?
так и 16-битных:
- Borland C++ 3.1
- Turbo C 2.01
- Pacific C 7.51
- SDCC 3.0.0 ?
- GCC for AVR ?
- GCC for HC11 ?
- GCC 4
- DJGPP (GCC 2.81)
- Open Watcom C/C++ 1.9
- Borland C++Builder 5.5
- Visual C++ ?
- LCC 4.2 ?
- TCC 0.9.25 ?
так и 16-битных:
- Borland C++ 3.1
- Turbo C 2.01
- Pacific C 7.51
- SDCC 3.0.0 ?
- GCC for AVR ?
- GCC for HC11 ?
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Надо компилятор RW1C улучшать - добавить возможность использовать локальные переменные (через ключевое слово LOCAL, а не через задницу) и функции поддержать внутри выражений, причём байткод при этом не изменится - всё будет работать на старых виртуальных машинах, если сделать так, как я предположил в ноябре 2004:

Кстати регистр H был поддержан на уровне компилятора ещё в версии 2.1.3 (29 ноября 2005), а вот функций до сих пор нетShaos wrote:Появится регистр H, означающий старшие 16 бит результата L (может оказаться полезным например при умножении).
Также появится возможность использовать функции - они будут преобразовываться в вызов подпрограмм препроцессором. Например:
res=2+fun1(2,3)/fun2(4)
преобразуется препроцессором в
A=2;B=3;CALL fun1;_1=L
A=4;CALL fun2;_2=L
res=2+_1/_2

Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
инкремент-декремент через ++ и -- (оба префикс и постфикс) тоже можно на уровне препроцессора реализовать (без изменения байткода)Shaos wrote:Надо компилятор RW1C улучшать - добавить возможность использовать локальные переменные (через ключевое слово LOCAL, а не через задницу) и функции поддержать внутри выражений, причём байткод при этом не изменится - всё будет работать на старых виртуальных машинах...
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
По идее перейти с 16-битной арифметики на 32-битную в RW0-байткоде ничего не мешает т.к. мы просто все регистры и все ячейки памяти объявляем 32-битными и всё - разве что можно ещё инструкций добавить для непосредственного ввода в стек и копирования в переменные больших 32-битных чисел (а заодно 8-битных и 24-битных):
Пару слов лучше наверное размещать по традиции как little-endian, т.е. младшие байты идут первыми...
Code: Select all
M - variable or constant (2-9 bytes):
0x00 W - signed integer (-32768...+32767)
0x01 W - variable in W cell (array[constant] is also compiled to this)
0x02 W1 W2 - array element (W1-begin of array, W2-variables with offset)
============== NEW if memory is still small (<64K)
0x03 B - byte (0...255)
0x04 BL BM BH - signed 24-bit integer (-8 millions ... +8 millions)
0x05 WL WH - signed 32-bit integer (-2 billions ... +2 billions)
============== NEW if memory is bigger (>=64K)
0x06 B - variable with tiny offset (<256)
0x07 BL BM BH - variable with 3-byte offset (< 16 millions)
0x08 WL WH - variable with long offset (< 4 billions)
0x09 W0 W2 WL WH - long array with long offset
.....
Expressions
-----------
.....
0xF5 W // PUSH W . -> W
0xF6 // [] A,B -> A[B]
============== NEW to push signed 32-bit integer
0xF7 W1 W2 // PUSH L . -> L
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: Расширение RW1 (Robby)
Вот наиболее полный список байткодов Robby VM версии 2.2:
P.S. Байткод 0x39 затерялся где-то в анналах истории - не могу нигде найти его реализацию и даже описание...
Code: Select all
Robot Warfare 1
RW0 bytecode description
Version 2.2
Alexander A. Shabarshin (shaos@mail.ru)
http://rwar.net
November 1998 - December 2012
Header:
-------
0x0000: 0x00..0x02 // Version (0 for v1.*, 1 for v1.99, 2 for v2.*)
0x0001: 2 bytes // CheckSum (sum of bytes from 0x0005 to the end)
0x0003: 2 bytes // Offset to bytecode entry point (in bytes)
0x0005: 1 byte // Length of the robot name (strlen)
0x0006: N bytes // Robot name
0x????: 0x00 // Terminal character for robot name
0x????: 2 bytes // Number of variables (plus arrays length)
0x????: 2 bytes // Code length in bytes (beginning from start point)
0x????: 3 bytes // Robot color (R,G,B)
0x????: 4 bytes // Equipments on the FRONT,RIGHT,BACK,LEFT (0-empty,1-eye,2-gun)
0x????: 1 byte // Image flag (0x00-image is absent, 0x20-image is present)
// if image present, then next 32 bytes describe the robot image (2pix/byte)
0x????: N bytes // Author nickname
0x????: 0x00 // Terminal character for author nickname
0x????: ?? ... // Reserved for additional data
// after that follows bytecode
START: // Entry point
Bytecode:
-----------------------------------------------------------------
B - byte (1 byte)
W - word (2 bytes - low byte + high byte)
M - variable or constant (3-5 bytes):
0x00 W - signed integer (-32768...+32767)
0x01 W - variable in W cell (array[constant] is also compiled to this)
0x02 W1 W2 - array element (W1-begin of array, W2-variables with offset)
Registers are variables (0x01 0x?? 0xFF) with the addresses:
0xFF00 (-256) X // register for relative X value
0xFF01 (-255) Y // register for relative Y value
0xFF02 (-254) D // register for distance value
0xFF03 (-253) N // register for object value
0xFF04 (-252) K // register for additional value
0xFF05 (-251) R // register for random value
0xFF06 (-250) T // register for timer value
0xFF07 (-249) E // register for our energy value
0xFF08 (-248) M // register for our missiles number
0xFF09 (-247) I // register for order number of robot
0xFF0A (-246) A // A-register for read/write
0xFF0B (-245) B // B-register for read/write
0xFF0C (-244) C // C-register for read/write
0xFF0D (-243) P // register for command pointer
0xFF0E (-242) L // register for the last value
0xFF0F (-241) S // register for stack length
0xFF16 (-234) U // register for higher word of timer value
0xFF1E (-226) H // register for higher word of the last value
labW - label with address W
* - old commands - supported by interpreter only
- - free time commands during interpretation
-----------------------------------------------------------------
0x01 W1 W2 // DEF arr[len] (W1-offset to array start, W2-len)
0x02 W1 W2 W3 ... // DEF arr[len]={list} (W3-number of words)
*0x10 W M1 M2 // IF M1<M2 : labW
*0x11 W M1 M2 // IF M1>M2 : labW
*0x12 W M1 M2 // IF M1<=M2 : labW
*0x13 W M1 M2 // IF M1>=M2 : labW
*0x14 W M1 M2 // IF M1==M2 : labW
*0x15 W M1 M2 // IF M1!=M2 : labW
-0x20 M1 M2 // M1=M2
*0x21 M1 M2 // M1=-M2
*0x22 M1 M2 M3 // M1=M2+M3
*0x23 M1 M2 M3 // M1=M2-M3
*0x24 M1 M2 M3 // M1=M2/M3
*0x25 M1 M2 M3 // M1=M2*M3
*0x26 M1 M2 M3 // M1=M2%M3
*0x27 M1 M2 M3 // M1=M2&M3 - binary AND
*0x28 M1 M2 M3 // M1=M2|M3 - binary OR
*0x29 M1 M2 M3 // M1=M2^M3 - binary XOR
*0x2A M1 M2 // M1=~M2 - binary NOT
*0x30 W // GOTO labW
*0x31 W // CALL labW
-0x33 // RET
0x34 // STEP
0x35 // LEFT
0x36 // RIGHT
0x37 ... 0x00 // SAY "string and/or &var"
0x38 M // PRINT var
0x3A M // ACT var (FRONT=0,RIGHT=1,BACK=2,LEFT=3)
0x3B // SPY
0x3C M // RADAR var
0x3F 0x00 B // DUMP B (Dump variables in B columns)
0x40 B ... // var=expr (B bytes)
-0x41 M1 M2 // IFY var1 var2
-0x42 M1 M2 // IFN var1 var2
-0x43 M // GOTO var
-0x44 M // CALL var
*0x51 W ... 0x00 // TEST "wildcard" label
0x52 ... 0x00 // TEST "wildcard" // result in L register
0x60 M // SHOT avar // copy 16 registers values to [avar]
0x61 M1 M2 // SEND var1 var2 // send code var1 to robot var2
0x62 M // RECV avar // receive code and save it to [avar]
-0x63 // POP // pop value from the stack and store it to register L
0x64 M1 M2 // PIXEL varx vary // draw a pixel by foreground color
0x65 M1 M2 // FILL vardx vardy // from last PIXEL with COLOR
0x66 ... 00 // TEXT "string" // from last PIXEL with COLOR
0x67 M // PLANE varn // set current plane for drawing (0 - default)
0x68 M // COLOR varn // set current color
0x69 M1 M2 // SELECT varx vary // select cell to draw
0x6A M1 M2 // SET var_plane [var_side] // draw tile to selected sell (default var_side=0)
0x6B M // GET [var_side] // get identifier of the drawn tile (default var_side=0)
0x6C ... 00 // ASM "string" // send some string directly to the asm output (RW1P2)
0x70 M1 M2 // COPYP avar1 avar2 // copy packet [avar2] to [avar1]
0x71 M1 M2 // SENDP avar var // send packet [avar] to robot var
0x72 M // RECVP avar // receive packet and save it to [avar]
0x73 // PUSH // push value from register L to the stack
0x74 M1 M2 // CLEAR varx vary // draw a pixel by background color
0x7F M // COMMAND var // high-level command
0xFF // END - end of bytecode
Expressions
-----------
expr uses var,label,(,),?:,+,-,*,/,%,&,|,^,~,!,&&,||,=,==,>,<,>=,<=,!=,<<,>>
0x80 // && A,B -> A&&B
0x81 // || A,B -> A||B
0x90 // == A,B -> A==B
0x91 // != A,B -> A!=B
0x92 // > A,B -> A>B
0x93 // < A,B -> A<B
0x94 // >= A,B -> A>=B
0x95 // <= A,B -> A<=B
0xA0 // + A,B -> A+B
0xA1 // - A,B -> A-B
0xB0 // * A,B -> A*B
0xB1 // / A,B -> A/B
0xB2 // % A,B -> A%B
0xC0 // & A,B -> A&B
0xC1 // | A,B -> A|B
0xC2 // ^ A,B -> A^B
0xD0 // >> A,B -> A>>B
0xD1 // << A,B -> A<<B
0xE0 // - A -> -A (negative)
0xE1 // ~ A -> ~A (bit inverse)
0xE2 // ! A -> !A (logic NOT)
0xF0 // ?: A,B,C -> A?B:C
0xF1 // DUP A -> A,A
0xF2 // ROL A,B -> B,A
0xF3 // LOAD A -> mem[A]
0xF4 // SAVE A,B -> . (mem[A]=B)
0xF5 W // PUSH W . -> W
0xF6 // [] A,B -> A[B]
Debug info
----------
Debug info is added to RW0-file by option -d in RW1C v2.1 or above.
After code compiler writes zero-terminated word "DEBUG" and list
of source files in form zero-terminated names. Two zero bytes
identify end of the list. Then we have list of variables:
? bytes - NAME,0
2 bytes - size of variable in words
2 bytes - index of variable
Then we have a number of 5-bytes structures:
1 byte - index of source file
2 bytes - number of line in the source file
2 bytes - address in code
End of structures is #FF byte.
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re:
А можно и без ключевого слова LOCAL обойтись - локальные переменные можно особым образом помечать, например если переменная начинается с подчеркивания, то компилятор с ней работает как с локальной переменной живущей только в пределах своего блока {} - для этого можно наделить команду DEF возможностью динамически аллоцировать массив в месте вызова (тогда надо будет еще завести команду UNDEF чтобы такой динамический массив освобождать) и компилятор будет вставлять DEF на соответствующее количество переменных в начале блока, где появляются локальные переменные.Shaos wrote:Надо компилятор RW1C улучшать - добавить возможность использовать локальные переменные (через ключевое слово LOCAL, а не через задницу) и функции поддержать внутри выражений, причём байткод при этом не изменится - всё будет работать на старых виртуальных машинах...
Еще можно сделать переменные типа беззнаковый байт, добавляя к имени суффикс $ - внутри такие однобайтовые переменные будут представлены как половинки обычных переменных, соответственно надо будет добавить 2 постфиксных спецоператора, которые могут выделять младший байт переменной ' и старший байт переменной " - препроцессор будет их вставлять в выражения вместо вызова соответствующих байтовых переменных
Еще одна мысль - поддержать наряду с сишным for еще и более модный вариант for(var in 1..10), а также for(var in array) где array - объявленный ранее массив (и все это можно сделать на уровне препроцессора)
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: Robby - расширение языка RW1
с суффиксом $ всё-таки логичнее объявлять строки т.к. сейчас
DEF ARR1[10]="abcd" // ARR1[0]=длина пакета ARR1[1]='a' ARR1[2]='b' и т.д.
DEF ARR2[10]='abcd' // ARR2[0]=длина пакета ARR2[1]='a'|('b'<<8| ARR2[2]='c'|('d'<<8)
то теперь вместо второго варианта можно будет просто писать
DEF ARR$="abcd" // размер массива будет вычисляться автоматически и $ будет означать что инициализирующая последовательность описывает байты, а не слова
в этом случае апострофы вновь будут только для обозначения символов использоваться
DEF ARR1[10]="abcd" // ARR1[0]=длина пакета ARR1[1]='a' ARR1[2]='b' и т.д.
DEF ARR2[10]='abcd' // ARR2[0]=длина пакета ARR2[1]='a'|('b'<<8| ARR2[2]='c'|('d'<<8)
то теперь вместо второго варианта можно будет просто писать
DEF ARR$="abcd" // размер массива будет вычисляться автоматически и $ будет означать что инициализирующая последовательность описывает байты, а не слова
в этом случае апострофы вновь будут только для обозначения символов использоваться
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: Robby - расширение языка RW1
В первую очередь надо поддержать вышепредложенный вариант DEF STRING$="aaa" (даже без квадратных скобок т.к. необходимый размер массива в словах будет вычисляться компилятором).
Во вторую очередь надо реализовать расширение for: for(A in 1..10) (как в аде или руби) и for(A in array) (как в джаваскрипте), причём на уровне препроцессора!
Также хочу количество регистров увеличить до 26, дабы охватить все буквы алфавита, а вот с локальнымм переменными надо подумать...
Во вторую очередь надо реализовать расширение for: for(A in 1..10) (как в аде или руби) и for(A in array) (как в джаваскрипте), причём на уровне препроцессора!
Также хочу количество регистров увеличить до 26, дабы охватить все буквы алфавита, а вот с локальнымм переменными надо подумать...
Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Doomed
- Posts: 665
- Joined: 01 Oct 2007 10:30
- Location: Ukraine
Re: Robby - расширение языка RW1
Вы придумали язык. А зачем? Столько уж кривых языков не придумали только. А Си, Паскаль, Бейсик и конечно Ява (новый язык) рулит.
Эмулятор OrionEXT:
http://www.orion-ext.narod.ru
http://www.orion-ext.narod.ru
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: Robby - расширение языка RW1
О - дайте две явы для Intel 8080 пжалстаAlekcandr wrote:Вы придумали язык. А зачем? Столько уж кривых языков не придумали только. А Си, Паскаль, Бейсик и конечно Ява (новый язык) рулит.

А вообще язык я придумал ещё в 1998 (т.е. он моложе этой вашей "новой" явы) и расширил в 2000 - с тех пор и тащу его везде

Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Supreme God
- Posts: 16682
- Joined: 21 Oct 2009 08:08
- Location: Россия
Re: Robby - расширение языка RW1
А насколько эффективный код генерирует твой язык для Intel 8080 ?Shaos wrote:...для Intel 8080 пжалста![]()
А вообще язык я придумал ещё в 1998 (т.е. он моложе этой вашей "новой" явы)
и расширил в 2000 - с тех пор и тащу его везде
iLavr
-
- Admin
- Posts: 24027
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: Robby - расширение языка RW1
Ну по любому побыстрее бейсика будетLavr wrote:А насколько эффективный код генерирует твой язык для Intel 8080 ?Shaos wrote:...для Intel 8080 пжалста![]()
А вообще язык я придумал ещё в 1998 (т.е. он моложе этой вашей "новой" явы)
и расширил в 2000 - с тех пор и тащу его везде

Я тут за главного - если что шлите мыло на me собака shaos точка net
-
- Supreme God
- Posts: 16682
- Joined: 21 Oct 2009 08:08
- Location: Россия
Re: Robby - расширение языка RW1
А супротив С ?Shaos wrote:Ну по любому побыстрее бейсика будетLavr wrote:А насколько эффективный код генерирует твой язык для Intel 8080 ?
iLavr