Beispiel #1
0
static AstExpression CheckBinaryExpression(AstExpression expr)
{
	expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);;
	expr->kids[1] = Adjust(CheckExpression(expr->kids[1]), 1);

	return (* BinaryOPCheckers[expr->op - OP_OR])(expr);
}
Beispiel #2
0
static AstExpression CheckFunctionCall(AstExpression expr)
{
	AstExpression arg;
	Type ty;
	AstNode *tail;
	int argNo, argFull;

	if (expr->kids[0]->op == OP_ID && LookupID(expr->kids[0]->val.p) == NULL)
	{
		expr->kids[0]->ty = DefaultFunctionType;
		expr->kids[0]->val.p = AddFunction(expr->kids[0]->val.p, DefaultFunctionType, TK_EXTERN);
	}
	else
	{
		expr->kids[0] = CheckExpression(expr->kids[0]);
	}
	expr->kids[0] = Adjust(expr->kids[0], 1);
	ty = expr->kids[0]->ty;

	if (! (IsPtrType(ty) && IsFunctionType(ty->bty)))
	{
		Error(&expr->coord, "The left operand must be function or function pointer");
	    ty = DefaultFunctionType;
	}
	else
	{
		ty = ty->bty;
	}

	tail = (AstNode *)&expr->kids[1];
	arg = expr->kids[1];
	argNo = 1;
	argFull = 0;
	while (arg != NULL && ! argFull)
	{
		*tail = (AstNode)CheckArgument((FunctionType)ty, arg, argNo, &argFull);
		tail = &(*tail)->next;
		arg = (AstExpression)arg->next;
		argNo++;
	}
	*tail = NULL;

	if (arg != NULL)
	{
		while (arg != NULL)
		{
			CheckExpression(arg);
			arg = (AstExpression)arg->next;
		}
		Error(&expr->coord, "Too many arguments");
	}
	else if (argNo < LEN(((FunctionType)ty)->sig->params))
	{
		Error(&expr->coord, "Too few arguments");
	}
	expr->ty = ty->bty;

	return expr;
}
Beispiel #3
0
static AstExpression CheckConditionalExpression(AstExpression expr)
{
	int qual;
	Type ty1, ty2;

	expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);

	if (! IsScalarType(expr->kids[0]->ty))
	{
		Error(&expr->coord, "The first expression shall be scalar type.");
	}
	expr->kids[1]->kids[0] = Adjust(CheckExpression(expr->kids[1]->kids[0]), 1);
	expr->kids[1]->kids[1] = Adjust(CheckExpression(expr->kids[1]->kids[1]), 1);

	ty1 = expr->kids[1]->kids[0]->ty;
	ty2 = expr->kids[1]->kids[1]->ty;
	if (BothArithType(ty1, ty2))
	{
		expr->ty = CommonRealType(ty1, ty2);
		expr->kids[1]->kids[0] = Cast(expr->ty, expr->kids[1]->kids[0]);
		expr->kids[1]->kids[1] = Cast(expr->ty, expr->kids[1]->kids[1]);

		return FoldConstant(expr);
	}
	else if (IsRecordType(ty1) && ty1 == ty2)
	{
		expr->ty = ty1;
	}
	else if (ty1->categ == VOID && ty2->categ == VOID)
	{
		expr->ty = T(VOID);
	}
	else if (IsCompatiblePtr(ty1, ty2))
	{
		qual = ty1->bty->qual | ty2->bty->qual;
		expr->ty  = PointerTo(Qualify(qual, CompositeType(Unqual(ty1->bty), Unqual(ty2->bty))));
	}
	else if (IsPtrType(ty1) && IsNullConstant(expr->kids[1]->kids[1]))
	{
		expr->ty = ty1;
	}
	else if (IsPtrType(ty2) && IsNullConstant(expr->kids[1]->kids[0]))
	{
		expr->ty = ty2;
	}
	else if (NotFunctionPtr(ty1) && IsVoidPtr(ty2) ||
	         NotFunctionPtr(ty2) && IsVoidPtr(ty1))
	{
		qual = ty1->bty->qual | ty2->bty->qual;
		expr->ty = PointerTo(Qualify(qual, T(VOID)));
	}
	else
	{
		Error(&expr->coord, "invalid operand for ? operator.");
		expr->ty = T(INT);
	}

	return expr;
}
Beispiel #4
0
static AstExpression CheckCommaExpression(AstExpression expr)
{
	expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
	expr->kids[1] = Adjust(CheckExpression(expr->kids[1]), 1);

	expr->ty = expr->kids[1]->ty;

	return expr;
}
Beispiel #5
0
static void CheckInitializer(AstInitializer init, Type ty)
{
	int offset = 0, error = 0;
	struct initData header;
	InitData tail = &header;
	InitData prev, curr;

	header.next = NULL;
	if (IsScalarType(ty) && init->lbrace)
	{
		init = (AstInitializer)init->initials;
	}
	else if (ty->categ == ARRAY && ! (ty->bty->categ == CHAR || ty->bty->categ == UCHAR))
	{
		if (! init->lbrace)
		{
			Error(&init->coord, "Can't initialize array without brace");
			return;
		}
	}
	else if ((ty->categ == STRUCT || ty->categ == UNION) && ! init->lbrace)
	{
		init->expr = Adjust(CheckExpression(init->expr), 1);
		if (! CanAssign(ty, init->expr))
		{
			Error(&init->coord, "Wrong initializer");
		}
		else
		{
			ALLOC(init->idata);
			init->idata->expr = init->expr;
			init->idata->offset = 0;
			init->idata->next = NULL;
		}
		return;
	}

	CheckInitializerInternal(&tail, init, ty, &offset, &error);
	if (error)
		return;

	init->idata = header.next;
	prev = NULL;
	curr = init->idata;
	while (curr)
	{
		if (prev != NULL && prev->offset == curr->offset)
		{
			prev->expr = BORBitField(prev->expr, curr->expr);
			prev->next = curr->next;
			curr = curr->next;
		}
		else
		{
			prev = curr;
			curr = curr->next;
		}
	}
}
Beispiel #6
0
AstExpression CheckConstantExpression(AstExpression expr)
{
	expr = CheckExpression(expr);
	if (! (expr->op == OP_CONST && IsIntegType(expr->ty)))
	{
		return NULL;
	}
	return expr;
}
Beispiel #7
0
static AstExpression CheckAssignmentExpression(AstExpression expr)
{
	int ops[] = 
	{ 
		OP_BITOR, OP_BITXOR, OP_BITAND, OP_LSHIFT, OP_RSHIFT, 
		OP_ADD,	  OP_SUB,    OP_MUL,    OP_DIV,    OP_MOD 
	};
	Type ty;
	
	expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 0);
	expr->kids[1] = Adjust(CheckExpression(expr->kids[1]), 1);

	if (! CanModify(expr->kids[0]))
	{
		Error(&expr->coord, "The left operand cannot be modified");
	}
	if (expr->op != OP_ASSIGN)
	{
		AstExpression lopr;

		CREATE_AST_NODE(lopr, Expression);
		lopr->coord   = expr->coord;
		lopr->op      = ops[expr->op - OP_BITOR_ASSIGN];
		lopr->kids[0] = expr->kids[0];
		lopr->kids[1] = expr->kids[1];

		expr->kids[1] = (*BinaryOPCheckers[lopr->op - OP_OR])(lopr);
	}

	ty = expr->kids[0]->ty;
	if (! CanAssign(ty, expr->kids[1]))
	{
		Error(&expr->coord, "Wrong assignment");
	}
	else
	{
		expr->kids[1] = Cast(ty, expr->kids[1]);
	}
	expr->ty = ty;
	return expr;
}
Beispiel #8
0
/**
 * Check argument.
 * @param fty function type
 * @param arg argument expression
 * @param argNo the argument's number in function call
 * @param argFull if the function's argument is full
 */
