Ejemplo n.º 1
0
void print_h_code (bool header)
{
  int i;

  if (header)
    printf ("extern ");
  printf ("const g4_bits g4_h_code [2] [64]");
  if (header)
    {
      printf (";\n");
      return;
    }
  printf (" =\n");
  printf ("  {\n");
  printf ("    {\n");
  printf ("      /* white */\n");
  for (i = 0; i <= 63; i++)
    emit_code (6, h_code [i][0], i == 63, 1, i);
  printf ("    },\n");
  printf ("    {\n");
  printf ("      /* black */\n");
  for (i = 0; i <= 63; i++)
    emit_code (6, h_code [i][1], i == 63, 1, i);
  printf ("    }\n");
  printf ("  };\n");
}
Ejemplo n.º 2
0
void print_makeup_code (bool header)
{
  int i;

  if (header)
    printf ("extern ");
  printf ("const g4_bits g4_makeup_code [2] [27]");
  if (header)
    {
      printf (";\n");
      return;
    }
  printf (" =\n");
  printf ("  {\n");
  printf ("    {\n");
  printf ("      /* white */\n");
  for (i = 0; i <= 26; i++)
    emit_code (6, makeup_code [i][0], i == 26, 1, (i + 1) * 64);
  printf ("    },\n");
  printf ("    {\n");
  printf ("      /* black */\n");
  for (i = 0; i <= 26; i++)
    emit_code (6, makeup_code [i][1], i == 26, 1, (i + 1) * 64);
  printf ("    }\n");
  printf ("  };\n");
}
Ejemplo n.º 3
0
int main(int argc, char *argv[]) {
  char out_filename[256];

  if (argc >= 2) {
    make_out_filename(out_filename, argv[1]);
    freopen(argv[1], "r", stdin);
    freopen(out_filename, "w", stdout);
  }

  puts("#include <stdio.h>");
  puts("#include <stdlib.h>");
  puts("#include <string.h>\n");

  puts("typedef unsigned char byte;");
  puts("static byte *ptr_start, *ptr_end, *ptr;\n");

  puts("#define MEM_SIZE   ( 32768 )");
  puts("#ifdef NOCHECK");
  puts("#define CHK(p)     ( p )");
  puts("#else");
  puts("#define CHK(p)     ( chk(p) )");
  puts("static void chk(byte *p){");
  puts("  if(p<ptr_start||ptr_end<=p){");
  puts("    fprintf(stderr,\"Error: Memory Out Of Bounds.\\n\");");
  puts("    exit(1);");
  puts("  }");
  puts("}");
  puts("#endif\n");

  puts("int main(int argc, char *argv[]){");
  puts("  int i=1,mem_size=MEM_SIZE;");
  puts("  for (; i < argc;){");
  puts("    if (strcmp(argv[i], \"-m\") == 0){");
  puts("      i++;");
  puts("      if (i < argc) mem_size=atoi(argv[i++]);");
  puts("    } else i++;");
  puts("  }");
  puts("  if (mem_size<1) mem_size=1;");
  puts("  ptr_start=(byte *)calloc(mem_size, 1);");
  puts("  ptr_end=ptr_start+mem_size;");
  puts("  ptr=ptr_start;");
  puts("/* -- translated code -- */");
  emit_code();
  while (g_indent_level > 0) {
    print_code("break;");
    --g_indent_level;
    print_code("}");
    fprintf(stderr, "Warning: Incorrect Nesting.\n");
  }
  puts("/* -- end -- */");
  puts("  putchar('\\n');");
  puts("  free(ptr_start);");
  puts("  return 0;");
  puts("}\n");
  return 0;
}
Ejemplo n.º 4
0
int main(int argc, char * argv[])
{
    char * opt = argc > 1 ? argv[1] : NULL;
    make_primes();
    make_ff();
    if (!opt)
        emit_code(0);
    else if (!strcmp(opt, "h") || !strcmp(opt, ".h") || !strcmp(opt, "-h"))
        emit_code(1);
    else if (!strcmp(opt, "c") || !strcmp(opt, ".c") || !strcmp(opt, "-c"))
        emit_code(0);
    else {
        fprintf(stderr, "Usage: ffgen [-h|-c]\n");
        fprintf(stderr, "  -h for header file\n");
        fprintf(stderr, "  -c for C source file\n");
        return 1;
    }
    return 0;
}
Ejemplo n.º 5
0
Archivo: poxc.c Proyecto: cjxgm/PoshX
/**
 * Read text from fp and generate grammer tree
 **
 * @param	fp: File pointer to the input file stream
 */
