示例#1
0
int
setline(void)
{
	tchar *i;
	tchar c;
	int	length;
	int	w, cnt, delim, rem, temp;
	tchar linebuf[NC];

	if (ismot(c = getch()))
		return (0);
	delim = cbits(c);
	vflag = 0;
	dfact = EM;
	length = quant(atoi(), HOR);
	dfact = 1;
	if (!length) {
		eat(delim);
		return (0);
	}
s0:
	if ((cbits(c = getch())) == delim) {
		ch = c;
		c = RULE | chbits;
	} else if (cbits(c) == FILLER)
		goto s0;
	w = width(c);
	i = linebuf;
	if (length < 0) {
		*i++ = makem(length);
		length = -length;
	}
	if (!(cnt = length / w)) {
		*i++ = makem(-(temp = ((w - length) / 2)));
		*i++ = c;
		*i++ = makem(-(w - length - temp));
		goto s1;
	}
	if (rem = length % w) {
		if (cbits(c) == RULE || cbits(c) == UNDERLINE ||
		    cbits(c) == ROOTEN)
			*i++ = c | ZBIT;
		*i++ = makem(rem);
	}
	if (cnt) {
		*i++ = RPT;
		*i++ = cnt;
		*i++ = c;
	}
s1:
	*i++ = 0;
	eat(delim);
	pushback(linebuf);

	return (0);
}
示例#2
0
void
setline(void)
{
	register tchar *i;
	tchar c, delim;
	int	length;
	int	w, cnt, rem, temp;
	tchar linebuf[NC];

	if (ismot(c = getch()))
		return;
	delim = c;
	vflag = 0;
	dfact = EM;
	length = quant(hatoi(), HOR);
	dfact = 1;
	if (!length) {
		eat(delim);
		return;
	}
s0:
	if (c = getch(), issame(c, delim)) {
		ch = c;
		c = RULE | chbits;
	} else if (cbits(c) == FILLER)
		goto s0;
	w = width(c);
	i = linebuf;
	if (length < 0) {
		*i++ = makem(length);
		length = -length;
	}
	if (!(cnt = length / w)) {
		*i++ = makem(-(temp = ((w - length) / 2)));
		*i++ = c;
		*i++ = makem(-(w - length - temp));
		goto s1;
	}
	if ((rem = length % w)) {
		if (connectchar(c))
			*i++ = c | ZBIT;
		*i++ = makem(rem);
	}
	if (cnt) {
		*i++ = RPT;
		*i++ = cnt;
		*i++ = c;
	}
s1:
	*i++ = 0;
	eat(delim);
	pushback(linebuf);
}
示例#3
0
文件: llist.c 项目: vaughan0/vlib
static int llist_iteration() {
  LList l[1];
  llist_init(l, sizeof(int));

  for (int i = 1; i <= 10; i++) {
    pushback(l, i);
  }

  int remove_even(void* data) {
    int val = *(int*)data;
    return (val % 2 == 0) ? LLIST_REMOVE : 0;
  }
示例#4
0
//压入栈
int push(LinkStack* myLinkStack, char* value)
{
	if (myLinkStack != nullptr && value!=nullptr)
	{
		if (myLinkStack->pHeadNode==nullptr)
		{
			pushback(&myLinkStack->pHeadNode, 1, value);
			myLinkStack->topNode = myLinkStack->pHeadNode;
		}
		else
		{
			pushback(&myLinkStack->topNode, myLinkStack->topNode->num+1, value);
			myLinkStack->topNode = myLinkStack->topNode->pnext;
		}
		return 1;
	}
	else
	{
		return 0;
	}
}
示例#5
0
文件: llist.c 项目: vaughan0/vlib
static int llist_basic() {
  LList l[1];
  llist_init(l, sizeof(int));

  pushfront(l, 3);
  pushback(l, 4);
  pushfront(l, 2);
  pushfront(l, 1);
  pushback(l, 5);

  assertEqual(l->size, 5);
  assertEqual(popfront(l), 1);
  assertEqual(popfront(l), 2);
  assertEqual(popfront(l), 3);
  assertEqual(popfront(l), 4);
  assertEqual(popfront(l), 5);
  assertEqual(l->size, 0);

  llist_close(l);
  return 0;
}
示例#6
0
void lunascan::scanspecial()
   {
   if (CH=='-' || CH=='+' || CH=='*' || CH=='/')
      {
      pushback(CH);
      getmychar();

      if (CH=='-' || CH=='+' || CH=='*' || CH=='/')
         {
         pushback(CH);
         getmychar();
         }
      }
   else
      if  (CH==':' || CH=='=' || CH=='<' || CH=='>')
         {
         pushback(CH);
         getmychar();

         if  (CH==':' || CH=='=' || CH=='<' || CH=='>')
            {
            pushback(CH);
            getmychar();
            }
         }
      else
         {
         pushback(CH);
         getmychar();
         }

   SERIAL=getstring(STRING);

   if (SERIAL!=LUNA_UNKNOWN) TOKEN=POOL[SERIAL].id;
   else TOKEN=LUNA_UNKNOWN;

   CHECKSPCL=TRUE;
   }
StringIterator* stringIteratorCreate(char*s){
  a.sz=0;
  char c,i;
  int now;
  now=0;
  for (i=0; s[i]; i++){
    if ((s[i]>='0')&&(s[i]<='9')){
      now*=10;
      now+=s[i]-'0';
    }
    else{
      if (now>0){
        a.ptr = pushback(a.ptr, &a.sz ,newPair(c,now));
      }
      c=s[i];
      now=0;
    }
  }
  if (now>0)
    a.ptr = pushback(a.ptr, &a.sz ,newPair(c,now));
  x=0;y=0;
  return ptr;
}
示例#8
0
ll MinWater(pair*bottle, int all_water_height){
    ll required_water = 0;
    water_levelSz=0;
    for(int i=0;i<bottleSz;i++){pair itr = bottle[i];
        int current = 0;
        if (itr.first >= all_water_height) 
            current = itr.first;
        else 
            current = min(itr.second, all_water_height);
        required_water += current;
        water_level=pushback(water_level, &water_levelSz, current);
    }
    return required_water;
}
示例#9
0
int main(){
    scanf("%d %d", &n, &m);
    if (n == 1)
        return puts("0")*0;
    if((n == 3 && m == 0) || (n == 2 && m == 0)) 
        return puts("-1")*0;
    for (int i = 1; i < n; i++) 
        V.ptr = pushback(V.ptr, &V.sz, newPair(i, i+1));
    if (!m){
        for (int i = 3; i <= n; i++) 
            V.ptr = pushback(V.ptr, &V.sz, newPair(1, i));
        V.ptr = pushback(V.ptr, &V.sz, newPair(2, n));
    }
    else{
        int cnt = n - 1 - m;
        for (int i = 1; i <= cnt; i++) 
            V.ptr = pushback(V.ptr, &V.sz, newPair(1, 2 + i));
    }
    printf("%d\n", V.sz);
    int k = 0;
    for(int z=0;z<V.sz;z++){pair it = V.ptr[z];
        printf("%d %d %d\n", it.first, it.second, ++k);
    }
}
示例#10
0
void lunascan::scanidentifier()
   {
   while ((CH>='a' && CH<='z') || (CH>='A' && CH<='Z') || CH=='_' || (CH>='0' && CH<='9'))
      {
      pushback(CH);
      getmychar();
      }

   SERIAL=getstring(STRING);

   if (SERIAL!=LUNA_UNKNOWN) TOKEN=POOL[SERIAL].id;
   else TOKEN=LUNA_UNKNOWN;

   CHECKIDNT=TRUE;
   }
void put(int h, char*str){
    bool found=false;
    int i;
    for(i=0;i<hashesSz;i++){
        if(hashes[i]==h){
            found=true;
            break;
        }
    }
    vecstr[i].ptr = pushback(vecstr[i].ptr, &vecstr[i].sz, str);
    if(!found){
        hashes[i]=h;
        hashesSz++;
    }
}
示例#12
0
void lunascan::gettext(char delimiter)
   {
   clear();

   if (CH!='\0')
      {
      while (CH!=delimiter && CH!='\0')
         {
         if (CH!='\r') pushback(CH);
         getmychar();
         }

      if (CH!=delimiter) SCANNERMSG("unterminated text");
      }

   TOKEN=LUNA_STRING;
   }
示例#13
0
void	push(t_no **list1, t_no **list2)
{
	t_no *ptr1;
	t_no *ptr2;

	ptr1 = *list1;
	ptr2 = *list2;
	ft_putstr("oi");
	ptr1 = pushback(ptr1, ptr2->val);
	if (ptr2->next)
		ptr2 = ptr2->next;
	else
		ptr2 = NULL;
	print_list(ptr1);
	print_list(ptr2);
		
}
示例#14
0
void lunascan::scanstring()
   {
   getmychar();

   while (CH!='"' && CH!='\n' && CH!='\r' && CH!='\0')
      if (CH=='\\')
         {
         getmychar();

         switch (CH)
            {
            case 'n': pushback('\n'); break;
            case 'r': pushback('\r'); break;
            case 't': pushback('\t'); break;
            case '\'': pushback('\''); break;
            case '"': pushback('"'); break;
            case '\\': pushback('\\'); break;
            case '0': pushback('\0'); break;
            default:
               SCANNERMSG("unknown escape sequence");
               pushback(CH);
               break;
            }

         getmychar();
         }
      else
         {
         pushback(CH);
         getmychar();
         }

   if (CH!='"') SCANNERMSG("unterminated string constant");

   getmychar();

   TOKEN=LUNA_STRING;
   }
示例#15
0
void lunascan::scanchar()
   {
   getmychar();

   if (CH=='\\')
      {
      getmychar();

      switch (CH)
         {
         case 'n': pushback('\n'); break;
         case 'r': pushback('\r'); break;
         case 't': pushback('\t'); break;
         case '\'': pushback('\''); break;
         case '"': pushback('"'); break;
         case '\\': pushback('\\'); break;
         case '0': pushback('\0'); break;
         default:
            SCANNERMSG("unknown escape sequence");
            pushback(CH);
            break;
         }

      getmychar();
      }
   else
      {
      pushback(CH);
      getmychar();
      }

   if (CH!='\'') SCANNERMSG("unterminated char constant");

   getmychar();

   TOKEN=LUNA_VALUE;
   VALUE=STRING[0];
   }
示例#16
0
int		open_file(t_list *list, char *str2)
{
  DIR		*rep;
  struct dirent	*file;
  int		pos;

  pos = 1;
  file = NULL;
  rep = opendir(str2);
  if (rep == NULL)
    return (-1);
  while ((file = readdir(rep)))
    {
      if (strcmp(file->d_name, "..") != 0 && strcmp(file->d_name, ".") != 0)
	pushback(list, file->d_name, pos);
      pos = pos + 1;
    }
  return (0);
}
示例#17
0
int
setbra(void)
{
	int	k;
	tchar i, *j, dwn;
	int	cnt, delim;
	tchar brabuf[NC];

	if (ismot(i = getch()))
		return (0);
	delim = cbits(i);
	j = brabuf + 1;
	cnt = 0;
#ifdef NROFF
	dwn = (2 * t.Halfline) | MOT | VMOT;
#endif
#ifndef NROFF
	dwn = EM | MOT | VMOT;
#endif
	while (((k = cbits(i = getch())) != delim) && (k != '\n') &&
	    (j <= (brabuf + NC - 4))) {
		*j++ = i | ZBIT;
		*j++ = dwn;
		cnt++;
	}
	if (--cnt < 0)
		return (0);
	else if (!cnt) {
		ch = *(j - 2);
		return (0);
	}
	*j = 0;
#ifdef NROFF
	*--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
#endif
#ifndef NROFF
	*--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
#endif
	*--j &= ~ZBIT;
	pushback(brabuf);

	return (0);
}
示例#18
0
void
setbra(void)
{
	register int k;
	tchar i, *j, dwn, delim;
	int	cnt;
	tchar brabuf[NC];

	if (ismot(i = getch()))
		return;
	delim = i;
	j = brabuf + 1;
	cnt = 0;
#ifdef NROFF
	dwn = sabsmot(2 * t.Halfline) | MOT | VMOT;
#endif
#ifndef NROFF
	dwn = sabsmot((int)EM) | MOT | VMOT;
#endif
	while ((k = cbits(i = getch()), !issame(delim, i)) && (k != '\n') &&  (j <= (brabuf + NC - 4))) {
		*j++ = i | ZBIT;
		*j++ = dwn;
		cnt++;
	}
	if (!issame(i, delim))
		nodelim(delim);
	if (--cnt < 0)
		return;
	else if (!cnt) {
		ch = *(j - 2);
		return;
	}
	*j = 0;
#ifdef NROFF
	*--j = *brabuf = sabsmot(cnt * t.Halfline) | MOT | NMOT | VMOT;
#endif
#ifndef NROFF
	*--j = *brabuf = sabsmot((cnt * (int)EM) / 2) | MOT | NMOT | VMOT;
#endif
	*--j &= ~ZBIT;
	pushback(brabuf);
}
示例#19
0
文件: n1.c 项目: 99years/plan9
void setxon(void)	/* \X'...' for copy through */
{
	Tchar xbuf[NC];
	Tchar *i;
	Tchar c;
	int delim, k;

	if (ismot(c = getch()))
		return;
	delim = cbits(c);
	i = xbuf;
	*i++ = XON | chbits;
	while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
		if (k == ' ')
			setcbits(c, WORDSP);
		*i++ = c | ZBIT;
	}
	*i++ = XOFF | chbits;
	*i = 0;
	pushback(xbuf);
}
示例#20
0
/*
 * expand_builtin - evaluate built-in macros.
 */
