Exemple #1
0
void JoinOperator::updateExpression(Expression *exp, unordered_map<string, Expression*> lm, unordered_map<string, Expression*> rm
        , string ltable, string rtable) {
    ExprType t = exp->getType();
    if(t != ExprType::COLEXPRESSION && t != ExprType::DOUBLEVALUEEXPRESSION && t != ExprType::STRINGVALUEEXPRESSION &&
       t != ExprType::LONGVALUEEXPRESSION && t != ExprType::DATEVALUEEXPRESSION){
        BinaryExpression* bexp = (BinaryExpression*)exp;
        updateExpression(bexp->getLeftExpression(), lm, rm, ltable, rtable);
        updateExpression(bexp->getRightExpression(), lm, rm, ltable, rtable);
    } else if(t == COLEXPRESSION){
        ColExpression* col = (ColExpression*)exp;
        if(lm.find(col->getQualifiedName()) != lm.end()){
            ColExpression* e = (ColExpression*)lm[col->getQualifiedName()];
            col->setType(e->getDataType());
            col->setColPos(e->getColPos());
            left.push_back(col);
        } else if(rm.find(col->getQualifiedName()) != rm.end()){
            ColExpression* e = (ColExpression*)rm[col->getQualifiedName()];
            col->setType(e->getDataType());
            col->setColPos(e->getColPos() + (int)lm.size());
            ColExpression *rcol = new ColExpression(col->getQualifiedName(), col->getColPos()-(int)lm.size(), col->getDataType());
            right.push_back(rcol);
        } else {
            std::cout << "column : " << col->getQualifiedName() << " not found in any schema " << std::endl;
        }
    }
}
void ProjectionOperator::updateExpression(Expression *newExp, unordered_map<std::string, Expression *> m, string tableName) {
	ExprType t = newExp->getType();
	if(t != ExprType::COLEXPRESSION && t != ExprType::DOUBLEVALUEEXPRESSION && t != ExprType::STRINGVALUEEXPRESSION &&
			t != ExprType::LONGVALUEEXPRESSION && t != ExprType::DATEVALUEEXPRESSION){
		BinaryExpression* b = (BinaryExpression*)newExp;
		updateExpression(b->getLeftExpression(), m, tableName);
		updateExpression(b->getRightExpression(), m, tableName);
	} else if(t == ExprType::COLEXPRESSION){
		if(((ColExpression*)newExp)->getTableName() == "")
			((ColExpression*)newExp)->setTableName(tableName);
		ColExpression* col = (ColExpression*)m[((ColExpression*)newExp)->getQualifiedName()];
		((ColExpression*)newExp)->setColPos(col->getColPos());
		((ColExpression*)newExp)->setType(col->getDataType());
	}
}
Exemple #3
0
static
String handle_static_binary_expression(CPrintStyleModule *state,
				       const SuifObject *obj)
{
  BinaryExpression *expr = to<BinaryExpression>(obj);
  LString opc = expr->get_opcode();
  String src_string1 = state->print_to_string(expr->get_source1());
  String src_string2 = state->print_to_string(expr->get_source2());
  // Should we special case: add, mod, etc?
  for (size_t i = 0; i < NUM_BINARY_OPER; i++ ) {
    if (*(binary_oper_table[i]._oper) == opc) {
      const char *op_char = binary_oper_table[i]._op_char;
      return(String("(") + src_string1 + op_char + src_string2 + ")");
    }
  }
      
  return(String(opc) + "(" + src_string1 + "," + src_string2 + ")");
}
VariableSymbol* ReferenceCleanupPass::FindVariable(Expression* e)
{
  LoadVariableExpression* lve = dynamic_cast<LoadVariableExpression*>(e) ;
  BinaryExpression* be = dynamic_cast<BinaryExpression*>(e) ;
    
  if (lve != NULL)
  {
    return lve->get_source() ;
  }

  if (be != NULL)
  {
    return FindVariable(be->get_source1()) ;
  }

  FormattedText tmpText ;
  e->print(tmpText) ;
  std::cout << tmpText.get_value() << std::endl ;

  return NULL ;
}
Exemple #5
0
ExpressionPtr OrExpression::getDNFImpl() const
{
    UnaryExpression * leftLeaf = dynamic_cast<UnaryExpression*>(left());
    UnaryExpression * rightLeaf = dynamic_cast<UnaryExpression*>(right());

    // A or B
    if (leftLeaf && rightLeaf)
    {
        return clone();
    }

    // A or (B and C) => (A and B) or (A and C)
    BinaryExpression * rightAnd = dynamic_cast<AndExpression*>(right());
    if (leftLeaf && rightAnd)
    {
        return Or(And(leftLeaf, rightAnd->left()),
                  And(leftLeaf, rightAnd->right()));
    }

    // (A and B) or C => (A and C) or (B and C)
    BinaryExpression * leftAnd = dynamic_cast<AndExpression*>(left());
    if (leftAnd && rightLeaf)
    {
        return Or(And(leftAnd->left(),  rightLeaf),
                  And(leftAnd->right(), rightLeaf));
    }

    return Or(left()->getDNF(), right()->getDNF());
}
Exemple #6
0
DataType Expression::getDataType() {
    ExprType t = this->getType();
    if(t == STRINGVALUEEXPRESSION)
        return STRING;
    if(t == DOUBLEVALUEEXPRESSION)
        return DOUBLE;
    if(t == LONGVALUEEXPRESSION)
        return LONG;
    if(t == DATEVALUEEXPRESSION)
        return DATE;
    if(t == ADDITIONEXPRESSION || t == SUBTRACTIONEXPRESSION || t == MULTIPLICATIONEXPRESSION || t == DIVISIONEXPRESSION){
        BinaryExpression* bexp = (BinaryExpression*)this;
        DataType t1 = bexp->getLeftExpression()->getDataType();
        DataType t2 = bexp->getRightExpression()->getDataType();
        if(t1 == DOUBLE || t2 == DOUBLE)
            return DOUBLE;
        return LONG;
    }
    if(t == COLEXPRESSION)
        return getDataType();
    //Boolean
    return LONG;
}
bool CombineSummationPass::IsSummation(Expression* e, VariableSymbol* v)
{
  assert(e != NULL) ;
  assert(v != NULL) ;

  BinaryExpression* binExp = dynamic_cast<BinaryExpression*>(e) ;
  if (binExp == NULL)
  {
    return false ;
  }

  if (binExp->get_opcode() != LString("add"))
  {
    return false ;
  }

  Expression* leftSide = binExp->get_source1() ;
  Expression* rightSide = binExp->get_source2() ;

  LoadVariableExpression* leftLoadVar = 
    dynamic_cast<LoadVariableExpression*>(leftSide) ;
  LoadVariableExpression* rightLoadVar = 
    dynamic_cast<LoadVariableExpression*>(rightSide) ;

  if (leftLoadVar != NULL && leftLoadVar->get_source() == v)
  {
    return true ;
  }
  
  if (rightLoadVar != NULL && rightLoadVar->get_source() == v)
  {
    return true ;
  }

  return IsSummation(leftSide, v) || IsSummation(rightSide, v) ;
}
Expression* ExpressionParser::parseExpression(std::vector<std::string> tokens){
	if(tokens.size() == 1)
		return leafExpression(tokens[0]);
	if(tokens.size() > 3 && tokens[tokens.size()-2] == "AS")
		return parseExpression(std::vector<std::string>(tokens.begin(), tokens.end()-2));
	for(int i = 0; i < tokens.size(); i++){
		if(logicalOperators.find(tokens[i]) != logicalOperators.end()){
			Expression *left = parseExpression(std::vector<std::string>(tokens.begin(), tokens.begin()+i));
			Expression *right = parseExpression(std::vector<std::string>(tokens.begin()+i+1, tokens.end()));
			BinaryExpression *op = NULL;
			op = binaryExpression(tokens[i]);
			op->setLeftExpression(left);
			op->setRightExpression(right);
			return op;
		}
	}
	for(int i = 0; i < tokens.size(); i++){
		if(relationalOperators.find(tokens[i]) != relationalOperators.end()){
			Expression *left = parseExpression(std::vector<std::string>(tokens.begin(), tokens.begin()+i));
			Expression *right = parseExpression(std::vector<std::string>(tokens.begin()+i+1, tokens.end()));
			BinaryExpression *op = NULL;
			op = binaryExpression(tokens[i]);
			op->setLeftExpression(left);
			op->setRightExpression(right);
			return op;
		}
	}
	for(int i = 0; i < tokens.size(); i++){
		if(arithmeticOperators.find(tokens[i]) != arithmeticOperators.end()){
			Expression *left = parseExpression(std::vector<std::string>(tokens.begin(), tokens.begin()+i));
			Expression *right = parseExpression(std::vector<std::string>(tokens.begin()+i+1, tokens.end()));
			BinaryExpression *op = NULL;
			op = binaryExpression(tokens[i]);
			op->setLeftExpression(left);
			op->setRightExpression(right);
			return op;
		}
	}
	raise_exception();
	return NULL;
}
Expression* CombineSummationPass::RemoveValue(Expression* original,
					      VariableSymbol* v)
{
  assert(original != NULL) ;
  assert(v != NULL) ;

  BinaryExpression* binExp = dynamic_cast<BinaryExpression*>(original) ;
  if (binExp == NULL)
  {
    return NULL ;
  }

  Expression* leftSide = binExp->get_source1() ;
  Expression* rightSide = binExp->get_source2() ;

  // Check to see if we are the correct format
  LoadVariableExpression* leftVar = 
    dynamic_cast<LoadVariableExpression*>(leftSide) ;
  LoadVariableExpression* rightVar = 
    dynamic_cast<LoadVariableExpression*>(rightSide) ;
  if (leftVar != NULL && leftVar->get_source() == v)
  {
    binExp->set_source2(NULL) ;
    return rightSide ;
  }
  if (rightVar != NULL && rightVar->get_source() == v)
  {
    binExp->set_source1(NULL) ;
    return leftSide ;
  }
  // Recursively go through and find the value
  Expression* leftSideReplacement = RemoveValue(leftSide, v) ;
  if (leftSideReplacement != NULL)
  {
    binExp->set_source2(leftSideReplacement) ;
    return binExp ;
  }
  Expression* rightSideReplacement = RemoveValue(rightSide, v) ;
  if (rightSideReplacement != NULL)
  {
    binExp->set_source2(rightSideReplacement) ;
    return binExp ;
  }
  return NULL ;
}
Exemple #10
0
void SemanticsVisitor::visit(BinaryExpression& bexpr) {
	visitChildren(bexpr);
	bexpr.setType(bexpr.binaryResultType());
}
Exemple #11
0
/* Another helper function for print_var_def().   This function
 * expects that it will need to add a return before printing
 * anything, and it expects that you will add a return after
 * it is done.
 * It returns the number of bits of initialization data that it
 * generates.
 */
