Skip to content

Instantly share code, notes, and snippets.

@benolee
Forked from ttilley/hello_world.txt
Created April 14, 2013 03:15
Show Gist options
  • Save benolee/5381260 to your computer and use it in GitHub Desktop.
Save benolee/5381260 to your computer and use it in GitHub Desktop.
#!/usr/bin/env PeanutButterJellyTime
# -----------------------------------------------------------------------------
# keyword => C equiv (description)
# -----------------------------------------------------------------------------
# peanut => ++*ptr (increase value of cell)
# PEANUT => ++ptr (move to next cell)
# butter => --*ptr (decrease value of cell)
# BUTTER => --ptr (move to previous cell)
# jelly => putchar(*ptr) (print character value of cell)
# JELLY => *ptr=getchar() (store numeric value of char input in cell)
# time => while (*ptr) { (start loop block that loops while the current
# cell is non-zero)
# TIME => } (end loop block)
# -----------------------------------------------------------------------------
# "Hello World!" written in "peanut butter jelly time" brainfuck variant
# -----------------------------------------------------------------------------
# initialize cell 0 to 10 to act as a loop counter
peanut peanut peanut peanut peanut
peanut peanut peanut peanut peanut
# current cell: 0
# set up cells for upper|lower|punctuation|newline
# start loop block
time
# move to cell 1
PEANUT
# add 7
peanut peanut peanut peanut peanut
peanut peanut
# current cell: 1
# move to cell 2
PEANUT
# add 10
peanut peanut peanut peanut peanut
peanut peanut peanut peanut peanut
# current cell: 2
# move to cell 3
PEANUT
# add 3
peanut peanut peanut
# current cell: 3
# move to cell 4
PEANUT
# add 1
peanut
# current cell: 4
# decrement loop counter
# move to cell 0
BUTTER BUTTER BUTTER BUTTER
# subtract 1
butter
# current cell: 0
# end loop block
TIME
# cells should now be: 0|70('F')|100('d')|30(RS)|10(NL)
# print 'H'
# move to cell 1
PEANUT
# add 2
peanut peanut
# cells should now be 0|72('H')|100('d')|30(RS)|10(NL)
# print char value
jelly
# print 'e'
# move to cell 2
PEANUT
# add 1
peanut
# cells should now be 0|72('H')|101('e')|30(RS)|10(NL)
# print char value
jelly
# print 'l'
# add 7 to cell 2
peanut peanut peanut peanut peanut
peanut peanut
# cells should now be 0|72('H')|108('l')|30(RS)|10(NL)
# print char value
jelly
# print 'l' again
jelly
# print 'o'
# add 3 to cell 2
peanut peanut peanut
# cells should now be 0|72('H')|111('o')|30(RS)|10(NL)
# print char value
jelly
# print ' '
# move to cell 3
PEANUT
# add 2
peanut peanut
# cells should now be 0|72('H')|111('o')|32(' ')|10(NL)
# print char value
jelly
# print 'W'
# move to cell 1
BUTTER BUTTER
# add 15
peanut peanut peanut peanut peanut
peanut peanut peanut peanut peanut
peanut peanut peanut peanut peanut
# cells should now be 0|87('W')|111('o')|32(' ')|10(NL)
# print char value
jelly
# print 'o'
# move to cell 2
PEANUT
# print char value
jelly
# print 'r'
# add 3 to cell 2
peanut peanut peanut
# cells should now be 0|87('W')|114('r')|32(' ')|10(NL)
# print char value
jelly
# print 'l'
# subtract 6 from cell 2
butter butter butter butter butter
butter
# cells should now be 0|87('W')|108('l')|32(' ')|10(NL)
# print char value
jelly
# print 'd'
# subtract 8 from cell 2
butter butter butter butter butter
butter butter butter
# cells should now be 0|87('W')|100('d')|32(' ')|10(NL)
# print char value
jelly
# print '!'
# move to cell 3
PEANUT
# add 1
peanut
# cells should now be 0|87('W')|100('d')|33('!')|10(NL)
# print char value
jelly
# print newline
# move to cell 4
PEANUT
# print char value
jelly
#include "pbjt.h"
void interpret(char *itape)
{
char *iop = itape;
while (*iop) {
switch (*iop) {
case NOP:
return;
break;
case INC_CELL:
++*cell;
++iop;
break;
case DEC_CELL:
--*cell;
++iop;
break;
case NEXT_CELL:
++cell;
++iop;
break;
case PREV_CELL:
--cell;
++iop;
break;
case PUT_CELL:
putchar(*cell);
++iop;
break;
case GET_CELL:
*cell = getchar();
++iop;
break;
case START_LOOP:
++iop;
char ltape[MAX_OPS];
char *lop = ltape;
while (*iop != END_LOOP) {
*lop = *iop;
++lop;
++iop;
}
while (*cell) {
interpret(ltape);
}
break;
case END_LOOP:
++iop;
break;
}
}
}
#ifndef PeanutButterJellyTime_pbjt_h
#define PeanutButterJellyTime_pbjt_h
#include <stdio.h>
enum tokens {
NOP = 0,
INC_CELL,
DEC_CELL,
NEXT_CELL,
PREV_CELL,
PUT_CELL,
GET_CELL,
START_LOOP,
END_LOOP
};
#ifndef MAX_CELLS
#define MAX_CELLS 30000
#endif
#ifndef MAX_OPS
#define MAX_OPS 1048576
#endif
char cells[MAX_CELLS];
char *cell;
char tape[MAX_OPS];
char *op;
void interpret(char *itape);
#endif
%{
#include "pbjt.h"
%}
%option nodefault
%option noyywrap
%option align
%option full
%option warn
%option batch
comment #[^\n]*\n
ws [ \t\r\n]+
%%
{comment} { /* Ignore comment */ }
{ws} { /* Ignore white spaces */ }
"peanut" { *op = INC_CELL; ++op; }
"PEANUT" { *op = NEXT_CELL; ++op; }
"butter" { *op = DEC_CELL; ++op; }
"BUTTER" { *op = PREV_CELL; ++op; }
"jelly" { *op = PUT_CELL; ++op; }
"JELLY" { *op = GET_CELL; ++op; }
"time" { *op = START_LOOP; ++op; }
"TIME" { *op = END_LOOP; ++op; }
%%
int main(int argc, char **argv)
{
if(argc > 1) {
if(!(yyin = fopen(argv[1], "r"))) {
perror(argv[1]);
return (1);
}
}
cell = cells;
op = tape;
yylex();
interpret(tape);
}
@benolee
Copy link
Author

benolee commented Apr 14, 2013

$ lex pbjt.l
pbjt.l:27: warning, -s option given but default rule can be matched
$ ls
hello_world.txt lex.yy.c        pbjt.c          pbjt.h          pbjt.l
$ cc -o pbjt lex.yy.c pbjt.c
$ ./pbjt < hello_world.txt
Hello World!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment