[gtk+/wip/otte/shader: 48/151] gskslfunction: Reorganize gsk_sl_function_matches()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 48/151] gskslfunction: Reorganize gsk_sl_function_matches()
- Date: Mon, 23 Oct 2017 01:23:17 +0000 (UTC)
commit 96a4757a1c9cd87c4842e2ac4976b67df6c3be3f
Author: Benjamin Otte <otte redhat com>
Date: Fri Sep 29 22:17:16 2017 +0200
gskslfunction: Reorganize gsk_sl_function_matches()
This is the first step towards implementing function overloading.
Instead of having the matches() vfunc the code now can query argument
type and count and uses this to implement a generic matches().
Constructors are checked seperately and manually. They also report 0
arguments.
gsk/gskslcompiler.h | 1 +
gsk/gskslexpression.c | 58 ++++++++++++-
gsk/gskslfunction.c | 219 +++++++++++++++++++-------------------------
gsk/gskslfunctionprivate.h | 12 ++-
4 files changed, 159 insertions(+), 131 deletions(-)
---
diff --git a/gsk/gskslcompiler.h b/gsk/gskslcompiler.h
index 4a23007..a042260 100644
--- a/gsk/gskslcompiler.h
+++ b/gsk/gskslcompiler.h
@@ -28,6 +28,7 @@
G_BEGIN_DECLS
typedef enum {
+ GSK_SL_COMPILER_ERROR_ARGUMENT_COUNT,
GSK_SL_COMPILER_ERROR_CONSTANT,
GSK_SL_COMPILER_ERROR_DECLARATION,
GSK_SL_COMPILER_ERROR_PREPROCESSOR,
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 9c9de36..973328a 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -1265,6 +1265,19 @@ gsk_sl_expression_error_new (void)
return (GskSlExpression *) constant;
}
+static gsize
+gsk_sl_constructor_get_args_by_type (const GskSlType *type)
+{
+ if (gsk_sl_type_is_scalar (type))
+ return 1;
+ else if (gsk_sl_type_is_vector (type))
+ return gsk_sl_type_get_length (type);
+ else if (gsk_sl_type_is_matrix (type))
+ return gsk_sl_type_get_length (type) * gsk_sl_constructor_get_args_by_type (gsk_sl_type_get_index_type
(type));
+ else
+ return 0;
+}
+
GskSlExpression *
gsk_sl_expression_parse_function_call (GskSlScope *scope,
GskSlPreprocessor *stream,
@@ -1274,6 +1287,7 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
const GskSlToken *token;
GskSlType **types;
GError *error = NULL;
+ gssize missing_args; /* only used for builtin constructors */
guint i;
call = gsk_sl_expression_new (GskSlExpressionFunctionCall, &GSK_SL_EXPRESSION_FUNCTION_CALL);
@@ -1287,6 +1301,11 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
}
gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
+ if (function && gsk_sl_function_is_builtin_constructor (function))
+ missing_args = gsk_sl_constructor_get_args_by_type (gsk_sl_function_get_return_type (function));
+ else
+ missing_args = -1;
+
token = gsk_sl_preprocessor_get (stream);
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
{
@@ -1299,12 +1318,49 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
g_ptr_array_add (arguments, expression);
+ if (function == NULL)
+ {
+ /* no checking necessary */
+ }
+ if (missing_args == 0)
+ {
+ gsk_sl_preprocessor_error (stream, ARGUMENT_COUNT,
+ "Too many arguments given to builtin constructor, only the first %u
are necessary.",
+ arguments->len);
+ function = NULL;
+ }
+ else if (missing_args > 0)
+ {
+ GskSlType *type = gsk_sl_expression_get_return_type (expression);
+ gsize provided = gsk_sl_constructor_get_args_by_type (type);
+
+ if (provided == 0)
+ {
+ gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+ "Invalid type %s for builtin constructor",
+ gsk_sl_type_get_name (type));
+ function = NULL;
+ }
+ else
+ {
+ missing_args -= MIN (missing_args, provided);
+ }
+ }
+
token = gsk_sl_preprocessor_get (stream);
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
break;
gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
}
+ if (missing_args > 0)
+ {
+ gsk_sl_preprocessor_error (stream, ARGUMENT_COUNT,
+ "Not enough arguments given to builtin constructor, %"G_GSIZE_FORMAT"
are missing.",
+ missing_args);
+ function = NULL;
+ }
+
call->n_arguments = arguments->len;
call->arguments = (GskSlExpression **) g_ptr_array_free (arguments, FALSE);
}
@@ -1312,7 +1368,7 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
types = g_newa (GskSlType *, call->n_arguments);
for (i = 0; i < call->n_arguments; i++)
types[i] = gsk_sl_expression_get_return_type (call->arguments[i]);
- if (function && !gsk_sl_function_matches (function, types, call->n_arguments, &error))
+ if (function && missing_args < 0 && !gsk_sl_function_matches (function, types, call->n_arguments, &error))
{
gsk_sl_preprocessor_emit_error (stream, TRUE, gsk_sl_preprocessor_get_location (stream), error);
g_clear_error (&error);
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 624cf81..75d4f1b 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -80,62 +80,23 @@ gsk_sl_function_builtin_constructor_get_name (const GskSlFunction *function)
return gsk_sl_type_get_name (builtin_constructor->type);
}
-static void
-gsk_sl_function_builtin_constructor_print (const GskSlFunction *function,
- GString *string)
+static gsize
+gsk_sl_function_builtin_constructor_get_n_arguments (const GskSlFunction *function)
{
+ return 0;
}
-static guint
-gsk_sl_function_builtin_get_args_by_type (const GskSlType *type)
+static GskSlType *
+gsk_sl_function_builtin_constructor_get_argument_type (const GskSlFunction *function,
+ gsize i)
{
- if (gsk_sl_type_is_scalar (type))
- return 1;
- else if (gsk_sl_type_is_vector (type))
- return gsk_sl_type_get_length (type);
- else if (gsk_sl_type_is_matrix (type))
- return gsk_sl_type_get_length (type) * gsk_sl_function_builtin_get_args_by_type
(gsk_sl_type_get_index_type (type));
- else
- return 0;
+ return NULL;
}
-static gboolean
-gsk_sl_function_builtin_constructor_matches (const GskSlFunction *function,
- GskSlType **arguments,
- gsize n_arguments,
- GError **error)
+static void
+gsk_sl_function_builtin_constructor_print (const GskSlFunction *function,
+ GString *string)
{
- const GskSlFunctionBuiltinConstructor *builtin_constructor = (const GskSlFunctionBuiltinConstructor *)
function;
- guint needed, provided;
- gsize i;
-
- if (n_arguments == 1 && gsk_sl_type_is_scalar (arguments[0]))
- return TRUE;
-
- needed = gsk_sl_function_builtin_get_args_by_type (builtin_constructor->type);
-
- for (i = 0; i < n_arguments; i++)
- {
- if (needed == 0)
- {
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Too many arguments given to
builtin_constructor, only the first %"G_GSIZE_FORMAT" are necessary.", i);
- return FALSE;
- }
-
- provided = gsk_sl_function_builtin_get_args_by_type (arguments[i]);
- if (provided == 0)
- {
- g_set_error (error,
- G_FILE_ERROR, G_FILE_ERROR_FAILED,
- "Invalid type %s for builtin_constructor in argument %"G_GSIZE_FORMAT,
- gsk_sl_type_get_name (arguments[i]), i + 1);
- return FALSE;
- }
-
- needed -= MIN (needed, provided);
- }
-
- return TRUE;
}
static guint32
@@ -149,8 +110,9 @@ static const GskSlFunctionClass GSK_SL_FUNCTION_BUILTIN_CONSTRUCTOR = {
gsk_sl_function_builtin_constructor_free,
gsk_sl_function_builtin_constructor_get_return_type,
gsk_sl_function_builtin_constructor_get_name,
+ gsk_sl_function_builtin_constructor_get_n_arguments,
+ gsk_sl_function_builtin_constructor_get_argument_type,
gsk_sl_function_builtin_constructor_print,
- gsk_sl_function_builtin_constructor_matches,
gsk_sl_function_builtin_constructor_write_spv,
};
@@ -190,47 +152,27 @@ gsk_sl_function_constructor_get_name (const GskSlFunction *function)
return gsk_sl_type_get_name (constructor->type);
}
-static void
-gsk_sl_function_constructor_print (const GskSlFunction *function,
- GString *string)
+static gsize
+gsk_sl_function_constructor_get_n_arguments (const GskSlFunction *function)
{
+ const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
+
+ return gsk_sl_type_get_n_members (constructor->type);
}
-static gboolean
-gsk_sl_function_constructor_matches (const GskSlFunction *function,
- GskSlType **arguments,
- gsize n_arguments,
- GError **error)
+static GskSlType *
+gsk_sl_function_constructor_get_argument_type (const GskSlFunction *function,
+ gsize i)
{
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
- guint i;
-
- if (n_arguments != gsk_sl_type_get_n_members (constructor->type))
- {
- g_set_error (error,
- GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
- "Constructor for %s needs %u arguments, but %"G_GSIZE_FORMAT" given.",
- gsk_sl_type_get_name (constructor->type),
- gsk_sl_type_get_n_members (constructor->type),
- n_arguments);
- return FALSE;
- }
- for (i = 0; i < n_arguments; i++)
- {
- if (!gsk_sl_type_can_convert (gsk_sl_type_get_member_type (constructor->type, i), arguments[i]))
- {
- g_set_error (error,
- GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
- "Cannot convert argument %u from %s to %s.",
- i,
- gsk_sl_type_get_name (arguments[i]),
- gsk_sl_type_get_name (gsk_sl_type_get_member_type (constructor->type, i)));
- return FALSE;
- }
- }
+ return gsk_sl_type_get_member_type (constructor->type, i);
+}
- return TRUE;
+static void
+gsk_sl_function_constructor_print (const GskSlFunction *function,
+ GString *string)
+{
}
static guint32
@@ -244,8 +186,9 @@ static const GskSlFunctionClass GSK_SL_FUNCTION_CONSTRUCTOR = {
gsk_sl_function_constructor_free,
gsk_sl_function_constructor_get_return_type,
gsk_sl_function_constructor_get_name,
+ gsk_sl_function_constructor_get_n_arguments,
+ gsk_sl_function_constructor_get_argument_type,
gsk_sl_function_constructor_print,
- gsk_sl_function_constructor_matches,
gsk_sl_function_constructor_write_spv,
};
@@ -299,6 +242,22 @@ gsk_sl_function_declared_get_name (const GskSlFunction *function)
return declared->name;
}
+static gsize
+gsk_sl_function_declared_get_n_arguments (const GskSlFunction *function)
+{
+ const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
+
+ return declared->n_arguments;
+}
+
+static GskSlType *
+gsk_sl_function_declared_get_argument_type (const GskSlFunction *function,
+ gsize i)
+{
+ const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
+
+ return gsk_sl_pointer_type_get_type (gsk_sl_variable_get_type (declared->arguments[i]));
+}
static void
gsk_sl_function_declared_print (const GskSlFunction *function,
GString *string)
@@ -330,45 +289,6 @@ gsk_sl_function_declared_print (const GskSlFunction *function,
g_string_append (string, "}\n");
}
-static gboolean
-gsk_sl_function_declared_matches (const GskSlFunction *function,
- GskSlType **arguments,
- gsize n_arguments,
- GError **error)
-{
- const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
- guint i;
-
- if (n_arguments != declared->n_arguments)
- {
- g_set_error (error,
- GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
- "Function %s needs %"G_GSIZE_FORMAT" arguments, but %"G_GSIZE_FORMAT" given.",
- declared->name,
- declared->n_arguments,
- n_arguments);
- return FALSE;
- }
-
- for (i = 0; i < n_arguments; i++)
- {
- GskSlType *type = gsk_sl_pointer_type_get_type (gsk_sl_variable_get_type (declared->arguments[i]));
-
- if (!gsk_sl_type_can_convert (type, arguments[i]))
- {
- g_set_error (error,
- GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
- "Cannot convert argument %u from %s to %s.",
- i,
- gsk_sl_type_get_name (arguments[i]),
- gsk_sl_type_get_name (type));
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
static guint32
gsk_sl_function_declared_write_spv (const GskSlFunction *function,
GskSpvWriter *writer)
@@ -421,8 +341,9 @@ static const GskSlFunctionClass GSK_SL_FUNCTION_DECLARED = {
gsk_sl_function_declared_free,
gsk_sl_function_declared_get_return_type,
gsk_sl_function_declared_get_name,
+ gsk_sl_function_declared_get_n_arguments,
+ gsk_sl_function_declared_get_argument_type,
gsk_sl_function_declared_print,
- gsk_sl_function_declared_matches,
gsk_sl_function_declared_write_spv,
};
@@ -609,6 +530,12 @@ gsk_sl_function_unref (GskSlFunction *function)
function->class->free (function);
}
+gboolean
+gsk_sl_function_is_builtin_constructor (const GskSlFunction *function)
+{
+ return function->class == &GSK_SL_FUNCTION_BUILTIN_CONSTRUCTOR;
+}
+
GskSlType *
gsk_sl_function_get_return_type (const GskSlFunction *function)
{
@@ -621,6 +548,19 @@ gsk_sl_function_get_name (const GskSlFunction *function)
return function->class->get_name (function);
}
+gsize
+gsk_sl_function_get_n_arguments (const GskSlFunction *function)
+{
+ return function->class->get_n_arguments (function);
+}
+
+GskSlType *
+gsk_sl_function_get_argument_type (const GskSlFunction *function,
+ gsize i)
+{
+ return function->class->get_argument_type (function, i);
+}
+
void
gsk_sl_function_print (const GskSlFunction *function,
GString *string)
@@ -634,7 +574,34 @@ gsk_sl_function_matches (const GskSlFunction *function,
gsize n_arguments,
GError **error)
{
- return function->class->matches (function, arguments, n_arguments, error);
+ guint i;
+
+ if (n_arguments != gsk_sl_function_get_n_arguments (function))
+ {
+ g_set_error (error,
+ GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
+ "Function %s needs %"G_GSIZE_FORMAT" arguments, but %"G_GSIZE_FORMAT" given.",
+ gsk_sl_function_get_name (function),
+ gsk_sl_function_get_n_arguments (function),
+ n_arguments);
+ return FALSE;
+ }
+
+ for (i = 0; i < n_arguments; i++)
+ {
+ if (!gsk_sl_type_can_convert (gsk_sl_function_get_argument_type (function, i), arguments[i]))
+ {
+ g_set_error (error,
+ GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
+ "Cannot convert argument %u from %s to %s.",
+ i + 1,
+ gsk_sl_type_get_name (arguments[i]),
+ gsk_sl_type_get_name (gsk_sl_function_get_argument_type (function, i)));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
}
guint32
diff --git a/gsk/gskslfunctionprivate.h b/gsk/gskslfunctionprivate.h
index 9e28374..ce38b8e 100644
--- a/gsk/gskslfunctionprivate.h
+++ b/gsk/gskslfunctionprivate.h
@@ -39,12 +39,11 @@ struct _GskSlFunctionClass {
GskSlType * (* get_return_type) (const GskSlFunction *function);
const char * (* get_name) (const GskSlFunction *function);
+ gsize (* get_n_arguments) (const GskSlFunction *function);
+ GskSlType * (* get_argument_type) (const GskSlFunction *function,
+ gsize i);
void (* print) (const GskSlFunction *function,
GString *string);
- gboolean (* matches) (const GskSlFunction *function,
- GskSlType **arguments,
- gsize n_arguments,
- GError **error);
guint32 (* write_spv) (const GskSlFunction *function,
GskSpvWriter *writer);
};
@@ -58,11 +57,16 @@ GskSlFunction * gsk_sl_function_new_parse (GskSlScope
GskSlFunction * gsk_sl_function_ref (GskSlFunction *function);
void gsk_sl_function_unref (GskSlFunction *function);
+gboolean gsk_sl_function_is_builtin_constructor (const GskSlFunction *function);
+
void gsk_sl_function_print (const GskSlFunction *function,
GString *string);
const char * gsk_sl_function_get_name (const GskSlFunction *function);
GskSlType * gsk_sl_function_get_return_type (const GskSlFunction *function);
+gsize gsk_sl_function_get_n_arguments (const GskSlFunction *function);
+GskSlType * gsk_sl_function_get_argument_type (const GskSlFunction *function,
+ gsize i);
gboolean gsk_sl_function_matches (const GskSlFunction *function,
GskSlType **arguments,
gsize n_arguments,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]