int
PrinterX86::process_value_block(ValueBlock *vblk)
{
    int bits_filled = 0;

    if (is_a<ExpressionValueBlock>(vblk)) {
	// An ExpressionValueBlock either holds a constant value or a
	// simple expression representing either an address relative to
	// a symbol or a pointer generated by conversion from an integer
	// constant (presumably zero).

	ExpressionValueBlock *evb = (ExpressionValueBlock*)vblk;
	Expression *exp = evb->get_expression();

	if (is_a<IntConstant>(exp)) {
	    IntConstant *ic = (IntConstant*)exp;
	    bits_filled = print_size_directive(ic->get_result_type());
	    fprint(out, ic->get_value());
	    cur_opnd_cnt++;
	}
	else if (is_a<FloatConstant>(exp)) {
	    FloatConstant *fc = (FloatConstant*)exp;
	    bits_filled = print_size_directive(fc->get_result_type());
	    fputs(fc->get_value().c_str(), out);
	    cur_opnd_cnt++;
	}
	else {
	    // We use non-constant ExpressionValueBlocks to hold a symbolic
	    // address, optionally with an offset, or a pointer initializer
	    // consisting of a `convert' expression.
	    // A SymbolAddressExpression represents a plain symbolic
	    // address.
	    // An address obtained by conversion from another type is a
	    // unary expression with opcode "convert".
	    // A symbol+delta is represented by an add whose first operand
	    // is the load-address and whose second is an IntConstant
	    // expression.
	    // No other kind of "expression" is recognized.

	    if (is_a<UnaryExpression>(exp)) {
		UnaryExpression *ux = (UnaryExpression*)exp;
		claim(ux->get_opcode() == k_convert,
		      "unexpected unary expression in expression block");
		DataType *tt = ux->get_result_type();	// target type
		claim(is_kind_of<PointerType>(tt),
		      "unexpected target type when converting initializer");
		exp = ux->get_source();
		if (is_a<IntConstant>(exp)) {
		    IntConstant *ic = (IntConstant*)exp;
		    bits_filled = print_size_directive(tt);
		    fprint(out, ic->get_value());
		    cur_opnd_cnt++;
		    return bits_filled;
		}
		// Fall through to handle symbol-relative address, on the
		// assumption that the front end validated the conversion.
	    }
	    SymbolAddressExpression *sax;
	    long delta;
	    if (is_a<BinaryExpression>(exp)) {
		BinaryExpression *bx = (BinaryExpression*)exp;
		claim(bx->get_opcode() == k_add,
		      "unexpected binary expression in expression block");
		Expression *s1 = bx->get_source1();
		Expression *s2 = bx->get_source2();
		sax = to<SymbolAddressExpression>(s1);
		delta = to<IntConstant>(s2)->get_value().c_long();
	    } else if (is_a<SymbolAddressExpression>(exp)) {
		sax = (SymbolAddressExpression*)exp;
		delta = 0;
	    } else {
		claim(false, "unexpected kind of expression block");
	    }
	    Sym *sym = sax->get_addressed_symbol();

	    // symbol initialization
	    bits_filled = print_size_directive(type_ptr);
	    print_sym(sym);
	    if (delta != 0) {
		fprintf(out, "%+ld", delta);
	    }
	    // always force the start of a new data directive
	    cur_opcode = opcode_null;
	    cur_opnd_cnt = 0;
	}
    }

    else if (is_a<MultiValueBlock>(vblk)) {
	MultiValueBlock *mvb = (MultiValueBlock*)vblk;
	for (int i = 0; i < mvb->get_sub_block_count(); i++ ) {
	    int offset = mvb->get_sub_block(i).first.c_int();
	    claim(offset >= bits_filled);

	    if (bits_filled < offset)		// pad to offset
		bits_filled += print_bit_filler(offset - bits_filled);
	    bits_filled += process_value_block(mvb->get_sub_block(i).second);
	}
	int all_bits = get_bit_size(mvb->get_type());
	if (all_bits > bits_filled)
	    bits_filled += print_bit_filler(all_bits - bits_filled);

    } else if (is_a<RepeatValueBlock>(vblk)) {
	// Simplifying assumption: We now expect the front-end
	// to remove initialization code of large arrays of zeros.
	RepeatValueBlock *rvb = (RepeatValueBlock*)vblk;
	int repeat_cnt = rvb->get_num_repetitions();

	if (repeat_cnt > 1) {		// insert .repeat pseudo-op
	    fprintf(out, "\n\t%s\t%d", x86_opcode_names[REPEAT], repeat_cnt);
	    cur_opcode = opcode_null;	// force new data directive
	}
	// actual data directive
	bits_filled = repeat_cnt * process_value_block(rvb->get_sub_block());

	if (repeat_cnt > 1) {		// insert .endr pseudo-op
	    fprintf(out, "\n\t%s", x86_opcode_names[ENDR]);
	    cur_opcode = opcode_null;	// force new data directive
	}

    } else if (is_a<UndefinedValueBlock>(vblk)) {
	bits_filled += print_bit_filler(get_bit_size(vblk->get_type()));

    } else {
	claim(false, "unexpected kind of ValueBlock");
    }
    return bits_filled;
}
void CombineSummationPass::do_procedure_definition(ProcedureDefinition* p)
{
  procDef = p ;
  assert(procDef != NULL) ;

  OutputInformation("Combine summation pass begins") ;

  StatementList* innermost = InnermostList(procDef) ;
  assert(innermost != NULL) ;

  bool change = false ;
  do
  {
    // Find the first summation
    StoreVariableStatement* firstStatement = NULL ;
    StoreVariableStatement* secondStatement = NULL ;
    change = false ;
    int i ;
    int firstStatementPosition = -1 ;
    i = 0 ;
    while (i < innermost->get_statement_count())
    {
      StoreVariableStatement* currentStoreVariable =
	dynamic_cast<StoreVariableStatement*>(innermost->get_statement(i)) ;
      if (currentStoreVariable != NULL && IsSummation(currentStoreVariable))
      {
	firstStatement = currentStoreVariable ;
	firstStatementPosition = i ;
	break ;
      }
	++i ;
    }
    
    if (firstStatement != NULL)
    {
      VariableSymbol* firstDest = firstStatement->get_destination() ;
      for (int j = i+1 ; j < innermost->get_statement_count() ; ++j)
      {
	StoreVariableStatement* nextStoreVar = 
	  dynamic_cast<StoreVariableStatement*>(innermost->get_statement(j));
	if (nextStoreVar != NULL && IsSummation(nextStoreVar, firstDest))
	{
	  secondStatement = nextStoreVar ;
	  break ;
	}
	if (IsDefinition(innermost->get_statement(j), firstDest) ||
	    HasUses(innermost->get_statement(j), firstDest))
	{
	  break ;
	}						
      }
    }
    if (secondStatement != NULL)
    {
      // Go through each of the variables used in the first statement and
      //  make sure there are no definitions to any of them.
      //  I only have to worry about variables and not array accesses because
      //  we don't allow them to read and write to array values.
      int originalPosition = DeterminePosition(innermost, firstStatement) ;
      assert(originalPosition >= 0) ;
      list<VariableSymbol*> usedVars = 
	AllUsedVariablesBut(firstStatement, firstStatement->get_destination());
      bool goodPath = true ;
      for (int j = originalPosition ; 
	   j < innermost->get_statement_count() && 
	     innermost->get_statement(j) != secondStatement ; 
	   ++j)
      {
	list<VariableSymbol*>::iterator usedIter = usedVars.begin() ;
	while (usedIter != usedVars.end())
	{
	  if (IsOutputVariable((*usedIter), innermost->get_statement(j)))
	  {
	    goodPath = false ;
	    break ;
	  }
	  ++usedIter ;
	}
	if (!goodPath) 
	{
	  break ;
	}
      }
      if (!goodPath)
      {
	continue ;
      }
      // Actually do the combining here
      change = true ;
      Expression* remains = RemoveValue(firstStatement) ;
      Expression* secondRemains = RemoveValue(secondStatement) ;
      // Create two binary expressions
      BinaryExpression* remainsSum = 
	create_binary_expression(theEnv,
				 remains->get_result_type(),
				 LString("add"),
				 remains,
				 secondRemains) ;
      LoadVariableExpression* loadDest = 
	create_load_variable_expression(theEnv,
	    secondStatement->get_destination()->get_type()->get_base_type(),
					secondStatement->get_destination()) ;
      BinaryExpression* finalSum =
	create_binary_expression(theEnv,
				 remainsSum->get_result_type(),
				 LString("add"),
				 remainsSum,
				 loadDest) ;

      secondStatement->set_value(finalSum) ;
      // Delete?
      innermost->remove_statement(firstStatementPosition) ;
    }
     
  } while (change == true) ;  

  OutputInformation("Combine summation pass ends") ;
}
/**
 * $ANTLR start boolean_term
 * /home/cross/workspace/djondb/db/grammars/filter_expression.g:88:1: boolean_term returns [BaseExpression* val] : b1= boolean_value ( AND b2= boolean_value )* ;
 */
