Exemplo n.º 1
0
// unary-expr ::= - unary expr
//                + unary expr
//                ! unary expr
//                primary expr
Expr*
parse_unary_expr(Parser& p, Token_stream& ts)
{
  if(ts.next()) {
    switch (ts.next()->kind()) {
      // negative
      case minus_tok: return parse_neg(p, ts);
      case plus_tok: return parse_pos(p, ts);
      case bang_tok: return parse_not(p, ts);
      default:
        return parse_primary_expr(p, ts);
    }
  }

  return nullptr;
}
Exemplo n.º 2
0
Data* parse_expression( char **p )
{
	/*TODO: logic */
	//return parse_aexpr(p);
	Data* ret = NULL;
	while(1)
	{
		char op;
		int neg ;
		Data* aexpr;
		if( ret )
		{/*if it is not the first expression , a logic operator expected*/
			if( p[0][0] == 'A' && p[0][1] == 'N' && p[0][2] == 'D' && ( p[0][3] = ' ' || p[0][3] == '\t' ) )
			{
				op = 'A';
				(*p)+=4;
			}
			else if( p[0][0] == 'O' && p[0][1] == 'R' && ( p[0][2] = ' ' || p[0][2] == '\t' ) )
			 {
				op = 'O';
				(*p)+=3;
			}
			else break; /*if not operator */
		}
		neg  = parse_neg(p);
		aexpr = parse_aexpr(p);
		parse_ws(p);
		if( aexpr->type == TYPE_ERROR )
		{
			dispose(ret);
			return aexpr;
		}
		if( **p == '=' || **p == '>' || **p == '<' )
		{ 
			int flag;
			Data* right/* = parse_aexpr(p)*/;
			switch(**p)
		 	{
			case '=':
#define EQ 0
				flag = 0;  /*EQ*/
				(*p)++;
				break;
			case '>':
				if( p[0][1] == '=' )
				{
					(*p)+=2;
#define GE 3
					flag = 3;   /*GE*/
				}
				else
				{
#define G 1
					(*p)++;
					flag = 1;   /*G*/
				}
				break;
			case '<':
				if( p[0][1] == '=' )
				{
					(*p)+=2;
#define LE 4
					flag = 4; /*LE*/
				}
				else if( p[0][1] == '>' )
				{
					(*p)+=2;
#define NE 5
					flag = 5;  /*NE*/
				}
				else
				{
					(*p)++;
#define L 2
					flag = 2; /*L*/
				}
			}
			right = parse_aexpr(p);
			if( right->type == TYPE_ERROR )
			{
				dispose(ret);
				dispose(aexpr);
				return right;
			}
			if( right->type == TYPE_STRING )
			{//String
				if( aexpr->type != TYPE_STRING )
				{
					dispose(ret);
					dispose(aexpr);
					dispose(right);
					return Raise(TYPE_MISMATCH);
				}
				else
				{
					Data* temp = Data_new(TYPE_INTEGER,(Storage)(short)0,1); 
					int result = strcmp( aexpr->storage.String , right->storage.String);
					switch(flag)
					{
					case EQ:
						temp->storage.Integer = (result == 0);
						break;
					case L:
						temp->storage.Integer = (result < 0 );
						break;
					case LE:
						temp->storage.Integer = (result <= 0 );
						break;
					case G:
						temp->storage.Integer = (result > 0 );
						break;
					case GE:
						temp->storage.Integer = (result >= 0 );
						break;
					case NE:
						temp->storage.Integer = (result != 0 );
					}
					dispose(aexpr);
					dispose(right);
					aexpr = temp;
	
				}
			} 
			else 
			{//numeric
				if( aexpr->type == TYPE_STRING )
				{
					dispose(right);
					dispose(aexpr);
					dispose(ret);
					return Raise(TYPE_MISMATCH); 
				}
				else
				{
					Data* temp = Data_new(TYPE_INTEGER,(Storage)(short)0,1); 
					int result ;
					if( aexpr->type == TYPE_INTEGER )
					{
						aexpr->type = TYPE_REAL;
						aexpr->storage.Real = aexpr->storage.Integer;
					}
					if( right->type == TYPE_INTEGER )
					{
						right->type = TYPE_REAL;
						right->storage.Real = right->storage.Integer;
					}
					double t = aexpr->storage.Real - right->storage.Real;
					if( t < 0 ) result = -1;
					if( t == 0 ) result = 0;
					if( t > 0 ) result = 1;
					switch(flag)
					{
					case EQ:
						temp->storage.Integer = (result == 0);
						break;
					case L:
						temp->storage.Integer = (result < 0 );
						break;
					case LE:
						temp->storage.Integer = (result <= 0 );
						break;
					case G:
						temp->storage.Integer = (result > 0 );
						break;
					case GE:
						temp->storage.Integer = (result >= 0 );
						break;
					case NE:
						temp->storage.Integer = (result != 0 );
					}
					dispose(aexpr);
					dispose(right);
					aexpr = temp;
				}
			}	
		}
		if( aexpr->type == TYPE_ERROR )
		{
			dispose(ret);
			return aexpr; 
		}
		if( neg )
		{/*one or more NOT parsed*/
			if( aexpr->type == TYPE_STRING ) /*NOT "illegal"*/
			{
				dispose(aexpr);
				dispose(ret);
				return Raise(TYPE_MISMATCH );
			}
			if( aexpr->type == TYPE_REAL )
			{
				aexpr->type = TYPE_INTEGER;
				aexpr->storage.Integer = (int)(aexpr->storage.Real+.001);	
			}
			if( aexpr->storage.Integer )
				aexpr->storage.Integer = 1;
			else
				aexpr->storage.Integer = 0;
			if( neg < 0 )
				aexpr->storage.Integer = !aexpr->storage.Integer;
		}
		if( !ret )
		{/* first expression */
			ret = aexpr;
		}
		else
		{
			ret = temp_var(ret);
			if( aexpr->type == TYPE_STRING )
			{
				dispose(aexpr);
				dispose(ret);
				return Raise(TYPE_MISMATCH);
			}
			if( aexpr->type == TYPE_REAL )
			{
				aexpr->type = TYPE_INTEGER;
				aexpr->storage.Integer = (int)(aexpr->storage.Real+.001);
			}
			if( ret->type == TYPE_REAL )
			{
				ret->type = TYPE_INTEGER;
				ret->storage.Integer = (int)(ret->storage.Real+.001);
			}
			if( op == 'A' )
				ret->storage.Integer &= aexpr->storage.Integer;
			else
				ret->storage.Integer |= aexpr->storage.Integer;
			dispose(aexpr);
		}
	}
	return ret;
}