nedoPC.org

Community for electronics hobbyists, established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 04 Oct 2024 23:25



Reply to topic  [ 34 posts ]  Go to page Previous  1, 2, 3  Next
Robby - расширение языка Robot Warfare 1 (RW1) 
Author Message
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
Lavr wrote:
Shaos wrote:
Lavr wrote:
А насколько эффективный код генерирует твой язык для Intel 8080 ?
Ну по любому побыстрее бейсика будет ;)

А супротив С ?

какого именно? их было поболее одного вроде как...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


30 May 2018 13:59
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Shaos wrote:
Lavr wrote:
Shaos wrote:
Lavr wrote:
А насколько эффективный код генерирует твой язык для Intel 8080 ?
Ну по любому побыстрее бейсика будет ;)
А супротив С ?
какого именно? их было поболее одного вроде как...

Так и бейсики - есть компиляторы... :wink:

_________________
iLavr


30 May 2018 14:00
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
для 8080 компиляторы бейсика? ты видел хотя бы один? ;)
и бейсик для 8080 вроде как был один - микрософтовский :)

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


30 May 2018 14:04
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Shaos wrote:
для 8080 компиляторы бейсика? ты видел хотя бы один? ;)

Видел и не один даже. Компилятор бейсика для 8080 под СР/М даже у меня есть.
А кросс-компиляторы, я даже здесь на форуме искал публично - так поболе одного!
Shaos wrote:
и бейсик для 8080 вроде как был один - микрософтовский :)

Ну если у меня есть СР/М-овский, то значит точно не один... :roll:

_________________
iLavr


30 May 2018 14:15
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
У микрософта даже свой CP/M-80 был - MSX-DOS назывался ;)

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


30 May 2018 16:03
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Shaos wrote:
У микрософта даже свой CP/M-80 был - MSX-DOS назывался ;)

А вот у меня CP/M, похоже, от DR, только вот кем адаптирована - не знаю, поскольку версия
не от Бриджиди. Его версия появилась позже.

Версия CP/M от Бриджиди адаптированная под "Специалист" у меня появилась только с эмулятором
от Шевцова, и я с ней так и не поигрался.


Но тем не менее - ты сравнивал свой Рубби с каким-либо компилятором С ?

_________________
iLavr


30 May 2018 16:17
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
У меня при необходимости (путём добавления более детальных правил в __RULES) можно добиться скорости ассемблерного кода, работающего с 16-битными словами - по поводу более продвинутой математики (умножить/разделить), то она была взята из исходников SmallC для CP/M - от него же собственно произошли другие существующе сишные кросс-компили для 8080 - в частности SDCC и Z88DK (который сейчас только Z80)
А вообще про 8080 компиляцию из Robby лучше говорить в соответствущем топике, например обсудить пример с двумя вложенными циклами:
http://www.nedopc.org/forum/viewtopic.php?p=144529#p144529

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


30 May 2018 17:47
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Shaos wrote:
А вообще про 8080 компиляцию из Robby лучше говорить в соответствущем топике...

Ну ты сам как бы дал здесь повод про 8080...
Shaos wrote:
дайте две явы для Intel 8080 пжалста :idea:

_________________
iLavr


30 May 2018 18:00
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
Lavr wrote:
Shaos wrote:
А вообще про 8080 компиляцию из Robby лучше говорить в соответствущем топике...

Ну ты сам как бы дал здесь повод про 8080...
Shaos wrote:
дайте две явы для Intel 8080 пжалста :idea:

Это был ответ на вопрос зачем я изобрёл свой собственный язык, если есть новая прекрасная ява :)
Одна из причин, почему я не использую яву - её попросту нету для целевых платформ, для которых пригоден мой язык
P.S. Причём напомню, что с RW1 всё началось на 16-битном x86 и MS-DOS...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


30 May 2018 18:07
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
Shaos wrote:
У микрософта даже свой CP/M-80 был - MSX-DOS назывался ;)

Про MSX отрезал и перенёс в форум MSX:
http://www.nedopc.org/forum/viewtopic.php?f=96&t=18866

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


01 Jun 2018 09:19
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
Простой интерпретатор RW0 я писал на PocketC прямо на своём пальме в мае-июне 2001 года (каких-то 22 года назад кхе-кхе) - не могу нигде тут на форуме найти где я про это писал - видимо нигде (форума тогда ещё небыло) - скопипащу сырцы прямо сюда:

 rw0.c