void
expand_builtin(const char *argv[], int argc, int td)
{
	int c, n;
	int ac;
	static int sysval = 0;

#ifdef DEBUG
	printf("argc = %d\n", argc);
	for (n = 0; n < argc; n++)
		printf("argv[%d] = %s\n", n, argv[n]);
	fflush(stdout);
#endif

 /*
  * if argc == 3 and argv[2] is null, then we
  * have macro-or-builtin() type call. We adjust
  * argc to avoid further checking..
  */
 /* we keep the initial value for those built-ins that differentiate
  * between builtin() and builtin.
  */
	ac = argc;

	if (argc == 3 && !*(argv[2]) && !mimic_gnu)
		argc--;

	switch (td & TYPEMASK) {

	case DEFITYPE:
		if (argc > 2)
			dodefine(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case PUSDTYPE:
		if (argc > 2)
			dopushdef(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case DUMPTYPE:
		dodump(argv, argc);
		break;

	case TRACEONTYPE:
		dotrace(argv, argc, 1);
		break;

	case TRACEOFFTYPE:
		dotrace(argv, argc, 0);
		break;

	case EXPRTYPE:
	/*
	 * doexpr - evaluate arithmetic
	 * expression
	 */
	{
		int base = 10;
		int maxdigits = 0;
		const char *errstr;

		if (argc > 3) {
			base = strtonum(argv[3], 2, 36, &errstr);
			if (errstr) {
				m4errx(1, "expr: base %s invalid.", argv[3]);
			}
		}
		if (argc > 4) {
			maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
			if (errstr) {
				m4errx(1, "expr: maxdigits %s invalid.", argv[4]);
			}
		}
		if (argc > 2)
			pbnumbase(expr(argv[2]), base, maxdigits);
		break;
	}

	case IFELTYPE:
		if (argc > 4)
			doifelse(argv, argc);
		break;

	case IFDFTYPE:
	/*
	 * doifdef - select one of two
	 * alternatives based on the existence of
	 * another definition
	 */
		if (argc > 3) {
			if (lookup_macro_definition(argv[2]) != NULL)
				pbstr(argv[3]);
			else if (argc > 4)
				pbstr(argv[4]);
		}
		break;

	case LENGTYPE:
	/*
	 * dolen - find the length of the
	 * argument
	 */
		pbnum((argc > 2) ? strlen(argv[2]) : 0);
		break;

	case INCRTYPE:
	/*
	 * doincr - increment the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) + 1);
		break;

	case DECRTYPE:
	/*
	 * dodecr - decrement the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) - 1);
		break;

	case SYSCTYPE:
	/*
	 * dosys - execute system command
	 */
		if (argc > 2) {
			fflush(stdout);
			sysval = system(argv[2]);
		}
		break;

	case SYSVTYPE:
	/*
	 * dosysval - return value of the last
	 * system call.
	 *
	 */
		pbnum(sysval);
		break;

	case ESYSCMDTYPE:
		if (argc > 2)
			doesyscmd(argv[2]);
		break;
	case INCLTYPE:
		if (argc > 2)
			if (!doincl(argv[2])) {
				if (mimic_gnu) {
					warn("%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
					exit_code = 1;
				} else
					err(1, "%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
			}
		break;

	case SINCTYPE:
		if (argc > 2)
			(void) doincl(argv[2]);
		break;
#ifdef EXTENDED
	case PASTTYPE:
		if (argc > 2)
			if (!dopaste(argv[2]))
				err(1, "%s at line %lu: paste(%s)", 
				    CURRENT_NAME, CURRENT_LINE, argv[2]);
		break;

	case SPASTYPE:
		if (argc > 2)
			(void) dopaste(argv[2]);
		break;
	case FORMATTYPE:
		doformat(argv, argc);
		break;
#endif
	case CHNQTYPE:
		dochq(argv, ac);
		break;

	case CHNCTYPE:
		dochc(argv, argc);
		break;

	case SUBSTYPE:
	/*
	 * dosub - select substring
	 *
	 */
		if (argc > 3)
			dosub(argv, argc);
		break;

	case SHIFTYPE:
	/*
	 * doshift - push back all arguments
	 * except the first one (i.e. skip
	 * argv[2])
	 */
		if (argc > 3) {
			for (n = argc - 1; n > 3; n--) {
				pbstr(rquote);
				pbstr(argv[n]);
				pbstr(lquote);
				pushback(COMMA);
			}
			pbstr(rquote);
			pbstr(argv[3]);
			pbstr(lquote);
		}
		break;

	case DIVRTYPE:
		if (argc > 2 && (n = atoi(argv[2])) != 0)
			dodiv(n);
		else {
			active = stdout;
			oindex = 0;
		}
		break;

	case UNDVTYPE:
		doundiv(argv, argc);
		break;

	case DIVNTYPE:
	/*
	 * dodivnum - return the number of
	 * current output diversion
	 */
		pbnum(oindex);
		break;

	case UNDFTYPE:
	/*
	 * doundefine - undefine a previously
	 * defined macro(s) or m4 keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_undefine(argv[n]);
		break;

	case POPDTYPE:
	/*
	 * dopopdef - remove the topmost
	 * definitions of macro(s) or m4
	 * keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_popdef(argv[n]);
		break;

	case MKTMTYPE:
	/*
	 * dotemp - create a temporary file
	 */
		if (argc > 2) {
			int fd;
			char *temp;

			temp = xstrdup(argv[2]);

			fd = mkstemp(temp);
			if (fd == -1)
				err(1,
	    "%s at line %lu: couldn't make temp file %s",
	    CURRENT_NAME, CURRENT_LINE, argv[2]);
			close(fd);
			pbstr(temp);
			free(temp);
		}
		break;

	case TRNLTYPE:
	/*
	 * dotranslit - replace all characters in
	 * the source string that appears in the
	 * "from" string with the corresponding
	 * characters in the "to" string.
	 */
		if (argc > 3) {
			char *temp;

			temp = xalloc(strlen(argv[2])+1, NULL);
			if (argc > 4)
				map(temp, argv[2], argv[3], argv[4]);
			else
				map(temp, argv[2], argv[3], null);
			pbstr(temp);
			free(temp);
		} else if (argc > 2)
			pbstr(argv[2]);
		break;

	case INDXTYPE:
	/*
	 * doindex - find the index of the second
	 * argument string in the first argument
	 * string. -1 if not present.
	 */
		pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
		break;

	case ERRPTYPE:
	/*
	 * doerrp - print the arguments to stderr
	 * file
	 */
		if (argc > 2) {
			for (n = 2; n < argc; n++)
				fprintf(stderr, "%s ", argv[n]);
			fprintf(stderr, "\n");
		}
		break;

	case DNLNTYPE:
	/*
	 * dodnl - eat-up-to and including
	 * newline
	 */
		while ((c = gpbc()) != '\n' && c != EOF)
			;
		break;

	case M4WRTYPE:
	/*
	 * dom4wrap - set up for
	 * wrap-up/wind-down activity
	 */
		if (argc > 2)
			dom4wrap(argv[2]);
		break;

	case EXITTYPE:
	/*
	 * doexit - immediate exit from m4.
	 */
		killdiv();
		exit((argc > 2) ? atoi(argv[2]) : 0);
		break;

	case DEFNTYPE:
		if (argc > 2)
			for (n = 2; n < argc; n++)
				dodefn(argv[n]);
		break;

	case INDIRTYPE:	/* Indirect call */
		if (argc > 2)
			doindir(argv, argc);
		break;

	case BUILTINTYPE: /* Builtins only */
		if (argc > 2)
			dobuiltin(argv, argc);
		break;

	case PATSTYPE:
		if (argc > 2)
			dopatsubst(argv, argc);
		break;
	case REGEXPTYPE:
		if (argc > 2)
			doregexp(argv, argc);
		break;
	case LINETYPE:
		doprintlineno(infile+ilevel);
		break;
	case FILENAMETYPE:
		doprintfilename(infile+ilevel);
		break;
	case SELFTYPE:
		pbstr(rquote);
		pbstr(argv[1]);
		pbstr(lquote);
		break;
	default:
		m4errx(1, "eval: major botch.");
		break;
	}
}
示例#21
0
文件: peep.c 项目: aigamo/isucon3egg
void
peep(void)
{
	Reg *r, *r1, *r2;
	Prog *p, *p1;
	int t;

	/*
	 * complete R structure
	 */
	t = 0;
	for(r=firstr; r!=R; r=r1) {
		r1 = r->link;
		if(r1 == R)
			break;
		p = r->prog->link;
		while(p != r1->prog)
		switch(p->as) {
		default:
			r2 = rega();
			r->link = r2;
			r2->link = r1;

			r2->prog = p;
			p->reg = r2;

			r2->p1 = r;
			r->s1 = r2;
			r2->s1 = r1;
			r1->p1 = r2;

			r = r2;
			t++;

		case ADATA:
		case AGLOBL:
		case ANAME:
		case ASIGNAME:
		case ALOCALS:
		case ATYPE:
			p = p->link;
		}
	}
	
	// byte, word arithmetic elimination.
	elimshortmov(r);

	// constant propagation
	// find MOV $con,R followed by
	// another MOV $con,R without
	// setting R in the interim
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case ALEAL:
		case ALEAQ:
			if(regtyp(&p->to))
			if(p->from.sym != S)
			if(p->from.index == D_NONE || p->from.index == D_CONST)
				conprop(r);
			break;

		case AMOVB:
		case AMOVW:
		case AMOVL:
		case AMOVQ:
		case AMOVSS:
		case AMOVSD:
			if(regtyp(&p->to))
			if(p->from.type == D_CONST)
				conprop(r);
			break;
		}
	}

loop1:
	if(debug['P'] && debug['v'])
		dumpit("loop1", firstr);

	t = 0;
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case AMOVL:
		case AMOVQ:
		case AMOVSS:
		case AMOVSD:
			if(regtyp(&p->to))
			if(regtyp(&p->from)) {
				if(copyprop(r)) {
					excise(r);
					t++;
				} else
				if(subprop(r) && copyprop(r)) {
					excise(r);
					t++;
				}
			}
			break;

		case AMOVBLZX:
		case AMOVWLZX:
		case AMOVBLSX:
		case AMOVWLSX:
			if(regtyp(&p->to)) {
				r1 = rnops(uniqs(r));
				if(r1 != R) {
					p1 = r1->prog;
					if(p->as == p1->as && p->to.type == p1->from.type){
						p1->as = AMOVL;
						t++;
					}
				}
			}
			break;

		case AMOVBQSX:
		case AMOVBQZX:
		case AMOVWQSX:
		case AMOVWQZX:
		case AMOVLQSX:
		case AMOVLQZX:
		case AMOVQL:
			if(regtyp(&p->to)) {
				r1 = rnops(uniqs(r));
				if(r1 != R) {
					p1 = r1->prog;
					if(p->as == p1->as && p->to.type == p1->from.type){
						p1->as = AMOVQ;
						t++;
					}
				}
			}
			break;

		case AADDL:
		case AADDQ:
		case AADDW:
			if(p->from.type != D_CONST || needc(p->link))
				break;
			if(p->from.offset == -1){
				if(p->as == AADDQ)
					p->as = ADECQ;
				else
				if(p->as == AADDL)
					p->as = ADECL;
				else
					p->as = ADECW;
				p->from = zprog.from;
				break;
			}
			if(p->from.offset == 1){
				if(p->as == AADDQ)
					p->as = AINCQ;
				else if(p->as == AADDL)
					p->as = AINCL;
				else
					p->as = AINCW;
				p->from = zprog.from;
				break;
			}
			break;

		case ASUBL:
		case ASUBQ:
		case ASUBW:
			if(p->from.type != D_CONST || needc(p->link))
				break;
			if(p->from.offset == -1) {
				if(p->as == ASUBQ)
					p->as = AINCQ;
				else
				if(p->as == ASUBL)
					p->as = AINCL;
				else
					p->as = AINCW;
				p->from = zprog.from;
				break;
			}
			if(p->from.offset == 1){
				if(p->as == ASUBQ)
					p->as = ADECQ;
				else
				if(p->as == ASUBL)
					p->as = ADECL;
				else
					p->as = ADECW;
				p->from = zprog.from;
				break;
			}
			break;
		}
	}
	if(t)
		goto loop1;

	// MOVLQZX removal.
	// The MOVLQZX exists to avoid being confused for a
	// MOVL that is just copying 32-bit data around during
	// copyprop.  Now that copyprop is done, remov MOVLQZX R1, R2
	// if it is dominated by an earlier ADDL/MOVL/etc into R1 that
	// will have already cleared the high bits.
	//
	// MOVSD removal.
	// We never use packed registers, so a MOVSD between registers
	// can be replaced by MOVAPD, which moves the pair of float64s
	// instead of just the lower one.  We only use the lower one, but
	// the processor can do better if we do moves using both.
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		if(p->as == AMOVLQZX)
		if(regtyp(&p->from))
		if(p->from.type == p->to.type)
		if(prevl(r, p->from.type))
			excise(r);
		
		if(p->as == AMOVSD)
		if(regtyp(&p->from))
		if(regtyp(&p->to))
			p->as = AMOVAPD;
	}

	// load pipelining
	// push any load from memory as early as possible
	// to give it time to complete before use.
	for(r=firstr; r!=R; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case AMOVB:
		case AMOVW:
		case AMOVL:
		case AMOVQ:
		case AMOVLQZX:
			if(regtyp(&p->to) && !regconsttyp(&p->from))
				pushback(r);
		}
	}
}
示例#22
0
文件: peep.c 项目: cloudaice/golang
void
peep(Prog *firstp)
{
	Flow *r, *r1;
	Graph *g;
	Prog *p, *p1;
	int t;

	g = flowstart(firstp, sizeof(Flow));
	if(g == nil)
		return;
	for(r=g->start, t=0; r!=nil; r=r->link, t++)
		r->active = t;

	// byte, word arithmetic elimination.
	elimshortmov(g);

	// constant propagation
	// find MOV $con,R followed by
	// another MOV $con,R without
	// setting R in the interim
	for(r=g->start; r!=nil; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case ALEAL:
		case ALEAQ:
			if(regtyp(&p->to))
			if(p->from.sym != S)
			if(p->from.index == D_NONE || p->from.index == D_CONST)
				conprop(r);
			break;

		case AMOVB:
		case AMOVW:
		case AMOVL:
		case AMOVQ:
		case AMOVSS:
		case AMOVSD:
			if(regtyp(&p->to))
			if(p->from.type == D_CONST)
				conprop(r);
			break;
		}
	}

