cbrain

From Esolang
Jump to navigation Jump to search

cbrain

The cbrain eso programming language is an extension of the pbrain programming language for use from OpenCOBOL that adds numbers and various operators. Pronounced see brain. pbrain was extended with the addition of instructions matching C augmented assignments, a few 'lettered' operators (breaking comment compatibility, adding {} cell neutral comment segments to compensate) and integer number support to pbrain instructions. pbrain was created by Paul M. Parks in 2004.

The source code linked by Daniel B Cristofani for pbrain.c looked like an excellent candidate for inclusion in the OpenCOBOL link library toolkit. This source was then modified as cbrain.c by Brian Tiffin in 2013.

hello

   0 (<<<<< <<<<<)
   > 72 > 101 > 7 o a c c +++ > 32 > 99 c - > 114 o - > 105 c > 5 a > 32 > 0
   : <<< [. >] << [. <] 10 .

displayed as

   Hello cbrain niarbc olleH

When is Easter?

From the Computus, Anonymous Gregorian algorithm

   {When is Easter?}
   0 > 89 > 101 > 97 > 114 > 63 > 32 > 0
   <[<]>[.>]<[<]
   =
   
   c > 19 % o > 100 d o > 4 d
   <<< @ >>>> ! > 8 a > 25 d <
   > ! o s + > 3 d <
   <<<<< < @ >>>>> >> ! > 19 m <<<<< < @ >>>>> >> ! a <<<< @ >>>>> ! s o s > 15 a > 30 %
   <<<<< @ >>>>> > ! > 4 d
   o <<<<< < @ >>>>> >> ! a > 2 m > 32 a <<< @ >>>> ! s o s > 7 %
   <<< @ >>>> ! > 11 m <<<<< <<<<< < @ >>>>> >>>>> >> ! a o > 22 m a > 451 d <
   o <<<<< @ >>>>> > ! a o > 7 m s > 114 a
   c > 31 % + 
   o > 31 d
   
   {yyyy/mm/dd form}
   <<<<< <<<<< <<<<< < n >>>>> >>>>> >>>>> > 47 . < n 47 . < n 10 . q
   

with a run of

   $ ./cbrainrun computus.cb
   Year? 2014
   2014/4/20

ASCII chart

   {Display an ASCII chart}
   0 > 65 > 83 > 67 > 73 c > 32 > 67 > 104 > 97 > 114 > 116 > 10
     > 45 c c c c c c c c c c > 10 > 0
   <[<] >[.>] <[<]
   
   32 > 128 o s [
      > 5 @ [ <
          o n >9.32.61.32.< . >9.<
          << + > -
          > ! - @ 
      ] < 
      o n >9.32.61.32.< . >10.<  
      << + > -
   ] 

