Cbrain

==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==
*Release tarball
*Files
Category:Languages
Category:Brainfuck derivatives
Category:Cell-based
Category:Implemented
Category:2013
Category:Turing complete