Handle array types and some initial work on implicit conversions.

This commit is contained in:
Roberto Raggi
2010-12-02 16:30:19 +01:00
parent 1cbfa220fc
commit dcd95f8d50
7 changed files with 102 additions and 20 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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"); }