Files
moxa/_gi_c/gi.c
Sebastien Binet 476a31322d Go get ellipsis (#1)
* gi: rename gi_c into _gi_c

* gi: rename test into _test

* gi: fix README syntax
2018-06-26 10:17:01 +02:00

136 lines
3.4 KiB
C

/* a go interpreter */
#define VERSION "gi-c-0.1"
static const char man_txt[] =
"NAME\n"
" gi - go interpreter\n"
"SYNOPSIS\n"
" gi [-acnsVx] [-A ast_file] [-C cfg_file] [--] [script_file [args ...]]\n"
"DESCRIPTION\n"
" gi is an interpreter that executes commands read from a file or the\n"
" standard input.\n"
"OPTIONS\n"
" -A ast_file \n"
" Write the abstract syntax tree in dot(1) format to ast_file or\n"
" standard output if ast_file is -\n"
" -a Display AST graph using dotty(1)\n"
" -C cfg_file \n"
" Write the control flow graph in dot(1) format to cfg_file or\n"
" standard output if cfg_file is -\n"
" -c Display CFG graph using dotty(1)\n"
" -n Compile only, do not run\n"
" -x Generate and execute machine code using a JIT compiler\n"
" -v Trace each instruction during execution\n"
" -V Print interpreter version and exit\n"
"BIP LANGUAGE\n"
" Commands are read in terms of lines of words separated by whitespaces\n"
" (blanks or tabs) and certain sequences of characters called ``operators''.\n"
" commands may also be separated by ';' or grouped between braces into a\n"
" list\n"
" OPERATORS\n"
" Bip uses the usual infix notation for operators (example: c = a + b).\n"
" Precedence rules identical to C are applied. Parenthesis are used to\n"
" group expression and make precedence explicit.\n"
" + - * / % \n"
" Arithmetic: addition, substraction, multiplication, division\n"
" and modulo.\n"
" < <= > >= == != \n"
" Comparison: lower, lower or equal, greater, greater or equal,\n"
" equal, not equal.\n"
" ! && || \n"
" Logical: not, and, or.\n"
" = Assignement.\n"
" << >> & | \n"
" Binary: left shift, right shift, boolean and, boolean or.\n"
" FLOW CONTROL\n"
" if cond list1 [else list0] \n"
" the cond is executed and if it returns a non zero value, list1\n"
" is executed. Otherwise, if defined, list0 is executed.\n"
" while cond list \n"
" cond and list are repeatedly executed while cond returns non zero.\n"
"AUTHORS\n"
" MV\n"
;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "init_go.h"
#include "trace.h"
#define MSIZE 4096
int source_stream(bip_t *ip, FILE *fd)
{
int len = 0, max = 0;
char *src = NULL;
while (len == max) { /* Grow src buffer until everything is read */
max += MSIZE;
src = (char *)realloc(src, max);
len += fread(src + len, 1, MSIZE, fd);
}
src[len] = 0;
eval_str(ip, NULL, src, len);
printf("%s", ip->out);
ip->out[0] = 0;
free(src);
return len;
}
int main(int argc, char *argv[], char *env[])
{
int opt;
bip_t *ip = bip_init(0);
FILE *fd;
while ((opt = getopt(argc, argv, "A:aC:chnpVvx")) != -1) {
switch (opt) {
case 'A':
ip->fd_ast = strcmp(optarg, "-") ?
fopen(optarg, "w") : stdout;
break;
case 'a':
ip->opt.a = 1;
break;
case 'C':
ip->fd_cfg = strcmp(optarg, "-") ?
fopen(optarg, "w") : stdout;
break;
case 'c':
ip->opt.c = 1;
break;
case 'h':
printf("%s", man_txt);
exit(0);
case 'n':
ip->opt.n = 1;
break;
case 'p':
ip->opt.p = 1;
break;
case 'v':
ip->opt.v = 1;
break;
case 'V':
printf("%s\n", VERSION);
exit(0);
case 'x':
ip->opt.x = 1;
break;
default:
fprintf(stderr, "Usage: b1 [-acnVvx] [-A astname] "
"[-C fgname] [file]\n");
exit(1);
}
}
fd = ((argc - optind) > 0) ? fopen(argv[optind], "r") : stdin;
if (fd == NULL)
return 1;
while (source_stream(ip, fd));
return 0;
}