Example #1
0
File: expr.c Project: M-ike/work
/**
 *  conditional-expression:
 *      logical-OR-expression
 *      logical-OR-expression ? expression : conditional-expression
 */
static AstExpression ParseConditionalExpression(void)
{
	AstExpression expr;

	expr = ParseBinaryExpression(Prec[OP_OR]);
	if (CurrentToken == TK_QUESTION)
	{
		AstExpression condExpr;

		CREATE_AST_NODE(condExpr, Expression);

		condExpr->op = OP_QUESTION;
		condExpr->kids[0] = expr;
		NEXT_TOKEN;

		CREATE_AST_NODE(condExpr->kids[1], Expression);

		condExpr->kids[1]->op = OP_COLON;
		condExpr->kids[1]->kids[0] = ParseExpression();
		Expect(TK_COLON);
		condExpr->kids[1]->kids[1] = ParseConditionalExpression();

		return condExpr;
	}

	return expr;
}
Example #2
0
/**
 * Check if the initializer expression is address constant.
 * e.g. 
 * int a;
 * int b = &a;
 */
static AstExpression CheckAddressConstant(AstExpression expr)
{
	AstExpression addr;
	AstExpression p;
	int offset = 0;

	if (! IsPtrType(expr->ty))
		return NULL;

	if (expr->op == OP_ADD || expr->op == OP_SUB)
	{
		addr = CheckAddressConstant(expr->kids[0]);
		if (addr == NULL || expr->kids[1]->op != OP_CONST)
			return NULL;
		
		expr->kids[0] = addr->kids[0];
		expr->kids[1]->val.i[0] += (expr->op == OP_ADD ? 1 : -1) * addr->kids[1]->val.i[0];

		return expr;
	}

	if (expr->op == OP_ADDRESS)
		addr = expr->kids[0];
	else
		addr = expr;

	while (addr->op == OP_INDEX || addr->op == OP_MEMBER)
	{
		if (addr->op == OP_INDEX)
		{
			if (addr->kids[1]->op != OP_CONST)
				return NULL;

			offset += addr->kids[1]->val.i[0] * addr->ty->size;
		}
		else
		{
			Field fld = addr->val.p;

			offset += fld->offset;
		}
		addr = addr->kids[0];
	}

	if (addr->op != OP_ID || (expr->op != OP_ADDRESS && ! addr->isarray && ! addr->isfunc))
		return NULL;


	((Symbol)addr->val.p)->ref++;

	CREATE_AST_NODE(p, Expression);
	p->op = OP_ADD;
	p->ty = expr->ty;
	p->kids[0] = addr;
	p->kids[1] = Constant(addr->coord, T(INT), p->val);

	return p;
}
Example #3
0
static AstExpression CastExpression(Type ty, AstExpression expr)
{
	AstExpression cast;

	if (expr->op == OP_CONST && ty->categ != VOID)
		return FoldCast(ty, expr);

	CREATE_AST_NODE(cast, Expression);

	cast->coord = expr->coord;
	cast->op = OP_CAST;
	cast->ty = ty;
	cast->kids[0] = expr;

	return cast;
}
Example #4
0
/**
 * Construct an expression to divide diff by size
 */
static AstExpression PointerDifference(AstExpression diff, int size)
{
	AstExpression expr;
	union value val;

	CREATE_AST_NODE(expr, Expression);

	expr->ty = diff->ty;
	expr->op = OP_DIV;
	expr->kids[0] = diff;
	val.i[1] = 0;
	val.i[0] = size;
	expr->kids[1] = Constant(diff->coord, diff->ty, val);

	return expr;
}
Example #5
0
/**
 * Construct an expression to multiply offset by scale.
 */
static AstExpression ScalePointerOffset(AstExpression offset, int scale)
{
	AstExpression expr;
	union value val;

	CREATE_AST_NODE(expr, Expression);

	expr->ty = offset->ty;
	expr->op = OP_MUL;
	expr->kids[0] = offset;
	val.i[1] = 0;
	val.i[0] = scale;
	expr->kids[1] = Constant(offset->coord, offset->ty, val);

	return FoldConstant(expr);
}
Example #6
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;
}
Example #7
0
File: expr.c Project: M-ike/work
/**
 *  expression:
 *      assignment-expression
 *      expression , assignment-expression
 */