static BaseExpression*
boolean_term(pfilter_expressionParser ctx)
{
    BaseExpression* val;


    BaseExpression* b1;
    #undef	RETURN_TYPE_b1
    #define	RETURN_TYPE_b1 BaseExpression*

    BaseExpression* b2;
    #undef	RETURN_TYPE_b2
    #define	RETURN_TYPE_b2 BaseExpression*

    /* Initialize rule variables
     */

    {
        // /home/cross/workspace/djondb/db/grammars/filter_expression.g:89:2: (b1= boolean_value ( AND b2= boolean_value )* )
        // /home/cross/workspace/djondb/db/grammars/filter_expression.g:89:4: b1= boolean_value ( AND b2= boolean_value )*
        {
            FOLLOWPUSH(FOLLOW_boolean_value_in_boolean_term138);
            b1=boolean_value(ctx);

            FOLLOWPOP();
            if  (HASEXCEPTION())
            {
                goto ruleboolean_termEx;
            }


            {

                	   val= 
                b1
                ;

                	
            }


            // /home/cross/workspace/djondb/db/grammars/filter_expression.g:93:3: ( AND b2= boolean_value )*

            for (;;)
            {
                int alt2=2;
                switch ( LA(1) )
                {
                case AND:
                	{
                		alt2=1;
                	}
                    break;

                }

                switch (alt2)
                {
            	case 1:
            	    // /home/cross/workspace/djondb/db/grammars/filter_expression.g:93:4: AND b2= boolean_value
            	    {
            	         MATCHT(AND, &FOLLOW_AND_in_boolean_term146);
            	        if  (HASEXCEPTION())
            	        {
            	            goto ruleboolean_termEx;
            	        }


            	        FOLLOWPUSH(FOLLOW_boolean_value_in_boolean_term150);
            	        b2=boolean_value(ctx);

            	        FOLLOWPOP();
            	        if  (HASEXCEPTION())
            	        {
            	            goto ruleboolean_termEx;
            	        }


            	        {

            	            	   BinaryExpression* be = new BinaryExpression(FO_AND);
            	            	   be->push(val
            	            );
            	            	   be->push(b2
            	            );
            	            	   val= be;

            	            	 
            	        }


            	    }
            	    break;

            	default:
            	    goto loop2;	/* break out of the loop */
            	    break;
                }
            }
            loop2: ; /* Jump out to here if this rule does not match */


        }

    }

    // This is where rules clean up and exit
    //
    goto ruleboolean_termEx; /* Prevent compiler warnings */
    ruleboolean_termEx: ;



    return val;
}
/**
 * $ANTLR start boolean_expr
 * /home/cross/workspace/djondb/db/grammars/filter_expression.g:76:1: boolean_expr returns [BaseExpression* val] : b1= boolean_term ( OR b2= boolean_term )* ;
 */
