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.