forked from qt-creator/qt-creator
Process binary expressions.
This commit is contained in:
@@ -219,6 +219,40 @@ bool Semantic::visit(BinaryExpressionAST *ast)
|
|||||||
ExprResult left = expression(ast->left);
|
ExprResult left = expression(ast->left);
|
||||||
ExprResult right = expression(ast->right);
|
ExprResult right = expression(ast->right);
|
||||||
_expr.isConstant = left.isConstant && right.isConstant;
|
_expr.isConstant = left.isConstant && right.isConstant;
|
||||||
|
switch (ast->kind) {
|
||||||
|
case AST::Kind_ArrayAccess:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST::Kind_Multiply:
|
||||||
|
case AST::Kind_Divide:
|
||||||
|
case AST::Kind_Modulus:
|
||||||
|
case AST::Kind_Plus:
|
||||||
|
case AST::Kind_Minus:
|
||||||
|
case AST::Kind_ShiftLeft:
|
||||||
|
case AST::Kind_ShiftRight:
|
||||||
|
_expr.type = left.type; // ### not exactly
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST::Kind_LessThan:
|
||||||
|
case AST::Kind_GreaterThan:
|
||||||
|
case AST::Kind_LessEqual:
|
||||||
|
case AST::Kind_GreaterEqual:
|
||||||
|
case AST::Kind_Equal:
|
||||||
|
case AST::Kind_NotEqual:
|
||||||
|
case AST::Kind_BitwiseAnd:
|
||||||
|
case AST::Kind_BitwiseXor:
|
||||||
|
case AST::Kind_BitwiseOr:
|
||||||
|
case AST::Kind_LogicalAnd:
|
||||||
|
case AST::Kind_LogicalXor:
|
||||||
|
case AST::Kind_LogicalOr:
|
||||||
|
_expr.type = _engine->boolType();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST::Kind_Comma:
|
||||||
|
_expr = right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +269,7 @@ bool Semantic::visit(TernaryExpressionAST *ast)
|
|||||||
ExprResult second = expression(ast->second);
|
ExprResult second = expression(ast->second);
|
||||||
ExprResult third = expression(ast->third);
|
ExprResult third = expression(ast->third);
|
||||||
_expr.isConstant = first.isConstant && second.isConstant && third.isConstant;
|
_expr.isConstant = first.isConstant && second.isConstant && third.isConstant;
|
||||||
|
_expr.type = second.type;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,24 +287,65 @@ bool Semantic::visit(MemberAccessExpressionAST *ast)
|
|||||||
if (const VectorType *vecTy = expr.type->asVectorType()) {
|
if (const VectorType *vecTy = expr.type->asVectorType()) {
|
||||||
if (Symbol *s = vecTy->find(*ast->field)) {
|
if (Symbol *s = vecTy->find(*ast->field)) {
|
||||||
_expr.type = s->type();
|
_expr.type = s->type();
|
||||||
|
} else {
|
||||||
|
_engine->error(ast->lineno, QString("`%1' has no member named `%2'").arg(vecTy->name()).arg(*ast->field));
|
||||||
}
|
}
|
||||||
} else if (const Struct *structTy = expr.type->asStructType()) {
|
} else if (const Struct *structTy = expr.type->asStructType()) {
|
||||||
if (Symbol *s = structTy->find(*ast->field)) {
|
if (Symbol *s = structTy->find(*ast->field)) {
|
||||||
_expr.type = s->type();
|
_expr.type = s->type();
|
||||||
|
} else {
|
||||||
|
_engine->error(ast->lineno, QString("`%1' has no member named `%2'").arg(structTy->name()).arg(*ast->field));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// error(ast->lineno, QString("Requested for member `%1', in a non class or vec instance").arg(*ast->field));
|
_engine->error(ast->lineno, QString("Requested for member `%1', in a non class or vec instance").arg(*ast->field));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Semantic::implicitCast(const Type *type, const Type *target) const
|
||||||
|
{
|
||||||
|
// ### implement me
|
||||||
|
return type->isEqualTo(target);
|
||||||
|
}
|
||||||
|
|
||||||
bool Semantic::visit(FunctionCallExpressionAST *ast)
|
bool Semantic::visit(FunctionCallExpressionAST *ast)
|
||||||
{
|
{
|
||||||
ExprResult expr = expression(ast->expr);
|
ExprResult expr = expression(ast->expr);
|
||||||
ExprResult id = functionIdentifier(ast->id);
|
ExprResult id = functionIdentifier(ast->id);
|
||||||
|
QVector<ExprResult> actuals;
|
||||||
for (List<ExpressionAST *> *it = ast->arguments; it; it = it->next) {
|
for (List<ExpressionAST *> *it = ast->arguments; it; it = it->next) {
|
||||||
ExprResult arg = expression(it->value);
|
ExprResult arg = expression(it->value);
|
||||||
|
actuals.append(arg);
|
||||||
|
}
|
||||||
|
if (id.isValid()) {
|
||||||
|
if (const Function *funTy = id.type->asFunctionType()) {
|
||||||
|
if (actuals.size() < funTy->argumentCount())
|
||||||
|
_engine->error(ast->lineno, QString("not enough arguments"));
|
||||||
|
else if (actuals.size() > funTy->argumentCount())
|
||||||
|
_engine->error(ast->lineno, QString("too many arguments"));
|
||||||
|
_expr.type = funTy->returnType();
|
||||||
|
} else if (const OverloadSet *overloads = id.type->asOverloadSetType()) {
|
||||||
|
QVector<GLSL::Function *> candidates;
|
||||||
|
foreach (GLSL::Function *f, overloads->functions()) {
|
||||||
|
if (f->argumentCount() == actuals.size()) {
|
||||||
|
int argc = 0;
|
||||||
|
for (; argc < actuals.size(); ++argc) {
|
||||||
|
const Type *actualTy = actuals.at(argc).type;
|
||||||
|
const Type *argumentTy = f->argumentAt(argc)->type();
|
||||||
|
if (! implicitCast(actualTy, argumentTy))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == actuals.size())
|
||||||
|
candidates.append(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidates.size() == 1)
|
||||||
|
_expr.type = candidates.first()->returnType();
|
||||||
|
else
|
||||||
|
_expr.type = overloads->functions().first()->returnType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ protected:
|
|||||||
Engine *switchEngine(Engine *engine);
|
Engine *switchEngine(Engine *engine);
|
||||||
Scope *switchScope(Scope *scope);
|
Scope *switchScope(Scope *scope);
|
||||||
|
|
||||||
|
bool implicitCast(const Type *type, const Type *target) const;
|
||||||
|
|
||||||
ExprResult expression(ExpressionAST *ast);
|
ExprResult expression(ExpressionAST *ast);
|
||||||
void statement(StatementAST *ast);
|
void statement(StatementAST *ast);
|
||||||
const Type *type(TypeAST *ast);
|
const Type *type(TypeAST *ast);
|
||||||
|
|||||||
Reference in New Issue
Block a user