Code:
// rw0.c
// May 2001

include "rw0code.hpp"

mload(pointer mem)
{
    int i,j,k,kk,sum;
    string s,ss;
    i=0;
    while(!mmeof())
    {
        s=mmgetl();
//         puts(s+"\n");
        k=strlen(s);
        if(k>16)
        {
            ss=strleft(s,16);
            s=ss;k=16;
        }
        for(j=0;j<k;j=j+2)
        {
          ss=substr(s,j,2);
          kk=ss@[0];
          if(kk<='9') kk=kk-'0';
          else kk=kk-'A'+10;
          sum=kk*16;
          kk=ss@[1];
          if(kk<='9') kk=kk-'0';
          else kk=kk-'A'+10;
          sum=sum+kk;
          mem[i++]=sum;
        }
    }
}

sload()
{
    int i=0;
    while(!mmeof())
    {
        spr[i++]=mmgetl();
        if(i>=NSPR) break;
    }
}

main()
{
int i,j,k,size=2000;
pointer mem;
string fr,fs;
string str="M";
clear();
puts("PocketRW1P2\n");
puts("http://shaos.h1.ru\n");
//str=gets("RW0 Name");
fr=str+".RW0";
fs=str+".SPR";
k=mmfind(fs);
if(k)
{
  puts(mmgetl()+" Loading\n");
  sload();
  mmclose();
}
k=k*mmfind(fr);
if(k)
{
  mem=malloc(size);
  puts(mmgetl()+" Loading\n");
  mload(mem);
  mmclose();
  rw0code(mem);
  graph_on();
  title(name);
  while(true)
  {
    text(130,0,hex(PC)+"   ");
//    puts(">"+hex(PC));
    k=code[PC];
//    puts(" "+hex(k)+"\n");
    if(!( (*op[k])())) break;
  }
  free(mem);
  free(var);
}
else puts("Error\n");
//wait();
}

 rw0code.c
Code:
// rw0code.hpp
// May 2001

#define RX 0
#define RY 1
#define RD 2
#define RN 3
#define RK 4
#define RR 5
#define RT 6
#define RE 7
#define RM 8
#define RI 9
#define RA 10
#define RB 11
#define RC 12
#define RP 13
#define RL 14
#define RS 15
#define BASE 0xFFFF
#define NSPR 32
#define SP reg[RS]
#define PC reg[RP]
#define SX reg[RX]
#define SY reg[RY]

string name;
int offset,codelen,varlen=1000;
int reg[16],stack[32];
pointer code,var,op[256];
string spr[NSPR];

int rvar(int a)
{int k;
 if(a>0xF000) k=reg[a-0xFF00];
 else k=var[a];
 return k;
}

wvar(int a,int k)
{if(a>0xF000) reg[a-0xFF00]=k;
 else {var[a]=k;
bitmap((a%20)*8,a/20*8+16,spr[0]);}
//puts("wvar "+hex(a)+" "+k+"\n");
}

int get1()
{return code[PC++];}
int get2()
{int k;
 k=get1() + (get1()<<8);
 if(k&0x8000) k=-1-(~k);
 return k;
}

int getv()
{int k;
 switch(get1())
 {case 0: k=get2();break;
   case 1: k=rvar(get2());break;
   case 2: k=var[get2() + rvar(get2())];break;
 }
 return k;
}

int geta()
{int k;
 switch(get1())
 {case 0: k=0;break;
   case 1: k=get2();break;
   case 2: k=get2() + rvar(get2());break;
 }
 return k;
}

include "rw0graf.hpp"

int op_err()
{
alert("Code Error!   [" +hex(PC)+"] "+hex(code[PC]));
return 0;
}

int op_def()
{
int a,n,k=0,i,o;
o=code[PC++];
a=get2();n=get2();
if(o==2)
{
 k=get2();
 for(i=0;i<k;i++) var[a+i]=get2();
}
return 1;
}

int op_var()
{
int a,k;
PC++;a=geta();k=getv();
wvar(a,k);return 1;
}

int op_if() // 41,42
{
int k,u,l;
k=code[PC++];u=getv();l=getv();
if(k==0x41&&u) PC=l;
if(k==0x42&&(!u)) PC=l;
return 1;
}

int op_goto() // 43
{
int l;
PC++;l=getv();PC=l;
return 1;
}