giving

   ASCII Chart
   -----------
   32   =      33       = !    34       = "    35       = #    36       = $    37       = %
   38   = &    39       = '    40       = (    41       = )    42       = *    43       = +
   44   = ,    45       = -    46       = .    47       = /    48       = 0    49       = 1
   50   = 2    51       = 3    52       = 4    53       = 5    54       = 6    55       = 7
   56   = 8    57       = 9    58       = :    59       = ;    60       = <    61       = =
   62   = >    63       = ?    64       = @    65       = A    66       = B    67       = C
   68   = D    69       = E    70       = F    71       = G    72       = H    73       = I
   74   = J    75       = K    76       = L    77       = M    78       = N    79       = O
   80   = P    81       = Q    82       = R    83       = S    84       = T    85       = U
   86   = V    87       = W    88       = X    89       = Y    90       = Z    91       = [
   92   = \    93       = ]    94       = ^    95       = _    96       = `    97       = a
   98   = b    99       = c    100      = d    101      = e    102      = f    103      = g
   104  = h    105      = i    106      = j    107      = k    108      = l    109      = m
   110  = n    111      = o    112      = p    113      = q    114      = r    115      = s
   116  = t    117      = u    118      = v    119      = w    120      = x    121      = y
   122  = z    123      = {    124      = |    125      = }    126      = ~    127      =

Built with OpenCOBOL

Tested using CALL from OpenCOBOL and compiled with each of

 cobc -x callcbrain.cob cbrain.c
 cobc -x cbrainrun.cob subcranial.cob cbrain.c -lreadline

and from C with

 gcc -o cbrainmain cbrainmain.c

or with the COBOL compiler

 cobc -x cbrainmain.c -lreadline
 cobc -x cbrainmain.c subcranial.cob -lreadline

from bf

Operation Meaning
+ increment value in current cell
- decrement value in current cell
> advance data cell index up 1
< retreat data cell index down 1
[ if current cell zero, scan source index forward to next ]
] if current cell non-zero, scan source index backwards to previous [
. output current cell as character value
, accept key value to current cell

from pbrain

Operation Meaning
( define procedure using current cell value as label
) end procedure definition
: evaluate procedure with label matching current cell value

cbrain adds

Operation Meaning
digits, 0 though 9 if last operation was digit, scale current cell up by 10, otherwise zero out and add in digit
{ scan forward through source text to position past balanced nested close brace }
* multiply current value by 10
/ integer divide current value by 10
a add current cell into previous cell and retreat
s subtract current cell from previous cell and retreat
m multiply current cell by previous cell into previous cell and retreat
d divide previous cell by current cell, leaving quotient in previous and remainder in current. No retreat.
^ bitwise xor current cell with previous cell and retreat
& bitwise and current cell with previous cell and retreat
| bitwise or current cell with previous cell and retreat
~ bitwise not of current cell into current cell
r right shift previous cell by current cell bits and retreat
l left shift previous cell by current cell bits and retreat
% compute modulus of previous cell by current cell into previous cell and retreat
@ fetch current cell value and place in memory register
! place content of memory register in current cell
x exchange current cell with previous
o copy previous cell over to next and advance
c copy current cell to next cell and advance
n output current cell as integer
# output current cell as formatted integer
b output current cell as base 2
= input integer and place value in current cell
" scan forward to ", call that COBOL module, passing current and then replacing with RETURN-CODE
t toggle step trace
? display current memory cells
g goback
q quit
help reserved word, calls "cbrainhelp", the OpenCOBOL module using cbrain quoted string.
file reserved word, loads script using rest of source text as filename.

reserved words MUST start in column one of the source text

cbrain interpreter

Many thanks to Daniel B Christofani and Paul M Park.

Well, the central interpreter is

   /* cbrain */
   /* pbrain interpreter in old-style C 
      This is an interpreter for Paul M. Parks's pbrain programming language,
          a variant of Urban Mueller's programming language.
      Do anything you want with this program.
      I welcome bug reports and feature requests.
      Daniel B Cristofani (http://www.hevanet.com/cristofd/)
   
      20130327, extended and put into service with OpenCOBOL as
      cbrain
      btiffin (https://sourceforge.net/users/btiffin)
   ...
   */
   scale=0;
   for(q=0;q<length;q++){
       switch(code[q]){
           case '(': case '[': s[sp++]=q; break;
           case ')': if(!sp--||code[s[sp]]!='(') {e(7); return(0);} t[s[sp]]=q; break;
           case ']': if(!sp--||code[t[t[s[sp]]=q]=s[sp]]!='[') {e(5); return(0);} break;
       }
   }
   if(sp) e(code[s[--sp]]=='['?4:6);
   for(q=0;q<=PROCEDURES;q++) ptable[q]=-1;
   for(q=0;q<length;q++){
       if (tracer && !isspace(code[q])) {
           tmp=isgraph(code[q])?code[q]:'.';
           fprintf(stderr, "[%c at %05d was %020ld, ", (char)tmp, p, a[p]);
           tracing=1;
       }
       switch(code[q]){
           /* bf */
           case '+': a[p]++; scale=0; break;
           case '-': a[p]--; scale=0; break;
           case '<': if(--p<0) {e(3); p=0; return(0);} scale=0; break;
           case '>': if(++p>=SIZE) {e(3); p=SIZE; return(-1);} scale=0; break;
           case '.': putchar(a[p]==10?'\n':a[p]); scale=0; break;
           case ',': if((c=getchar())!=EOF) a[p]=c=='\n'?10:c; scale=0; break;
           case '[': if(!a[p]) q=t[q]; scale=0; break;
           case ']': if(a[p]) q=t[q]; scale=0; break;
           /* pbrain */
           case '(': ptable[a[p]]=q; q=t[q]; scale=0; break;
           case ')': q=s[--sp]; scale=0; break;
           case ':': s[sp++]=q; if((q=ptable[a[p]])<0) e(2); scale=0; break;
           /* cbrain */
           case '{': tmp=1; while(tmp&&q++<length) {tmp-=(code[q]=='}'); tmp+=(code[q]=='{');} if(tmp) {e(9); return(0);} scale=0; break;
           case '}': e(10); return(0); scale=0; break;
           case '*': a[p]*=10; scale=0; break;
           case '/': a[p]/=10; scale=0; break;
           case '&': if(p<1) {e(3); return(0);} a[--p]&=a[p+1]; scale=0; break;
           case '|': if(p<1) {e(3); return(0);} a[--p]|=a[p+1]; scale=0; break;
           case '^': if(p<1) {e(3); return(0);} a[--p]^=a[p+1]; scale=0; break;
           case '~': a[p]=~a[p]; scale=0; break;
           case 'a': if(p<1) {e(3); return(0);} a[--p]+=a[p+1]; scale=0; break;
           case 's': if(p<1) {e(3); return(0);} a[--p]-=a[p+1]; scale=0; break;
           case 'm': if(p<1) {e(3); return(0);} a[--p]*=a[p+1]; scale=0; break;
           case 'd': if(p<1) {e(3); return(0);} if(a[p]) {tmp=a[p-1]; a[p-1]/=a[p]; a[p]=tmp-a[p]*a[p-1];} scale=0; break;
           case '%': if(p<1) {e(3); return(0);} a[--p]%=a[p+1]; scale=0; break;
           case 'r': if(p<1) {e(3); return(0);} a[--p]>>=a[p+1]; scale=0; break;
           case 'l': if(p<1) {e(3); return(0);} a[--p]<<=a[p+1]; scale=0; break;
           case '0': a[p]*=(scale++>0)?10:0; break;
           case '1': a[p]*=(scale++>0)?10:0; a[p]+=1; break;
           case '2': a[p]*=(scale++>0)?10:0; a[p]+=2; break;
           case '3': a[p]*=(scale++>0)?10:0; a[p]+=3; break;
           case '4': a[p]*=(scale++>0)?10:0; a[p]+=4; break;
           case '5': a[p]*=(scale++>0)?10:0; a[p]+=5; break;
           case '6': a[p]*=(scale++>0)?10:0; a[p]+=6; break;
           case '7': a[p]*=(scale++>0)?10:0; a[p]+=7; break;
           case '8': a[p]*=(scale++>0)?10:0; a[p]+=8; break;
           case '9': a[p]*=(scale++>0)?10:0; a[p]+=9; break;
           case '=': scanf("%d", &a[p]); scale=0; break;
           case 'n': printf("%d", a[p]); scale=0; break;
           case '#': printf("%020ld ", a[p]); scale=0; break;
           case 'b': printf("%64s", long_to_binary(a[p])); scale=0; break;
           case 'x': tmp=a[p];a[p]=a[p-1];a[p-1]=tmp; scale=0; break;
           case 'c': if(p>=SIZE) {e(3); return(0);} a[++p]=a[p-1]; scale=0; break;
           case 'o': if(p<1||p>=SIZE) {e(3); return(0);} a[++p]=a[p-2]; scale=0; break;
           case '@': memreg=a[p]; scale=0; break;
           case '!': a[p]=memreg; scale=0; break;
           case '"': a[p]=opencobol(a[p]); scale=0; break;
           case '?': tmp=p; while(tmp-->=0) printf("[%05d is %020ld]\n", tmp+1, a[tmp+1]); scale=0; break;
           case 't': tracer=(tracer?0:1); scale=0; break;
           case 'g': return (p+1);
           case 'q': return(-1);
           default: scale=0;
       }
       if (tracing && !isspace(code[q])) {
           fprintf(stderr, " after %05d is %020ld]\n", p, a[p]);
           tracing=0;
       }
   }
   /* COBOL is an ordinal language, first is 1 */
   return(p+1);


OpenCOBOL test head

   OCOBOL >>SOURCE FORMAT IS FIXED
         *> *******************************************************
         *> Author:    Brian Tiffin
         *> Date:      20130326
         *> Purpose:   cbrain
         *> Tectonics: cobc -x callcbrain.cob cbrain.c
         *> *******************************************************
          identification division.
          program-id. callcbrain.
   
          data division.
          working-storage section.
          01 cbrain-cmd           pic x(132).
          01 string-cell          pic z(19)9.
          01 fielded-variable     pic xxx.
          01 cell                 pic s9(8).
          01 looper               pic s9(8).
          01 brain-cells.
             05 brain-cell usage binary-c-long occurs 65536 times.
   
         *> *******************************************************
          procedure division.
         *call "cbrain" using brain-cells
         *    by content "file hoc.cb" & x"00"
         *end-call
   
          initialize brain-cells       
          call "cbrain" using brain-cells
              by content "file bitwise.cb" & x"00"
              returning cell
          end-call
          display "OC: from bitwise.cb " brain-cell(cell) end-display
   
          call "cbrain" using brain-cells
              by content "127 > 85 ^" & x"00"
              returning cell
          end-call
          display "OC: from expression " brain-cell(cell) end-display
   
          call "cbrain" using brain-cells
              "{127 xor 85}" &
              "{define procedure 1 for newline}" &
              "0+(@ 10 . !)" &
              "{place 127 in memory 0," &
              "  place 85 in memory 1," &
              "  bitwise XOR," &
              "  display as number." &
              "  Then, call procedure 1 for a newline," &
              "  fetching and restoring current afterwards}" &
              "127" &
              "> 85 ^ #" &
              "@ 1 : !" & x"00"
              returning cell
          end-call
          display "OC: 127 xor 85 = " brain-cell(cell) end-display
   
          initialize brain-cells       
          call "cbrain" using brain-cells
              by content "file morehello.cb" & x"00"
              returning cell
              on exception continue
          end-call
   
          initialize brain-cells       
          call "cbrain" using brain-cells
              by content "file pbrains.cb" & x"00"
              returning cell
              on exception continue
          end-call
   
         *> this is why bitwise might actually get written someday
          move 123 to fielded-variable
          initialize brain-cells
          call "cbrain" using brain-cells
              by content function concatenate(
                  fielded-variable 
                  "> 31 &", x"00")
              returning cell
          end-call
          display "OC: fielded-variable " fielded-variable " and 31 is "
              brain-cell(cell)
          end-display 
   
          perform varying looper from 1 by 1 until looper > 5
              move looper to string-cell
              string
                  string-cell delimited by size
                  " > 91 a #  > 38 . 32 . <  > 31 # &  > 61 . 32 . < # b" &
                  " @ 10 . !"  delimited by size
                  x"00" delimited by size
                  into cbrain-cmd
                  on overflow
                      display "too much brain" end-display
              end-string
   
              initialize brain-cells
              call "cbrain" using brain-cells
                  by content cbrain-cmd
                  returning cell
                  on exception continue
              end-call
         *    display "OC: " brain-cell(cell) end-display
          end-perform
          
          goback.
          end program callcbrain.

Giving a run sample on Fedora 18 and OpenCOBOL 1.1CE

   +00000008 
   +00000014 
   +00000015 
   -00000009 
   +00000015 
   +00000001 
   +00000003 
   +555000000 
   OC: from bitwise.cb +00000000000555000000
   OC: from expression +00000000000000000042
   +00000042 
   OC: 127 xor 85 = +00000000000000000042
   Hello OpenCOBOL!
   'Sup earth
   Hello cbrain niarbc olleH
   8
   ABCDE
  EsoAPI required
   OC: fielded-variable 123 and 31 is +00000000000000000027
   +00000092 & +00000031 = +00000028 0000000000000000000000000000000000000000000000000000000000011100 
   +00000093 & +00000031 = +00000029 0000000000000000000000000000000000000000000000000000000000011101 
   +00000094 & +00000031 = +00000030 0000000000000000000000000000000000000000000000000000000000011110 
   +00000095 & +00000031 = +00000031 0000000000000000000000000000000000000000000000000000000000011111 
   +00000096 & +00000031 = +00000000 0000000000000000000000000000000000000000000000000000000000000000 

and steps trace on standard error of

   [00244 0 at 00014 was         1,  after 00014 is         0]
   [00246 { at 00014 was         0,  after 00014 is         0]
   [00293 + at 00014 was         0,  after 00014 is         1]
   [00294 + at 00014 was         1,  after 00014 is         2]
   [00295 + at 00014 was         2,  after 00014 is         3]
   [00296 + at 00014 was         3,  after 00014 is         4]
   [00297 + at 00014 was         4,  after 00014 is         5]
   [00299 > at 00014 was         5,  after 00015 is        10]
   [00301 0 at 00015 was        10,  after 00015 is         0]
   [00303 + at 00015 was         0,  after 00015 is         1]
   [00304 + at 00015 was         1,  after 00015 is         2]
   [00305 + at 00015 was         2,  after 00015 is         3]
   [00306 + at 00015 was         3,  after 00015 is         4]
   [00307 + at 00015 was         4,  after 00015 is         5]
   [00308 + at 00015 was         5,  after 00015 is         6]
   [00309 + at 00015 was         6,  after 00015 is         7]
   [00310 + at 00015 was         7,  after 00015 is         8]
   [00311 + at 00015 was         8,  after 00015 is         9]
   [00312 + at 00015 was         9,  after 00015 is        10]
   [00314 * at 00015 was        10,  after 00015 is       100]
   [00316 m at 00015 was       100,  after 00014 is       500]
   [00318 > at 00014 was       500,  after 00015 is       100]
   [00320 5 at 00015 was       100,  after 00015 is         5]
   [00321 5 at 00015 was         5,  after 00015 is        55]
   [00323 a at 00015 was        55,  after 00014 is       555]
   [00325 * at 00014 was       555,  after 00014 is      5550]
   [00326 * at 00014 was      5550,  after 00014 is     55500]
   [00327 * at 00014 was     55500,  after 00014 is    555000]
   [00328 * at 00014 was    555000,  after 00014 is   5550000]
   [00329 * at 00014 was   5550000,  after 00014 is  55500000]
   [00330 * at 00014 was  55500000,  after 00014 is 555000000]
   [00332 # at 00014 was 555000000,  after 00014 is 555000000]
   [00334 t at 00014 was 555000000,  after 00014 is 555000000]

with morehello.cb

   [-][bf style]
   +++++ +++++             {initialize counter (cell #0) to 10}
   [                       {use loop to set the next four cells to 70/100/30/10}
       > +++++ ++              {add  7 to cell #1}
       > +++++ +++++           {add 10 to cell #2}
       > +++                   {add  3 to cell #3}
       > +                     {add  1 to cell #4}
       <<<< -                  {decrement counter (cell #0)}
   ]                   
   > ++ .                  {print 'H'}
   > + .                   {print 'e'}
   +++++ ++ .              {print 'l'}
   .                       {print 'l'}
   +++ .                   {print 'o'}
   > ++ .                  {print ' '}
   << +++++ ++ .           {print 'O'}
   > + .                   {print 'p'}
   ----- ----- - .         {print 'e'}
   +++++ ++++ .            {print 'n'}
   < ----- ----- -- .      {print 'C'}
   +++++ +++++ ++ .        {print 'O'}
   ----- ----- --- .       {print 'B'}
   +++++ +++++ +++ .       {print 'O'}
   --- .                   {print 'L'}
   >> + .                  {print '!'}
   > .                     {print '\n'}
   
   0[eso style]
   39 > 83 > 117 > 112 > 32 > 101 > 97 > 114 > 116 > 104 > 0
   < < < < < < < < < <
   [. >] > 01 * .
   
   {cbrain style}
   0 (<<<<< <<<<<)
   > 72 > 101 > 7 o a c c +++ > 32 > 99 c -> 114 o - > 105 c > 5 a > 32 > 0
   : <<< [. >] << [. <] 10 .

displayed as

   Hello OpenCOBOL!
   'Sup earth
   Hello cbrain niarbc olleH

help

help is built into a sub module system

   OCOBOL >>SOURCE FORMAT IS FREE
         *> ********************************************************
         *> Author:    Brian Tiffin
         *> Date:      20130331
         *> Purpose:   submodule for cbrain
         *> Tectonics: cobc -x cbrainrun.cob subcranial.cob cbrain.c -lreadline
         *>            cb: 23 # "subcranial" #
         *> ********************************************************
          identification division.
          program-id. subcranial.
          data division.
          linkage section.
          01 brain-cell usage binary-long.
   
         *> ********************************************************
          procedure division using by value brain-cell.
          move 104 to return-code
       >>D display
       >>D     "OC: got " brain-cell " returning " return-code
       >>D end-display
          goback.
          end program subcranial.
         *> ********************************************************
          
         *> ********************************************************
          identification division.
          program-id. cbrainhelp.
   
          environment division.
          configuration section.
          repository.
              function all intrinsic.
   
          data division.
          working-storage section.
          01 jars                 value "012345678901234567890".
             03 flies.
                05 fly            pic 9 occurs 21 times.
          linkage section.
          01 brain-cell usage binary-long.
   
         *> ********************************************************
          procedure division using by value brain-cell.
          evaluate brain-cell
              when 104
                  display "10-4 back expect 10-2" end-display
                  display "cbrain 10 code special helps are:" end-display
                  display "    10-4  : ok, help help" end-display
                  display "    10-28 : identify station" end-display
                  display "    10-34 : send help" end-display
                  display "    10-36 : correct time is ..." end-display
                  display "    10-94 : request for long count, frogsort and quit" end-display
                  display "    other : cbrain help" end-display
                  move 102 to return-code
                  goback
              when 1028 
                  display "10-28 received, cbrain v0.42, Apr 2013, expect 10-4" end-display
                  display "Daniel B Cristofani posted pbrain.c, modified for cbrain by Brian Tiffin" end-display
                  display "Tectonics:" &x"0a" "    cobc -x cbrainmain.c subcranial.cob -lreadline -g -debug -fdebugging-line" end-display
                  display "    cobc -x cbrainrun.cob subcranial.cob cbrain.c -lreadline" end-display
                  move 104 to return-code
                  goback
              when 1034 
                  display "10-4 good buddy" end-display
                  display "CB 10-codes: " end-display
                  display "---------------" end-display
                  display "10-1 receiving poorly " end-display
                  display "10-2 receiving well " end-display
                  display "10-3 stop transmitting" end-display
                  display "10-4 OK, got message" end-display
                  display "10-5 relay message" end-display
                  display "10-6 busy, please stand by" end-display
                  display "10-7 out of service, and off air" end-display
                  display "10-8 in service, ready" end-display
                  display "10-9 please repeat" end-display
                  display "10-10 completed and standing by" end-display
                  display "10-11 talking too fast" end-display
                  display "10-12 visitors present" end-display
                  display "10-13 how's the weather and road?" end-display
                  display "10-16 pick up at ..." end-display
                  display "10-17 urgent" end-display
                  display "10-18 do you have anything?" end-display
                  display "10-19 nothing for you, come on in" end-display
                  display "10-20 location is ..." end-display
                  display "10-21 call by phone" end-display
                  display "10-22 come on in and see ..." end-display
                  display "10-23 please stand by" end-display
                  display "10-24 last assignment complete" end-display
                  display "10-25 can you contact ..." end-display
                  display "10-26 disregard last" end-display
                  display "10-27 moving to channel ..." end-display
                  display "10-28 identify yourself" end-display
                  display "10-29 time's up" end-display
                  display "10-30 radio use not conforming to rules" end-display
                  display "10-32 will give radio check" end-display
                  display "10-33 emergency traffic on channel" end-display
                  display "10-34 trouble, help requested" end-display
                  display "10-35 confidential" end-display
                  display "10-36 correct time is ..." end-display
                  display "10-37 tow requested at ..." end-display
                  display "10-38 ambulance requested at ..." end-display
                  display "10-39 message delivered" end-display
                  display "10-41 go to channel" end-display
                  display "10-42 traffic accident at ..." end-display
                  display "10-43 traffic congestion at ..." end-display
                  display "10-44 message for you " end-display
                  display "10-45 all units please report" end-display
                  display "10-50 break channel" end-display
                  display "10-60 what is next message number?" end-display
                  display "10-62 unable to hear, use alternate" end-display
                  display "10-63 net redirect to ..." end-display
                  display "10-64 net clear" end-display
                  display "10-65 awaiting next message" end-display
                  display "10-67 all units follow" end-display
                  display "10-70 fire reported at ..." end-display
                  display "10-71 proceed in sequence " end-display
                  display "10-77 negative contact" end-display
                  display "10-81 are you drunk?" end-display
                  display "10-82 need room for ..." end-display
                  display "10-84 telephone number is ..." end-display
                  display "10-85 address is ..." end-display
                  display "10-91 closer to the mike please" end-display
                  display "10-93 hows my frequency on this channel?" end-display
                  display "10-94 can I get a long count?" end-display
                  display "10-99 mission complete" end-display
                  display "10-100 rest stop" end-display
                  display "10-200 police needed at ..." end-display
                  display "----------------------------" x"0a" end-display
                  move 102 to return-code
                  goback
              when 1036  
                  display locale-date(current-date(1:8)) " " locale-time(current-date(9:6)) end-display
                  move 104 to return-code
                  goback
              when 1094
                  call "frogsort" using flies end-call
              when other
                  display "cbrainhelp received " brain-cell " and will return 10-4 on successful completion." end-display
          end-evaluate
   
          display x"0a" & "===From bf===" end-display
          display "+, increment current cell" end-display
          display "-, decrement current cell" end-display
          display ">, advance data cell index up 1" end-display
          display "<, retreat data cell index down 1" end-display
          display "[, if current cell zero, scan source index forward to next ]" end-display
          display "], if current cell non-zero, scan source index backwards to previous [" end-display
          display "., output current cell" end-display
          display ",, accept key value to current cell" end-display
   
          display x"0a" & "===From pbrain===" end-display
          display "(, define procedure using current cell value as label" end-display
          display "), end procedure definition" end-display
          display ":, evalute labelled procedure using current cell value" end-display
   
          display x"0a" & "===cbrain adds===" end-display
          display "digits, 0 though 9, if last operation was digit, scale current cell up by 10, otherwise zero out and add in digit" end-display
          display "{, scan through source text to position past next balanced end brace }" end-display
          display "*, multiply current value by 10" end-display
          display "/, integer divide current value by 10" end-display
          display "a, add current cell into previous cell and retreat" end-display
          display "s, subtract current cell from previous cell and retreat" end-display
          display "m, multiply current cell by previous cell into previous cell and retreat" end-display
          display "d, divide previous cell by current cell leaving quotient in previous and remainder in current, no retreat" end-display
          display "^, bitwise xor current cell with previous cell and retreat" end-display
          display "&, bitwise and current cell with previous cell and retreat" end-display
          display "|, bitwise or current cell with previous cell and retreat" end-display
          display "~, bitwise not of current cell into current cell" end-display
          display "r, right shift previous cell by current cell bits and retreat" end-display
          display "l, left shift previous cell by current cell bits and retreat" end-display
          display "%, compute modulus of previous cell by current cell into previous cell and retreat" end-display
          display "@, fetch current cell value and place in memory register" end-display
          display "!, store content of memory register in current cell" end-display
          display "x, exchange current cell with previous" end-display
          display "o, copy previous cell over to next and advance" end-display
          display "c, copy current cell to next cell and advance" end-display
          display "n, output current cell as integer" end-display
          display "#, output current cell as formatted integer" end-display
          display "b, output current cell as base 2" end-display
          display "=, input integer and place value in current cell" end-display
          display '", scan forward to ", call that COBOL module, passing current and then replacing with RETURN-CODE' end-display
          display "?, display memory up to current" end-display
          display "t, toggle step trace" end-display
          display "g, goback" end-display
          display "q, quit" end-display
          display "reserved word 'help'" ', calls "cbrainhelp", the OpenCOBOL module using cbrain quoted string.' end-display
          display "reserved word 'file ' loads script using rest of source text as filename." end-display
          move 104 to return-code
          goback.
          end program cbrainhelp.
         *> ********************************************************
   
         *> ********************************************************
         *>  frogSort, called for help with 10-94, request for count
         *> ********************************************************
          identification division.
          program-id. frogsort.
          data division.
          working-storage section.
          01 opinion          usage binary-long.
          01 shared-value     pic 99.
             88 fair          value 1.
          01 caveman-count    pic x(12) value "[-]+++++++++".
          01 spacer           pic x(10) value spaces.
   
          linkage section.
          01 jars.
             05 flies        pic 9 occurs 21 times.
   
         *> ********************************************************
          procedure division using jars.
          start-here.
          move function length(jars) to shared-value
          display "Grog sort jars.  frogSort" end-display
          display "http://www.smbc-comics.com/?id=2831" end-display
          .
   
          forkyourself.
              call "fork" returning opinion end-call
              if opinion is zero then
                  subtract 1 from shared-value
                  if not fair then go forkyourself.
          .
    
          call "sleep" using by value flies(shared-value) end-call
          display
              "Jar: " function char(shared-value + 65) " reporting "
              caveman-count(1 : flies(shared-value) + 3) " flies,"
              spacer(1 : 10 - flies(shared-value))
              "that would be " flies(shared-value) " to you, futureman."
          end-display
          call "wait" using by value 0 end-call
   
          stop run returning 107.
          end program frogsort.

with a run sample of

   $ cat Makefile 
   cbrainrun: cbrainrun.cob subcranial.cob cbrain.c
           cobc -x cbrainrun.cob subcranial.cob cbrain.c -lreadline -g -debug
   [cbrain]$ ./cbrainrun 
   10-12 Welcome to cbrain v0.42
   cb: 104
   cb: help
   10-4 back expect 10-2
   cbrain 10 code special helps are:
       10-4  : ok, help help
       10-28 : identify station
       10-34 : send help
       10-36 : correct time is ...
       10-94 : request for long count, frogsort and quit 10-7
       other : cbrain help
   cb: help
   cbrainhelp received +0000000102 and will return 10-4 on successful completion.
   
   ===From bf===
   +, increment current cell
   -, decrement current cell
   >, advance data cell index up 1
   <, retreat data cell index down 1
   [, if current cell zero, scan source index forward to matching ]
   ], if current cell non-zero, scan source index backwards to previous [
   ., output current cell
   ,, accept key value to current cell
   
   ===From pbrain===
   (, define procedure using current cell value as label
   ), end procedure definition
   :, evalute procedure using current cell value as label
   
   ===cbrain adds===
   {, scan through source text to position past next encountered }
   digits, 0 though 9, if last operation was digit, scale current cell up by 10, otherwise zero out and add in digit
   *, multiply current value by 10
   /, integer divide current value by 10
   a, add current cell into previous cell and retreat
   s, subtract current cell from previous cell and retreat
   m, multiply current cell by previous cell into previous cell and retreat
   d, divide previous cell by current cell leaving quotient in previous and remainder in current, no retreat
   ^, bitwise xor current cell with previous cell and retreat
   &, bitwise and current cell with previous cell and retreat
   |, bitwise or current cell with previous celll and retreat
   ~, bitwise not of current cell into current cell
   r, right shift previous cell by current cell bits and retreat
   l, left shift previous cell by current cell bits and retreat
   %, compute modulus of previous cell by current cell into previous cell and retreat
   @, fetch current cell value and place in memory register
   !, place content of memory register in current cell
   x, exchange current cell with previous
   o, copy previous cell over to next and advance
   c, copy current cell to next cell and advance
   n, output current cell as integer
   #, output current cell as formatted integer
   b, output current cell as base 2
   =, input integer and place value in current cell
   ", scan forward to ", call that COBOL module, passing current and then replacing with RETURN-CODE
   t, toggle step trace
   g, goback
   q, quit
   reserved word 'help', calls "cbrainhelp", the OpenCOBOL module using cbrain quoted string.
   reserved word 'file ' loads script using rest of source text as filename.
   cb: 1036
   cb: help
   04/02/2013 07:17:19 AM
   cb: 1028
   cb: help
   10-28 received, cbrain v0.42, May 2013, expect 10-4
   Daniel B Cristofani posted pbrain.c, modified for cbrain
   Tectonics:
       cobc -x cbrainmain.c subcranial.cob -lreadline -g -debug -fdebugging-line
       cobc -x cbrainrun.cob subcranial.cob cbrain.c -lreadline
   cb: 1094
   cb: help
   Grog sort jars.  frogSort
   http://www.smbc-comics.com/?id=2831
   Jar: U reporting [-] flies,          that would be 0 to you, futureman.
   Jar: K reporting [-] flies,          that would be 0 to you, futureman.
   Jar: A reporting [-] flies,          that would be 0 to you, futureman.
   Jar: L reporting [-]+ flies,         that would be 1 to you, futureman.
   Jar: B reporting [-]+ flies,         that would be 1 to you, futureman.
   Jar: M reporting [-]++ flies,        that would be 2 to you, futureman.
   Jar: C reporting [-]++ flies,        that would be 2 to you, futureman.
   Jar: N reporting [-]+++ flies,       that would be 3 to you, futureman.
   Jar: D reporting [-]+++ flies,       that would be 3 to you, futureman.
   Jar: O reporting [-]++++ flies,      that would be 4 to you, futureman.
   Jar: E reporting [-]++++ flies,      that would be 4 to you, futureman.
   Jar: P reporting [-]+++++ flies,     that would be 5 to you, futureman.
   Jar: F reporting [-]+++++ flies,     that would be 5 to you, futureman.
   Jar: Q reporting [-]++++++ flies,    that would be 6 to you, futureman.
   Jar: G reporting [-]++++++ flies,    that would be 6 to you, futureman.
   Jar: R reporting [-]+++++++ flies,   that would be 7 to you, futureman.
   Jar: H reporting [-]+++++++ flies,   that would be 7 to you, futureman.
   Jar: S reporting [-]++++++++ flies,  that would be 8 to you, futureman.
   Jar: I reporting [-]++++++++ flies,  that would be 8 to you, futureman.
   Jar: T reporting [-]+++++++++ flies, that would be 9 to you, futureman.
   Jar: J reporting [-]+++++++++ flies, that would be 9 to you, futureman.

The 10-94 help displays a frog sort of 21 digits, using sleep sort technology.

Criticism

Totally breaks the BF tradition and adds numbers. Comments trip as well.

Implementation

OpenCOBOL and C sources posted to the OpenCOBOL project space on SourceForge at OpenCOBOL discussion on SourceForge

Based on the pbrain implementation. The pbrain page has

   A concise interpreter in C is available at http://www.hevanet.com/cristofd/pbrain.c.
   I have tried to complete the semantics the cleanest way I could.

And yes, Daniel wrote a superb little engine.

External resources