inline void poxc_parse(FILE * fp)
{
	poxc_lex(fp);
	for (;;){
		if (lex_finished) break;

#ifdef __DEBUG__
		if (tk_type == TYPE_KEY)
			debug("LEX[%d]\t%s", tk_type, tk_text);
		else if (tk_type == TYPE_LABEL)
			debug("LEX[%d]\t(LABEL)*%d", tk_type, tk_value);
		else if (tk_type == TYPE_VALUE)
			debug("LEX[%d]\t(VALUE)*%d", tk_type, tk_value);
		else
			debug("LEX[%d]\t(VAR)*%d", tk_type, tk_value);
#endif

		// Instruction
		if (tk_type == TYPE_KEY){
			// Save old STRING
			char * tt = tk_text;

			// Get parameter
			poxc_lex(fp);

			if (strcmp(tt, "label") == 0) {
				// Label definition...
				if (tk_type == TYPE_LABEL){
					symtab_set_label(tk_value, current_code);
					poxc_lex(fp);
				}
				else throw(ERR_UNEXPECTED_V);
			}
			else {
				// ...or normal code
				emit_code(tt);
				if (tk_type != TYPE_KEY) poxc_lex(fp);
			}
			free(tt);
		}

		// Unknow?
		else throw(ERR_UNEXPECTED_V);
	}
}
Ejemplo n.º 6
0
void print_long_makeup_code (bool header)
{
  int i;

  if (header)
    printf ("extern ");
  printf ("const g4_bits g4_long_makeup_code [12]");
  if (header)
    {
      printf (";\n");
      return;
    }
  printf (" =\n");
  printf ("  {\n");
  for (i = 0; i < 12; i++)
    emit_code (4, long_makeup_code [i], i == 11, 1, i * 64 + 1792);
  printf ("  };\n");
}
Ejemplo n.º 7
0
void print_v_code (bool header)
{
  int i;

  if (header)
    printf ("extern ");
  printf ("const g4_bits g4_vert_code [7]");
  if (header)
    {
      printf (";\n");
      return;
    }
  printf ("=\n");
  printf ("  {\n");
  for (i = 0; i <= 6; i++)
    emit_code (4, v_code [i], i == 6, 1, i - 3);
  printf ("  };\n");
}
Ejemplo n.º 8
0
/* Generate C source code for the parser */
void ReportTable(struct lmno *lmnop, int mhflag)
{
	FILE *out, *in;
	char line[LINESIZE];
	int  lineno;
	struct state *stp;
	struct action *ap;
	struct rule *rp;
	struct acttab *pActtab;
	int i, j, n;
	int mnTknOfst, mxTknOfst;
	int mnNtOfst, mxNtOfst;
	struct axset *ax;

	// open input template and target output file and advance to first insertion
	in = tplt_open(lmnop);
	if(in == 0)
		return;
	out = (lmnop->export_c ?
			file_open(lmnop,".c","w") :
			file_open(lmnop,".cpp","w") );
	if(out == 0)
	{
		fclose(in);
		return;
	}
	lineno = 1;
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	// insert user's copyright and license information.
	copyright_print(out, lmnop, &lineno);
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate the action table and its associates:
	 **
	 **  yy_action[]		A single table containing all actions.
	 **  yy_lookahead[]	 A table containing the lookahead for each entry in
	 **					 yy_action.  Used to detect hash collisions.
	 **  yy_shift_ofst[]	For each state, the offset into yy_action for
	 **					 shifting terminals.
	 **  yy_reduce_ofst[]   For each state, the offset into yy_action for
	 **					 shifting non-terminals after a reduce.
	 **  yy_default[]	   Default action for each state.
	 */
	
	/* Compute the actions on all states and count them up */
	ax = malloc(sizeof(ax[0])*lmnop->nstate*2);
	if(ax==0)
	{
		fprintf(stderr,"malloc failed\n");
		exit(1);
	}
	for(i=0; i<lmnop->nstate; i++)
	{
		stp = lmnop->sorted[i];
		stp->nTknAct = stp->nNtAct = 0;
		stp->iDflt = lmnop->nstate + lmnop->nrule;
		stp->iTknOfst = NO_OFFSET;
		stp->iNtOfst = NO_OFFSET;
		for(ap=stp->ap; ap; ap=ap->next)
		{
			if(compute_action(lmnop,ap)>=0)
			{
				if(ap->sp->index<lmnop->nterminal)
				{
					stp->nTknAct++;
				}
				else if(ap->sp->index<lmnop->nsymbol)
				{
					stp->nNtAct++;
				}
				else
				{
					stp->iDflt = compute_action(lmnop, ap);
				}
			}
		}
		ax[i*2].stp = stp;
		ax[i*2].isTkn = 1;
		ax[i*2].nAction = stp->nTknAct;
		ax[i*2+1].stp = stp;
		ax[i*2+1].isTkn = 0;
		ax[i*2+1].nAction = stp->nNtAct;
	}
	mxTknOfst = mnTknOfst = 0;
	mxNtOfst = mnNtOfst = 0;
	
	/* Compute the action table.  In order to try to keep the size of the
	 ** action table to a minimum, the heuristic of placing the largest action
	 ** sets first is used.
	 */
	qsort(ax, lmnop->nstate*2, sizeof(ax[0]), axset_compare);
	pActtab = acttab_alloc();
	for(i=0; i<lmnop->nstate*2 && ax[i].nAction>0; i++)
	{
		stp = ax[i].stp;
		if(ax[i].isTkn)
		{
			for(ap=stp->ap; ap; ap=ap->next)
			{
				int action;
				if(ap->sp->index>=lmnop->nterminal)
					continue;
				action = compute_action(lmnop, ap);
				if(action<0)
					continue;
				acttab_action(pActtab, ap->sp->index, action);
			}
			stp->iTknOfst = acttab_insert(pActtab);
			if(stp->iTknOfst<mnTknOfst)
				mnTknOfst = stp->iTknOfst;
			if(stp->iTknOfst>mxTknOfst)
				mxTknOfst = stp->iTknOfst;
		}
		else
		{
			for(ap=stp->ap; ap; ap=ap->next)
			{
				int action;
				if(ap->sp->index<lmnop->nterminal)
					continue;
				if(ap->sp->index==lmnop->nsymbol)
					continue;
				action = compute_action(lmnop, ap);
				if(action<0)
					continue;
				acttab_action(pActtab, ap->sp->index, action);
			}
			stp->iNtOfst = acttab_insert(pActtab);
			if(stp->iNtOfst<mnNtOfst)
				mnNtOfst = stp->iNtOfst;
			if(stp->iNtOfst>mxNtOfst)
				mxNtOfst = stp->iNtOfst;
		}
	}
	free(ax);
	
	/* Output the yy_action table */
	fprintf(out,"static YYACTIONTYPE yy_action[] = {\n");
	lineno++;
	n = acttab_size(pActtab);
	for(i=j=0; i<n; i++)
	{
		int action = acttab_yyaction(pActtab, i);
		if(action<0)
			action = lmnop->nsymbol + lmnop->nrule + 2;
		if(j==0)
			fprintf(out," /* %5d */ ", i);
		fprintf(out, " %4d,", action);
		if(j==9 || i==n-1)
		{
			fprintf(out, "\n");
			lineno++;
			j = 0;
		}
		else
		{
			j++;
		}
	}
	fprintf(out, "};\n"); lineno++;
	
	/* Output the yy_lookahead table */
	fprintf(out,"static YYCODETYPE yy_lookahead[] = {\n");
	lineno++;
	for(i=j=0; i<n; i++)
	{
		int la = acttab_yylookahead(pActtab, i);
		if(la<0)
			la = lmnop->nsymbol;
		if(j==0)
			fprintf(out," /* %5d */ ", i);
		fprintf(out, " %4d,", la);
		if(j==9 || i==n-1)
		{
			fprintf(out, "\n");
			lineno++;
			j = 0;
		}
		else
		{
			j++;
		}
	}
	fprintf(out, "};\n");
	lineno++;
	
	/* Output the yy_shift_ofst[] table */
	fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1);
	lineno++;
	fprintf(out, "static %s yy_shift_ofst[] = {\n", 
			minimum_size_type(mnTknOfst-1, mxTknOfst));
	lineno++;
	n = lmnop->nstate;
	for(i=j=0; i<n; i++)
	{
		int ofst;
		stp = lmnop->sorted[i];
		ofst = stp->iTknOfst;
		if(ofst==NO_OFFSET)
			ofst = mnTknOfst - 1;
		if(j==0)
			fprintf(out," /* %5d */ ", i);
		fprintf(out, " %4d,", ofst);
		if(j==9 || i==n-1)
		{
			fprintf(out, "\n");
			lineno++;
			j = 0;
		}
		else
		{
			j++;
		}
	}
	fprintf(out, "};\n"); lineno++;
	
	/* Output the yy_reduce_ofst[] table */
	fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1);
	lineno++;
	fprintf(out, "static %s yy_reduce_ofst[] = {\n", 
			minimum_size_type(mnNtOfst-1, mxNtOfst));
	lineno++;
	n = lmnop->nstate;
	for(i=j=0; i<n; i++)
	{
		int ofst;
		stp = lmnop->sorted[i];
		ofst = stp->iNtOfst;
		if(ofst==NO_OFFSET)
			ofst = mnNtOfst - 1;
		if(j==0)
			fprintf(out," /* %5d */ ", i);
		fprintf(out, " %4d,", ofst);
		if(j==9 || i==n-1)
		{
			fprintf(out, "\n");
			lineno++;
			j = 0;
		}
		else
		{
			j++;
		}
	}
	fprintf(out, "};\n"); lineno++;
	
	/* Output the default action table */
	fprintf(out, "static YYACTIONTYPE yy_default[] = {\n");
	lineno++;
	n = lmnop->nstate;
	for(i=j=0; i<n; i++)
	{
		stp = lmnop->sorted[i];
		if(j==0)
			fprintf(out," /* %5d */ ", i);
		fprintf(out, " %4d,", stp->iDflt);
		if(j==9 || i==n-1)
		{
			fprintf(out, "\n");
			lineno++;
			j = 0;
		}
		else
		{
			j++;
		}
	}
	fprintf(out, "};\n");
	lineno++;
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate the table of fallback tokens.
	 */
	if(lmnop->has_fallback)
	{
		for(i=0; i<lmnop->nterminal; i++)
		{
			struct symbol *p = lmnop->symbols[i];
			if(p->fallback==0)
			{
				fprintf(out, "	0,  /* %10s => nothing */\n", p->name);
			}
			else
			{
				fprintf(out, "  %3d,  /* %10s => %s */\n", p->fallback->index,
						p->name, p->fallback->name);
			}
			lineno++;
		}
	}
	tplt_xfer(lmnop->name, in, out, &lineno);
	
	/* Generate a table containing the symbolic name of every symbol
	 */
	for(i=0; i<lmnop->nsymbol; i++)
	{
		sprintf(line,"\"%s\",",lmnop->symbols[i]->name);
		fprintf(out,"  %-15s",line);
		if((i&3)==3)
		{
			fprintf(out,"\n");
			lineno++;
		}
	}
	if((i&3)!=0)
	{
		fprintf(out,"\n");
		lineno++;
	}
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate a table containing a text string that describes every
	 ** rule in the rule set of the grammer.  This information is used
	 ** when tracing REDUCE actions.
	 */
	for(i=0, rp=lmnop->rule; rp; rp=rp->next, i++)
	{
		assert(rp->index==i);
		fprintf(out," /* %3d */ \"%s ->", i, rp->lhs->name);
		for(j=0; j<rp->nrhs; j++)
			fprintf(out," %s",rp->rhs[j]->name);
		fprintf(out,"\",\n");
		lineno++;
	}
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate code which executes every time a symbol is popped from
	 ** the stack while processing errors or while destroying the parser. 
	 ** (In other words, generate the %destructor actions)
	 */
	if(lmnop->tokendest)
	{
		for(i=0; i<lmnop->nsymbol; i++)
		{
			struct symbol *sp = lmnop->symbols[i];
			if(sp==0 || sp->type!=TERMINAL) continue;
			fprintf(out,"	case %d:\n",sp->index);
			lineno++;
		}
		for(i=0; i<lmnop->nsymbol && lmnop->symbols[i]->type!=TERMINAL; i++) { }
		if(i<lmnop->nsymbol)
		{
			emit_destructor_code(out,lmnop->symbols[i],lmnop,&lineno);
			fprintf(out,"	  break;\n");
			lineno++;
		}
	}
	for(i=0; i<lmnop->nsymbol; i++)
	{
		struct symbol *sp = lmnop->symbols[i];
		if(sp==0 || sp->type==TERMINAL || sp->destructor==0)
			continue;
		fprintf(out,"	case %d:\n",sp->index);
		lineno++;
		
		/* Combine duplicate destructors into a single case */
		for(j=i+1; j<lmnop->nsymbol; j++)
		{
			struct symbol *sp2 = lmnop->symbols[j];
			if(sp2 && sp2->type!=TERMINAL && sp2->destructor &&
				sp2->dtnum==sp->dtnum &&
				strcmp(sp->destructor,sp2->destructor)==0)
			{
				fprintf(out,"	case %d:\n",sp2->index);
				lineno++;
				sp2->destructor = 0;
			}
		}
		
		emit_destructor_code(out,lmnop->symbols[i],lmnop,&lineno);
		fprintf(out,"	  break;\n");
		lineno++;
	}
	if(lmnop->vardest)
	{
		struct symbol *dflt_sp = 0;
		for(i=0; i<lmnop->nsymbol; i++)
		{
			struct symbol *sp = lmnop->symbols[i];
			if(sp==0 || sp->type==TERMINAL ||
				sp->index<=0 || sp->destructor!=0)
				continue;
			fprintf(out,"	case %d:\n",sp->index);
			lineno++;
			dflt_sp = sp;
		}
		if(dflt_sp!=0)
		{
			emit_destructor_code(out,dflt_sp,lmnop,&lineno);
			fprintf(out,"	  break;\n");
			lineno++;
		}
	}
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate code which executes whenever the parser stack overflows */
	if(lmnop->export_c)
	{
		tplt_print(out,lmnop,lmnop->overflow,lmnop->overflowln,&lineno);
		tplt_xfer(lmnop->name,in,out,&lineno);
	}
	
	/* Generate the table of rule information 
	 **
	 ** Note: This code depends on the fact that rules are number
	 ** sequentually beginning with 0.
	 */
	for(rp=lmnop->rule; rp; rp=rp->next)
	{
		fprintf(out,"  { %d, %d },\n",rp->lhs->index,rp->nrhs);
		lineno++;
	}
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate code which execution during each REDUCE action */
	for(rp=lmnop->rule; rp; rp=rp->next)
	{
		if(rp->code)
			translate_code(lmnop, rp);
	}
	for(rp=lmnop->rule; rp; rp=rp->next)
	{
		struct rule *rp2;
		if(rp->code==0)
			continue;
		fprintf(out,"	  case %d:\n",rp->index);
		lineno++;
		for(rp2=rp->next; rp2; rp2=rp2->next)
		{
			if(rp2->code==rp->code)
			{
				fprintf(out,"	  case %d:\n",rp2->index);
				lineno++;
				rp2->code = 0;
			}
		}
		emit_code(out,rp,lmnop,&lineno);
		fprintf(out,"		break;\n");
		lineno++;
	}
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate code which executes if a parse fails */
	tplt_print(out,lmnop,lmnop->failure,lmnop->failureln,&lineno);
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate code which executes when a syntax error occurs */
	tplt_print(out,lmnop,lmnop->error,lmnop->errorln,&lineno);
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Generate code which executes when the parser accepts its input */
	tplt_print(out,lmnop,lmnop->accept,lmnop->acceptln,&lineno);
	tplt_xfer(lmnop->name,in,out,&lineno);
	
	/* Append any addition code the user desires */
	tplt_print(out,lmnop,lmnop->extracode,lmnop->extracodeln,&lineno);
	
	fclose(in);
	fclose(out);
	return;
}
Ejemplo n.º 9
0
Archivo: bf.c Proyecto: blin00/bf
int main(int argc, char* argv[]) {
    // deal with args
    if (argc < 2) {
        print_usage();
        return 1;
    }
    int c;
    unsigned char ch;
    bool onlyPrint = false, verbose = false;
    opterr = 0;
    while ((c = getopt(argc, argv, ":e:t:" BOUNDS_ARGS "hpv")) != -1) {
        ch = (unsigned char) c;
        if (c == 'e') {
            onEof = EOF_VALUE;
            eofValue = (unsigned char) atoi(optarg);
        } else if (c == 't') {
            int len = atoi(optarg);
            if (len <= 0) {
                fprintf(stderr, "err: tape size must be positive integer\n");
                return 1;
            }
            tapeLength = (size_t) len;
#ifndef NO_CHECK_BOUNDS
        } else if (c == 'b') {
            check = true;
        } else if (c == 'c') {
            check = circular = true;
            if (infinite) {
                fprintf(stderr, "err: options 'c', 'f' mutually exclusive\n");
                return 1;
            }
        } else if (c == 'f') {
            check = infinite = true;
            if (circular) {
                fprintf(stderr, "err: options 'c', 'f' mutually exclusive\n");
                return 1;
            }
#endif
        } else if (c == 'h') {
            print_usage();
            return 0;
        } else if (c == 'p') {
            onlyPrint = true;
        } else if (c == 'v') {
            verbose = true;
        } else if (c == '?') {
            fprintf(stderr, "err: unknown option '%c'\n", optopt);
            return 1;
        } else if (c == ':') {
            fprintf(stderr, "err: option '%c' requires argument\n", optopt);
            return 1;
        }
    }
    if (optind >= argc) {
        fprintf(stderr, "err: no file provided\n");
        return 1;
    }
    // read entire file
    FILE* f = fopen(argv[optind], "r");
    if (!f) {
        fprintf(stderr, "err: unable to open file '%s'\n", argv[1]);
        return 1;
    }
    size_t i, length = 0, maxLength = 1024, depth = 0, maxDepth = 1, line = 1, col = 0;
    unsigned char* code = malloc(maxLength * sizeof(char));
    if (!code) {
        fprintf(stderr, "err: failed to allocate file read buffer\n");
        fclose(f);
        return 1;
    }
    while ((c = fgetc(f)) != EOF) {
        ch = (unsigned char) c;
        if (ch == '\n') {
            line++;
            col = 0;
        }
        col++;
        if (ch != '+' && ch != '-' && ch != '<' && ch != '>' && ch != '[' && ch != ']' && ch != '.' && ch != ',')
            continue;
        if (ch == '[') {
            depth++;
            if (depth > maxDepth) {
                // overestimate of loop depth b/c later optimizations, should be good enough
                maxDepth = depth;
            }
        } else if (ch == ']') {
            if (depth == 0) {
                fprintf(stderr, "err: closing bracket with no opening bracket at line %zu col %zu\n", line, col);
                fclose(f);
                free(code);
                return 1;
            }
            depth--;
        }
        length++;
        if (length > maxLength) {
            maxLength *= 2;
            unsigned char* newCode = realloc(code, maxLength * sizeof(char));
            if (!newCode) {
                fprintf(stderr, "err: failed to allocate file read buffer\n");
                fclose(f);
                free(code);
                return 1;
            }
            code = newCode;
        }
        code[length - 1] = ch;
    }
    fclose(f);
    if (depth != 0) {
        fprintf(stderr, "err: opening bracket with no closing bracket (need %zu at end)\n", depth);
        free(code);
        return 1;
    }
    if (verbose) fprintf(stderr, "read %zu bf instructions\n", length);
    // convert bf into optimized bytecode-like structure
    size_t instrCt;
    // true only if cell currently pointed to during execution must be zero (program start, end of loop)
    bool definiteZero = true;
    unsigned char deltaInc;
    int deltaShift;
    i = instrCt = depth = deltaInc = deltaShift = 0;
    size_t *stk = malloc(maxDepth * sizeof(size_t));
    if (!stk) {
        fprintf(stderr, "err: failed to allocate stack\n");
        free(code);
        return 1;
    }
    // quite a bit more memory that we will probably end up using...
    // can't easily realloc later without moving ptrs around
    Code* bytecode = calloc(length + 1, sizeof(Code));
    if (!bytecode) {
        fprintf(stderr, "err: failed to allocate bytecode\n");
        free(code);
        free(stk);
        return 1;
    }
    bf_func bf_getc = onEof == EOF_UNCHANGED ? bf_getc_unc : bf_getc_val;
    while (i < length) {
        ch = code[i];
        // optimize simple loops that set cell to 0 ([-], [+])
        if (!definiteZero && i < length - 2 && ch == '[' && (code[i + 1] == '+' || code[i + 1] == '-') && code[i + 2] == ']') {
            // definiteZero == true case handled below along with other loops
            if (deltaShift) {
                emit_code(&bytecode[instrCt], deltaInc, deltaShift);
                deltaInc = deltaShift = 0;
                instrCt++;
            }
            deltaInc = 0;
            bytecode[instrCt].func = bf_zero;
            i += 2;
            instrCt++;
            definiteZero = true;
        } else if (ch == '<') {
            deltaShift--;
            definiteZero = false;
        } else if (ch == '>') {
            deltaShift++;
            definiteZero = false;
        } else if (ch == '-') {
            if (deltaShift) {
                emit_code(&bytecode[instrCt], deltaInc, deltaShift);
                deltaInc = deltaShift = 0;
                instrCt++;
            }
            deltaInc--;
            definiteZero = false;
        } else if (ch == '+') {
            if (deltaShift) {
                emit_code(&bytecode[instrCt], deltaInc, deltaShift);
                deltaInc = deltaShift = 0;
                instrCt++;
            }
            deltaInc++;
            definiteZero = false;
        } else if (ch == '[') {
            bool emitted = false;
            if (deltaInc || deltaShift) {
                emit_code(&bytecode[instrCt], deltaInc, deltaShift);
                deltaInc = deltaShift = 0;
                //instrCt++;    // don't increment instrction count yet
                definiteZero = false;
                emitted = true;
            }
            // prune dead code
            if (definiteZero) {
                size_t currentDepth = depth;
                depth++;
                while (depth > currentDepth) {
                    i++;
                    if (code[i] == '[') depth++;
                    else if (code[i] == ']') depth--;
                    // i now pts to closing bracket, but incremented again at bottom of loop
                }
            } else {
                bytecode[instrCt].func = emitted ? bf_inc_shift_lb : bf_lb;
                stk[depth++] = instrCt;
                // now increment ct here
                instrCt++;
            }
        } else if (ch == ']') {
            bool emitted = false;
            if (deltaInc || deltaShift) {
                emit_code(&bytecode[instrCt], deltaInc, deltaShift);
                deltaInc = deltaShift = 0;
                //instrCt++;    // similar to above
                definiteZero = false;
                emitted = true;
            }
            bytecode[instrCt].func = emitted ? bf_inc_shift_rb : definiteZero ? bf_rb_nop : bf_rb;
            size_t open = stk[--depth];
            // point at each other for now, will get changed later
            bytecode[open].branch = &bytecode[instrCt];
            bytecode[instrCt].branch = &bytecode[open];
            instrCt++;
            definiteZero = true;
        } else if (ch == '.') {
            if (deltaInc || deltaShift) {
                emit_code(&bytecode[instrCt], deltaInc, deltaShift);
                deltaInc = deltaShift = 0;
                instrCt++;
                definiteZero = false;
            }
            bytecode[instrCt].func = bf_putc;
            instrCt++;
        } else if (ch == ',') {
            if (deltaInc || deltaShift) {
                emit_code(&bytecode[instrCt], deltaInc, deltaShift);
                deltaInc = deltaShift = 0;
                instrCt++;
            }
            deltaInc = 0;
            bytecode[instrCt].func = bf_getc;
            instrCt++;
            definiteZero = false;
        }
        i++;
    }
    if (deltaInc || deltaShift) {
        emit_code(&bytecode[instrCt], deltaInc, deltaShift);
        deltaInc = deltaShift = 0;
        instrCt++;
    }
    free(code);
    free(stk);
    if (onlyPrint) {
        print_code(stdout, bytecode, instrCt, true);
        free(bytecode);
        return 0;
    }
    // set next ptrs
    size_t realCt = 0;
    for (i = 0; i < instrCt; i++) {
        // addition loop: left bracket + inc_shift + inc_shift_rb, where the shifts are opposite
        if (i < instrCt - 2) {
            if ((bytecode[i].func == bf_lb || bytecode[i].func == bf_inc_shift_lb)
                && bytecode[i + 1].func == bf_inc_shift && bytecode[i + 2].func == bf_inc_shift_rb) {
                if (bytecode[i + 1].inc == (unsigned char) -1 && bytecode[i + 1].shift == -bytecode[i + 2].shift) {
                    bytecode[i + 1].func = bf_nop;
                    bytecode[i + 2].func = bf_nop;
                    size_t change;
                    if (bytecode[i].func == bf_inc_shift_lb) {
                        bytecode[i].func = bf_inc_shift;
                        change = i + 1;
                    } else {
                        change = i;
                    }
                    bytecode[change].func = bf_add;
                    bytecode[change].inc = bytecode[i + 2].inc;
                    bytecode[change].shift = bytecode[i + 1].shift;
                }
            }
        }
        // micro-opt: skip nops
        if (bytecode[i].func == bf_rb_nop) {
            (*(bytecode[i].branch - 1)).branch = &bytecode[realCt];
        } else if (bytecode[i].func != bf_nop) {
            if (i != realCt) {
                memcpy(&bytecode[realCt], &bytecode[i], sizeof(Code));
            }
            if (bytecode[realCt].func == bf_lb || bytecode[realCt].func == bf_inc_shift_lb) {
                bytecode[realCt].branch->branch = &bytecode[realCt + 1];
            } else if (bytecode[realCt].func == bf_rb || bytecode[realCt].func == bf_inc_shift_rb) {
                (*(bytecode[realCt].branch - 1)).branch = &bytecode[realCt + 1];
            }
            bytecode[realCt].next = &bytecode[realCt + 1];
            realCt++;
        }
    }
    // emit last instruction
    // realCt == number of instructions not counting this last one
    bytecode[realCt].func = bf_end;
    // run
    if (verbose) fprintf(stderr, "translated to %zu bytecode instructions\n", realCt);
    tape = tapePtr = calloc((size_t) tapeLength, sizeof(unsigned char));
    if (!tape) {
        fprintf(stderr, "err: failed to allocate tape\n");
        free(bytecode);
        return 1;
    }
#ifndef NO_CHECK_BOUNDS
    tapeEnd = tape + tapeLength;
#endif
    // ip
    Code* ptr = bytecode;
    while (ptr) {
        ptr = ptr->func(ptr);
    }
    free(bytecode);
    free(tape);
    return 0;
}
Ejemplo n.º 10
0
static int compile_operator(compiletime c)
{
	int operand_count = 0;

	const char *op = pop_operator(c, &operand_count);

	if (!strcmp(op, "*"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, multiply_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "**"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, power_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "/"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, divide_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "%"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, modulo_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "="))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, assign_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, ";"))
	{
	}
	else if (!strcmp(op, "if"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, if_tc, val1);
		DEBUG printf("emit '%s' %s\n", val1, op);
		c->level++;
	}
	else if (!strcmp(op, "else"))
	{
		c->level--;
		emit1(c, else_tc);
		c->level++;
		DEBUG printf("emit %s\n", op);
	}
	else if (!strcmp(op, "fi"))
	{
		c->level--;
		emit1(c, fi_tc);
		DEBUG printf("emit %s\n", op);
	}
	else if (!strcmp(op, "!"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, not_tc, val1);
		DEBUG printf("emit '%s' %s\n", val1, op);
	}
	else if (!strcmp(op, "+"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, add_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "-"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, subtract_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, ">"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, gt_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, ">="))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, geq_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "<="))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, leq_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "<"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, lt_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "&&"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, and_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "||"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, or_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "^^"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, xor_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "&"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, bit_and_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "|"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, bit_or_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "^"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, bit_xor_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "~"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, bit_negate_tc, val1);
		DEBUG printf("emit %s %s\n", val1, op);
	}
	else if (!strcmp(op, "<<"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, shift_left_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, ">>"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, shift_right_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, ">>>"))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, logical_shift_right_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "=="))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, eq_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "!="))
	{
		const char *val2 = pop_operand(c);
		const char *val1 = pop_operand(c);
		emit3(c, neq_tc, val1, val2);
		DEBUG printf("emit %s %s %s\n", val1, op, val2);
	}
	else if (!strcmp(op, "fold-case"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_fold_case_tc, val1);
		DEBUG printf("emit %s %s\n", op, val1);
	}
	else if (!strcmp(op, "size"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_size_tc, val1);
		DEBUG printf("emit %s %s\n", op, val1);
	}
	else if (!strcmp(op, "print"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_print_tc, val1);
		DEBUG printf("emit %s %s\n", op, val1);
	}
	else if (!strcmp(op, "jday"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_jday_tc, val1);
		DEBUG printf("emit %s %s\n", op, val1);
	}
	else if (!strcmp(op, "dow"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_dow_tc, val1);
		DEBUG printf("emit %s %s\n", op, val1);
	}
	else if (!strcmp(op, "equals"))
	{
		emit_code(c, func_eq_tc, operand_count);

		while (operand_count--)
		{
			const char *val1 = pop_operand(c);
			emit_value(c, val1);
			DEBUG printf("emit %s '%s'\n", op, val1);
		}
	}
	else if (!strcmp(op, "contains"))
	{
		emit_code(c, func_contains_tc, operand_count);

		while (operand_count--)
		{
			const char *val1 = pop_operand(c);
			emit_value(c, val1);
			DEBUG printf("emit %s '%s'\n", op, val1);
		}
	}
	else if (!strcmp(op, "begins-with"))
	{
		emit_code(c, func_begins_with_tc, operand_count);

		while (operand_count--)
		{
			const char *val1 = pop_operand(c);
			emit_value(c, val1);
			DEBUG printf("emit %s '%s'\n", op, val1);
		}
	}
	else if (!strcmp(op, "ends-with"))
	{
		emit_code(c, func_ends_with_tc, operand_count);

		while (operand_count--)
		{
			const char *val1 = pop_operand(c);
			emit_value(c, val1);
			DEBUG printf("emit %s '%s'\n", op, val1);
		}
	}
	else if (!strcmp(op, "int"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_is_int_tc, val1);
		DEBUG printf("emit %s '%s'\n", op, val1);
	}
	else if (!strcmp(op, "real"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_is_real_tc, val1);
		DEBUG printf("emit %s '%s'\n", op, val1);
	}
	else if (!strcmp(op, "nan"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_is_nan_tc, val1);
		DEBUG printf("emit %s '%s'\n", op, val1);
	}
	else if (!strcmp(op, "string"))
	{
		const char *val1 = pop_operand(c);
		emit2(c, func_is_string_tc, val1);
		DEBUG printf("emit %s '%s'\n", op, val1);
	}
	else if (!strcmp(op, "("))
	{
		return 1;
	}
	else if (!strcmp(op, ")"))
	{
		return 1;
	}
	else
	{
		DEBUG printf("bad operator '%s'\n", op);
		return 0;
	}

	push_operand(c, "_STACK");
	return 1;
}
Ejemplo n.º 11
0
static void emit3(compiletime c, typecode tc, const char *v1, const char *v2)
{
	emit_code(c, tc, 2);
	emit_value(c, v1);
	emit_value(c, v2);
}
Ejemplo n.º 12
0
static void emit2(compiletime c, typecode tc, const char *v1)
{
	emit_code(c, tc, 1);
	emit_value(c, v1);
}
Ejemplo n.º 13
0
static void emit1(compiletime c, typecode tc)
{
	emit_code(c, tc, 0);
}
Ejemplo n.º 14
0
static int 
emit_code(Node * node)
{
	int             source;
#if 0
	unsigned int    shift;
#endif
	int             target = node->value;
	switch (node->opcode) {
	case IDENTITY:
		break;
	case NEGATE:
		source = emit_code(node->parent);
		printf("\tNEGATE,");
		t = -t;
#ifdef verbose
		fprintf(stdout, "%d = 0 - %d\n", target, source);
#endif
		break;
	case SHIFT_ADD:
		source = emit_code(node->parent);
		emit_shift(target - 1, source);
#ifdef verbose
		fprintf(stdout, "%d = %d + 1\n", target, target - 1);
#endif
		printf("\tSHIFT_ADD, %d,", n);
		t = (t << n) + src;
		break;
	case SHIFT_SUB:
		source = emit_code(node->parent);
		emit_shift(target + 1, source);
#ifdef verbose
		fprintf(stdout, "%d = %d - 1\n", target, target + 1);
#endif
		printf("\tSHIFT_SUB, %d,",n);
		t = (t << n) - src;
		break;
	case SHIFT_REV:
		source = emit_code(node->parent);
		emit_shift(1 - target, source);
#ifdef verbose
		fprintf(stdout, "%d = 1 - %d\n", target, 1 - target);
#endif
		printf("\tSHIFT_REV, %d,",n);
		t = src - (t << n);
		break;
	case FACTOR_ADD:
		source = emit_code(node->parent);
		emit_shift(target - source, source);
#ifdef verbose
		fprintf(stdout, "%d = %d + %d\n", target, target - source, source);
#endif
		t = (t << n) + t;
		printf("\tFACTOR_ADD, %d,",n);
		break;
	case FACTOR_SUB:
		source = emit_code(node->parent);
		emit_shift(target + source, source);
#ifdef verbose
		fprintf(stdout, "%d = %d - %d\n", target, target + source, source);
#endif
		t = (t << n) - t;
		printf("\tFACTOR_SUB, %d,",n);
		break;
	case FACTOR_REV:
		source = emit_code(node->parent);
		emit_shift(source - target, source);
#ifdef verbose
		fprintf(stdout, "%d = %d - %d\n", target, source, source - target);
#endif
		t = t - (t << n);
		printf("\tFACTOR_REV, %d,",n);
		break;
	}
	return target;
}