loop1:
	if(debug['P'] && debug['v'])
		dumpit("loop1", g->start, 0);

	t = 0;
	for(r=g->start; r!=nil; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case AMOVL:
		case AMOVQ:
		case AMOVSS:
		case AMOVSD:
			if(regtyp(&p->to))
			if(regtyp(&p->from)) {
				if(copyprop(g, r)) {
					excise(r);
					t++;
				} else
				if(subprop(r) && copyprop(g, r)) {
					excise(r);
					t++;
				}
			}
			break;

		case AMOVBLZX:
		case AMOVWLZX:
		case AMOVBLSX:
		case AMOVWLSX:
			if(regtyp(&p->to)) {
				r1 = rnops(uniqs(r));
				if(r1 != nil) {
					p1 = r1->prog;
					if(p->as == p1->as && p->to.type == p1->from.type){
						p1->as = AMOVL;
						t++;
					}
				}
			}
			break;

		case AMOVBQSX:
		case AMOVBQZX:
		case AMOVWQSX:
		case AMOVWQZX:
		case AMOVLQSX:
		case AMOVLQZX:
		case AMOVQL:
			if(regtyp(&p->to)) {
				r1 = rnops(uniqs(r));
				if(r1 != nil) {
					p1 = r1->prog;
					if(p->as == p1->as && p->to.type == p1->from.type){
						p1->as = AMOVQ;
						t++;
					}
				}
			}
			break;

		case AADDL:
		case AADDQ:
		case AADDW:
			if(p->from.type != D_CONST || needc(p->link))
				break;
			if(p->from.offset == -1){
				if(p->as == AADDQ)
					p->as = ADECQ;
				else
				if(p->as == AADDL)
					p->as = ADECL;
				else
					p->as = ADECW;
				p->from = zprog.from;
				break;
			}
			if(p->from.offset == 1){
				if(p->as == AADDQ)
					p->as = AINCQ;
				else if(p->as == AADDL)
					p->as = AINCL;
				else
					p->as = AINCW;
				p->from = zprog.from;
				break;
			}
			break;

		case ASUBL:
		case ASUBQ:
		case ASUBW:
			if(p->from.type != D_CONST || needc(p->link))
				break;
			if(p->from.offset == -1) {
				if(p->as == ASUBQ)
					p->as = AINCQ;
				else
				if(p->as == ASUBL)
					p->as = AINCL;
				else
					p->as = AINCW;
				p->from = zprog.from;
				break;
			}
			if(p->from.offset == 1){
				if(p->as == ASUBQ)
					p->as = ADECQ;
				else
				if(p->as == ASUBL)
					p->as = ADECL;
				else
					p->as = ADECW;
				p->from = zprog.from;
				break;
			}
			break;
		}
	}
	if(t)
		goto loop1;

	// MOVLQZX removal.
	// The MOVLQZX exists to avoid being confused for a
	// MOVL that is just copying 32-bit data around during
	// copyprop.  Now that copyprop is done, remov MOVLQZX R1, R2
	// if it is dominated by an earlier ADDL/MOVL/etc into R1 that
	// will have already cleared the high bits.
	//
	// MOVSD removal.
	// We never use packed registers, so a MOVSD between registers
	// can be replaced by MOVAPD, which moves the pair of float64s
	// instead of just the lower one.  We only use the lower one, but
	// the processor can do better if we do moves using both.
	for(r=g->start; r!=nil; r=r->link) {
		p = r->prog;
		if(p->as == AMOVLQZX)
		if(regtyp(&p->from))
		if(p->from.type == p->to.type)
		if(prevl(r, p->from.type))
			excise(r);
		
		if(p->as == AMOVSD)
		if(regtyp(&p->from))
		if(regtyp(&p->to))
			p->as = AMOVAPD;
	}

	// load pipelining
	// push any load from memory as early as possible
	// to give it time to complete before use.
	for(r=g->start; r!=nil; r=r->link) {
		p = r->prog;
		switch(p->as) {
		case AMOVB:
		case AMOVW:
		case AMOVL:
		case AMOVQ:
		case AMOVLQZX:
			if(regtyp(&p->to) && !regconsttyp(&p->from))
				pushback(r);
		}
	}

	flowend(g);
}
示例#23
0
main(int argc, char *argv[])
{
  int ch,err,notdone,vowflag,initflag;
  errorcount=0;
  switcher='~';
  true=1;
  false=0;
  tamilflag=false;
  tdelim=1;  /* i.e. control-a ::: if yah don't like it, change it */
  tspace[0]=tdelim;
  tspace[1]=' ';
  haccbox();
  vowflag=0;
  if (argc > 1) input = fopen(argv[1],"rb");
  if (input == (FILE *) NULL) {
	/* prompt for and open input file */
	for ( ; input == (FILE *) NULL ; input=get_file("rb","Enter name of input file: ")) ;
        }
        /* we are making these binary, as we have no guarantee what kind */
        /* of character may be in the transcription: we don't care about */
        /* ends of lines, as we are reading character by character */
   if (argc > 2) output = fopen(argv[2],"wb");
   if (output == (FILE *) NULL) {
	for ( ; output == (FILE *) NULL ; output=get_file("wb","Enter name of output file: ")) ;
	/* prompt for and open output file */
        }
   while ((ch = getc(input)) != EOF) {
	if (ch == switcher) changestate();
	else {
		if (ch == '|') {
                  vowflag=1;
		  notdone=1;
		  initflag=2;
		  while (notdone) {
		  ch=getc(input);
                  if (isalnum(ch)) {
                    initflag--;
                    if (vowflag==0) {
		       if (! isvowel(ch)) stringout("\\-");
                       }
		    if (isvowel(ch)) vowflag=1;
                    else vowflag=0;
                    }
                  else {
                     vowflag=1;
                     initflag=2;
                     }
		  if (ch==EOF) notdone=0;
		  else {
		    switch(ch) {
		      case '2': stringout("\\ndot{}");
		      	break;
		      case '3': stringout("\\nndot{}");
		      	break;
		      case '4': stringout("\\skts{}");
			break;
		      case '5': stringout("\\paln{}");
		      	break;
		      case '6': stringout("\\rdot{}");
		      	break;
		      case '7': stringout("\\rdotdot{}");
			break;
		      case 'T': stringout("\\tdot{}");
			 break;
		      case 'D': stringout("\\dotd{}");
			 break;
		      case '8':
		                 if ( initflag > 0 ) stringout("\\tdot{}");
		                 else {
		                      err=getc(input);
		                      if (err == '8') stringout("\\tdot{}\\tdot{}");
				      else {
					  stringout("\\dotd{}");
					  pushback(err);
					  }
		                      }
		      	break;
		      case '9': stringout("\\dotl{}");
		      	break;
		      case '|': notdone=0;
		        break;
		      default: putc(ch,output);
			} /* endcase */
		  } /* end else */
		} /* endwhile */
		} /* endif */
		else putc(ch,output);
	}  /* endelse */
	} /* endwhile */
   fclose(input);
   fclose(output);
   puts("Tamilize is done.");
}
示例#24
0
static int
nexttoken(rconlexer* lexer)
{
    int token;
    int c;
    if(lexer->pushedback)
	{token = lexer->token; lexer->pushedback = 0; goto done;}
    token = 0;
    textclear(&lexer->text);
    while(token==0) {
	c=readc(lexer);
	lexer->charno++;
	if(c == EOF) {
	    token = EOF;
	    lexer->charno--;
	    break;
	} else if(c == '\n') {
	    lexer->lineno++;
	    lexer->charno = 1;
	} else if(c == '/') { 
	    c = readc(lexer);
	    if(c == '/') {/* single line comment */
	        while((c=readc(lexer)) != EOF) {if(c == '\n') break;}
	    } else {
		pushback(lexer,c); c = '/';
	    }
	}
	if(c <= ' ' || c == '\177') {
	    /* ignore */
	} else if(strchr(delims,c) != NULL) {
	    textadd(&lexer->text,c);
	    token = c;
	} else if(c == '"') {
	    int more = 1;
	    while(more) {
		c = readc(lexer);
		switch (c) {
		case EOF: goto fail;
		case '"': more=0; break;
		case '\\':
		    textadd(&lexer->text,c);
		    c=readc(lexer);
		    textadd(&lexer->text,c);		    
		    break;
		default: textadd(&lexer->text,c);
		}
	    }
	    if(!removeescapes(lexer)) goto fail;
	    token=_STRING;
	} else { /* Treat like a string without quotes */
	    textadd(&lexer->text,c);
	    while((c=readc(lexer))) {
		if(c == '/' || c <= ' ' || c == '\177') {pushback(lexer,c); break;}
		else if(strchr(delims,c) != NULL) {pushback(lexer,c); break;}
		textadd(&lexer->text,c);
	    }
	    if(!removeescapes(lexer)) goto fail;
	    /* check for keyword */
	    if(strcmp(lexer->text.text,"true") == 0) {
		token = _TRUE;
	    } else if(strcmp(lexer->text.text,"false") == 0) {
		token = _FALSE;
	    } else if(strcmp(lexer->text.text,"null") == 0) {
		token = _NULL;
	    } else { /* See if this looks like a number */
		double d;
		if(sscanf(lexer->text.text,"%lg",&d) == 1)
		    token = _NUMBER;
		else
		    token = _STRING;
	    }
	}
    }
done:
    lexer->token = token;
    if(rcondebug > 1)
	dumptoken(lexer,0);
    return token;
fail:
    return EOF;
}
示例#25
0
int parse_db(struct _asm_context *asm_context, int null_term_flag)
{
char token[TOKENLEN];
int token_type;
int data32;

  if (asm_context->segment==SEGMENT_BSS)
  {
    printf("Error: .bss segment doesn't support initialized data at %s:%d\n", asm_context->filename, asm_context->line);
    return -1;
  }

  while(1)
  {
    token_type=get_token(asm_context, token, TOKENLEN);
    if (token_type==TOKEN_EOL || token_type==TOKEN_EOF) break;

    if (token_type==TOKEN_QUOTED)
    {
      unsigned char *s=(unsigned char *)token;
      while(*s!=0)
      {
        if (*s=='\\')
        {
          int e=escape_char(asm_context, s);
          if (e==0)
          {
            return -1;
          }
          s=s+e;
        }

        memory_write_inc(asm_context, *s, DL_DATA);

        asm_context->data_count++;
        s++;
      }

      if (null_term_flag==1)
      {
        memory_write_inc(asm_context, 0, DL_DATA);
        asm_context->data_count++;
      }
    }
      else
    {
      pushback(asm_context, token, token_type);
      if (eval_expression(asm_context, &data32)==-1)
      {
        eat_operand(asm_context);
      }

      memory_write_inc(asm_context, (unsigned char)data32, DL_DATA);
      asm_context->data_count++;
    }

    token_type=get_token(asm_context, token, TOKENLEN);
    if (token_type==TOKEN_EOL || token_type==TOKEN_EOF) break;

    if (IS_NOT_TOKEN(token,','))
    {
      printf("Parse error: expecting a ',' on line %d.\n", asm_context->line);
      return -1;
    }
  }

  asm_context->line++;

  return 0;
}
示例#26
0
/*
 * expand_macro - user-defined macro expansion
 */