AstExpression ParseExpression(void)
{
	AstExpression expr, comaExpr;

	expr = ParseAssignmentExpression();
	while(CurrentToken == TK_COMMA)
	{
		CREATE_AST_NODE(comaExpr, Expression);

		comaExpr->op = OP_COMMA;
		comaExpr->kids[0] = expr;
		NEXT_TOKEN;
		comaExpr->kids[1] = ParseAssignmentExpression();

		expr = comaExpr;
	}

	return expr;
}
Example #8
0
static AstExpression BORBitField(AstExpression expr1, AstExpression expr2)
{
	AstExpression bor;

	if (expr1->op == OP_CONST && expr2->op == OP_CONST)
	{
		expr1->val.i[0] |= expr2->val.i[0];
		return expr1;
	}
	
	CREATE_AST_NODE(bor, Expression);

	bor->coord = expr1->coord;
	bor->ty = expr1->ty;
	bor->op = OP_BITOR;
	bor->kids[0] = expr1;
	bor->kids[1] = expr2;

	return bor;
}
Example #9
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;
}
Example #10
0
File: expr.c Project: M-ike/work
/**
 *  assignment-expression:
 *      conditional-expression
 *      unary-expression assignment-operator assignment-expression
 *  assignment-operator:
 *      = *= /= %= += -= <<= >>= &= ^= |=
 *  There is a little twist here: the parser always treats the first nonterminal
 *  as a conditional expression.
 */
AstExpression ParseAssignmentExpression(void)
{
	AstExpression expr;

	expr = ParseConditionalExpression();
	if (CurrentToken >= TK_ASSIGN && CurrentToken <= TK_MOD_ASSIGN)
	{
		AstExpression asgnExpr;

		CREATE_AST_NODE(asgnExpr, Expression);

		asgnExpr->op = BINARY_OP;
		asgnExpr->kids[0] = expr;
		NEXT_TOKEN;
		asgnExpr->kids[1] = ParseAssignmentExpression();

		return asgnExpr;
	}

	return expr;
}
Example #11
0
static AstExpression PlaceBitField(Field fld, AstExpression expr)
{
	AstExpression lsh;
	union value val;

	if (expr->op == OP_CONST)
	{
		expr->val.i[0] <<= fld->pos;
		return expr;
	}

	CREATE_AST_NODE(lsh, Expression);

	lsh->coord = expr->coord;
	lsh->ty = expr->ty;
	lsh->op = OP_LSHIFT;
	lsh->kids[0] = expr;
	val.i[1] = 0;
	val.i[0] = fld->pos;
	lsh->kids[1] = Constant(expr->coord, T(INT), val);

	return lsh;
}
Example #12
0
File: expr.c Project: M-ike/work
/**
 * Parse a binary expression, from logical-OR-expresssion to multiplicative-expression
 */
static AstExpression ParseBinaryExpression(int prec)
{
	AstExpression binExpr;
	AstExpression expr;
	int newPrec;

	expr = ParseUnaryExpression();
	/// while the following binary operater's precedence is higher than current
	/// binary operator's precedence, parses a higer precedence expression
	while (IsBinaryOP(CurrentToken) && (newPrec = Prec[BINARY_OP]) >= prec)
	{
		CREATE_AST_NODE(binExpr, Expression);

		binExpr->op = BINARY_OP;
		binExpr->kids[0] = expr;
		NEXT_TOKEN;
		binExpr->kids[1] = ParseBinaryExpression(newPrec + 1);

		expr = binExpr;
	}

	return expr;

}
Example #13
0
File: expr.c Project: M-ike/work
/**
 *  primary-expression:
 *		ID
 *		constant
 *		string-literal
 *		( expression )
 */
static AstExpression ParsePrimaryExpression(void)
{
	AstExpression expr;


	switch (CurrentToken)
	{
	case TK_ID:

		CREATE_AST_NODE(expr, Expression);

		expr->op = OP_ID;
		expr->val = TokenValue;
		NEXT_TOKEN;

		return expr;

	/// Notice: Only when parsing constant and string literal,
	/// ty member in astExpression is used since from OP_CONST
	/// and OP_STR alone the expression's type can't be determined
	case TK_INTCONST:
	case TK_UINTCONST:
	case TK_LONGCONST:
	case TK_ULONGCONST:
	case TK_LLONGCONST:
	case TK_ULLONGCONST:
	case TK_FLOATCONST:
	case TK_DOUBLECONST:
	case TK_LDOUBLECONST:

		CREATE_AST_NODE(expr, Expression);

		if (CurrentToken >= TK_FLOATCONST)
			CurrentToken++;

		/// nasty, requires that both from TK_INTCONST to TK_LDOUBLECONST
		/// and from INT to LDOUBLE are consecutive
		expr->ty = T(INT + CurrentToken - TK_INTCONST);
		expr->op = OP_CONST;
		expr->val = TokenValue;
		NEXT_TOKEN;

		return expr;

	case TK_STRING:
	case TK_WIDESTRING:

		CREATE_AST_NODE(expr, Expression);

		expr->ty = ArrayOf(((String)TokenValue.p)->len + 1, CurrentToken == TK_STRING ? T(CHAR) : WCharType);
		expr->op = OP_STR;
		expr->val = TokenValue;
		NEXT_TOKEN;

		return expr;

	case TK_LPAREN:

		NEXT_TOKEN;
		expr = ParseExpression();
		Expect(TK_RPAREN);

		return expr;

	default:
		Error(&TokenCoord, "Expect identifier, string, constant or (");
		return Constant0;
	}
}
Example #14
0
File: expr.c Project: M-ike/work
/**
 *  unary-expression:
 *		postfix-expression
 *		unary-operator unary-expression
 *		( type-name ) unary-expression
 *		sizeof unary-expression
 *		sizeof ( type-name )
 *
 *  unary-operator:
 *		++ -- & * + - ! ~
 */