static AstExpression CheckArgument(FunctionType fty, AstExpression arg, int argNo, int *argFull)
{
	Parameter param;
	int parLen = LEN(fty->sig->params);

	arg = Adjust(CheckExpression(arg), 1);

	if (fty->sig->hasProto && parLen == 0)
	{
		*argFull = 1;
		return arg;
	}

	if (argNo == parLen && ! fty->sig->hasEllipse)
		*argFull = 1;
	
	if (! fty->sig->hasProto)
	{
		arg = PromoteArgument(arg);

		if (parLen != 0)
		{
			param = GET_ITEM(fty->sig->params, argNo - 1);
			if (! IsCompatibleType(arg->ty, param->ty))
				goto err;
		}

		return arg;
	}
	else if (argNo <= parLen)
	{
		param = GET_ITEM(fty->sig->params, argNo - 1);
		if (! CanAssign(param->ty, arg))
			goto err;

		if (param->ty->categ < INT)
			arg = Cast(T(INT), arg);
		else
			arg = Cast(param->ty, arg);

		return arg;
	}
	else
	{
		return PromoteArgument(arg);
	}

err:
	Error(&arg->coord, "Incompatible argument");
	return arg;
}
Beispiel #9
0
static AstExpression CheckPostfixExpression(AstExpression expr)
{
	switch (expr->op)
	{
	case OP_INDEX:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		expr->kids[1] = Adjust(CheckExpression(expr->kids[1]), 1);
		if (IsIntegType(expr->kids[0]->ty))
		{
			SWAP_KIDS(expr);
		}
		if (IsObjectPtr(expr->kids[0]->ty) && IsIntegType(expr->kids[1]->ty))
		{
			expr->ty = expr->kids[0]->ty->bty;
			expr->lvalue = 1;
			expr->kids[1] = DoIntegerPromotion(expr->kids[1]);
			expr->kids[1] = ScalePointerOffset(expr->kids[1], expr->ty->size);
			return expr;
		}
		REPORT_OP_ERROR;

	case OP_CALL:
		return CheckFunctionCall(expr);

	case OP_MEMBER:
	case OP_PTR_MEMBER:
		return CheckMemberAccess(expr);

	case OP_POSTINC:
	case OP_POSTDEC:
		return TransformIncrement(expr);

	default:
		assert(0);
	}

	REPORT_OP_ERROR;
}
Beispiel #10
0
static AstExpression CheckTypeCast(AstExpression expr)
{
	Type ty;

	ty = CheckTypeName((AstTypeName)expr->kids[0]);
	expr->kids[1] = Adjust(CheckExpression(expr->kids[1]), 1);

	if (! (BothScalarType(ty, expr->kids[1]->ty) || ty->categ == VOID))
	{
		Error(&expr->coord, "Illegal type cast");
		return expr->kids[1];
	}

	return Cast(ty, expr->kids[1]);
}
Beispiel #11
0
static AstExpression TransformIncrement(AstExpression expr)
{
	AstExpression casgn;
	union value val;
	
	val.i[1] = 0; val.i[0] = 1;
	CREATE_AST_NODE(casgn, Expression);
	casgn->coord = expr->coord;
	casgn->op = (expr->op == OP_POSTINC || expr->op == OP_PREINC) ? OP_ADD_ASSIGN : OP_SUB_ASSIGN;
	casgn->kids[0] = expr->kids[0];
	casgn->kids[1] = Constant(expr->coord, T(INT), val);

	expr->kids[0] = CheckExpression(casgn);
	expr->ty = expr->kids[0]->ty;
	return expr;
}
Beispiel #12
0
static AstExpression CheckMemberAccess(AstExpression expr)
{
	Type ty;
	Field fld;

	expr->kids[0] = CheckExpression(expr->kids[0]);
	if (expr->op == OP_MEMBER)
	{
		expr->kids[0] = Adjust(expr->kids[0], 0);
		ty = expr->kids[0]->ty;
		if (! IsRecordType(ty))
		{
			REPORT_OP_ERROR;
		}
		expr->lvalue = expr->kids[0]->lvalue;
	}
	else
	{
		expr->kids[0] = Adjust(expr->kids[0], 1);
		ty = expr->kids[0]->ty;
		if (! (IsPtrType(ty) && IsRecordType(ty->bty)))
		{
			REPORT_OP_ERROR;
		}
		ty = ty->bty;
		expr->lvalue = 1;
	}
	
	fld = LookupField(Unqual(ty), expr->val.p);
	if (fld == NULL)
	{
		Error(&expr->coord, "struct or union member %s doesn't exsist", expr->val.p);
		expr->ty = T(INT);
		return expr;
	}
	expr->ty = Qualify(ty->qual, fld->ty);
	expr->val.p = fld;
	expr->bitfld = fld->bits != 0;
	return expr;
}
Beispiel #13
0
static AstInitializer CheckInitializerInternal(InitData *tail, AstInitializer init, Type ty, 
                                               int *offset, int *error)
{
	AstInitializer p;
	int size = 0;
	InitData initd;

	if (IsScalarType(ty))
	{
		p = init;
		if (init->lbrace)
		{
			Error(&init->coord, "Can't use brace-enclosed initializer list for scalar");
			*error = 1;
			p = (AstInitializer)init->initials;
		}
		
		p->expr = Adjust(CheckExpression(p->expr), 1);
		if (! CanAssign(ty, p->expr))
		{
			Error(&init->coord, "Wrong initializer");
			*error = 1;
		}
		else
		{
			p->expr = Cast(ty, p->expr);
		}
		ALLOC(initd);
		initd->offset = *offset;
		initd->expr = p->expr;
		initd->next = NULL;
		(*tail)->next = initd;
		*tail = initd;

		return (AstInitializer)init->next;
	}
	else if (ty->categ == UNION)
	{
		p = init->lbrace ? (AstInitializer)init->initials : init;
		ty = ((RecordType)ty)->flds->ty;

		p = CheckInitializerInternal(tail, p, ty, offset, error);

		if (init->lbrace)
		{
			if (p != NULL)
			{
				Error(&init->coord, "too many initializer for union");
			}
			return (AstInitializer)init->next;
		}

		return p;
	}
	else if (ty->categ == ARRAY)
	{
		int start = *offset;
		p = init->lbrace ? (AstInitializer)init->initials : init;

		if (((init->lbrace && ! p->lbrace && p->next == NULL) || ! init->lbrace) &&
		    p->expr->op == OP_STR && ty->categ / 2 == p->expr->ty->categ / 2)
		{
			size = p->expr->ty->size;
			if (ty->size == 0 || ty->size == size)
			{
				ty->size = size;
			}
			else if (ty->size == size - 1)
			{
				p->expr->ty->size = size - 1;
			}
			else if (ty->size < size)
			{
				Error(&init->coord, "string is too long");
				*error = 1;
			}
			ALLOC(initd);
			initd->offset = *offset;
			initd->expr = p->expr;
			initd->next = NULL;
			(*tail)->next = initd;
			*tail = initd;

			return (AstInitializer)init->next;
		}

		while (p != NULL)
		{
			p = CheckInitializerInternal(tail, p, ty->bty, offset, error);
			size += ty->bty->size;
			*offset = start + size;
			if (ty->size == size)
				break;
		}
		
		if (ty->size == 0)
		{
			ty->size = size;
		}
		else if (ty->size < size)
		{
			Error(&init->coord, "too many initializer");
			*error = 1;
		}
	
		if (init->lbrace)
		{
			return (AstInitializer)init->next;
		}
		return p;
	}
	else if (ty->categ == STRUCT)
	{
		int start = *offset;
		Field fld = ((RecordType)ty)->flds;
		p = init->lbrace ? (AstInitializer)init->initials : init;
		
		while (fld && p)
		{
			*offset = start + fld->offset;
			p = CheckInitializerInternal(tail, p, fld->ty, offset, error);
			if (fld->bits != 0)
			{
				(*tail)->expr = PlaceBitField(fld, (*tail)->expr);
			}
			fld = fld->next;
		}

		if (init->lbrace)
		{
			if (p != NULL)
			{
				Error(&init->coord, "too many initializer");
				*error = 1;
			}
			*offset = ty->size;
			return (AstInitializer)init->next;
		}

		return (AstInitializer)p;
	}

	return init;
}
Beispiel #14
0
static struct lhsParseNode *CheckExpression(
  void *theEnv,
  struct lhsParseNode *exprPtr,
  struct lhsParseNode *lastOne,
  int whichCE,
  struct symbolHashNode *slotName,
  int theField)
  {
   struct lhsParseNode *rv;
   int i = 1;

   while (exprPtr != NULL)
     {
      /*===============================================================*/
      /* Check that single field variables contained in the expression */
      /* were previously defined in the LHS. Also check to see if the  */
      /* variable has unmatchable constraints.                         */
      /*===============================================================*/

      if (exprPtr->type == SF_VARIABLE)
        {
         if (exprPtr->referringNode == NULL)
           {
            VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,
                                          whichCE,slotName,theField);
            return(exprPtr);
           }
         else if ((UnmatchableConstraint(exprPtr->constraints)) &&
                  EnvGetStaticConstraintChecking(theEnv))
           {
            ConstraintReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,i,
                                            whichCE,slotName,theField);
            return(exprPtr);
           }
        }

      /*==================================================*/
      /* Check that multifield variables contained in the */
      /* expression were previously defined in the LHS.   */
      /*==================================================*/

      else if ((exprPtr->type == MF_VARIABLE) && (exprPtr->referringNode == NULL))
        {
         VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,
                                       whichCE,slotName,theField);
         return(exprPtr);
        }

      /*=====================================================*/
      /* Check that global variables are referenced properly */
      /* (i.e. if you reference a global variable, it must   */
      /* already be defined by a defglobal construct).       */
      /*=====================================================*/

