tests/C_C++/flex/brainfuck.c
2024-12-10 20:40:17 +01:00

142 lines
4.5 KiB
C

/* @BAKE
re2c -W -o $*.re.c $@
gcc -o $* $*.re.c -ggdb
./$* pure_hw.bf
@STOP
*/
#include <stdio.h>
char data[30000];
char * data_ptr = data;
// #define YYDEBUG(n, c) fprintf(stderr, "rule %n (%c)\n", l, c)
/* Review of this bullshit software called re2c 3.1:
* + the comment thing is kinda smart
* - it generates very small scanners so having them inline is not insanity
* - you can nest them in your source, without breaking your highlighting or making the lls cry
* + it can generate state transition graphs, thats kinda cool
* + neither the "free-form" or the "function-like" API seems to work;
* theres no error or acknoledgement either
* + the first example in the documentation is fucking broken
* - it uses undocumented cli flags (like some others)
* - they feed a string, but only one character is ever evaluated
* + '\00' gives a syntax error for no damn reason
* + switches it generates hurt my eye. why the fuck do they need a label and a goto for each case?,
* sure there is string/regex matching which cannot fit inside a case,
* however what if only those were to jmp?
* + the default rule ('*') is not properly documented
* + for whatever reason fallthough is the default behaviour so you have to spam either
* continue or goto
* + the default default rule is a fallthrough too;
* not a jam, but whatever rule the transpiler decided to insert to the top
* (spoiler alert: they are not even in the order of declaration)
* + what the literal fuck is this syntax?
* `re2c:api:style`
* 1) you dont need the prefix re2c, its utter bloat
* 2) namespacing for 20 or so options???
* 3) my bad, *should be 20 so optoins, instead we have shit like this:
* re2c:bit-vectors, re2c:flags:bit-vectors, re2c:flags:b
* to do the same fucking thing
* and just to stress this, they have namespaces, but you can just no use them.
* when? option dependent.
* + do we have comments inside re2c blocks? dunno. not documented.
* + the cli help is too verbose; useless line breaks makes it hard to grep
* + while we are at it, why do we need so many fucking options?
* $ re2c --help | grep -e '^\W*-' | sort | uniq | wc -l
* 77
* $ flex --help | grep -e '^\W*-' | sort | uniq | wc -l
* 46
* # and this shit is suppose to be smaller
* + -d is useless; YYDEBUG is simply not fit to tracing, since it does not tell you
* which lexer it is or the line number
* + i get duplicate output. now, it very well might be my fault,
* however i have no proper means of debugging and im not
* wasting more time on this software
*/
int yylex(const char * const s) {
const char * YYCURSOR = s;
INITIAL:
while (*YYCURSOR)
/*!re2c
re2c:yyfill:enable = 0;
re2c:define:YYCTYPE = char;
'>' { ++data_ptr; continue; }
'<' { --data_ptr; continue; }
'+' { ++(*data_ptr); continue; }
'-' { --(*data_ptr); continue; }
'.' { putchar(*data_ptr); continue; }
',' { *data_ptr = getchar(); continue; }
'[' {
if (!*data_ptr) {
goto IN_SKIP_FORWARD;
}
continue;
}
']' {
if (!*data_ptr) {
goto IN_SKIP_BACKWARD;
}
continue;
}
* { continue; }
'\x00' { return 0; }
*/
IN_SKIP_FORWARD:
while (*YYCURSOR)
/*!re2c
']' {
goto INITIAL;
}
* { continue; }
'\x00' { return 0; }
*/
/* I cant seem to make this thing go backwards,
* so everything is broken
*/
IN_SKIP_BACKWARD:
#define YYSKIP --YYCURSOR
while (*YYCURSOR)
/*!re2c
//re2c:api:style = free-form;
//re2c:define:YYSKIP = "--YYCURSOR;";
'[' {
++YYCURSOR;
goto INITIAL;
}
* { continue; }
'\x00' { return 0; }
*/
return 0;
}
signed main(int argc, char * argv[]) {
if (argc != 2) {
printf("%s <file>", argv[0]);
return 1;
}
FILE* f = fopen(argv[1], "r");
if(!f){ return 2; }
fseek(f, 0, SEEK_END);
int flen = ftell(f);
rewind(f);
char fstr[flen+1];
fstr[flen] = '\00';
fread(fstr, flen, sizeof(char), f);
fclose(f);
yylex(fstr);
return 0;
}