int op_call() // 44
{
int l;PC++;l=getv();
stack[SP++]=PC;PC=l;
return 1;
}

int op_ret() // 33
{
int l;
SP--;PC=stack[SP];
return 1;
}

int op_expr() // 40
{
int i,b,k,s,x1,x2,x3;
s=SP;PC++;k=get1();
for(i=0;i<k;i++)
{
 b=get1();
 if(b>=0x80&&b<=0xD1)
{s--;x2=stack[s];s--;x1=stack[s];}
 if(b>=0xE0&&b<=0xE2)
{s--;x1=stack[s];}
 switch(b)
 {
   case 0x80: stack[s++]=(x1&&x2); break;
   case 0x81: stack[s++]=(x1||x2); break;
   case 0x90: stack[s++]=(x1==x2); break;
   case 0x91: stack[s++]=(x1!=x2); break;
   case 0x92: stack[s++]=(x1>x2); break;
   case 0x93: stack[s++]=(x1<x2); break;
   case 0x94: stack[s++]=(x1>=x2); break;
   case 0x95: stack[s++]=(x1<=x2); break;
   case 0xA0: stack[s++]=(x1+x2); break;
   case 0xA1: stack[s++]=(x1-x2); break;
   case 0xB0: stack[s++]=(x1*x2); break;
   case 0xB1: stack[s++]=(x1/x2); break;
   case 0xB2: stack[s++]=(x1%x2); break;
   case 0xC0: stack[s++]=(x1&x2); break;
   case 0xC1: stack[s++]=(x1|x2); break;
   case 0xC2: stack[s++]=(x1^x2); break;
   case 0xD0: stack[s++]=(x1>>x2); break;
   case 0xD1: stack[s++]=(x1<<x2); break;
   case 0xE0: stack[s++]=(-x1);break;
   case 0xE1: stack[s++]=(~x1);break;
   case 0xE2: stack[s++]=(!x1); break;
   case 0xF0:
    s--;x1=stack[s];
    s--;x2=stack[s];
    s--;x3=stack[s];
    if(x3) stack[s++]=x2;
    else stack[s++]=x1;
    break;
   case 0xF1:
    s--;x1=stack[s];
    stack[s++]=x1;
    stack[s++]=x1;
    break;
   case 0xF2:
    s--;x1=stack[s];
    s--;x2=stack[s];
    stack[s++]=x1;
    stack[s++]=x2;
    break;
   case 0xF3:
    s--;x1=stack[s];
    stack[s++]=rvar(x1);
    break;
   case 0xF4:
    s--;x1=stack[s];
    s--;x2=stack[s];
    wvar(x2,x1);
    break;
   case 0xF5:
    i=i+2;
    stack[s++]=get2();   
    break;
   case 0xF6:
    s--;x1=stack[s];
    s--;x2=stack[s];
    stack[s++]=x2+x1;
    break;
 }
}
return 1;
}

rw0code(pointer mem)
{
    int i,k;
    name="test                ";
    offset=mem[3]+(mem[4]<<8);
    code=&mem[offset];
    puts("offset="+offset+"\n");
    SP=0;PC=0;
    k=mem[5];
    for(i=0;i<k;i++) name@[i]=mem[i+6];
    name@[k]=0;
    puts("name="+name+"\n");
    k=k+7;
    codelen=mem[k+2]+(mem[k+3]<<8);
    puts("codelen="+codelen+"\n");
    varlen=mem[k]+(mem[k+1]<<8);
    puts("varlen="+varlen+"\n");
    var=malloc(varlen);
    for(i=0;i<varlen;i++) var[i]=0;
    for(i=0;i<256;i++) op[i]=op_err;
    op[1]=op_def;op[2]=op_def;
    op[0x20]=op_var;
    op[0x33]=op_ret;
    op[0x40]=op_expr;   
    op[0x41]=op_if;
    op[0x42]=op_if;
    op[0x43]=op_goto;
    op[0x44]=op_call;
    op[0x69]=op_graf;
    op[0x6A]=op_graf;

}

 rw0graf.hpp
Code:
// rw0graf.hpp
// June 2001

int op_graf()
{
int k,x,y,m;
k=code[PC++];
x=getv();y=getv();
if(k==0x69)
{SX=x;SY=y;}
if(k==0x6A)
{
puts("set "+SX+":"+SY+" "+hex(x)+"\n");
m=x-0x1000;
if(m>=0&&m<NSPR) bitmap(SX*8,SY*8+16,spr[m]);
}
return 1;
}