#if DEFGLOBAL_CONSTRUCT
      else if (exprPtr->type == GBL_VARIABLE)
        {
         int count;

         if (FindImportedConstruct(theEnv,"defglobal",NULL,ValueToString(exprPtr->value),
                                   &count,TRUE,NULL) == NULL)
           {
            VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,
                                          whichCE,slotName,theField);
            return(exprPtr);
           }
        }
#endif

      /*============================================*/
      /* Recursively check other function calls to  */
      /* insure variables are referenced correctly. */
      /*============================================*/

      else if (((exprPtr->type == FCALL)
#if DEFGENERIC_CONSTRUCT
             || (exprPtr->type == GCALL)
#endif
#if DEFFUNCTION_CONSTRUCT
             || (exprPtr->type == PCALL)
#endif
         ) && (exprPtr->bottom != NULL))
        {
         if ((rv = CheckExpression(theEnv,exprPtr->bottom,exprPtr,whichCE,slotName,theField)) != NULL)
           { return(rv); }
        }

      /*=============================================*/
      /* Move on to the next part of the expression. */
      /*=============================================*/

      i++;
      exprPtr = exprPtr->right;
     }

   /*================================================*/
   /* Return NULL to indicate no error was detected. */
   /*================================================*/

   return(NULL);
  }
