gsksl: Redo declaration "decorator" parsing

Instead of parsing into a list of flags, have an array of values that
can be set to certain values. This way, we can reuse it for layout()
contents.
This commit is contained in:
Benjamin Otte
2017-09-25 22:56:29 +02:00
parent cf40318d9b
commit a7fce5603a
4 changed files with 131 additions and 266 deletions

View File

@@ -353,13 +353,11 @@ gsk_sl_node_parse_statement (GskSlScope *scope,
case GSK_SL_TOKEN_DMAT4X4:
{
GskSlType *type;
GskSlPointerTypeFlags flags;
GskSlDecorations decoration;
gboolean success;
success = gsk_sl_type_qualifier_parse (preproc,
GSK_SL_POINTER_TYPE_PARAMETER_QUALIFIER
| GSK_SL_POINTER_TYPE_MEMORY_QUALIFIER,
&flags);
success = gsk_sl_decoration_list_parse (preproc,
&decoration);
type = gsk_sl_type_new_parse (preproc);
if (type == NULL)
@@ -391,7 +389,7 @@ gsk_sl_node_parse_statement (GskSlScope *scope,
{
GskSlPointerType *pointer_type;
pointer_type = gsk_sl_pointer_type_new (type, flags | GSK_SL_POINTER_TYPE_LOCAL);
pointer_type = gsk_sl_pointer_type_new (type, TRUE, decoration.values[GSK_SL_DECORATION_CALLER_ACCESS].value);
node = gsk_sl_node_parse_declaration (scope, preproc, pointer_type);
gsk_sl_pointer_type_unref (pointer_type);
}

View File

@@ -30,12 +30,14 @@ struct _GskSlPointerType {
GskSlType *type;
GskSlPointerTypeFlags flags;
gboolean local;
GskSlDecorationAccess access;
};
GskSlPointerType *
gsk_sl_pointer_type_new (GskSlType *type,
GskSlPointerTypeFlags flags)
gboolean local,
GskSlDecorationAccess access)
{
GskSlPointerType *result;
@@ -43,227 +45,170 @@ gsk_sl_pointer_type_new (GskSlType *type,
result->ref_count = 1;
result->type = gsk_sl_type_ref (type);
result->flags = flags;
result->local = local;
result->access = access;
return result;
}
static gboolean
gsk_sl_decoration_list_set (GskSlPreprocessor *preproc,
GskSlDecorations *list,
GskSlDecoration decoration,
gint value)
{
list->values[decoration].set = TRUE;
list->values[decoration].value = value;
return TRUE;
}
static gboolean
gsk_sl_decoration_list_add_simple (GskSlPreprocessor *preproc,
GskSlDecorations *list,
GskSlDecoration decoration)
{
if (list->values[decoration].set)
{
gsk_sl_preprocessor_error (preproc, "Duplicate qualifier.");
return FALSE;
}
return gsk_sl_decoration_list_set (preproc, list, decoration, 1);
}
gboolean
gsk_sl_type_qualifier_parse (GskSlPreprocessor *stream,
GskSlPointerTypeFlags allowed_flags,
GskSlPointerTypeFlags *parsed_flags)
gsk_sl_decoration_list_parse (GskSlPreprocessor *preproc,
GskSlDecorations *list)
{
const GskSlToken *token;
guint flags = 0;
gboolean success = TRUE;
memset (list, 0, sizeof (GskSlDecorations));
while (TRUE)
{
token = gsk_sl_preprocessor_get (stream);
token = gsk_sl_preprocessor_get (preproc);
switch ((guint) token->type)
{
case GSK_SL_TOKEN_CONST:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_CONST))
{
gsk_sl_preprocessor_error (stream, "\"const\" qualifier not allowed here.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_CONST)
{
gsk_sl_preprocessor_error (stream, "\"const\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_CONST;
}
gsk_sl_preprocessor_consume (stream, NULL);
success &= gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_CONST);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_IN:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_IN))
if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
{
gsk_sl_preprocessor_error (stream, "\"in\" qualifier not allowed here.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_IN)
{
gsk_sl_preprocessor_error (stream, "\"in\" qualifier specified twice.");
gsk_sl_preprocessor_error (preproc, "\"in\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_IN;
success &= gsk_sl_decoration_list_set (preproc, list,
GSK_SL_DECORATION_CALLER_ACCESS,
list->values[GSK_SL_DECORATION_CALLER_ACCESS].value | GSK_SL_DECORATION_ACCESS_READ);
}
gsk_sl_preprocessor_consume (stream, NULL);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_OUT:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_OUT))
if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
{
gsk_sl_preprocessor_error (stream, "\"out\" qualifier not allowed here.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_OUT)
{
gsk_sl_preprocessor_error (stream, "\"out\" qualifier specified twice.");
gsk_sl_preprocessor_error (preproc, "\"out\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_OUT;
success &= gsk_sl_decoration_list_set (preproc, list,
GSK_SL_DECORATION_CALLER_ACCESS,
list->values[GSK_SL_DECORATION_CALLER_ACCESS].value | GSK_SL_DECORATION_ACCESS_WRITE);
}
gsk_sl_preprocessor_consume (stream, NULL);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_INOUT:
if ((allowed_flags & (GSK_SL_POINTER_TYPE_IN | GSK_SL_POINTER_TYPE_OUT)) != (GSK_SL_POINTER_TYPE_IN | GSK_SL_POINTER_TYPE_OUT))
if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
{
gsk_sl_preprocessor_error (stream, "\"inout\" qualifier not allowed here.");
gsk_sl_preprocessor_error (preproc, "\"in\" qualifier already used.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_IN)
else if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
{
gsk_sl_preprocessor_error (stream, "\"in\" qualifier already used.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_OUT)
{
gsk_sl_preprocessor_error (stream, "\"out\" qualifier already used.");
gsk_sl_preprocessor_error (preproc, "\"out\" qualifier already used.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_IN | GSK_SL_POINTER_TYPE_OUT;
success &= gsk_sl_decoration_list_set (preproc, list,
GSK_SL_DECORATION_CALLER_ACCESS,
GSK_SL_DECORATION_ACCESS_READWRITE);
}
gsk_sl_preprocessor_consume (stream, NULL);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_INVARIANT:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_INVARIANT))
{
gsk_sl_preprocessor_error (stream, "\"invariant\" qualifier not allowed here.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_INVARIANT)
{
gsk_sl_preprocessor_error (stream, "\"invariant\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_INVARIANT;
}
gsk_sl_preprocessor_consume (stream, NULL);
success &= gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_INVARIANT);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_COHERENT:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_COHERENT))
{
gsk_sl_preprocessor_error (stream, "\"coherent\" qualifier not allowed here.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_COHERENT)
{
gsk_sl_preprocessor_error (stream, "\"coherent\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_COHERENT;
}
gsk_sl_preprocessor_consume (stream, NULL);
success &= gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_COHERENT);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_VOLATILE:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_VOLATILE))
{
gsk_sl_preprocessor_error (stream, "\"volatile\" qualifier not allowed here.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_VOLATILE)
{
gsk_sl_preprocessor_error (stream, "\"volatile\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_VOLATILE;
}
gsk_sl_preprocessor_consume (stream, NULL);
success &= gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_VOLATILE);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_RESTRICT:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_RESTRICT))
{
gsk_sl_preprocessor_error (stream, "\"restrict\" qualifier not allowed here.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_RESTRICT)
{
gsk_sl_preprocessor_error (stream, "\"restrict\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_RESTRICT;
}
gsk_sl_preprocessor_consume (stream, NULL);
success &= gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_RESTRICT);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_READONLY:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_READONLY))
if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
{
gsk_sl_preprocessor_error (stream, "\"readonly\" qualifier not allowed here.");
gsk_sl_preprocessor_error (preproc, "\"readonly\" qualifier specified twice.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_READONLY)
else if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
{
gsk_sl_preprocessor_error (stream, "\"readonly\" qualifier specified twice.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_WRITEONLY)
{
gsk_sl_preprocessor_error (stream, "\"writeonly\" qualifier already used.");
gsk_sl_preprocessor_error (preproc, "\"writeonly\" qualifier already used.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_READONLY;
success &= gsk_sl_decoration_list_set (preproc, list,
GSK_SL_DECORATION_ACCESS,
GSK_SL_DECORATION_ACCESS_READ);
}
gsk_sl_preprocessor_consume (stream, NULL);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
case GSK_SL_TOKEN_WRITEONLY:
if (!(allowed_flags & GSK_SL_POINTER_TYPE_WRITEONLY))
if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
{
gsk_sl_preprocessor_error (stream, "\"writeonly\" qualifier not allowed here.");
gsk_sl_preprocessor_error (preproc, "\"readonly\" qualifier already used.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_READONLY)
else if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
{
gsk_sl_preprocessor_error (stream, "\"readonly\" qualifier already used.");
success = FALSE;
}
else if (flags & GSK_SL_POINTER_TYPE_WRITEONLY)
{
gsk_sl_preprocessor_error (stream, "\"writeonly\" qualifier specified twice.");
gsk_sl_preprocessor_error (preproc, "\"writeonly\" qualifier specified twice.");
success = FALSE;
}
else
{
flags |= GSK_SL_POINTER_TYPE_WRITEONLY;
success &= gsk_sl_decoration_list_set (preproc, list,
GSK_SL_DECORATION_ACCESS,
GSK_SL_DECORATION_ACCESS_WRITE);
}
gsk_sl_preprocessor_consume (stream, NULL);
gsk_sl_preprocessor_consume (preproc, NULL);
break;
default:
{
*parsed_flags = flags;
return success;
}
return success;
}
}
}
@@ -297,31 +242,12 @@ void
gsk_sl_pointer_type_print (const GskSlPointerType *type,
GString *string)
{
if (type->flags & GSK_SL_POINTER_TYPE_CONST)
g_string_append (string, "const ");
if (type->flags & GSK_SL_POINTER_TYPE_OUT)
{
if (type->flags & GSK_SL_POINTER_TYPE_IN)
g_string_append (string, "inout ");
else
g_string_append (string, "out ");
}
else if (type->flags & GSK_SL_POINTER_TYPE_IN)
{
g_string_append (string, "out ");
}
if (type->flags & GSK_SL_POINTER_TYPE_INVARIANT)
g_string_append (string, "invariant ");
if (type->flags & GSK_SL_POINTER_TYPE_COHERENT)
g_string_append (string, "coherent ");
if (type->flags & GSK_SL_POINTER_TYPE_VOLATILE)
g_string_append (string, "volatile ");
if (type->flags & GSK_SL_POINTER_TYPE_RESTRICT)
g_string_append (string, "restrict ");
if (type->flags & GSK_SL_POINTER_TYPE_READONLY)
g_string_append (string, "readonly ");
if (type->flags & GSK_SL_POINTER_TYPE_WRITEONLY)
g_string_append (string, "writeonly ");
if (type->access == GSK_SL_DECORATION_ACCESS_READWRITE)
g_string_append (string, "inout ");
else if (type->access == GSK_SL_DECORATION_ACCESS_READ)
g_string_append (string, "in ");
else if (type->access == GSK_SL_DECORATION_ACCESS_WRITE)
g_string_append (string, "out ");
g_string_append (string, gsk_sl_type_get_name (type->type));
}
@@ -332,70 +258,16 @@ gsk_sl_pointer_type_get_type (const GskSlPointerType *type)
return type->type;
}
gboolean
gsk_sl_pointer_type_is_const (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_CONST ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_in (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_IN ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_out (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_OUT ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_invariant (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_INVARIANT ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_coherent (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_COHERENT ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_volatile (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_VOLATILE ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_restrict (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_RESTRICT ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_readonly (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_READONLY ? TRUE : FALSE;
}
gboolean
gsk_sl_pointer_type_is_writeonly (const GskSlPointerType *type)
{
return type->flags & GSK_SL_POINTER_TYPE_WRITEONLY ? TRUE : FALSE;
}
GskSpvStorageClass
gsk_sl_pointer_type_get_storage_class (const GskSlPointerType *type)
{
if (type->flags & GSK_SL_POINTER_TYPE_LOCAL)
if (type->local)
return GSK_SPV_STORAGE_CLASS_FUNCTION;
if (type->flags & GSK_SL_POINTER_TYPE_OUT)
if (type->access & GSK_SL_DECORATION_ACCESS_WRITE)
return GSK_SPV_STORAGE_CLASS_OUTPUT;
if (type->flags & GSK_SL_POINTER_TYPE_IN)
if (type->access & GSK_SL_DECORATION_ACCESS_READ)
return GSK_SPV_STORAGE_CLASS_INPUT;
return GSK_SPV_STORAGE_CLASS_PRIVATE;

View File

@@ -27,33 +27,39 @@
G_BEGIN_DECLS
typedef enum {
GSK_SL_POINTER_TYPE_LOCAL = (1 << 0),
GSK_SL_POINTER_TYPE_CONST = (1 << 1),
GSK_SL_POINTER_TYPE_IN = (1 << 2),
GSK_SL_POINTER_TYPE_OUT = (1 << 3),
GSK_SL_POINTER_TYPE_INVARIANT = (1 << 4),
GSK_SL_POINTER_TYPE_COHERENT = (1 << 5),
GSK_SL_POINTER_TYPE_VOLATILE = (1 << 6),
GSK_SL_POINTER_TYPE_RESTRICT = (1 << 7),
GSK_SL_POINTER_TYPE_READONLY = (1 << 8),
GSK_SL_POINTER_TYPE_WRITEONLY = (1 << 9)
} GskSlPointerTypeFlags;
GSK_SL_DECORATION_CONST,
GSK_SL_DECORATION_CALLER_ACCESS,
GSK_SL_DECORATION_INVARIANT,
GSK_SL_DECORATION_COHERENT,
GSK_SL_DECORATION_VOLATILE,
GSK_SL_DECORATION_RESTRICT,
GSK_SL_DECORATION_ACCESS,
/* add */
GSK_SL_N_DECORATIONS
} GskSlDecoration;
#define GSK_SL_POINTER_TYPE_PARAMETER_QUALIFIER (GSK_SL_POINTER_TYPE_CONST \
| GSK_SL_POINTER_TYPE_IN \
| GSK_SL_POINTER_TYPE_OUT)
#define GSK_SL_POINTER_TYPE_MEMORY_QUALIFIER (GSK_SL_POINTER_TYPE_COHERENT \
| GSK_SL_POINTER_TYPE_VOLATILE \
| GSK_SL_POINTER_TYPE_RESTRICT \
| GSK_SL_POINTER_TYPE_READONLY \
| GSK_SL_POINTER_TYPE_WRITEONLY)
typedef enum {
GSK_SL_DECORATION_ACCESS_READ = (1 << 0),
GSK_SL_DECORATION_ACCESS_WRITE = (2 << 0),
GSK_SL_DECORATION_ACCESS_READWRITE = GSK_SL_DECORATION_ACCESS_READ | GSK_SL_DECORATION_ACCESS_WRITE,
} GskSlDecorationAccess;
gboolean gsk_sl_type_qualifier_parse (GskSlPreprocessor *stream,
GskSlPointerTypeFlags allowed_flags,
GskSlPointerTypeFlags *parsed_flags);
typedef struct _GskSlDecorations GskSlDecorations;
struct _GskSlDecorations
{
struct {
gboolean set;
gint value;
} values[GSK_SL_N_DECORATIONS];
};
gboolean gsk_sl_decoration_list_parse (GskSlPreprocessor *stream,
GskSlDecorations *list);
GskSlPointerType * gsk_sl_pointer_type_new (GskSlType *type,
GskSlPointerTypeFlags flags);
gboolean local,
GskSlDecorationAccess access);
GskSlPointerType * gsk_sl_pointer_type_ref (GskSlPointerType *type);
void gsk_sl_pointer_type_unref (GskSlPointerType *type);
@@ -62,15 +68,6 @@ void gsk_sl_pointer_type_print (const G
GString *string);
GskSlType * gsk_sl_pointer_type_get_type (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_const (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_in (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_out (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_invariant (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_coherent (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_volatile (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_restrict (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_readonly (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_is_writeonly (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_equal (gconstpointer a,
gconstpointer b);

View File

@@ -96,14 +96,12 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
{
GskSlType *type;
const GskSlToken *token;
GskSlPointerTypeFlags flags;
GskSlDecorations decoration;
gboolean success;
char *name;
success = gsk_sl_type_qualifier_parse (preproc,
GSK_SL_POINTER_TYPE_PARAMETER_QUALIFIER
| GSK_SL_POINTER_TYPE_MEMORY_QUALIFIER,
&flags);
success = gsk_sl_decoration_list_parse (preproc,
&decoration);
type = gsk_sl_type_new_parse (preproc);
if (type == NULL)
@@ -117,7 +115,7 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
{
if (success)
{
GskSlPointerType *ptype = gsk_sl_pointer_type_new (type, flags);
GskSlPointerType *ptype = gsk_sl_pointer_type_new (type, FALSE, decoration.values[GSK_SL_DECORATION_CALLER_ACCESS].value);
GskSlVariable *variable = gsk_sl_variable_new (ptype, NULL);
gsk_sl_pointer_type_unref (ptype);
program->variables = g_slist_append (program->variables, variable);
@@ -155,7 +153,7 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
{
GskSlPointerType *pointer_type;
pointer_type = gsk_sl_pointer_type_new (type, flags);
pointer_type = gsk_sl_pointer_type_new (type, FALSE, decoration.values[GSK_SL_DECORATION_CALLER_ACCESS].value);
success &= gsk_sl_program_parse_variable (program, scope, preproc, pointer_type, name);
gsk_sl_pointer_type_unref (pointer_type);
}