static AstExpression ParseUnaryExpression()
{
	AstExpression expr;
	int t;

	switch (CurrentToken)
	{
	case TK_INC:
	case TK_DEC:
	case TK_BITAND:
	case TK_MUL:
	case TK_ADD:
	case TK_SUB:
	case TK_NOT:
	case TK_COMP:

		CREATE_AST_NODE(expr, Expression);

		expr->op = UNARY_OP;
		NEXT_TOKEN;
		expr->kids[0] = ParseUnaryExpression();

		return expr;

	case TK_LPAREN:

		/// When current token is (, it may be a type cast expression
		/// or a primary expression, we need to look ahead one token,
		/// if next token is type name, the expression is treated as
		/// a type cast expression; otherwise a primary expresion
		BeginPeekToken();
		t = GetNextToken();
		if (IsTypeName(t))
		{
			EndPeekToken();

			CREATE_AST_NODE(expr, Expression);

			expr->op = OP_CAST;
			NEXT_TOKEN;
			expr->kids[0] =  (AstExpression)ParseTypeName();
			Expect(TK_RPAREN);
			expr->kids[1] = ParseUnaryExpression();

			return expr;
		}
		else
		{
			EndPeekToken();
			return ParsePostfixExpression();
		}
		break;

	case TK_SIZEOF:

		/// this case hase the same issue with TK_LPAREN case
		CREATE_AST_NODE(expr, Expression);

		expr->op = OP_SIZEOF;
		NEXT_TOKEN;
		if (CurrentToken == TK_LPAREN)
		{
			BeginPeekToken();
			t = GetNextToken();
			if (IsTypeName(t))
			{
				EndPeekToken();

				NEXT_TOKEN;
				/// In this case, the first kid is not an expression,
				/// but thanks to both type name and expression have a 
				/// kind member to discriminate them.
				expr->kids[0] = (AstExpression)ParseTypeName();
				Expect(TK_RPAREN);
			}
			else
			{
				EndPeekToken();
				expr->kids[0] = ParseUnaryExpression();
			}
		}
		else
		{
			expr->kids[0] = ParseUnaryExpression();
		}

		return expr;

	default:
		return ParsePostfixExpression();
	}
}
Example #15
0
File: expr.c Project: M-ike/work
/**
 *  postfix-expression:
 *		primary-expression
 *		postfix-expression [ expression ]
 *		postfix-expression ( [argument-expression-list] )
 *		postfix-expression . identifier
 *		postfix-expression -> identifier
 *		postfix-expression ++
 *		postfix-expression --
 */
static AstExpression ParsePostfixExpression(void)
{
	AstExpression expr, p;

	expr = ParsePrimaryExpression();

	while (1)
	{
		switch (CurrentToken)
		{
		case TK_LBRACKET:

			CREATE_AST_NODE(p, Expression);

			p->op = OP_INDEX;
			p->kids[0] = expr;
			NEXT_TOKEN;
			p->kids[1] = ParseExpression();
			Expect(TK_RBRACKET);

			expr = p;
			break;

		case TK_LPAREN:

			CREATE_AST_NODE(p, Expression);

			p->op = OP_CALL;
			p->kids[0] = expr;
			NEXT_TOKEN;
			if (CurrentToken != TK_RPAREN)
			{
				AstNode *tail;

				/// function call expression's second kid is actually
				/// a list of expression instead of a single expression
				p->kids[1] = ParseAssignmentExpression();
				tail = &p->kids[1]->next;
				while (CurrentToken == TK_COMMA)
				{
					NEXT_TOKEN;
					*tail = (AstNode)ParseAssignmentExpression();
					tail = &(*tail)->next;
				}
			}
			Expect(TK_RPAREN);

			expr = p;
			break;

		case TK_DOT:
		case TK_POINTER:

			CREATE_AST_NODE(p, Expression);

			p->op = (CurrentToken == TK_DOT ? OP_MEMBER : OP_PTR_MEMBER);
			p->kids[0] = expr;
			NEXT_TOKEN;
			if (CurrentToken != TK_ID)
			{
				Error(&p->coord, "Expect identifier as struct or union member");
			}
			else
			{
				p->val = TokenValue;
				NEXT_TOKEN;
			}

			expr = p;
			break;

		case TK_INC:
		case TK_DEC:

			CREATE_AST_NODE(p, Expression);

			p->op = (CurrentToken == TK_INC) ? OP_POSTINC : OP_POSTDEC;
			p->kids[0] = expr;
			NEXT_TOKEN;

			expr = p;
			break;

		default:

			return expr;
		}
	}
}