Beispiel #15
0
static intBool UnboundVariablesInPattern(
  void *theEnv,
  struct lhsParseNode *theSlot,
  int pattern)
  {
   struct lhsParseNode *andField;
   struct lhsParseNode *rv;
   int result;
   struct lhsParseNode *orField;
   struct symbolHashNode *slotName;
   CONSTRAINT_RECORD *theConstraints;
   int theField;

   /*===================================================*/
   /* If a multifield slot is being checked, then check */
   /* each of the fields grouped with the multifield.   */
   /*===================================================*/

   if (theSlot->multifieldSlot)
     {
      theSlot = theSlot->bottom;
      while (theSlot != NULL)
        {
         if (UnboundVariablesInPattern(theEnv,theSlot,pattern))
           { return(TRUE); }
         theSlot = theSlot->right;
        }

      return(FALSE);
     }

   /*=======================*/
   /* Check a single field. */
   /*=======================*/

   slotName = theSlot->slot;
   theField = theSlot->index;
   theConstraints = theSlot->constraints;

   /*===========================================*/
   /* Loop through each of the '|' constraints. */
   /*===========================================*/

   for (orField = theSlot->bottom;
        orField != NULL;
        orField = orField->bottom)
     {
      /*===========================================*/
      /* Loop through each of the fields connected */
      /* by the '&' within the '|' constraint.     */
      /*===========================================*/

      for (andField = orField;
           andField != NULL;
           andField = andField->right)
        {
         /*=======================================================*/
         /* If this is not a binding occurence of a variable and  */
         /* there is no previous binding occurence of a variable, */
         /* then generate an error message for a variable that is */
         /* referred to but not bound.                            */
         /*=======================================================*/

         if (((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE)) &&
             (andField->referringNode == NULL))
           {
            VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) andField->value,NULL,pattern,
                                          slotName,theField);
            return(TRUE);
           }

         /*==============================================*/
         /* Check predicate and return value constraints */
         /* to insure that all variables used within the */
         /* constraint have been previously bound.       */
         /*==============================================*/

         else if ((andField->type == PREDICATE_CONSTRAINT) ||
                  (andField->type == RETURN_VALUE_CONSTRAINT))
           {
            rv = CheckExpression(theEnv,andField->expression,NULL,pattern,slotName,theField);
            if (rv != NULL) return(TRUE);
           }

         /*========================================================*/
         /* If static constraint checking is being performed, then */
         /* determine if constant values have violated the set of  */
         /* derived constraints for the slot/field (based on the   */
         /* deftemplate definition and propagated constraints).    */
         /*========================================================*/

         else if (((andField->type == INTEGER) || (andField->type == FLOAT) ||
                   (andField->type == SYMBOL) || (andField->type == STRING) ||
                   (andField->type == INSTANCE_NAME)) &&
                  EnvGetStaticConstraintChecking(theEnv))
           {
            result = ConstraintCheckValue(theEnv,andField->type,andField->value,theConstraints);
            if (result != NO_VIOLATION)
              {
               ConstraintViolationErrorMessage(theEnv,"A literal restriction value",
                                               NULL,FALSE,pattern,
                                               slotName,theField,result,
                                               theConstraints,TRUE);
               return(TRUE);
              }
           }
        }
     }

   /*===============================*/
   /* Return FALSE to indicate that */
   /* no errors were detected.      */
   /*===============================*/

   return(FALSE);
  }