Роботы загружались из хексов, хранящихся как странички блокнота пальма вот в таком виде:

 M.RW0
Code:
M.RW0
029BEA2100064D61
7047656E00ED0081
04FFFFFF00000000
005368616F730000
00010000C8002001:0x6
C800000E002001C9:0xe
000002002001CA00:0x16
0002002001CB0000:0x1e
05002001CC000014:0x26
0001CD000A0001D7:0x2e
000A002001E10000:0x36
00002001E2000000:0x3e
002001E300000000:0x46
20010AFF00020020:0x4e
010BFF0014002001:0x56
0CFF000A004400F2:0x5e
012001E400000000:0x66
2001E50000000040:0x6e
0CF50EFFF5E500F3:0x76
F50A0093F442010E:0x7e
FF0093012001E600:0x86
000000400CF50EFF:0x8e
F5E600F3F5140093:0x96
F442010EFF008101:0x9e
4011F50CFFF50000:0xa6
F5E400F3F6F3F504:0xae
00D0F4400CF5E400:0xb6
F5E400F3F50100A0:0xbe
F46901E60001E500:0xc6
400CF50EFFF50CFF:0xce
F3F5000090F44201:0xd6
0EFF00E3006A0020:0xde
00000000400CF50E:0xe6
FFF50CFFF3F50100:0xee
90F442010EFF00FF:0xf6
006A004F00000000:0xfe
400CF50EFFF50CFF:0x106
F3F5020090F44201:0x10e
0EFF001B016A0040:0x116
00000000400CF50E:0x11e
FFF50CFFF3F50300:0x126
90F442010EFF0037:0x12e
016A002300000000:0x136
400CF50EFFF50CFF:0x13e
F3F5040090F44201:0x146
0EFF0053016A002A:0x14e
00000000400CF50E:0x156
FFF50CFFF3F50600:0x15e
90F442010EFF006F:0x166
016A005200000000:0x16e
400CF5E600F5E600:0x176
F3F50100A0F44300:0x17e
8A00400CF5E500F5:0x186
E500F3F50100A0F4:0x18e
43006E0043009301:0x196
430000004010F5C8:0x19e
00F55562F5C800F3:0x1a6
B0F51936A0F4401E:0x1ae
F50CFFF5C800F3F5:0x1b6
00FFC0F5C800F3F5:0x1be
0800D0F5C800F3F5:0x1c6
FF00C0C2C1F44008:0x1ce
F50EFFF50AFFF3F4:0x1d6
42010EFF00F10140:0x1de
11F50CFFF50CFFF3:0x1e6
F5FF7FC0F50AFFF3:0x1ee
B2F4332001E70001:0x1f6
0AFF2001E200010B:0x1fe
FF2001E300010CFF:0x206
400DF5E800F5E200:0x20e
F3F5E300F3B0F440:0x216
0DF5E900F5E700F3:0x21e
F5C900F3B0F4400D:0x226
F5EA00F5E700F3F5:0x22e
CA00F3B0F4400DF5:0x236
EB00F5E700F3F5CB:0x23e
00F3B0F4400DF5EC:0x246
00F5E700F3F5CC00:0x24e
F3B0F420010CFF00:0x256
000020010BFF0000:0x25e
00400DF50EFFF50B:0x266
FFF3F5EC00F393F4:0x26e
42010EFF00B60240:0x276
0DF50EFFF50000F5:0x27e
0CFFF3F6F3F44201:0x286
0EFF009B0220010A:0x28e
FF01E80044009B01:0x296
4300760220020000:0x29e
0CFF002500400CF5:0x2a6
0BFFF50BFFF3F501:0x2ae
00A0F44300600220:0x2b6
010BFF000000400D:0x2be
F50EFFF50BFFF3F5:0x2c6
EA00F393F442010E:0x2ce
FF001303400DF50E:0x2d6
FFF50000F50CFFF3:0x2de
F6F3F442010EFF00:0x2e6
F80220010AFF01E8:0x2ee
0044009B014300D3:0x2f6
02200200000CFF00:0x2fe
1000400CF50BFFF5:0x306
0BFFF3F50100A0F4:0x30e
4300BD0220010BFF:0x316
000000400DF50EFF:0x31e
F50BFFF3F5EB00F3:0x326
93F442010EFF00BB:0x32e
03400DF50EFFF500:0x336
00F50CFFF3F6F3F4:0x33e
42010EFF00550320:0x346
010AFF01E8004400:0x34e
9B01430030032002:0x356
00000CFF00300040:0x35e
0CF50EFFF5E100F3:0x366
F50A0093F442010E:0x36e
FF00A9034012F5CD:0x376
00F5E100F3F6F50B:0x37e
FFF3F5E200F3B2F4:0x386
4012F5D700F5E100:0x38e
F3F6F50BFFF3F5E2:0x396
00F3B1F4400CF5E1:0x39e
00F5E100F3F50100:0x3a6
A0F4400CF50BFFF5:0x3ae
0BFFF3F50100A0F4:0x3b6
43001A0320010BFF:0x3be
000000400DF50EFF:0x3c6
F50BFFF3F5E900F3:0x3ce
93F442010EFF0018:0x3d6
04400DF50EFFF500:0x3de
00F50CFFF3F6F3F4:0x3e6
42010EFF00FD0320:0x3ee
010AFF01E8004400:0x3f6
9B014300D8032002:0x3fe
00000CFF00400040:0x406
0CF50BFFF50BFFF3:0x40e
F50100A0F44300C2:0x416
0320010BFF000000:0x41e
400DF50EFFF50BFF:0x426
F3F5E700F393F442:0x42e
010EFF007F04400D:0x436
F50EFFF50000F50C:0x43e
FFF3F6F3F442010E:0x446
FF005A0420010AFF:0x44e
01E80044009B0143:0x456
0035044011F50000:0x45e
F50CFFF3F6F56000:0x466
F50BFFF3A0F4400C:0x46e
F50BFFF50BFFF3F5:0x476
0100A0F443001F04:0x47e
33FF

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


