forked from qt-creator/qt-creator
Handle array types and some initial work on implicit conversions.
This commit is contained in:
@@ -52,12 +52,12 @@ class MemoryPool;
|
|||||||
class Type;
|
class Type;
|
||||||
class UndefinedType;
|
class UndefinedType;
|
||||||
class VoidType;
|
class VoidType;
|
||||||
|
class ScalarType;
|
||||||
class BoolType;
|
class BoolType;
|
||||||
class IntType;
|
class IntType;
|
||||||
class UIntType;
|
class UIntType;
|
||||||
class FloatType;
|
class FloatType;
|
||||||
class DoubleType;
|
class DoubleType;
|
||||||
class OpaqueType;
|
|
||||||
class IndexType;
|
class IndexType;
|
||||||
class VectorType;
|
class VectorType;
|
||||||
class MatrixType;
|
class MatrixType;
|
||||||
|
|||||||
@@ -185,6 +185,12 @@ const MatrixType *Engine::matrixType(const Type *elementType, int columns, int r
|
|||||||
vectorType(elementType, rows)));
|
vectorType(elementType, rows)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ArrayType *Engine::arrayType(const Type *elementType)
|
||||||
|
{
|
||||||
|
return _arrayTypes.intern(ArrayType(elementType));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QList<DiagnosticMessage> Engine::diagnosticMessages() const
|
QList<DiagnosticMessage> Engine::diagnosticMessages() const
|
||||||
{
|
{
|
||||||
return _diagnosticMessages;
|
return _diagnosticMessages;
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ public:
|
|||||||
const SamplerType *samplerType(int kind);
|
const SamplerType *samplerType(int kind);
|
||||||
const VectorType *vectorType(const Type *elementType, int dimension);
|
const VectorType *vectorType(const Type *elementType, int dimension);
|
||||||
const MatrixType *matrixType(const Type *elementType, int columns, int rows);
|
const MatrixType *matrixType(const Type *elementType, int columns, int rows);
|
||||||
|
const ArrayType *arrayType(const Type *elementType);
|
||||||
|
|
||||||
// symbols
|
// symbols
|
||||||
Namespace *newNamespace();
|
Namespace *newNamespace();
|
||||||
@@ -136,6 +137,7 @@ private:
|
|||||||
QSet<QString> _numbers;
|
QSet<QString> _numbers;
|
||||||
TypeTable<VectorType> _vectorTypes;
|
TypeTable<VectorType> _vectorTypes;
|
||||||
TypeTable<MatrixType> _matrixTypes;
|
TypeTable<MatrixType> _matrixTypes;
|
||||||
|
TypeTable<ArrayType> _arrayTypes;
|
||||||
TypeTable<SamplerType> _samplerTypes;
|
TypeTable<SamplerType> _samplerTypes;
|
||||||
MemoryPool _pool;
|
MemoryPool _pool;
|
||||||
QList<DiagnosticMessage> _diagnosticMessages;
|
QList<DiagnosticMessage> _diagnosticMessages;
|
||||||
|
|||||||
@@ -198,7 +198,11 @@ bool Semantic::visit(LiteralExpressionAST *ast)
|
|||||||
if (ast->value) {
|
if (ast->value) {
|
||||||
_expr.isConstant = true;
|
_expr.isConstant = true;
|
||||||
|
|
||||||
if (ast->value->endsWith(QLatin1Char('u')) || ast->value->endsWith(QLatin1Char('U')))
|
if (ast->value->at(0) == QLatin1Char('t') && *ast->value == QLatin1String("true"))
|
||||||
|
_expr.type = _engine->boolType();
|
||||||
|
else if (ast->value->at(0) == QLatin1Char('f') && *ast->value == QLatin1String("false"))
|
||||||
|
_expr.type = _engine->boolType();
|
||||||
|
else if (ast->value->endsWith(QLatin1Char('u')) || ast->value->endsWith(QLatin1Char('U')))
|
||||||
_expr.type = _engine->uintType();
|
_expr.type = _engine->uintType();
|
||||||
else if (ast->value->endsWith(QLatin1String("lf")) || ast->value->endsWith(QLatin1String("LF")))
|
else if (ast->value->endsWith(QLatin1String("lf")) || ast->value->endsWith(QLatin1String("LF")))
|
||||||
_expr.type = _engine->doubleType();
|
_expr.type = _engine->doubleType();
|
||||||
@@ -217,11 +221,17 @@ bool Semantic::visit(BinaryExpressionAST *ast)
|
|||||||
_expr.isConstant = left.isConstant && right.isConstant;
|
_expr.isConstant = left.isConstant && right.isConstant;
|
||||||
switch (ast->kind) {
|
switch (ast->kind) {
|
||||||
case AST::Kind_ArrayAccess:
|
case AST::Kind_ArrayAccess:
|
||||||
|
if (left.type) {
|
||||||
|
if (const IndexType *idxType = left.type->asIndexType())
|
||||||
|
_expr = idxType->indexElementType();
|
||||||
|
else
|
||||||
|
_engine->error(ast->lineno, QString("Invalid type `%1' for array subscript").arg(left.type->toString()));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AST::Kind_Modulus:
|
||||||
case AST::Kind_Multiply:
|
case AST::Kind_Multiply:
|
||||||
case AST::Kind_Divide:
|
case AST::Kind_Divide:
|
||||||
case AST::Kind_Modulus:
|
|
||||||
case AST::Kind_Plus:
|
case AST::Kind_Plus:
|
||||||
case AST::Kind_Minus:
|
case AST::Kind_Minus:
|
||||||
case AST::Kind_ShiftLeft:
|
case AST::Kind_ShiftLeft:
|
||||||
@@ -301,8 +311,56 @@ bool Semantic::visit(MemberAccessExpressionAST *ast)
|
|||||||
|
|
||||||
bool Semantic::implicitCast(const Type *type, const Type *target) const
|
bool Semantic::implicitCast(const Type *type, const Type *target) const
|
||||||
{
|
{
|
||||||
// ### implement me
|
if (! (type && target)) {
|
||||||
return type->isEqualTo(target);
|
return false;
|
||||||
|
} else if (type->isEqualTo(target)) {
|
||||||
|
return true;
|
||||||
|
} else if (target->asUIntType() != 0) {
|
||||||
|
return type->asIntType() != 0;
|
||||||
|
} else if (target->asFloatType() != 0) {
|
||||||
|
return type->asIntType() != 0 ||
|
||||||
|
type->asUIntType() != 0;
|
||||||
|
} else if (target->asDoubleType() != 0) {
|
||||||
|
return type->asIntType() != 0 ||
|
||||||
|
type->asUIntType() != 0 ||
|
||||||
|
type->asFloatType() != 0;
|
||||||
|
} else if (const VectorType *targetVecTy = target->asVectorType()) {
|
||||||
|
if (const VectorType *vecTy = type->asVectorType()) {
|
||||||
|
if (targetVecTy->dimension() == vecTy->dimension()) {
|
||||||
|
const Type *targetElementType = targetVecTy->elementType();
|
||||||
|
const Type *elementType = vecTy->elementType();
|
||||||
|
|
||||||
|
if (targetElementType->asUIntType() != 0) {
|
||||||
|
// uvec* -> ivec*
|
||||||
|
return elementType->asIntType() != 0;
|
||||||
|
} else if (targetElementType->asFloatType() != 0) {
|
||||||
|
// vec* -> ivec* | uvec*
|
||||||
|
return elementType->asIntType() != 0 ||
|
||||||
|
elementType->asUIntType() != 0;
|
||||||
|
} else if (targetElementType->asDoubleType() != 0) {
|
||||||
|
// dvec* -> ivec* | uvec* | fvec*
|
||||||
|
return elementType->asIntType() != 0 ||
|
||||||
|
elementType->asUIntType() != 0 ||
|
||||||
|
elementType->asFloatType() != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (const MatrixType *targetMatTy = target->asMatrixType()) {
|
||||||
|
if (const MatrixType *matTy = type->asMatrixType()) {
|
||||||
|
if (targetMatTy->columns() == matTy->columns() &&
|
||||||
|
targetMatTy->rows() == matTy->rows()) {
|
||||||
|
const Type *targetElementType = targetMatTy->elementType();
|
||||||
|
const Type *elementType = matTy->elementType();
|
||||||
|
|
||||||
|
if (targetElementType->asDoubleType() != 0) {
|
||||||
|
// dmat* -> mat*
|
||||||
|
return elementType->asFloatType() != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Semantic::visit(FunctionCallExpressionAST *ast)
|
bool Semantic::visit(FunctionCallExpressionAST *ast)
|
||||||
@@ -337,11 +395,19 @@ bool Semantic::visit(FunctionCallExpressionAST *ast)
|
|||||||
candidates.append(f);
|
candidates.append(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (candidates.size() == 1)
|
|
||||||
_expr.type = candidates.first()->returnType();
|
|
||||||
else
|
|
||||||
_expr.type = overloads->functions().first()->returnType();
|
|
||||||
|
|
||||||
|
if (candidates.isEmpty()) {
|
||||||
|
// ### error, unresolved call.
|
||||||
|
Q_ASSERT(! overloads->functions().isEmpty());
|
||||||
|
|
||||||
|
_expr.type = overloads->functions().first()->returnType();
|
||||||
|
} else {
|
||||||
|
_expr.type = candidates.first()->returnType();
|
||||||
|
|
||||||
|
if (candidates.size() != 1) {
|
||||||
|
// ### error, ambiguous call
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// called as constructor, e.g. vec2(a, b)
|
// called as constructor, e.g. vec2(a, b)
|
||||||
_expr.type = id.type;
|
_expr.type = id.type;
|
||||||
@@ -693,7 +759,7 @@ bool Semantic::visit(ArrayTypeAST *ast)
|
|||||||
const Type *elementType = type(ast->elementType);
|
const Type *elementType = type(ast->elementType);
|
||||||
Q_UNUSED(elementType);
|
Q_UNUSED(elementType);
|
||||||
ExprResult size = expression(ast->size);
|
ExprResult size = expression(ast->size);
|
||||||
// ### array type
|
_type = _engine->arrayType(elementType); // ### ignore the size for now
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#define GLSLSEMANTIC_H
|
#define GLSLSEMANTIC_H
|
||||||
|
|
||||||
#include "glslastvisitor.h"
|
#include "glslastvisitor.h"
|
||||||
|
#include "glsltype.h"
|
||||||
|
|
||||||
namespace GLSL {
|
namespace GLSL {
|
||||||
|
|
||||||
@@ -43,8 +44,15 @@ public:
|
|||||||
ExprResult(const Type *type = 0, bool isConstant = false)
|
ExprResult(const Type *type = 0, bool isConstant = false)
|
||||||
: type(type), isConstant(isConstant) {}
|
: type(type), isConstant(isConstant) {}
|
||||||
|
|
||||||
bool isValid() const { return type != 0; }
|
bool isValid() const {
|
||||||
operator bool() const { return type != 0; }
|
if (! type)
|
||||||
|
return false;
|
||||||
|
else if (type->asUndefinedType() != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const { return isValid(); }
|
||||||
|
|
||||||
const Type *type;
|
const Type *type;
|
||||||
bool isConstant;
|
bool isConstant;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
virtual const UIntType *asUIntType() const { return 0; }
|
virtual const UIntType *asUIntType() const { return 0; }
|
||||||
virtual const FloatType *asFloatType() const { return 0; }
|
virtual const FloatType *asFloatType() const { return 0; }
|
||||||
virtual const DoubleType *asDoubleType() const { return 0; }
|
virtual const DoubleType *asDoubleType() const { return 0; }
|
||||||
virtual const OpaqueType *asOpaqueType() const { return 0; }
|
virtual const ScalarType *asScalarType() const { return 0; }
|
||||||
virtual const IndexType *asIndexType() const { return 0; }
|
virtual const IndexType *asIndexType() const { return 0; }
|
||||||
virtual const VectorType *asVectorType() const { return 0; }
|
virtual const VectorType *asVectorType() const { return 0; }
|
||||||
virtual const MatrixType *asMatrixType() const { return 0; }
|
virtual const MatrixType *asMatrixType() const { return 0; }
|
||||||
|
|||||||
@@ -38,10 +38,10 @@
|
|||||||
|
|
||||||
namespace GLSL {
|
namespace GLSL {
|
||||||
|
|
||||||
class GLSL_EXPORT OpaqueType: public Type
|
class GLSL_EXPORT ScalarType: public Type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const OpaqueType *asOpaqueType() const { return this; }
|
virtual const ScalarType *asScalarType() const { return this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class GLSL_EXPORT UndefinedType: public Type
|
class GLSL_EXPORT UndefinedType: public Type
|
||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
virtual bool isLessThan(const Type *other) const;
|
virtual bool isLessThan(const Type *other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GLSL_EXPORT BoolType: public Type
|
class GLSL_EXPORT BoolType: public ScalarType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual QString toString() const { return QLatin1String("bool"); }
|
virtual QString toString() const { return QLatin1String("bool"); }
|
||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
virtual bool isLessThan(const Type *other) const;
|
virtual bool isLessThan(const Type *other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GLSL_EXPORT IntType: public Type
|
class GLSL_EXPORT IntType: public ScalarType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual QString toString() const { return QLatin1String("int"); }
|
virtual QString toString() const { return QLatin1String("int"); }
|
||||||
@@ -80,7 +80,7 @@ public:
|
|||||||
virtual bool isLessThan(const Type *other) const;
|
virtual bool isLessThan(const Type *other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GLSL_EXPORT UIntType: public Type
|
class GLSL_EXPORT UIntType: public ScalarType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual QString toString() const { return QLatin1String("uint"); }
|
virtual QString toString() const { return QLatin1String("uint"); }
|
||||||
@@ -89,7 +89,7 @@ public:
|
|||||||
virtual bool isLessThan(const Type *other) const;
|
virtual bool isLessThan(const Type *other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GLSL_EXPORT FloatType: public Type
|
class GLSL_EXPORT FloatType: public ScalarType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual QString toString() const { return QLatin1String("float"); }
|
virtual QString toString() const { return QLatin1String("float"); }
|
||||||
@@ -98,7 +98,7 @@ public:
|
|||||||
virtual bool isLessThan(const Type *other) const;
|
virtual bool isLessThan(const Type *other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GLSL_EXPORT DoubleType: public Type
|
class GLSL_EXPORT DoubleType: public ScalarType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual QString toString() const { return QLatin1String("double"); }
|
virtual QString toString() const { return QLatin1String("double"); }
|
||||||
|
|||||||
Reference in New Issue
Block a user