static BaseExpression*
boolean_expr(pfilter_expressionParser ctx)
{
    BaseExpression* val;


    BaseExpression* b1;
    #undef	RETURN_TYPE_b1
    #define	RETURN_TYPE_b1 BaseExpression*

    BaseExpression* b2;
    #undef	RETURN_TYPE_b2
    #define	RETURN_TYPE_b2 BaseExpression*

    /* Initialize rule variables
     */

    {
        // /home/cross/workspace/djondb/db/grammars/filter_expression.g:77:2: (b1= boolean_term ( OR b2= boolean_term )* )
        // /home/cross/workspace/djondb/db/grammars/filter_expression.g:77:4: b1= boolean_term ( OR b2= boolean_term )*
        {
            FOLLOWPUSH(FOLLOW_boolean_term_in_boolean_expr107);
            b1=boolean_term(ctx);

            FOLLOWPOP();
            if  (HASEXCEPTION())
            {
                goto ruleboolean_exprEx;
            }


            {

                	   val= 
                b1
                ;

                	
            }


            // /home/cross/workspace/djondb/db/grammars/filter_expression.g:81:2: ( OR b2= boolean_term )*

            for (;;)
            {
                int alt1=2;
                switch ( LA(1) )
                {
                case OR:
                	{
                		alt1=1;
                	}
                    break;

                }

                switch (alt1)
                {
            	case 1:
            	    // /home/cross/workspace/djondb/db/grammars/filter_expression.g:81:3: OR b2= boolean_term
            	    {
            	         MATCHT(OR, &FOLLOW_OR_in_boolean_expr115);
            	        if  (HASEXCEPTION())
            	        {
            	            goto ruleboolean_exprEx;
            	        }


            	        FOLLOWPUSH(FOLLOW_boolean_term_in_boolean_expr119);
            	        b2=boolean_term(ctx);

            	        FOLLOWPOP();
            	        if  (HASEXCEPTION())
            	        {
            	            goto ruleboolean_exprEx;
            	        }


            	        {

            	            	   BinaryExpression* be = new BinaryExpression(FO_OR);
            	            	   be->push(val
            	            );
            	            	   be->push(b2
            	            );
            	            	   val= be;

            	            	
            	        }


            	    }
            	    break;

            	default:
            	    goto loop1;	/* break out of the loop */
            	    break;
                }
            }
            loop1: ; /* Jump out to here if this rule does not match */


        }

    }

    // This is where rules clean up and exit
    //
    goto ruleboolean_exprEx; /* Prevent compiler warnings */
    ruleboolean_exprEx: ;



    return val;
}
/**
 * $ANTLR start nonparentherized_boolean
 * /home/cross/workspace/djondb/db/grammars/filter_expression.g:114:1: nonparentherized_boolean returns [BaseExpression* val] : u1= unary_expr ( OPER u2= unary_expr )* ;
 */