23 Apr 2023 20:17
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
Зарегал доменное имя robby.club - может там какую обучалку пошаговую размещу по языку Robby на подобие https://try.ruby-lang.org/ :lol:

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


30 Apr 2023 00:07
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
Shaos wrote:
В первую очередь надо поддержать вышепредложенный вариант DEF STRING$="aaa" (даже без квадратных скобок т.к. необходимый размер массива в словах будет вычисляться компилятором).
Во вторую очередь надо реализовать расширение for: for(A in 1..10) (как в аде или руби) и for(A in array) (как в джаваскрипте), причём на уровне препроцессора!
Также хочу количество регистров увеличить до 26, дабы охватить все буквы алфавита, а вот с локальнымм переменными надо подумать...

Цикл for(A in 1..10) превращается в тоже самое как и for(A=1;A<=10;A++) - это просто, а вот с for(A in array) надо помудрить ибо A в данном случае не индекс, а значение соответствующего элемента из массива, т.е. придётся для хранения индекса заводить "скрытую" переменную _1 (и далее _2, _3 и т.д.), которая будет инкрементироваться для доступа ко всем элементам массива array и A в цикле "под водой" будет присваиваться значение array[_1]. Обязательность скобок можно отменить - тогда синтаксис циклов будет похож на Rust. Аналогичный подход со скрытыми переменными, которые генерит сам компилятор, я планировал использовать для реализации вызовов функций в составе арифметических выражений.

А по регистрам кроме всех 26 букв (для того чтобы добить до 32) можно ещё добавить регистры ALPHA, BETA, GAMMA, DELTA, а также GPIO и GPIODIR (для так давно желаемой платформы микроконтроллеров RW1P4)...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


21 May 2023 01:31
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
Примерно с 2007 по 2016 годы я хотел называть расширение языка RW1 аббревиатурой ROBERTA (Real Object Basic Environment Reflecting Ttransactional Architecture) - см. закрытый топик viewtopic.php?f=46&t=8635&hilit=roberta - и только потом передумал и назвал язык Robby. Сейчас можно снова немножко это вспомнить и начать позиционировать язык программирования Robby как "Robot Oriented Programming Language" (ROPL) :lol:

Можно таки сделать объектную модель, где объекты описываются роботами, которые обмениваются сообщениями, включая возможность компилировать такие программы в бинарники ретроплатформ через nedoPC SDK для запуска в пределах одной системы либо в сети ретрокомпьютеров - вот ранний текст на эту тему, который я написал ещё в 2002 году и распространял как текстовый файл rw1_para.txt:
Code:
RW1 КАК ЯЗЫК ПРОГРАММИРОВАНИЯ ПАРАЛЛЕЛЬНЫХ ПРОЦЕССОВ
----------------------------------------------------