Beispiel #16
0
static int TestCEAnalysis(
  void *theEnv,
  struct lhsParseNode *patternPtr,
  struct lhsParseNode *theExpression,
  int secondary,
  int *errorFlag,
  struct nandFrame *theNandFrames)
  {
   struct lhsParseNode *rv, *theList, *tempList, *tempRight;

   if (theExpression == NULL) return FALSE;
   
   /*=====================================================*/
   /* Verify that all variables were referenced properly. */
   /*=====================================================*/

   rv = CheckExpression(theEnv,theExpression,NULL,(int) patternPtr->whichCE,NULL,0);

   /*====================================================================*/
   /* Temporarily disconnect the right nodes. If this is a pattern node  */
   /* with an attached test CE, we only want to propagate to following   */
   /* patterns, not to nodes of this pattern which preceded the test CE. */
   /*====================================================================*/
   
   tempRight = patternPtr->right;
   patternPtr->right = NULL;
      
   /*=========================================================*/
   /* Determine the type and value constraints implied by the */
   /* expression and propagate these constraints to other     */
   /* variables in the LHS. For example, the expression       */
   /* (+ ?x 1) implies that ?x is a number.                   */
   /*=========================================================*/
   
   theList = GetExpressionVarConstraints(theEnv,theExpression);
   for (tempList = theList; tempList != NULL; tempList = tempList->right)
      {
       if (PropagateVariableDriver(theEnv,patternPtr,patternPtr,NULL,SF_VARIABLE,
                                   (SYMBOL_HN *) tempList->value,tempList,FALSE,TEST_CE))
         {
          ReturnLHSParseNodes(theEnv,theList);
          patternPtr->right = tempRight;
          return(TRUE);
         }
      }
      
   ReturnLHSParseNodes(theEnv,theList);
   
   /*============================*/
   /* Reconnect the right nodes. */
   /*============================*/
   
   patternPtr->right = tempRight;
   
   /*========================================================*/
   /* If the variables in the expression were all referenced */
   /* properly, then create the expression to use in the     */
   /* join network.                                          */
   /*========================================================*/

   if (rv != NULL)
     { *errorFlag = TRUE; }
   else if (secondary)
     { patternPtr->secondaryNetworkTest = CombineExpressions(theEnv,patternPtr->secondaryNetworkTest,GetvarReplace(theEnv,theExpression,FALSE,theNandFrames)); }
   else
     { patternPtr->networkTest = CombineExpressions(theEnv,patternPtr->networkTest,GetvarReplace(theEnv,theExpression,FALSE,theNandFrames)); }
     
   return FALSE;
  }