static BaseExpression*
nonparentherized_boolean(pfilter_expressionParser ctx)
{
    BaseExpression* val;


    pANTLR3_COMMON_TOKEN    OPER6;
    BaseExpression* u1;
    #undef	RETURN_TYPE_u1
    #define	RETURN_TYPE_u1 BaseExpression*

    BaseExpression* u2;
    #undef	RETURN_TYPE_u2
    #define	RETURN_TYPE_u2 BaseExpression*

    /* Initialize rule variables
     */

    OPER6       = NULL;

    {
        // /home/cross/workspace/djondb/db/grammars/filter_expression.g:115:2: (u1= unary_expr ( OPER u2= unary_expr )* )
        // /home/cross/workspace/djondb/db/grammars/filter_expression.g:115:4: u1= unary_expr ( OPER u2= unary_expr )*
        {
            FOLLOWPUSH(FOLLOW_unary_expr_in_nonparentherized_boolean215);
            u1=unary_expr(ctx);

            FOLLOWPOP();
            if  (HASEXCEPTION())
            {
                goto rulenonparentherized_booleanEx;
            }


            {

                	   val= 
                u1
                ;

                	
            }


            // /home/cross/workspace/djondb/db/grammars/filter_expression.g:117:4: ( OPER u2= unary_expr )*

            for (;;)
            {
                int alt4=2;
                switch ( LA(1) )
                {
                case OPER:
                	{
                		alt4=1;
                	}
                    break;

                }

                switch (alt4)
                {
            	case 1:
            	    // /home/cross/workspace/djondb/db/grammars/filter_expression.g:117:6: OPER u2= unary_expr
            	    {
            	        OPER6 = (pANTLR3_COMMON_TOKEN) MATCHT(OPER, &FOLLOW_OPER_in_nonparentherized_boolean221);
            	        if  (HASEXCEPTION())
            	        {
            	            goto rulenonparentherized_booleanEx;
            	        }


            	        FOLLOWPUSH(FOLLOW_unary_expr_in_nonparentherized_boolean225);
            	        u2=unary_expr(ctx);

            	        FOLLOWPOP();
            	        if  (HASEXCEPTION())
            	        {
            	            goto rulenonparentherized_booleanEx;
            	        }


            	        {

            	            	   FILTER_OPERATORS oper = parseFilterOperator((char*)(OPER6->getText(OPER6))->chars);
            	            	   BinaryExpression* be = new BinaryExpression(oper);
            	            	   be->push(
            	            val
            	            );
            	            	   be->push(u2
            	            );
            	            	   val= be;

            	            	
            	        }


            	    }
            	    break;

            	default:
            	    goto loop4;	/* break out of the loop */
            	    break;
                }
            }
            loop4: ; /* Jump out to here if this rule does not match */


        }

    }

    // This is where rules clean up and exit
    //
    goto rulenonparentherized_booleanEx; /* Prevent compiler warnings */
    rulenonparentherized_booleanEx: ;



    return val;
}
Exemple #16
0
// visitForTest helps optimize statements with expressions like:
//    if (x && y || z)
//
// Where, with a naive conversion we would reduce (x && y) to a boolean, and
// then reduce (that || z) to another boolean, and another test - we can simply
// test each individual component and combine the jump paths with the paths
// the if-test needs to take.
//
// Unfortunately, this logic comes at a complexity price: it is illegal to
// emit non-statements from SemA, since the following situation could occur:
//    (1) SemA builds HIR chain #1 for statement X.
//    (2) SemA builds HIR chain #2 for statement X.
//    (3) SemA forces HIR chain #2 to be emitted to the code stream.
//    (4) SemA emits statement X, with HIR chain #1.
//
// In this situation, the HIR chains have been emitted out-of-order. So,
// visitForTest takes in a HIRList which it populates with instructions, which
// may include internal statements (like jumps and binds).
//
// The trueBranch and falseBranch parameters are self-explanatory. The
// fallthrough case describes which branch comes immediately after the
// test. This is used to optimize cases like:
//   if (x) {
//     ...
//   }
//   do {
//     ...
//   } while (y);
//
// After testing |x|, if it evaluated to true, there is no need to jump to the
// true branch, because we'll fallthrough (as long as the expression does not
// have logical ands/ors which could short-circuit). Similarly for |y|, the
// false condition does not need an actual jump target.
//
void
SemanticAnalysis::visitForTest(HIRList *output,
                               Expression *expr,
                               Label *trueBranch,
                               Label *falseBranch,
                               Label *fallthrough)
{
  Type *boolType = cc_.types()->getPrimitive(PrimitiveType::Bool);

  // Handle logical and/or.
  BinaryExpression *bin = expr->asBinaryExpression();
  if (bin && (bin->token() == TOK_AND || bin->token() == TOK_OR)) {
    HLabel *next = new (pool_) HLabel();
    if (bin->token() == TOK_AND)
      visitForTest(output, bin->left(), next, falseBranch, next);
    else
      visitForTest(output, bin->left(), trueBranch, next, next);
    output->append(new (pool_) HBind(expr, next));
    visitForTest(output, bin->right(), trueBranch, falseBranch, fallthrough);
    return;
  }

  // Handle equality and relational operators.
  if (bin && (bin->token() >= TOK_EQUALS && bin->token() <= TOK_GE)) {
    HIR *left = rvalue(bin->left());
    HIR *right = rvalue(bin->right());
    if (!left || !right)
      return;
    Type *coercion = coercionType(bin->token(), left, right);
    if (!coercion ||
        ((left = coerce(left, coercion, Coerce_Arg)) == nullptr) ||
        ((right = coerce(right, coercion, Coerce_Arg)) == nullptr))
    {
      return;
    }
    Label *target = (fallthrough == trueBranch) ? falseBranch : trueBranch;
    TokenKind token = (fallthrough == trueBranch)
                      ? InvertTest(bin->token())
                      : bin->token();
    output->append(new (pool_) HCompareAndJump(bin, token, left, right, target));
    return;
  }

  // Handle unary not (!)
  UnaryExpression *unary = expr->asUnaryExpression();
  if (unary && unary->token() == TOK_NOT) {
    // Re-invoke visitForTest but invert the branches. Note that we don't touch
    // |fallthrough|, since it's used to determine whether to jump on success
    // or failure, so inverting it as well would do nothing.
    visitForTest(output, unary->expression(), falseBranch, trueBranch, fallthrough);
    return;
  }

  // We couldn't match anything easy, so just coerce the input to a boolean.
  HIR *hir = rvalue(expr);
  if (!hir || ((hir = coerce(hir, boolType, Coerce_Assign)) == nullptr))
    return;

  if (fallthrough == falseBranch)
    output->append(new (pool_) HJump(expr, hir, true, trueBranch));
  else
    output->append(new (pool_) HJump(expr, hir, false, falseBranch));
}