void
expand_macro(const char *argv[], int argc)
{
	const char *t;
	const char *p;
	int n;
	int argno;

	t = argv[0];		       /* defn string as a whole */
	p = t;
	while (*p)
		p++;
	p--;			       /* last character of defn */
	while (p > t) {
		if (*(p - 1) != ARGFLAG)
			PUSHBACK(*p);
		else {
			switch (*p) {

			case '#':
				pbnum(argc - 2);
				break;
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				if ((argno = *p - '0') < argc - 1)
					pbstr(argv[argno + 1]);
				break;
			case '*':
				if (argc > 2) {
					for (n = argc - 1; n > 2; n--) {
						pbstr(argv[n]);
						pushback(COMMA);
					}
					pbstr(argv[2]);
				}
				break;
                        case '@':
				if (argc > 2) {
					for (n = argc - 1; n > 2; n--) {
						pbstr(rquote);
						pbstr(argv[n]);
						pbstr(lquote);
						pushback(COMMA);
					}
					pbstr(rquote);
					pbstr(argv[2]);
					pbstr(lquote);
				}
                                break;
			default:
				PUSHBACK(*p);
				PUSHBACK('$');
				break;
			}
			p--;
		}
		p--;
	}
	if (p == t)		       /* do last character */
		PUSHBACK(*p);
}
示例#27
0
void processtamil()
{
  char ch;
  int  newsyl;
  newsyl=true;
  for (tamilflag=true; tamilflag==true; ) {
    ch = getc(input);
    if (ch == EOF) abort();
    if (ch == switcher) changestate();
    else if (isspace(ch)) {
            stringout(tspace);
            charout(ch);            
            for ( ch=getc(input); isspace(ch); ch=getc(input)) charout(ch);
            pushback(ch);
            newsyl=true;
	    }
    else if (ispunct(ch) ) {
             if (ch == 125) printf("\nCharacter } encountered while scanning tamil -- probable error.\n");
             romanout(ch);
             newsyl=true;
             }
    else {
            switch (ch) {
                case 'a':
                case 'e':
                case 'i':
                case 'o':
                case 'u': if (newsyl==true) {
			      charout(tdelim);
			      newsyl=false;
			      }
                          charout(ch);
                          break;
                case 'c':
                case 't':
                case 'p':
                case 'm':
                case 'y':
                case 'r':
                case 'l':
                case 'v':
                case 's':
                case 'j':
                case 'x':
                case 'h': charout(tdelim);
                          charout(ch);
                          newsyl=false;
                          break;
                case 'k': charout(tdelim);
                          ch=getc(input);
                          if (ch=='4') charout('X');
                          else {
                              charout('k');
                              pushback(ch);
                              }
                          newsyl=false;
                          break;
                case '2': charout(tdelim);
                          charout('N');
                          newsyl=false;
                          break;
                case '3': charout(tdelim);
                          stringout("NN");
                          newsyl=false;
                          break;
                case '4': charout(tdelim);
                          charout('S');
                          newsyl=false;
                          break;
                case '5': charout(tdelim);
                          stringout("NY");
                          newsyl=false;
                          break;
                case '6': charout(tdelim);
                          charout('R');
                          newsyl=false;
                          break;
                case '7': charout(tdelim);
                          charout('Z');
                          newsyl=false;
                          break;
                case '8': charout(tdelim);
                          charout('T');
                          newsyl=false;
                          break;
                case '9': charout(tdelim);
                          charout('L');
                          newsyl=false;
                          break;
                case 'n': charout(tdelim);
                          ch=getc(input);
                          if (ch=='g') stringout("ng");
                          else {
                              charout('n');
                              pushback(ch);
                              }
                          newsyl=false;
                          break;
                default : transcribe_err(ch);
                          newsyl=true;
                } /* endcase */
    }  /* endif */
  }  /* endfor*/
}
示例#28
0
文件: main.c 项目: Alkzndr/freebsd
/*
 * macro - the work horse..
 */