Beispiel #17
0
void main()
{
  bool riesegui = false;

  do
  {
    // Letting the user insert a string
    cout << "Insert a string down here:\n";

    // Catching the string
    cin.getline(expression, 300);

    // Rimuovo gli spazi
    remove_spaces(expression);

    // Checking expression
    if (!CheckExpression(expression))
    {
      cout << "\nExpression syntax error...";
      getch();
      return;
    }

    parentesizza();

    aggiorna_posizioni();

    int max_level = 0;

    do
    {
      // Finding max level
      max_level = 0;

      for (int i = 0; i <= max_record_number; i++)
      {
        if (par[i].level > max_level) max_level = par[i].level;
      }

      //cout << "\nMax reached level: " << max_level;

      // Itering through the records with the higher level

      // Questa variabile conterrà il numero di expressioni
      // trovate in questo livello.
      int expressionNumber = 0;

      for (int a = 0; a <= max_record_number; a++)
      {

        // Entering here if we are enetering in the max level
        if (par[a].level == max_level)
        {

          // Itering through the number of operators present
          char tmp_expression[300];
          int c = 0;

          // Copying the string
          for (int b = (par[a].pos_open + 1); b < par[a].pos_close; b++)
          {
            tmp_expression[c++] = expression[b];
          }

          tmp_expression[c] = '\0';

          // Showing the string
          cout << "\nExpression: " << tmp_expression;

          // Copio la stringa in tmp_expression in splittedExpression
          for (b = 0; b < DIM_STRINGA_FINALE; b++)
          {
            splittedExpression[expressionNumber][b] = tmp_expression[b];
          }

          // Incremento il numero di espressioni estrette dalle parentesi
          // di livello maggiore nel ciclo corrente
          expressionNumber++;
        }
      }

      /*
      A questo punto splittedExpression[][] avrà tutte le espressioni
      contenute nelle parentesi più interne della prima espressione
      che devo risolvere. Il numero di espressioni estratte è determinato
      da (expressionNumber - 1).
      */

      // Risolvo tutte le espressioni
      // ============================

      // Ciclo su tutte le expressioni
      for (a = 0; a <= expressionNumber; a++)
      {
        // Ciclo su tutti gli elementi dell'array
        // Prima controlla la presenza di radici
        for (int b = 0; splittedExpression[a][b] != '\0';)
        {
          double secondoOperatore, risultato;

          // Se c'è scritta la r e dopo la r c'è un numero allora svolgo la raltrimenti lascio che prima venga svolto il resto
          if (splittedExpression[a][b] == 'r' && ((int)splittedExpression[a][b + 1] < 48 || (int)splittedExpression[a][b + 1] > 57) && splittedExpression[a][b + 1] != '+' && splittedExpression[a][b + 1] != '-')
          {
            riesegui = true;
            break;
          }

          if (splittedExpression[a][b] == 'r' && (((int)splittedExpression[a][b + 1] >= 48 && (int)splittedExpression[a][b + 1] <= 57) || splittedExpression[a][b + 1] == '+' || splittedExpression[a][b + 1] == '-'))
          {
            // Ho trovato una radice
            //find_first_second_operator(splittedExpression[a], b,
            //primoOperatore, secondoOperatore);
            secondoOperatore = find_argument(splittedExpression[a], b);

            risultato = sqrt(secondoOperatore);

            if (risultato < 0) 
            {
              cout << "\nNo number to the power of 2 is negative.\nThe program is not yet able to handle complex number.\n";
              return;
            }

            substitute_result(splittedExpression[a], b, risultato);

            //b = 0;

            cout << '\n' << splittedExpression[a];

            continue;
          }
          b++;
        }

        // Controllo la presenza di funzione trigonometriche nell'espressione
        for (b = 0; splittedExpression[a][b] != '\0';)
        {
          double risultato;

          switch((char)splittedExpression[a][b])
          {  
            // Se c'è scritta una di queste lettere controllo se è una funzione trigonometrica
            case 's':
            case 'c':
            case 't':
            case 'a':
            {
              double argomento = find_argument(splittedExpression[a], b);
              short int tipo_trigonometrica = istrigonometric(b, splittedExpression[a]);

              // So che è una trigonometrica, prima sapevo solamente che era una
              // parola che cominciava per quella lettera.
              if (tipo_trigonometrica)
              {

                switch(tipo_trigonometrica)
                {
                  case 1: {risultato = sin(argomento); break;}
                  case 2: {risultato = cos(argomento); break;}
                  case 3: {risultato = tan(argomento); break;}
                  case 4: {risultato = asin(argomento); break;}
                  case 5: {risultato = acos(argomento); break;}
                  case 6: {risultato = atan(argomento); break;}
                  case 7: {risultato = 1/tan(argomento); break;}
                  case 8: {risultato = 1/cos(argomento); break;}
                  case 9: {risultato = 1/sin(argomento); break;}
                  
                }
              
                substitute_result(splittedExpression[a], b, risultato);

                b = 0;

                //cout << '\n' << splittedExpression[a];

                continue;
              }
              else
              {
                cout << "\nError! Not recognised symbol.";
                getch();
                return;
              }
            }
          }
          b++;
        }

        // e successivamente di potenze
        for (b = 0; splittedExpression[a][b] != '\0';)
        {
          double primoOperatore, secondoOperatore, risultato;

          if (splittedExpression[a][b] == '^')
          {
            // Ho trovato una potenza
            find_first_second_operator(splittedExpression[a], b,
            primoOperatore, secondoOperatore);

            risultato = pow(primoOperatore, secondoOperatore);

            sostituisci(a, b, risultato);

            b = 0;

            cout << '\n' << splittedExpression[a];

            break;
          }
          b++;
        }

        for (b = 0; splittedExpression[a][b] != '\0';)
        {
          double primoOperatore, secondoOperatore, risultato;

          switch((char)splittedExpression[a][b])
          {
            case '*':
            {
              find_first_second_operator(splittedExpression[a], b,
              primoOperatore, secondoOperatore);

              risultato = primoOperatore * secondoOperatore;

              sostituisci(a, b, risultato);

              b = 0;

              cout << '\n' << splittedExpression[a];

              break;
            }
            case '/':
            {
              find_first_second_operator(splittedExpression[a], b,
              primoOperatore, secondoOperatore);
  
              risultato = primoOperatore / secondoOperatore;

              sostituisci(a, b, risultato);

              b = 0;

              cout << '\n' << splittedExpression[a];

              break;
            }
            default: b++;
          }
        }

        for (b = 0; splittedExpression[a][b] != '\0';)
        {        
          /*
          1. Trovo la posizione del simbolo
          2. Trovo i valori che stanno prima e dopo
             NOTA: Se non c'è ne sono allora visualizzo un msg d'errore
          3. Eseguo l'operazione determinata dal simbolo tra le due variabili
             contenenti i due valori.
          4. Sostituisco il risultato al posto dell'operazione.
          5. Continua il ciclo
          */

          double primoOperatore, secondoOperatore, risultato;

          // Se trovo un simbolo presente tra quelli consentiti
          switch((char)splittedExpression[a][b])
          {
            // In caso il simbolo sia + ...
            case '+':
            {
              // Trovo valore prima e dopo
              find_first_second_operator(splittedExpression[a], b /* posizione dell'operatore */,
              primoOperatore, secondoOperatore /*Passo l'indirizzo della variabile*/);

              // Eseguo l'operazione
              risultato = primoOperatore + secondoOperatore;

              // Sostituisco il risultato al posto dell'operazione
              sostituisci(a /* indice */, b /* posizione dell'operatore*/, risultato);

              // Azzero b per ricominciare da capo l'itering della stringa
              b = 0;

              // Showing the result
              cout << '\n' << splittedExpression[a];

              // breaking della case
              break;
            }
            case '-':
            {
              // Devo controllare che il segno sia inteso come operando
              if (b == 0) {b++; break;}

              // Controllo che prima ci sia un numero
              if (splittedExpression[a][b - 1] < 48 || splittedExpression[a][b - 1] > 57) {b++; break;} 

              find_first_second_operator(splittedExpression[a], b,
              primoOperatore, secondoOperatore);

              risultato = primoOperatore - secondoOperatore;

              sostituisci(a, b, risultato);

              b = 0;

              cout << '\n' << splittedExpression[a];

              break;
            }
            default: b++;
          }
        }
        if (riesegui == true) {a = -1; riesegui = false;}
      }

      // Dovrei aver ottenuto un numero di valori senza operatori pari a (expressionNumber - 1)

      // Visualizzo i risultati di tutte le parentesi (quelle con il lvello più alto
      /*for (int a = 0; a < expressionNumber; a++)
      {
        cout << splittedExpression[expressionNumber];
      }*/

      // Risolvo tutte le espressioni
      // Riciclo sull'espressione iniziale (expression[])
      // Quando incontro una parentesi di livello massimo
      // sostituisco il contenuto con il suo risultato.
      /*
        NOTA: Se c'è un simbolo prima della parentesi allora lo
        lascio, altrimenti metto il *
      */

      /*
        Vado a sostituire i valori risolti delle parentesi più interne all'interno
        dell'espressione intera e ricomincia il ciclo.
        max_record_number = numero di parentesi;
        max_level = livello massimo;
        splittedExpression[] = espressioni da sostituire;
        expressionNumber = numero di espressioni da sostituire;
        expression[] = espressione intera da risolvere;3.30
      */

      int numero_parentesi = max_record_number;

      int b = 0;

      for (a = 0; a <= numero_parentesi; a++)
      {
        if (par[a].level == max_level)
        {
          double numero = atof(splittedExpression[b++]);
          sostituisci_parentesi(par[a].pos_open, par[a].pos_close, numero);
          a = 0;
        }
      }
    } 
    while(max_level > 1);

    cout << "\n\n";
  }
  while(1);

  cout << '\n';

  return;
}
Beispiel #18
0
static AstExpression CheckUnaryExpression(AstExpression expr)
{
	Type ty;

	switch (expr->op)
	{
	case OP_PREINC:
	case OP_PREDEC:
		return TransformIncrement(expr);

	case OP_ADDRESS:
		expr->kids[0] = CheckExpression(expr->kids[0]);
		ty = expr->kids[0]->ty;
		if (expr->kids[0]->op == OP_DEREF)
		{
			expr->kids[0]->kids[0]->lvalue = 0;
			return expr->kids[0]->kids[0];
		}
		else if (expr->kids[0]->op == OP_INDEX)
		{
			expr->kids[0]->op = OP_ADD;
			expr->kids[0]->ty = PointerTo(ty);
			expr->kids[0]->lvalue = 0;
			return expr->kids[0];
		}
		else if (IsFunctionType(ty) || 
			     (expr->kids[0]->lvalue && ! expr->kids[0]->bitfld && ! expr->kids[0]->inreg))
		{
			expr->ty = PointerTo(ty);
			return expr;
		}
		break;

	case OP_DEREF:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		ty = expr->kids[0]->ty;
		if (expr->kids[0]->op == OP_ADDRESS)
		{
			expr->kids[0]->kids[0]->ty = ty->bty;
			return expr->kids[0]->kids[0];
		}
		else if (expr->kids[0]->op == OP_ADD && expr->kids[0]->kids[0]->isarray)
		{
			expr->kids[0]->op = OP_INDEX;
			expr->kids[0]->ty = ty->bty;
			expr->kids[0]->lvalue = 1;
			return expr->kids[0];
		}
		if (IsPtrType(ty))
		{
			expr->ty = ty->bty;
			if (IsFunctionType(expr->ty))
			{
				return expr->kids[0];
			}
			expr->lvalue = 1;
			return expr;
		}
		break;

	case OP_POS:
	case OP_NEG:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		if (IsArithType(expr->kids[0]->ty))
		{
			expr->kids[0] = DoIntegerPromotion(expr->kids[0]);
			expr->ty = expr->kids[0]->ty;
			return expr->op == OP_POS ? expr->kids[0] : FoldConstant(expr);
		}
		break;

	case OP_COMP:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		if (IsIntegType(expr->kids[0]->ty))
		{
			expr->kids[0] = DoIntegerPromotion(expr->kids[0]);
			expr->ty = expr->kids[0]->ty;
			return FoldConstant(expr);
		}
		break;

	case OP_NOT:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		if (IsScalarType(expr->kids[0]->ty))
		{
			expr->ty = T(INT);
			return FoldConstant(expr);
		}
		break;

	case OP_SIZEOF:
		if (expr->kids[0]->kind == NK_Expression)
		{
			expr->kids[0] = CheckExpression(expr->kids[0]);
			if (expr->kids[0]->bitfld)
				goto err;
			ty = expr->kids[0]->ty;
		}
		else
		{
			ty = CheckTypeName((AstTypeName)expr->kids[0]);
		}
		if (IsFunctionType(ty) || ty->size == 0)
			goto err;

		expr->ty = T(UINT);
		expr->op = OP_CONST;
		expr->val.i[0] = ty->size;
		return expr;

	case OP_CAST:
		return CheckTypeCast(expr);

	default:
		assert(0);
	}

err:
	REPORT_OP_ERROR;

}