Author | Jakob Wakeling <[email protected]> |
Date | 2020-07-14 01:19:48 |
Commit | 1dbad8b9aeadce33deef132408056ee00d1cbdb9 |
Parent | 44e07d6c967d25f6473f026083580cff382a8b08 |
Restructure and refactor interpreter
Diffstat
M | CMakeLists.txt | | | 2 | +- |
D | ext/optget.h | | | 169 | -------------------------------------------------------------------------------- |
D | src/main.c | | | 136 | -------------------------------------------------------------------------------- |
A | src/obfi.c | | | 148 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
D | src/parse.c | | | 76 | ---------------------------------------------------------------------------- |
D | src/parse.h | | | 58 | ---------------------------------------------------------- |
6 files changed, 149 insertions, 440 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index cac770c..e18fc46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) -ADD_COMPILE_DEFINITIONS(VERSION="1.0.1") +ADD_COMPILE_DEFINITIONS(VERSION="1.0.2") FILE(GLOB SOURCES ${CMAKE_SOURCE_DIR}/src/*) diff --git a/ext/optget.h b/ext/optget.h deleted file mode 100644 index cc9ed90..0000000 --- a/ext/optget.h +++ /dev/null @@ -1,169 +0,0 @@ -// optget.h, version 1.5.1 -// OMKOV optget library -// Copyright (C) 2020, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Copyright (C) 2020, Jakob Wakeling -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#ifndef OMKOV_OPTGET_H_W3LIZK1S -#define OMKOV_OPTGET_H_W3LIZK1S - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include <stdio.h> -#include <string.h> - -#define ARG_NUL 0 -#define ARG_REQ 1 -#define ARG_OPT 2 - -typedef struct { - char *str; - int arg, val; -} lop_t; - -typedef struct { - int ind, opt, pos, nop; - char *arg, *lop, *str; - lop_t *lops; -} opt_t; - -static const opt_t OPTGET_INIT = { 1, 0, 1, 0, NULL, NULL, NULL, NULL }; - -static inline void _permute(char *argv[], int ind, int n); - -#define cur argv[opt->ind] - -/* - Parse the next command line argument -*/ -static inline int optget(opt_t *opt, char *argv[], int flags) { - if (flags & 1) { - for (; cur && (cur[0] != '-' || cur[1] == 0); ++opt->ind, ++opt->nop); - if (!cur) { opt->ind -= opt->nop; opt->nop = 0; return -1; } - } - else if (!cur || (cur[0] != '-' || cur[1] == 0)) { return -1; } - - int optind = opt->ind, optret; - - if (cur[1] == '-') { - if (cur[2] == 0) { if (opt->nop) { - _permute(argv, opt->ind++, opt->nop); - opt->ind -= opt->nop; opt->nop = 0; - } else { ++opt->ind; } return -1; - } - - int optend, lop; optret = '?'; opt->opt = 0; opt->lop = cur; - if (!opt->lops) { goto nol; } - for (optend = 2; cur[optend] != '=' && cur[optend] != 0; ++optend) {} - - for (lop = 0; opt->lops[lop].str; ++lop) { - if (strncmp(&cur[2], opt->lops[lop].str, (size_t)optend - 2) == 0) { - if (!opt->lops[lop].str[optend - 2]) { - optret = opt->opt = opt->lops[lop].val; - break; - } - } - } - - if (opt->lops[lop].arg > ARG_NUL) { - if (cur[optend]) { opt->arg = &cur[optend + 1]; } - else if (argv[opt->ind + 1]) { opt->arg = argv[++opt->ind]; } - else { - if (opt->lops[lop].arg == ARG_REQ) { optret = ':'; } - opt->arg = NULL; - } - } - else { opt->arg = NULL; } - -nol: opt->pos = 0; - } - else { - optret = opt->opt = cur[opt->pos++]; opt->lop = NULL; - const char *optchr = strchr(opt->str, opt->opt); - - if (!optchr) { optret = '?'; } - else if (optchr[1] == ':') { - if (cur[opt->pos]) { opt->arg = &cur[opt->pos]; } - else if (argv[opt->ind + 1]) { opt->arg = argv[++opt->ind]; } - else { opt->arg = NULL; optret = ':'; } - opt->pos = 0; - } - else { opt->arg = NULL; } - } - - if (!opt->pos || !cur[opt->pos]) { - ++opt->ind; opt->pos = 1; - if (opt->nop) for (; optind < opt->ind; ++optind) { - _permute(argv, optind, opt->nop); - } - } - - if (optret == '?' && opt->str[0] != ':') { - if (opt->opt) { - fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], opt->opt); - } - else if (opt->lop) { - fprintf(stderr, "%s: invalid option '%s'\n", argv[0], opt->lop); - } - } - if (optret == ':' && opt->str[0] != ':') { - if (opt->opt) { - fprintf(stderr, "%s: option requires argument -- '%c'\n", argv[0], - opt->opt); - } - else if (opt->lop) { - fprintf(stderr, "%s: option requires argument '%s'\n", argv[0], - opt->lop); - } - } - - return optret; -} - -/* - Permute arguments -*/ -static inline void _permute(char *argv[], int ind, int n) { - char *arg = argv[ind]; - for (int i = ind; i > ind - n; --i) { argv[i] = argv[i - 1]; } - argv[ind - n] = arg; - return; -} - -#undef cur // argv[opt->ind] - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // OMKOV_OPTGET_H_W3LIZK1S diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 119d803..0000000 --- a/src/main.c +++ /dev/null @@ -1,136 +0,0 @@ -// main.c -// Main source file for OBFI -// Copyright (C) 2020, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Copyright (C) 2020, Jakob Wakeling -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#include "parse.h" - -#include "error.h" -#include "optget.h" - -#include <sys/stat.h> - -#include <errno.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -static int execute(tok_t *toks); - -static void help(void); -static void version(void); - -int main(int argc, char *argv[]) { - lop_t lops[] = { - { "help", ARG_NUL, 256 }, - { "version", ARG_NUL, 257 }, - { NULL, 0, 0 } - }; - - opt_t opt = OPTGET_INIT; opt.str = ""; opt.lops = lops; int o; - while ((o = optget(&opt, argv, 1)) != -1) switch (o) { - case 256: { help(); return 0; } - case 257: { version(); return 0; } - default: { return 1; } - } - - if (opt.ind == argc) { error(1, "%s: missing operand", argv[0]); } - - char *file = argv[opt.ind]; struct stat fs; - if (stat(file, &fs)) { error(1, "%s: %s: %s", argv[0], file, serrno); } - - char *fb = malloc(sizeof (*fb) * fs.st_size + 1); fb[fs.st_size] = 0; - if (!fb) { error(1, "%s: %s", argv[0], serrno); } - - FILE *fi = fopen(file, "r"); - if (!fi) { free(fb); error(1, "%s: %s: %s", argv[0], file, serrno); } - - fread(fb, 1, fs.st_size, fi); fclose(fi); - if (errno) { free(fb); error(1, "%s: %s: %s", argv[0], file, serrno); } - - tok_t *toks = parse(fb, fs.st_size); free(fb); - if (!toks) { error(1, "%s: %s", argv[0], serrno); } - - if (execute(toks)) { free(toks); error(1, "%s: %s", argv[0], serrno); } - - free(toks); return 0; -} - -static int execute(tok_t *toks) { - uint8_t arr[30000] = { 0 }, *ptr = arr; - - size_t cap = 64, top = 0; tok_t **dat; - if (!(dat = malloc(sizeof (*dat) * cap))) { return 1; } - - for (tok_t *t = toks; t->typ != EOF; ++t) switch (t->typ) { - case RGT: { ptr += t->num; break; } - case LFT: { ptr -= t->num; break; } - case ADD: { *ptr += t->num; break; } - case SUB: { *ptr -= t->num; break; } - case PUT: { fputc(*ptr, stdout); break; } - case GET: { *ptr = fgetc(stdin); break; } - case OPN: { - if (!*ptr) { for (size_t i = 1; i != 0; ++t) { - if ((t + 1)->typ == OPN) { ++i; } - else if ((t + 1)->typ == CLS) { --i; } - } break; } - - if (top == cap) { - tok_t **old = dat; cap *= 2; dat = realloc(dat, cap); - if (!dat) { free(old); return 1; } - } dat[top++] = t; break; - } - case CLS: { if (*ptr) { t = dat[top - 1]; } else { --top; } break; } - } - - free(dat); return 0; -} - -static void help(void) { - puts("obfi - interpret brainfuck source file\n"); - puts("usage: obfi file\n"); - puts("options:"); - puts(" --help Display help information"); - puts(" --version Display version information"); - return; -} - -static void version(void) { - puts("OMKOV Brainfuck Interpreter, version " VERSION); - puts("Copyright (C) 2020, Jakob Wakeling"); - puts("All rights reserved."); - puts("OMKOV Permissive Licence (https://www.omkov.net/OLPE)"); - return; -} diff --git a/src/obfi.c b/src/obfi.c new file mode 100644 index 0000000..7574d77 --- /dev/null +++ b/src/obfi.c @@ -0,0 +1,148 @@ +// obfi.c +// Main source file for OBFI +// Copyright (C) 2020, Jakob Wakeling +// All rights reserved. + +/* +OMKOV Permissive Licence, version 1.0 + +Copyright (C) 2020, Jakob Wakeling +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimers. +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimers in the documentation and/or + other materials provided with the distribution. +* Neither the names of the copyright holders, nor the names of its contributors + may be used to endorse or promote products derived from this Software without + specific prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT +HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. +*/ + +#include "error.h" + +#include <errno.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define TAPELEN 30000 + +static inline int cmp(const char *s1, const char *s2); +static inline int run(const char *b, const long *c); + +int main(int ac, char *av[]) { + if (ac == 1) { error(1, "%s: missing operand", av[0]); } + + FILE *fi = fopen(av[1], "r"); + if (!fi) { error(1, "%s: %s: %s", av[0], av[1], serrno); } + + fseek(fi, 0, SEEK_END); size_t fl = ftell(fi); rewind(fi); + + char *fb = malloc(fl + 1 * sizeof (*fb)); fb[fl] = 0; + if (!fb) { error(1, "%s: %s", av[0], serrno); } + + long *fc = malloc(fl * sizeof (*fc)); + if (!fc) { error(1, "%s: %s", av[0], serrno); } + + fread(fb, 1, fl, fi); fclose(fi); + + char *p = fb, *q = fb; + for (; *p; ++p) if (strchr("><+-.,[]", *p)) { *q++ = *p; } *q = 0; + + register size_t i, j; + for (i = 0; fb[i]; ++i) { + switch (fb[i]) { + case '<': case '-': { fc[i] = -1; break; } + default: { fc[i] = 1; break; } + } + switch (fb[i]) { + case '>': case '<': { fb[i] = '>'; break; } + case '+': case '-': { fb[i] = '+'; break; } + } + } + + for (i = 0, j = 0; fb[i]; ++j) { + fb[j] = fb[i]; fc[j] = fc[i]; + if (strchr(">+", fb[++i])) for (; fb[j] == fb[i]; fc[j] += fc[i++]); + } fb[j] = 0; + + for (i = 0; fb[i]; ++i) { + if (cmp(fb + i, "[+]")) { fb[i] = 'Z'; fb[i + 1] = fb[i + 2] = ' '; } + else if (cmp(fb + i, "[>]")) { + fb[i] = 'T'; fb[i + 1] = fb[i + 2] = ' '; fc[i] = fc[i + 1]; + } + else if (cmp(fb + i, "[+>+>]") && fc[i + 1] == -1 && fc[i + 3] == 1 && + fc[i + 2] == -fc[i + 4]) { + fb[i] = 'M'; + fb[i + 1] = fb[i + 2] = fb[i + 3] = fb[i + 4] = fb[i + 5] = ' '; + fc[i] = fc[i + 2]; + } + else if (cmp(fb + i, "[>+>+]") && fc[i + 4] == -1 && fc[i + 2] == 1 && + fc[i + 1] == -fc[i + 3]) { + fb[i] = 'M'; + fb[i + 1] = fb[i + 2] = fb[i + 3] = fb[i + 4] = fb[i + 5] = ' '; + fc[i] = fc[i + 1]; + } + } + + for (i = 0, j = 0; fb[i]; ++i) if (fb[i] != ' ') { + fb[j] = fb[i]; fc[j] = fc[i]; ++j; + } fb[j] = 0; + + for (i = 0; fb[i]; ++i) { + for (j = 0; fb[i] != ">+.,[]ZTM"[j]; ++j) {} fb[i] = j + 1; + } + + size_t l = 1024, t = 0, *S = malloc(l * sizeof (*S)); + if (!S) { error(1, "%s: %s", av[0], serrno); } + + for (size_t i = 0; fb[i]; ++i) switch (fb[i]) { + case 5: { S[t++] = i; break; } + case 6: { --t; fc[S[t]] = i - S[t]; fc[i] = S[t] - i; break; } + } + + if (run(fb, fc)) { error(1, "%s: %s", av[0], serrno); } + + free(S); free(fb); free(fc); return 0; +} + +static inline int cmp(const char *s1, const char *s2) { + size_t i = 0; for (; s2[i] && s1[i] == s2[i]; ++i) {} return !s2[i]; +} + +static inline int run(const char *fb, const long *fc) { + uint_fast8_t *M = calloc(TAPELEN, sizeof (*M)), *p = M; + if (!M) { return 1; } + + for (size_t i = 0; fb[i]; ++i) switch (fb[i]) { + case 1: { p += fc[i]; break; } + case 2: { *p += fc[i]; break; } + case 3: { fputc(*p, stdout); break; } + case 4: { *p = fgetc(stdin); break; } + case 5: { i += !*p ? fc[i] : 0; break; } + case 6: { i += *p ? fc[i] : 0; break; } + case 7: { *p = 0; break; } + case 8: { for (; *p; p += fc[i]) {} break; } + case 9: { *(p + fc[i]) += *p; *p = 0; break; } + } + + free(M); return 0; +} diff --git a/src/parse.c b/src/parse.c deleted file mode 100644 index 4a0b3d0..0000000 --- a/src/parse.c +++ /dev/null @@ -1,76 +0,0 @@ -// parse.c -// Parser source file for OBFI -// Copyright (C) 2020, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Copyright (C) 2020, Jakob Wakeling -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#include "parse.h" - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define TOKSET(type) tok.typ = type; tok.ln = line; tok.cl = col - -static inline tok_t lex(char *str) { - static char *p; static size_t line, col; tok_t tok; - if (str) { p = str; line = 0; col = 0; } tok.num = 1; - - for (; *p; ++p) switch (*p) { - case '>': { TOKSET(RGT); goto count; } - case '<': { TOKSET(LFT); goto count; } - case '+': { TOKSET(ADD); goto count; } - case '-': { TOKSET(SUB); goto count; } - case '.': { TOKSET(PUT); ++p; ++col; return tok; } - case ',': { TOKSET(GET); ++p; ++col; return tok; } - case '[': { TOKSET(OPN); ++p; ++col; return tok; } - case ']': { TOKSET(CLS); ++p; ++col; return tok; } - case '\n': { ++line; col = 0; continue; } - count: { - for (register char c = *p++; *p == c; ++p) { ++tok.num; } - col += tok.num; return tok; - } - } - - tok.typ = END; return tok; -} - -tok_t *parse(char *str, size_t len) { - tok_t *toks = malloc(sizeof (*toks) * len); - if (!toks) { return NULL; } - - register tok_t *p = toks; - *p = lex(str); while (p->typ != END) { *++p = lex(NULL); } - - return toks; -} diff --git a/src/parse.h b/src/parse.h deleted file mode 100644 index 453a6fe..0000000 --- a/src/parse.h +++ /dev/null @@ -1,58 +0,0 @@ -// parse.h -// Parser header file for OBFI -// Copyright (C) 2020, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Copyright (C) 2020, Jakob Wakeling -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#ifndef OMKOV_OBFI_PARSE_H_AD07BU3C -#define OMKOV_OBFI_PARSE_H_AD07BU3C - -#include <stddef.h> -#include <stdio.h> - -enum { - END = EOF, // EOF - RGT = 1, // '>' - LFT = 2, // '<' - ADD = 3, // '+' - SUB = 4, // '-' - PUT = 5, // '.' - GET = 6, // ',' - OPN = 7, // '[' - CLS = 8, // ']' -}; - -typedef struct { int typ; size_t num, ln, cl; } tok_t; - -extern tok_t *parse(char *str, size_t len); - -#endif // OMKOV_OBFI_PARSE_H_AD07BU3C