namespace GL {
namespace SL {
+bool is_scalar(const BasicTypeDeclaration &type)
+{
+ return (type.kind==BasicTypeDeclaration::INT || type.kind==BasicTypeDeclaration::FLOAT);
+}
+
+bool is_vector_or_matrix(const BasicTypeDeclaration &type)
+{
+ return (type.kind==BasicTypeDeclaration::VECTOR || type.kind==BasicTypeDeclaration::MATRIX);
+}
+
+BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &type)
+{
+ if(is_vector_or_matrix(type) || type.kind==BasicTypeDeclaration::ARRAY)
+ {
+ BasicTypeDeclaration *basic_base = dynamic_cast<BasicTypeDeclaration *>(type.base_type);
+ return (basic_base ? get_element_type(*basic_base) : 0);
+ }
+ else
+ return &type;
+}
+
+bool can_convert(const BasicTypeDeclaration &from, const BasicTypeDeclaration &to)
+{
+ if(from.kind==BasicTypeDeclaration::INT && to.kind==BasicTypeDeclaration::FLOAT)
+ return from.size<=to.size;
+ else if(from.kind!=to.kind)
+ return false;
+ else if(is_vector_or_matrix(from) && from.size==to.size)
+ {
+ BasicTypeDeclaration *from_base = dynamic_cast<BasicTypeDeclaration *>(from.base_type);
+ BasicTypeDeclaration *to_base = dynamic_cast<BasicTypeDeclaration *>(to.base_type);
+ return (from_base && to_base && can_convert(*from_base, *to_base));
+ }
+ else
+ return false;
+}
+
+
unsigned TypeComparer::next_tag = 1;
TypeComparer::TypeComparer():
namespace GL {
namespace SL {
+bool is_scalar(const BasicTypeDeclaration &);
+bool is_vector_or_matrix(const BasicTypeDeclaration &);
+BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
+bool can_convert(const BasicTypeDeclaration &, const BasicTypeDeclaration &);
+
/** Compares two types for equality. Struct types are compared recursively. */
class TypeComparer: private NodeVisitor
{
#include <algorithm>
#include <msp/core/raii.h>
#include <msp/strings/utils.h>
+#include "reflect.h"
#include "resolve.h"
using namespace std;
return r_any_resolved;
}
-bool ExpressionResolver::is_scalar(BasicTypeDeclaration &type)
-{
- return (type.kind==BasicTypeDeclaration::INT || type.kind==BasicTypeDeclaration::FLOAT);
-}
-
-bool ExpressionResolver::is_vector_or_matrix(BasicTypeDeclaration &type)
-{
- return (type.kind==BasicTypeDeclaration::VECTOR || type.kind==BasicTypeDeclaration::MATRIX);
-}
-
-BasicTypeDeclaration *ExpressionResolver::get_element_type(BasicTypeDeclaration &type)
-{
- if(is_vector_or_matrix(type) || type.kind==BasicTypeDeclaration::ARRAY)
- {
- BasicTypeDeclaration *basic_base = dynamic_cast<BasicTypeDeclaration *>(type.base_type);
- return (basic_base ? get_element_type(*basic_base) : 0);
- }
- else
- return &type;
-}
-
-bool ExpressionResolver::can_convert(BasicTypeDeclaration &from, BasicTypeDeclaration &to)
-{
- if(from.kind==BasicTypeDeclaration::INT && to.kind==BasicTypeDeclaration::FLOAT)
- return from.size<=to.size;
- else if(from.kind!=to.kind)
- return false;
- else if((from.kind==BasicTypeDeclaration::VECTOR || from.kind==BasicTypeDeclaration::MATRIX) && from.size==to.size)
- {
- BasicTypeDeclaration *from_base = dynamic_cast<BasicTypeDeclaration *>(from.base_type);
- BasicTypeDeclaration *to_base = dynamic_cast<BasicTypeDeclaration *>(to.base_type);
- return (from_base && to_base && can_convert(*from_base, *to_base));
- }
- else
- return false;
-}
-
ExpressionResolver::Compatibility ExpressionResolver::get_compatibility(BasicTypeDeclaration &left, BasicTypeDeclaration &right)
{
if(&left==&right)
bool apply(Stage &);
private:
- static bool is_scalar(BasicTypeDeclaration &);
- static bool is_vector_or_matrix(BasicTypeDeclaration &);
- static BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
- static bool can_convert(BasicTypeDeclaration &, BasicTypeDeclaration &);
static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
return result_id;
}
-BasicTypeDeclaration &SpirVGenerator::get_element_type(BasicTypeDeclaration &basic)
-{
- if(basic.kind==BasicTypeDeclaration::BOOL || basic.kind==BasicTypeDeclaration::INT || basic.kind==BasicTypeDeclaration::FLOAT)
- return basic;
- else if((basic.kind==BasicTypeDeclaration::VECTOR || basic.kind==BasicTypeDeclaration::MATRIX) && basic.base_type)
- return get_element_type(dynamic_cast<BasicTypeDeclaration &>(*basic.base_type));
- else
- throw invalid_argument("SpirVGenerator::get_element_type");
-}
-
void SpirVGenerator::visit(Block &block)
{
for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
return;
BasicTypeDeclaration &basic = dynamic_cast<BasicTypeDeclaration &>(*unary.expression->type);
- BasicTypeDeclaration &elem = get_element_type(basic);
+ BasicTypeDeclaration &elem = *get_element_type(basic);
if(constant_expression && elem.kind!=BasicTypeDeclaration::BOOL && elem.kind!=BasicTypeDeclaration::INT)
/* SPIR-V allows constant operations on floating-point values only for
BasicTypeDeclaration &basic_left = dynamic_cast<BasicTypeDeclaration &>(*binary.left->type);
BasicTypeDeclaration &basic_right = dynamic_cast<BasicTypeDeclaration &>(*binary.right->type);
// Expression resolver ensures that element types are the same
- BasicTypeDeclaration &elem = get_element_type(basic_left);
+ BasicTypeDeclaration &elem = *get_element_type(basic_left);
if(constant_expression && elem.kind!=BasicTypeDeclaration::BOOL && elem.kind!=BasicTypeDeclaration::INT)
/* SPIR-V allows constant operations on floating-point values only for
for(NodeArray<Expression>::const_iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
if(BasicTypeDeclaration *basic_arg = dynamic_cast<BasicTypeDeclaration *>((*i)->type))
{
- BasicTypeDeclaration &elem_arg = get_element_type(*basic_arg);
+ BasicTypeDeclaration &elem_arg = *get_element_type(*basic_arg);
switch(elem_arg.kind)
{
case BasicTypeDeclaration::BOOL: arg_types += 'b'; break;
return;
}
- BasicTypeDeclaration &elem = get_element_type(*basic);
+ BasicTypeDeclaration &elem = *get_element_type(*basic);
BasicTypeDeclaration &basic_arg0 = dynamic_cast<BasicTypeDeclaration &>(*call.arguments[0]->type);
- BasicTypeDeclaration &elem_arg0 = get_element_type(basic_arg0);
+ BasicTypeDeclaration &elem_arg0 = *get_element_type(basic_arg0);
if(basic->kind==BasicTypeDeclaration::MATRIX)
{
Id write_expression(Opcode, Id, Id, Id);
void write_deconstruct(Id, Id, Id *, unsigned);
Id write_construct(Id, const Id *, unsigned);
- static BasicTypeDeclaration &get_element_type(BasicTypeDeclaration &);
virtual void visit(Block &);
virtual void visit(Literal &);