Александр Шабаршин (shaos@mail.ru)
http://robots.shaos.ru

В статье затрагивается возможность использования языка
программирования роботов RW1 в качестве языка
параллельных процессов (агентов).

Язык RW1 к версии 2.1 прошел путь от ассемблероподобного
языка к языку типа Си (http://shaos.ru/main_rus/rw1_r.htm).
Чтобы представить специфику языка, приведем пример простой
программы:

 robot "Program 1"
 author "A.Shabarshin"
 +rw1_std.rwi
 main()
 {
  while(1)
  {
   // вечный цикл
  }
 }

Данная программа не делает ничего, но в ней можно увидеть
то, что должно быть обязательно в любой RW1 программе.
Это ключевое слово ROBOT, за которым следует имя программы
в кавычках. Слово AUTHOR, за которым идет имя автора
программы в кавычках. Основная функция программы main(),
которая должна быть самой первой функцией программы.
Кроме того, внутри программы организуется вечный цикл.
В файле RW1_STD.RWI определены некоторые полезные макросы.

Будем подразумевать, что мы используем подход RW1P1 -
Robot Warfare 1 Platform 1, что может быть перенесено и
на RW1P2 (см. http://shaos.ru/main_rus/rw1_r.htm#RW1P1).

В среде исполнения может быть запущено несколько роботов
(программ или агентов), которые могут взаимодействовать
друг с другом посредством сообщений. Каждый робот в
системе имеет свой уникальный идентификационный номер,
который можно узнать, прочитав регистр I. Например, так:

 id=I; say "ID=&id "

Идентификаторы присваиваются начиная с 1. Идентификатор
0 обозначает всех роботов в системе (для широковещательных
сообщений).

Самым простым типом сообщений является передача одного
числового значения с помощью команды SEND, которое
может быть принято командой RECV. Пример:

 send -13 10 // отправить роботу с номером 10 число -13
 recv info   // если буфер не пуст, принять число и
             // сохранить его в переменной info

Команда RECV является очень информативной - кроме
сохранения принятого числа, она располагает некоторую
информацию в регистрах робота: регистр N - порядковый
номер робота-передатчика (если N равен 0, то буфер
принятых сообщений пуст); в регистрах X и Y записываются
относительные координаты робота-передатчика (в случае,
если пространственная привязка имеет смысл); в регистр
K помещается значение времени, в которое был отправлен код.

Такое почисловое взаимодействие не слишком информативно.
Более мощным средством межпроцессного обмена языка RW1,
появившемся в версии 2.1, является прием/передача "пакетов".
Итак, что же такое "пакет" в языке RW1? Пакет - это массив
чисел, первое из которых обозначает количество оставшихся.
Например:

 def pack1[5] = {4, 1,2,3,4}

В данном случае создается массив pack1, который является
RW1-пакетом с длиной 4. Этот пакет можно передать в
качестве сообщения другому роботу с помощью команды SENDP:

 sendp pack1 10    // отправить пакет роботу 10, или
 sendp pack1[0] 10 // то же самое

Если вы смогли догадаться, можно отправить и часть массива,
и даже не с нулевого элемента. Пример:

 sendp pack1[2] 10 // отправляем пакет c ячейки 2 - в ней
 // мы имеем число 2, поэтому отправляется только 2 числа

Прием пакета осуществляется командой RECVP:

 def pack0[10]
 recvp pack0
 if(n) say "принят пакет размером &k ячеек"
 else  say "ошибка приема"

Для копирования пакетов используется команда COPYP:

 copyp target source // копирование пакета из source

Интересно отметить, что пара SEND и RECVP совместимы.
Только при этом одно число будет превращаться в пакет
(массив с двумя элементами), первое из которых будет 1.
Вторая пара SENDP и RECV совместима лишь частично - при
этом происходит потеря всех данных за исключением первого
числа. Так что если вы решили использовать для
межпроцессного взаимодействия пакеты, не пользуйтесь
командой RECV. Командой SEND пользоваться можно, так как
приходящие отдельные сообщения успешно принимаются пакетной
командой RECVP (как было указано выше).

Итак, типовая программа-робот будет выглядеть так:

 robot "Program 2"
 author "A.Shabarshin"
 +rw1_std.rwi
 main()
 {
   // определение и инициализация массивов
   def buff[256]
   time = 0 // определение момента активности
   while(1)
   { // вечный цикл
     if(time>=T)
     { // некие действия
       send 111 // послать широковещательное сообщение
       // возможно тут будет переназначение time
     }
     recvp buff // получение сообщения
     if(n)
     { // анализ полученного сообщения
       say "> &n &x &y &k received"
     }
   }
 }

Следует разъяснить что у нас будет храниться в переменной
TIME. Здесь мы будет сохранять метку времени, по достижению
которой наш робот должен проявить некую самостоятельную
активность. Регистр T используется для контроля времени -
в нем хранится количество тиков от момента старта системы.
Если мы имеем привязку к реальному времени (+RW1P1.RWI),
то в T хранится время в десятых долях секунды (другое
значение делителя может быть установленно отдельно).
Кроме того, активность будет проявляться при получении
какого-либо сообщения извне.

Попробуем написать робота, который определяет количество
своих собратьев (экземпляров данного процесса) в системе.

 robot "Program 3 - count me"
 author "A.Shabarshin"
 +rw1_std.rwi
 +rw1p1.rwi
 main()
 {
   def buff[256]
   def robots[100] // надеюсь их будет не больше 100 ;)
   nrobot = 0  // начальное значение счетчика
   time = 10 // определение момента активности
   say "I'm &I "
   while(1)
   { // вечный цикл
     if(time>=T)
     { // некие действия
       // вывести список найденных роботов
       for(ii=0;ii<nrobot;ii++)
       {
         jj = ii+1
         say "&jj id=&robots[ii] "
       }
       nrobot = 0 // обнуляем
       send 111 // послать широковещательное сообщение
       time = time + @TIME_SEC(5) // повторить через 5 секунд
     }
     recv buff[0] // получение сообщения
     if(n)
     { // анализ полученного сообщения
       if(buff[0]==111) // это кто-то наш :)
       {
         robots[nrobot] = n
         nrobot = nrobot+1
       }
     }
   }
 }

Copyright (c) 2002, Alexander Shabarshin

Более того, реализация RobbyVM в браузере уже многое из вышеперечисленного делает - надо просто описать это всё единообразно с возможностью использования в разных применениях, в частности на базе программирования для Circuits.CC

P.S. А может быть ещё и соревнования роботов вернуть?

https://web.archive.org/web/20020114102449/http://robots.shaos.ru/cgi/stat.cgi?top10


Attachments:
Screenshot from 2024-07-05 15-19-08.png
Screenshot from 2024-07-05 15-19-08.png [ 174.66 KiB | Viewed 817 times ]

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973
05 Jul 2024 15:08
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23355
Location: Silicon Valley
Reply with quote
В апреле 2023 года я обнаружил косяк в своём компиляторе Robby - CONTINUE внутри FOR не меняет счётчик - первопричина кроется в том, как я изначально переводил сложные синтаксические конструкции языка в простые через препроцессор:
Code:

 for(expr1,expr2,expr3)
 {
                        expr1
                        l1:
                        (expr2);IFN L l2
                  -->
  continue              GOTO l1

  break                 GOTO l2

                        expr3;
                        GOTO l1
 }                      l2:
на самом деле оно должно быть так (чтобы expr3 выполнялось по continue тоже):
Code:

 for(expr1,expr2,expr3)
 {
                        expr1
                        l1:
                        (expr2);IFN L l2
                  -->
  continue              GOTO l3 <<<<<<<

  break                 GOTO l2

                >>>>>>> l3: expr3;
                        GOTO l1
 }                      l2:
или если нумеровать метки по порядку:
Code:

 for(expr1,expr2,expr3)
 {
                        expr1
                        l1:
                        (expr2);IFN L l3
                  -->
  continue              GOTO l2

  break                 GOTO l3

                        l2:
                        expr3;
                        GOTO l1
 }                      l3:
осталось вспомнить как я кодил такие преобразования 24 года назад - заодно можно и for(A in 1..10) поддержать...

P.S. Ещё когда я в 2018 году кодил TERNARO то наткнулся на другой косяк компилятора, когда сложные условия в if() работали неправильно - то ли я с приоритетами операций напутал, толи ещё что связанное с моим JS-фреймворком, но мне пришлось наставить скобок либо вообще разбить сложный if на пачку простых...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


20 Jul 2024 00:56
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 34 posts ]  Go to page Previous  1, 2, 3  Next

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.