static void
macro(void)
{
	char token[MAXTOK+1];
	int t, l;
	ndptr p;
	int  nlpar;

	cycle {
		t = gpbc();

		if (LOOK_AHEAD(t,lquote)) {	/* strip quotes */
			nlpar = 0;
			record(quotes, nlpar++);
			/*
			 * Opening quote: scan forward until matching
			 * closing quote has been found.
			 */
			do {

				l = gpbc();
				if (LOOK_AHEAD(l,rquote)) {
					if (--nlpar > 0)
						outputstr(rquote);
				} else if (LOOK_AHEAD(l,lquote)) {
					record(quotes, nlpar++);
					outputstr(lquote);
				} else if (l == EOF) {
					if (nlpar == 1)
						warnx("unclosed quote:");
					else
						warnx("%d unclosed quotes:", nlpar);
					dump_stack(quotes, nlpar);
					exit(1);
				} else {
					if (nlpar > 0) {
						if (sp < 0)
							reallyputchar(l);
						else
							CHRSAVE(l);
					}
				}
			}
			while (nlpar != 0);
		} else if (sp < 0 && LOOK_AHEAD(t, scommt)) {
			reallyoutputstr(scommt);

			for(;;) {
				t = gpbc();
				if (LOOK_AHEAD(t, ecommt)) {
					reallyoutputstr(ecommt);
					break;
				}
				if (t == EOF)
					break;
				reallyputchar(t);
			}
		} else if (t == '_' || isalpha(t)) {
			p = inspect(t, token);
			if (p != NULL)
				pushback(l = gpbc());
			if (p == NULL || (l != LPAREN &&
			    (macro_getdef(p)->type & NEEDARGS) != 0))
				outputstr(token);
			else {
		/*
		 * real thing.. First build a call frame:
		 */
				pushf(fp);	/* previous call frm */
				pushf(macro_getdef(p)->type); /* type of the call  */
				pushf(is_traced(p));
				pushf(0);	/* parenthesis level */
				fp = sp;	/* new frame pointer */
		/*
		 * now push the string arguments:
		 */
				pushs1(macro_getdef(p)->defn);	/* defn string */
				pushs1((char *)macro_name(p));	/* macro name  */
				pushs(ep);			/* start next..*/

				if (l != LPAREN && PARLEV == 0) {
				    /* no bracks  */
					chrsave(EOS);

					if (sp == (int)STACKMAX)
						errx(1, "internal stack overflow");
					eval((const char **) mstack+fp+1, 2,
					    CALTYP, TRACESTATUS);

					ep = PREVEP;	/* flush strspace */
					sp = PREVSP;	/* previous sp..  */
					fp = PREVFP;	/* rewind stack...*/
				}
			}
		} else if (t == EOF) {
			if (!mimic_gnu /* you can puke right there */
			    && sp > -1 && ilevel <= 0) {
				warnx( "unexpected end of input, unclosed parenthesis:");
				dump_stack(paren, PARLEV);
				exit(1);
			}
			if (ilevel <= 0)
				break;			/* all done thanks.. */
			release_input(infile+ilevel--);
			emit_synchline();
			bufbase = bbase[ilevel];
			continue;
		} else if (sp < 0) {		/* not in a macro at all */
			reallyputchar(t);	/* output directly..	 */
		}

		else switch(t) {

		case LPAREN:
			if (PARLEV > 0)
				chrsave(t);
			while (isspace(l = gpbc())) /* skip blank, tab, nl.. */
				if (PARLEV > 0)
					chrsave(l);
			pushback(l);
			record(paren, PARLEV++);
			break;

		case RPAREN:
			if (--PARLEV > 0)
				chrsave(t);
			else {			/* end of argument list */
				chrsave(EOS);

				if (sp == (int)STACKMAX)
					errx(1, "internal stack overflow");

				eval((const char **) mstack+fp+1, sp-fp,
				    CALTYP, TRACESTATUS);

				ep = PREVEP;	/* flush strspace */
				sp = PREVSP;	/* previous sp..  */
				fp = PREVFP;	/* rewind stack...*/
			}
			break;

		case COMMA:
			if (PARLEV == 1) {
				chrsave(EOS);		/* new argument   */
				while (isspace(l = gpbc()))
					;
				pushback(l);
				pushs(ep);
			} else
				chrsave(t);
			break;

		default:
			if (LOOK_AHEAD(t, scommt)) {
				char *cp;
				for (cp = scommt; *cp; cp++)
					chrsave(*cp);
				for(;;) {
					t = gpbc();
					if (LOOK_AHEAD(t, ecommt)) {
						for (cp = ecommt; *cp; cp++)
							chrsave(*cp);
						break;
					}
					if (t == EOF)
					    break;
					CHRSAVE(t);
				}
			} else
				CHRSAVE(t);		/* stack the char */
			break;
		}
	}
}
示例#29
0
文件: grammar.c 项目: nbdd0121/SakiOS
static js_token_t *lookahead(grammar_t *gmr) {
    js_token_t *ret = next(gmr);
    pushback(gmr, ret);
    return ret;
}
示例#30
0
static int parse_ifdef_expression(struct _asm_context *asm_context, int *num, int paren_count, int precedence, int state)
{
char token[TOKENLEN];
struct _operator operator;
int token_type;
//int state=0;  // 0 = get next num to process
int not=0;
int n1=0;
int n;

  operator.operation=OPER_NONE;
  operator.precedence=precedence;
  n=*num;

  while(1)
  {
    token_type=get_token(asm_context, token, TOKENLEN);

#ifdef DEBUG
printf("debug> #if: %d) %s   n=%d paren_count=%d precedence=%d state=%d\n", token_type, token, n, paren_count, precedence, state);
#endif

    if (token_type==TOKEN_EOL || token_type==TOKEN_EOF)
    {
      pushback(asm_context, token, token_type);

      if (paren_count!=0)
      {
        print_error("Unbalanced parentheses.", asm_context);
        return -1;
      }

      if (state!=1)
      {
        print_error("Unexpected end of expression.", asm_context);
        return -1;
      }

      if (operator.operation!=OPER_NONE)
      {
        n=eval_operation(operator.operation,n1,n);
#ifdef DEBUG
printf("debug> #if eval_operation() @EOL  n=%d precedence=%d state=%d\n", n, precedence, state);
#endif
        if (n==-1) { return -1; }
      }

      *num=n;
      return 0;
    }

    if (state!=1)
    {
      if (state==2)
      {
        n1=n;
      }

      if (token_type==TOKEN_SYMBOL)
      {
        if (IS_TOKEN(token,'!'))
        {
          not^=1;
          continue;
        }
          else
        if (IS_TOKEN(token,'('))
        {
          if (parse_ifdef_expression(asm_context, &n, paren_count+1, PREC_OR, 0)==-1) return -1;
        }
          else
        if (IS_TOKEN(token,')'))
        {
          if (paren_count==0)
          {
            print_error_unexp(token, asm_context);
            return -1;
          }

          if (state!=1)
          {
            print_error("Unexpected end of expression.", asm_context);
            return -1;
          }

          if (operator.operation!=OPER_NONE)
          {
            n=eval_operation(operator.operation,n1,n);
#ifdef DEBUG
printf("debug> #if eval_operation() @paren  n=%d\n", n);
#endif
            if (n==-1) { return -1; }
          }

          *num=n;
          return 0;
        }
      }
        else
      if (token_type==TOKEN_STRING)
      {
        int param_count;
        char *value=defines_heap_lookup(&asm_context->defines_heap, token, &param_count);

        if (strcasecmp(token, "defined")==0)
        {
          n=parse_defined(asm_context);
#ifdef DEBUG
printf("debug> #if: parse_defined()=%d\n", n);
#endif
          if (n==-1) return -1;
        }
          else
        if (value!=NULL && param_count==0 && is_num(value))
        {
          n=atoi(value);
        }
          else
        {
          print_error_unexp(token, asm_context);
          return -1;
        }
      }
        else
      if (token_type==TOKEN_NUMBER)
      {
        n=atoi(token);
      }

      if (not==1)
      {
        if (n==0)
        { n=1; }
          else
        { n=0; }

        not=0;
      }

#if 0
      if (state==2)
      {
#ifdef DEBUG
printf("debug> #if eval_operation() n1=%d n=%d\n", n1, n);
#endif
        n=eval_operation(operator.operation,n1,n);
        state=0;
#ifdef DEBUG
printf("debug> #if eval_operation() n=%d operation=%d\n", n, operator.operation);
#endif
      }
#endif

      state=1;
      continue;
    }

    if (token_type==TOKEN_SYMBOL || token_type==TOKEN_EQUALITY)
    {
      struct _operator next_operator;

      if (get_operator(token, &next_operator)==-1)
      {
        print_error_unexp(token, asm_context);
        return -1;
      }

#ifdef DEBUG
printf("debug> #if get_operator() token=%s operation=%d precedence=%d\n", token, next_operator.operation, next_operator.precedence);
#endif

      if (next_operator.precedence>precedence)
      {
        pushback(asm_context, token, token_type);
        if (parse_ifdef_expression(asm_context, &n, paren_count, next_operator.precedence, 1)==-1) return -1;
      }
        else
      if (next_operator.precedence<precedence)
      {
        pushback(asm_context, token, token_type);
        return 0;
      }
        else
      {
        state=2;

        if (operator.operation!=OPER_NONE)
        {
          n=eval_operation(operator.operation,n1,n);
#ifdef DEBUG
printf("debug> #if eval_operation() @ state 2  n=%d\n", n);
#endif
          if (n==-1) { return -1; }
        }

        operator=next_operator;
      }

      continue;
    }

    print_error_unexp(token, asm_context);
    return -1;
  }

  return -1;
}