gsksl: Turn functions into functions
Don't use a GskSlNode subclass to handle declared functions but make them a GskSlFunction subclass.
This commit is contained in:
@@ -20,7 +20,12 @@
|
||||
|
||||
#include "gskslfunctionprivate.h"
|
||||
|
||||
#include "gskslnodeprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslscopeprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
static GskSlFunction *
|
||||
gsk_sl_function_alloc (const GskSlFunctionClass *klass,
|
||||
@@ -58,22 +63,27 @@ gsk_sl_function_constructor_free (GskSlFunction *function)
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_constructor_get_return_type (GskSlFunction *function)
|
||||
gsk_sl_function_constructor_get_return_type (const GskSlFunction *function)
|
||||
{
|
||||
GskSlFunctionConstructor *constructor = (GskSlFunctionConstructor *) function;
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
|
||||
return constructor->type;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_function_constructor_print_name (GskSlFunction *function,
|
||||
GString *string)
|
||||
gsk_sl_function_constructor_print_name (const GskSlFunction *function,
|
||||
GString *string)
|
||||
{
|
||||
GskSlFunctionConstructor *constructor = (GskSlFunctionConstructor *) function;
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
|
||||
g_string_append (string, gsk_sl_type_get_name (constructor->type));
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_function_constructor_print (const GskSlFunction *function,
|
||||
GString *string)
|
||||
{
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_function_builtin_get_args_by_type (const GskSlType *type)
|
||||
@@ -89,12 +99,12 @@ gsk_sl_function_builtin_get_args_by_type (const GskSlType *type)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_function_constructor_matches (GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error)
|
||||
gsk_sl_function_constructor_matches (const GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error)
|
||||
{
|
||||
GskSlFunctionConstructor *constructor = (GskSlFunctionConstructor *) function;
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
guint needed, provided;
|
||||
gsize i;
|
||||
|
||||
@@ -127,11 +137,161 @@ gsk_sl_function_constructor_matches (GskSlFunction *function,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_constructor_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const GskSlFunctionClass GSK_SL_FUNCTION_CONSTRUCTOR = {
|
||||
gsk_sl_function_constructor_free,
|
||||
gsk_sl_function_constructor_get_return_type,
|
||||
gsk_sl_function_constructor_print_name,
|
||||
gsk_sl_function_constructor_print,
|
||||
gsk_sl_function_constructor_matches,
|
||||
gsk_sl_function_constructor_write_spv,
|
||||
};
|
||||
|
||||
/* DECLARED */
|
||||
|
||||
typedef struct _GskSlFunctionDeclared GskSlFunctionDeclared;
|
||||
|
||||
struct _GskSlFunctionDeclared {
|
||||
GskSlFunction parent;
|
||||
|
||||
GskSlScope *scope;
|
||||
GskSlType *return_type;
|
||||
char *name;
|
||||
GSList *statements;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_function_declared_free (GskSlFunction *function)
|
||||
{
|
||||
GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
|
||||
|
||||
if (declared->scope)
|
||||
gsk_sl_scope_unref (declared->scope);
|
||||
if (declared->return_type)
|
||||
gsk_sl_type_unref (declared->return_type);
|
||||
g_free (declared->name);
|
||||
g_slist_free_full (declared->statements, (GDestroyNotify) gsk_sl_node_unref);
|
||||
|
||||
g_slice_free (GskSlFunctionDeclared, declared);
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_declared_get_return_type (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
|
||||
return declared->return_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_function_declared_print_name (const GskSlFunction *function,
|
||||
GString *string)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
|
||||
g_string_append (string, declared->name);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_function_declared_print (const GskSlFunction *function,
|
||||
GString *string)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
GSList *l;
|
||||
|
||||
g_string_append (string, gsk_sl_type_get_name (declared->return_type));
|
||||
g_string_append (string, "\n");
|
||||
|
||||
g_string_append (string, declared->name);
|
||||
g_string_append (string, " (");
|
||||
g_string_append (string, ")\n");
|
||||
|
||||
g_string_append (string, "{\n");
|
||||
for (l = declared->statements; l; l = l->next)
|
||||
{
|
||||
g_string_append (string, " ");
|
||||
gsk_sl_node_print (l->data, string);
|
||||
g_string_append (string, ";\n");
|
||||
}
|
||||
g_string_append (string, "}\n");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_function_declared_matches (const GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error)
|
||||
{
|
||||
if (n_arguments > 0)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Function only takes %u arguments.", 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_declared_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
|
||||
guint32 return_type_id, function_type_id, function_id, label_id;
|
||||
GSList *l;
|
||||
|
||||
/* declare type of function */
|
||||
return_type_id = gsk_spv_writer_get_id_for_type (writer, declared->return_type);
|
||||
function_type_id = gsk_spv_writer_next_id (writer);
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_DECLARE,
|
||||
3, GSK_SPV_OP_TYPE_FUNCTION,
|
||||
(guint32[2]) { function_type_id,
|
||||
return_type_id });
|
||||
|
||||
/* add debug info */
|
||||
/* FIXME */
|
||||
|
||||
/* add function body */
|
||||
function_id = gsk_spv_writer_next_id (writer);
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
5, GSK_SPV_OP_FUNCTION,
|
||||
(guint32[4]) { return_type_id,
|
||||
function_id,
|
||||
0,
|
||||
function_type_id });
|
||||
label_id = gsk_spv_writer_next_id (writer);
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
2, GSK_SPV_OP_LABEL,
|
||||
(guint32[1]) { label_id });
|
||||
|
||||
for (l = declared->statements; l; l = l->next)
|
||||
{
|
||||
gsk_sl_node_write_spv (l->data, writer);
|
||||
}
|
||||
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
1, GSK_SPV_OP_FUNCTION_END,
|
||||
NULL);
|
||||
|
||||
return function_id;
|
||||
}
|
||||
|
||||
static const GskSlFunctionClass GSK_SL_FUNCTION_DECLARED = {
|
||||
gsk_sl_function_declared_free,
|
||||
gsk_sl_function_declared_get_return_type,
|
||||
gsk_sl_function_declared_print_name,
|
||||
gsk_sl_function_declared_print,
|
||||
gsk_sl_function_declared_matches,
|
||||
gsk_sl_function_declared_write_spv,
|
||||
};
|
||||
|
||||
/* API */
|
||||
@@ -148,6 +308,85 @@ gsk_sl_function_new_constructor (GskSlType *type)
|
||||
return &constructor->parent;
|
||||
}
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_function_new_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlType *return_type,
|
||||
const char *name)
|
||||
{
|
||||
GskSlFunctionDeclared *function;
|
||||
const GskSlToken *token;
|
||||
gboolean success = TRUE;
|
||||
|
||||
function = gsk_sl_function_new (GskSlFunctionDeclared, &GSK_SL_FUNCTION_DECLARED);
|
||||
function->return_type = gsk_sl_type_ref (return_type);
|
||||
function->name = g_strdup (name);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Expected an openening \"(\"");
|
||||
gsk_sl_function_unref ((GskSlFunction *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Expected a closing \")\"");
|
||||
gsk_sl_function_unref ((GskSlFunction *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) function);
|
||||
return (GskSlFunction *) function;
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Expected an opening \"{\"");
|
||||
gsk_sl_function_unref ((GskSlFunction *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) function);
|
||||
|
||||
function->scope = gsk_sl_scope_new (scope, function->return_type);
|
||||
|
||||
for (token = gsk_sl_preprocessor_get (preproc);
|
||||
!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE) && !gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
|
||||
token = gsk_sl_preprocessor_get (preproc))
|
||||
{
|
||||
GskSlNode *statement;
|
||||
|
||||
statement = gsk_sl_node_parse_statement (function->scope, preproc);
|
||||
if (statement)
|
||||
function->statements = g_slist_append (function->statements, statement);
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Missing closing \"}\" at end.");
|
||||
gsk_sl_function_unref ((GskSlFunction *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) function);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
gsk_sl_function_unref ((GskSlFunction *) function);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (GskSlFunction *) function;
|
||||
}
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_function_ref (GskSlFunction *function)
|
||||
{
|
||||
@@ -172,24 +411,38 @@ gsk_sl_function_unref (GskSlFunction *function)
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_function_get_return_type (GskSlFunction *function)
|
||||
gsk_sl_function_get_return_type (const GskSlFunction *function)
|
||||
{
|
||||
return function->class->get_return_type (function);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_print_name (GskSlFunction *function,
|
||||
GString *string)
|
||||
gsk_sl_function_print_name (const GskSlFunction *function,
|
||||
GString *string)
|
||||
{
|
||||
function->class->print_name (function, string);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_print (const GskSlFunction *function,
|
||||
GString *string)
|
||||
{
|
||||
function->class->print (function, string);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_function_matches (GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error)
|
||||
gsk_sl_function_matches (const GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error)
|
||||
{
|
||||
return function->class->matches (function, arguments, n_arguments, error);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_function_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return function->class->write_spv (function, writer);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,27 +37,40 @@ struct _GskSlFunction
|
||||
struct _GskSlFunctionClass {
|
||||
void (* free) (GskSlFunction *function);
|
||||
|
||||
GskSlType * (* get_return_type) (GskSlFunction *function);
|
||||
void (* print_name) (GskSlFunction *function,
|
||||
GString *string);
|
||||
gboolean (* matches) (GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error);
|
||||
GskSlType * (* get_return_type) (const GskSlFunction *function);
|
||||
void (* print_name) (const GskSlFunction *function,
|
||||
GString *string);
|
||||
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);
|
||||
};
|
||||
|
||||
GskSlFunction * gsk_sl_function_new_constructor (GskSlType *type);
|
||||
GskSlFunction * gsk_sl_function_new_constructor (GskSlType *type);
|
||||
GskSlFunction * gsk_sl_function_new_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream,
|
||||
GskSlType *return_type,
|
||||
const char *name);
|
||||
|
||||
GskSlFunction * gsk_sl_function_ref (GskSlFunction *function);
|
||||
void gsk_sl_function_unref (GskSlFunction *function);
|
||||
GskSlFunction * gsk_sl_function_ref (GskSlFunction *function);
|
||||
void gsk_sl_function_unref (GskSlFunction *function);
|
||||
|
||||
void gsk_sl_function_print_name (GskSlFunction *function,
|
||||
GString *string);
|
||||
GskSlType * gsk_sl_function_get_return_type (GskSlFunction *function);
|
||||
gboolean gsk_sl_function_matches (GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error);
|
||||
void gsk_sl_function_print (const GskSlFunction *function,
|
||||
GString *string);
|
||||
|
||||
void gsk_sl_function_print_name (const GskSlFunction *function,
|
||||
GString *string);
|
||||
GskSlType * gsk_sl_function_get_return_type (const GskSlFunction *function);
|
||||
gboolean gsk_sl_function_matches (const GskSlFunction *function,
|
||||
GskSlType **arguments,
|
||||
gsize n_arguments,
|
||||
GError **error);
|
||||
guint32 gsk_sl_function_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
546
gsk/gskslnode.c
546
gsk/gskslnode.c
@@ -47,109 +47,42 @@ gsk_sl_node_alloc (const GskSlNodeClass *klass,
|
||||
}
|
||||
#define gsk_sl_node_new(_name, _klass) ((_name *) gsk_sl_node_alloc ((_klass), sizeof (_name)))
|
||||
|
||||
/* FUNCTION */
|
||||
/* EMPTY */
|
||||
|
||||
typedef struct _GskSlNodeFunction GskSlNodeFunction;
|
||||
/* FIXME: This exists only so we dont return NULL from empty statements (ie just a semicolon)
|
||||
*/
|
||||
|
||||
struct _GskSlNodeFunction {
|
||||
typedef struct _GskSlNodeEmpty GskSlNodeEmpty;
|
||||
|
||||
struct _GskSlNodeEmpty {
|
||||
GskSlNode parent;
|
||||
|
||||
GskSlScope *scope;
|
||||
GskSlType *return_type;
|
||||
char *name;
|
||||
GSList *statements;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_node_function_free (GskSlNode *node)
|
||||
gsk_sl_node_empty_free (GskSlNode *node)
|
||||
{
|
||||
GskSlNodeFunction *function = (GskSlNodeFunction *) node;
|
||||
GskSlNodeEmpty *empty = (GskSlNodeEmpty *) node;
|
||||
|
||||
if (function->scope)
|
||||
gsk_sl_scope_unref (function->scope);
|
||||
if (function->return_type)
|
||||
gsk_sl_type_unref (function->return_type);
|
||||
g_free (function->name);
|
||||
g_slist_free_full (function->statements, (GDestroyNotify) gsk_sl_node_unref);
|
||||
|
||||
g_slice_free (GskSlNodeFunction, function);
|
||||
g_slice_free (GskSlNodeEmpty, empty);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_node_function_print (GskSlNode *node,
|
||||
GString *string)
|
||||
gsk_sl_node_empty_print (GskSlNode *node,
|
||||
GString *string)
|
||||
{
|
||||
GskSlNodeFunction *function = (GskSlNodeFunction *) node;
|
||||
GSList *l;
|
||||
|
||||
g_string_append (string, gsk_sl_type_get_name (function->return_type));
|
||||
g_string_append (string, "\n");
|
||||
|
||||
g_string_append (string, function->name);
|
||||
g_string_append (string, " (");
|
||||
g_string_append (string, ")\n");
|
||||
|
||||
g_string_append (string, "{\n");
|
||||
for (l = function->statements; l; l = l->next)
|
||||
{
|
||||
g_string_append (string, " ");
|
||||
gsk_sl_node_print (l->data, string);
|
||||
g_string_append (string, ";\n");
|
||||
}
|
||||
g_string_append (string, "}\n");
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_node_function_write_spv (const GskSlNode *node,
|
||||
GskSpvWriter *writer)
|
||||
gsk_sl_node_empty_write_spv (const GskSlNode *node,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
GskSlNodeFunction *function = (GskSlNodeFunction *) node;
|
||||
guint32 return_type_id, function_type_id, function_id, label_id;
|
||||
GSList *l;
|
||||
|
||||
/* declare type of function */
|
||||
return_type_id = gsk_spv_writer_get_id_for_type (writer, function->return_type);
|
||||
function_type_id = gsk_spv_writer_next_id (writer);
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_DECLARE,
|
||||
3, GSK_SPV_OP_TYPE_FUNCTION,
|
||||
(guint32[2]) { function_type_id,
|
||||
return_type_id });
|
||||
|
||||
/* add debug info */
|
||||
/* FIXME */
|
||||
|
||||
/* add function body */
|
||||
function_id = gsk_spv_writer_next_id (writer);
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
5, GSK_SPV_OP_FUNCTION,
|
||||
(guint32[4]) { return_type_id,
|
||||
function_id,
|
||||
0,
|
||||
function_type_id });
|
||||
label_id = gsk_spv_writer_next_id (writer);
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
2, GSK_SPV_OP_LABEL,
|
||||
(guint32[4]) { label_id });
|
||||
|
||||
for (l = function->statements; l; l = l->next)
|
||||
{
|
||||
gsk_sl_node_write_spv (l->data, writer);
|
||||
}
|
||||
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
1, GSK_SPV_OP_FUNCTION_END,
|
||||
NULL);
|
||||
return function_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const GskSlNodeClass GSK_SL_NODE_FUNCTION = {
|
||||
gsk_sl_node_function_free,
|
||||
gsk_sl_node_function_print,
|
||||
gsk_sl_node_function_write_spv
|
||||
static const GskSlNodeClass GSK_SL_NODE_EMPTY = {
|
||||
gsk_sl_node_empty_free,
|
||||
gsk_sl_node_empty_print,
|
||||
gsk_sl_node_empty_write_spv
|
||||
};
|
||||
|
||||
/* DECLARATION */
|
||||
@@ -312,52 +245,6 @@ static const GskSlNodeClass GSK_SL_NODE_EXPRESSION = {
|
||||
|
||||
/* API */
|
||||
|
||||
static GskSlNodeFunction *
|
||||
gsk_sl_node_parse_function_prototype (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream)
|
||||
{
|
||||
GskSlType *type;
|
||||
GskSlNodeFunction *function;
|
||||
const GskSlToken *token;
|
||||
|
||||
type = gsk_sl_type_new_parse (stream);
|
||||
if (type == NULL)
|
||||
return NULL;
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected a function name");
|
||||
gsk_sl_type_unref (type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function = gsk_sl_node_new (GskSlNodeFunction, &GSK_SL_NODE_FUNCTION);
|
||||
function->return_type = type;
|
||||
function->name = g_strdup (token->str);
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected an openening \"(\"");
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected a closing \")\"");
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
static GskSlNode *
|
||||
gsk_sl_node_parse_declaration (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream,
|
||||
@@ -391,239 +278,228 @@ gsk_sl_node_parse_declaration (GskSlScope *scope,
|
||||
}
|
||||
|
||||
GskSlNode *
|
||||
gsk_sl_node_parse_function_definition (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream)
|
||||
gsk_sl_node_parse_statement (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlNodeFunction *function;
|
||||
const GskSlToken *token;
|
||||
gboolean result = TRUE;
|
||||
GskSlNode *node;
|
||||
|
||||
function = gsk_sl_node_parse_function_prototype (scope, stream);
|
||||
if (function == NULL)
|
||||
return FALSE;
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
return (GskSlNode *) function;
|
||||
}
|
||||
switch ((guint) token->type)
|
||||
{
|
||||
case GSK_SL_TOKEN_SEMICOLON:
|
||||
node = (GskSlNode *) gsk_sl_node_new (GskSlNodeEmpty, &GSK_SL_NODE_EMPTY);
|
||||
break;
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected an opening \"{\"");
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
return FALSE;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
case GSK_SL_TOKEN_EOF:
|
||||
gsk_sl_preprocessor_error (preproc, "Unexpected end of document");
|
||||
return NULL;
|
||||
|
||||
function->scope = gsk_sl_scope_new (scope);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
switch ((guint) token->type)
|
||||
case GSK_SL_TOKEN_CONST:
|
||||
case GSK_SL_TOKEN_IN:
|
||||
case GSK_SL_TOKEN_OUT:
|
||||
case GSK_SL_TOKEN_INOUT:
|
||||
case GSK_SL_TOKEN_INVARIANT:
|
||||
case GSK_SL_TOKEN_COHERENT:
|
||||
case GSK_SL_TOKEN_VOLATILE:
|
||||
case GSK_SL_TOKEN_RESTRICT:
|
||||
case GSK_SL_TOKEN_READONLY:
|
||||
case GSK_SL_TOKEN_WRITEONLY:
|
||||
case GSK_SL_TOKEN_VOID:
|
||||
case GSK_SL_TOKEN_FLOAT:
|
||||
case GSK_SL_TOKEN_DOUBLE:
|
||||
case GSK_SL_TOKEN_INT:
|
||||
case GSK_SL_TOKEN_UINT:
|
||||
case GSK_SL_TOKEN_BOOL:
|
||||
case GSK_SL_TOKEN_BVEC2:
|
||||
case GSK_SL_TOKEN_BVEC3:
|
||||
case GSK_SL_TOKEN_BVEC4:
|
||||
case GSK_SL_TOKEN_IVEC2:
|
||||
case GSK_SL_TOKEN_IVEC3:
|
||||
case GSK_SL_TOKEN_IVEC4:
|
||||
case GSK_SL_TOKEN_UVEC2:
|
||||
case GSK_SL_TOKEN_UVEC3:
|
||||
case GSK_SL_TOKEN_UVEC4:
|
||||
case GSK_SL_TOKEN_VEC2:
|
||||
case GSK_SL_TOKEN_VEC3:
|
||||
case GSK_SL_TOKEN_VEC4:
|
||||
case GSK_SL_TOKEN_DVEC2:
|
||||
case GSK_SL_TOKEN_DVEC3:
|
||||
case GSK_SL_TOKEN_DVEC4:
|
||||
case GSK_SL_TOKEN_MAT2:
|
||||
case GSK_SL_TOKEN_MAT3:
|
||||
case GSK_SL_TOKEN_MAT4:
|
||||
case GSK_SL_TOKEN_DMAT2:
|
||||
case GSK_SL_TOKEN_DMAT3:
|
||||
case GSK_SL_TOKEN_DMAT4:
|
||||
case GSK_SL_TOKEN_MAT2X2:
|
||||
case GSK_SL_TOKEN_MAT2X3:
|
||||
case GSK_SL_TOKEN_MAT2X4:
|
||||
case GSK_SL_TOKEN_MAT3X2:
|
||||
case GSK_SL_TOKEN_MAT3X3:
|
||||
case GSK_SL_TOKEN_MAT3X4:
|
||||
case GSK_SL_TOKEN_MAT4X2:
|
||||
case GSK_SL_TOKEN_MAT4X3:
|
||||
case GSK_SL_TOKEN_MAT4X4:
|
||||
case GSK_SL_TOKEN_DMAT2X2:
|
||||
case GSK_SL_TOKEN_DMAT2X3:
|
||||
case GSK_SL_TOKEN_DMAT2X4:
|
||||
case GSK_SL_TOKEN_DMAT3X2:
|
||||
case GSK_SL_TOKEN_DMAT3X3:
|
||||
case GSK_SL_TOKEN_DMAT3X4:
|
||||
case GSK_SL_TOKEN_DMAT4X2:
|
||||
case GSK_SL_TOKEN_DMAT4X3:
|
||||
case GSK_SL_TOKEN_DMAT4X4:
|
||||
{
|
||||
case GSK_SL_TOKEN_SEMICOLON:
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
break;
|
||||
GskSlType *type;
|
||||
GskSlPointerTypeFlags flags;
|
||||
gboolean success;
|
||||
|
||||
case GSK_SL_TOKEN_EOF:
|
||||
gsk_sl_preprocessor_error (stream, "Unexpected end of function, expected \"}\"");
|
||||
goto out;
|
||||
success = gsk_sl_type_qualifier_parse (preproc,
|
||||
GSK_SL_POINTER_TYPE_PARAMETER_QUALIFIER
|
||||
| GSK_SL_POINTER_TYPE_MEMORY_QUALIFIER,
|
||||
&flags);
|
||||
|
||||
case GSK_SL_TOKEN_RIGHT_BRACE:
|
||||
goto out;
|
||||
|
||||
case GSK_SL_TOKEN_CONST:
|
||||
case GSK_SL_TOKEN_IN:
|
||||
case GSK_SL_TOKEN_OUT:
|
||||
case GSK_SL_TOKEN_INOUT:
|
||||
case GSK_SL_TOKEN_INVARIANT:
|
||||
case GSK_SL_TOKEN_COHERENT:
|
||||
case GSK_SL_TOKEN_VOLATILE:
|
||||
case GSK_SL_TOKEN_RESTRICT:
|
||||
case GSK_SL_TOKEN_READONLY:
|
||||
case GSK_SL_TOKEN_WRITEONLY:
|
||||
case GSK_SL_TOKEN_VOID:
|
||||
case GSK_SL_TOKEN_FLOAT:
|
||||
case GSK_SL_TOKEN_DOUBLE:
|
||||
case GSK_SL_TOKEN_INT:
|
||||
case GSK_SL_TOKEN_UINT:
|
||||
case GSK_SL_TOKEN_BOOL:
|
||||
case GSK_SL_TOKEN_BVEC2:
|
||||
case GSK_SL_TOKEN_BVEC3:
|
||||
case GSK_SL_TOKEN_BVEC4:
|
||||
case GSK_SL_TOKEN_IVEC2:
|
||||
case GSK_SL_TOKEN_IVEC3:
|
||||
case GSK_SL_TOKEN_IVEC4:
|
||||
case GSK_SL_TOKEN_UVEC2:
|
||||
case GSK_SL_TOKEN_UVEC3:
|
||||
case GSK_SL_TOKEN_UVEC4:
|
||||
case GSK_SL_TOKEN_VEC2:
|
||||
case GSK_SL_TOKEN_VEC3:
|
||||
case GSK_SL_TOKEN_VEC4:
|
||||
case GSK_SL_TOKEN_DVEC2:
|
||||
case GSK_SL_TOKEN_DVEC3:
|
||||
case GSK_SL_TOKEN_DVEC4:
|
||||
case GSK_SL_TOKEN_MAT2:
|
||||
case GSK_SL_TOKEN_MAT3:
|
||||
case GSK_SL_TOKEN_MAT4:
|
||||
case GSK_SL_TOKEN_DMAT2:
|
||||
case GSK_SL_TOKEN_DMAT3:
|
||||
case GSK_SL_TOKEN_DMAT4:
|
||||
case GSK_SL_TOKEN_MAT2X2:
|
||||
case GSK_SL_TOKEN_MAT2X3:
|
||||
case GSK_SL_TOKEN_MAT2X4:
|
||||
case GSK_SL_TOKEN_MAT3X2:
|
||||
case GSK_SL_TOKEN_MAT3X3:
|
||||
case GSK_SL_TOKEN_MAT3X4:
|
||||
case GSK_SL_TOKEN_MAT4X2:
|
||||
case GSK_SL_TOKEN_MAT4X3:
|
||||
case GSK_SL_TOKEN_MAT4X4:
|
||||
case GSK_SL_TOKEN_DMAT2X2:
|
||||
case GSK_SL_TOKEN_DMAT2X3:
|
||||
case GSK_SL_TOKEN_DMAT2X4:
|
||||
case GSK_SL_TOKEN_DMAT3X2:
|
||||
case GSK_SL_TOKEN_DMAT3X3:
|
||||
case GSK_SL_TOKEN_DMAT3X4:
|
||||
case GSK_SL_TOKEN_DMAT4X2:
|
||||
case GSK_SL_TOKEN_DMAT4X3:
|
||||
case GSK_SL_TOKEN_DMAT4X4:
|
||||
{
|
||||
GskSlType *type;
|
||||
GskSlPointerTypeFlags flags;
|
||||
gboolean success;
|
||||
GskSlNode *node = NULL;
|
||||
|
||||
success = gsk_sl_type_qualifier_parse (stream,
|
||||
GSK_SL_POINTER_TYPE_PARAMETER_QUALIFIER
|
||||
| GSK_SL_POINTER_TYPE_MEMORY_QUALIFIER,
|
||||
&flags);
|
||||
|
||||
type = gsk_sl_type_new_parse (stream);
|
||||
if (type == NULL)
|
||||
type = gsk_sl_type_new_parse (preproc);
|
||||
if (type == NULL)
|
||||
{
|
||||
node = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
|
||||
if (token->type == GSK_SL_TOKEN_LEFT_BRACE)
|
||||
{
|
||||
GskSlExpression *expression = gsk_sl_expression_parse_constructor_call (function->scope, stream, type);
|
||||
if (token->type == GSK_SL_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
GskSlExpression *expression = gsk_sl_expression_parse_constructor_call (scope, preproc, type);
|
||||
|
||||
if (expression)
|
||||
{
|
||||
GskSlNodeExpression *node;
|
||||
|
||||
node = gsk_sl_node_new (GskSlNodeExpression, &GSK_SL_NODE_EXPRESSION);
|
||||
node->expression = expression;
|
||||
|
||||
function->statements = g_slist_append (function->statements, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GskSlPointerType *pointer_type;
|
||||
|
||||
pointer_type = gsk_sl_pointer_type_new (type, flags | GSK_SL_POINTER_TYPE_LOCAL);
|
||||
node = gsk_sl_node_parse_declaration (function->scope, stream, pointer_type);
|
||||
gsk_sl_pointer_type_unref (pointer_type);
|
||||
}
|
||||
|
||||
gsk_sl_type_unref (type);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
gsk_sl_node_unref (node);
|
||||
}
|
||||
else if (node)
|
||||
{
|
||||
function->statements = g_slist_append (function->statements, node);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_RETURN:
|
||||
{
|
||||
GskSlNodeReturn *return_node;
|
||||
|
||||
return_node = gsk_sl_node_new (GskSlNodeReturn, &GSK_SL_NODE_RETURN);
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) return_node);
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
return_node->value = gsk_sl_expression_parse (function->scope, stream);
|
||||
if (return_node->value == NULL)
|
||||
{
|
||||
gsk_sl_node_unref ((GskSlNode *) return_node);
|
||||
break;
|
||||
}
|
||||
if (function->return_type == NULL)
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Cannot return a value from a void function.");
|
||||
gsk_sl_node_unref ((GskSlNode *) return_node);
|
||||
break;
|
||||
}
|
||||
else if (!gsk_sl_type_can_convert (function->return_type, gsk_sl_expression_get_return_type (return_node->value)))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Cannot convert return type %s to function type %s.",
|
||||
gsk_sl_type_get_name (gsk_sl_expression_get_return_type (return_node->value)),
|
||||
gsk_sl_type_get_name (function->return_type));
|
||||
gsk_sl_node_unref ((GskSlNode *) return_node);
|
||||
break;
|
||||
}
|
||||
if (expression)
|
||||
{
|
||||
GskSlNodeExpression *node_expression;
|
||||
|
||||
node_expression = gsk_sl_node_new (GskSlNodeExpression, &GSK_SL_NODE_EXPRESSION);
|
||||
node_expression->expression = expression;
|
||||
node = (GskSlNode *) node_expression;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function->return_type != NULL)
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Return statement does not return a value.");
|
||||
gsk_sl_node_unref ((GskSlNode *) return_node);
|
||||
break;
|
||||
}
|
||||
node = NULL;
|
||||
}
|
||||
function->statements = g_slist_append (function->statements, return_node);
|
||||
}
|
||||
break;
|
||||
else
|
||||
{
|
||||
GskSlPointerType *pointer_type;
|
||||
|
||||
pointer_type = gsk_sl_pointer_type_new (type, flags | GSK_SL_POINTER_TYPE_LOCAL);
|
||||
node = gsk_sl_node_parse_declaration (scope, preproc, pointer_type);
|
||||
gsk_sl_pointer_type_unref (pointer_type);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
GskSlExpression * expression = gsk_sl_expression_parse (function->scope, stream);
|
||||
gsk_sl_type_unref (type);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
gsk_sl_node_unref (node);
|
||||
node = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (expression)
|
||||
{
|
||||
GskSlNodeExpression *node;
|
||||
|
||||
node = gsk_sl_node_new (GskSlNodeExpression, &GSK_SL_NODE_EXPRESSION);
|
||||
node->expression = expression;
|
||||
case GSK_SL_TOKEN_RETURN:
|
||||
{
|
||||
GskSlNodeReturn *return_node;
|
||||
GskSlType *return_type;
|
||||
|
||||
function->statements = g_slist_append (function->statements, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FALSE;
|
||||
return_node = gsk_sl_node_new (GskSlNodeReturn, &GSK_SL_NODE_RETURN);
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) return_node);
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
return_node->value = gsk_sl_expression_parse (scope, preproc);
|
||||
|
||||
if (return_node->value == NULL)
|
||||
{
|
||||
gsk_sl_node_unref ((GskSlNode *) return_node);
|
||||
node = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return_type = gsk_sl_scope_get_return_type (scope);
|
||||
node = (GskSlNode *) return_node;
|
||||
|
||||
if (return_type == NULL)
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Cannot return from here.");
|
||||
gsk_sl_node_unref (node);
|
||||
node = NULL;
|
||||
}
|
||||
else if (return_node->value == NULL)
|
||||
{
|
||||
if (!gsk_sl_type_equal (return_type, gsk_sl_type_get_scalar (GSK_SL_VOID)))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Functions expectes a return value of type %s", gsk_sl_type_get_name (return_type));
|
||||
gsk_sl_node_unref (node);
|
||||
node = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gsk_sl_type_equal (return_type, gsk_sl_type_get_scalar (GSK_SL_VOID)))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Cannot return a value from a void function.");
|
||||
gsk_sl_node_unref (node);
|
||||
node = NULL;
|
||||
}
|
||||
else if (!gsk_sl_type_can_convert (return_type, gsk_sl_expression_get_return_type (return_node->value)))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc,
|
||||
"Cannot convert type %s to return type %s.",
|
||||
gsk_sl_type_get_name (gsk_sl_expression_get_return_type (return_node->value)),
|
||||
gsk_sl_type_get_name (return_type));
|
||||
gsk_sl_node_unref (node);
|
||||
node = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
GskSlExpression * expression = gsk_sl_expression_parse (scope, preproc);
|
||||
|
||||
if (expression)
|
||||
{
|
||||
GskSlNodeExpression *node_expression;
|
||||
|
||||
node_expression = gsk_sl_node_new (GskSlNodeExpression, &GSK_SL_NODE_EXPRESSION);
|
||||
node_expression->expression = expression;
|
||||
|
||||
node = (GskSlNode *) node_expression;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
if (result)
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
return (GskSlNode *) function;
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
gsk_sl_preprocessor_error (preproc, "No semicolon at end of statement.");
|
||||
gsk_sl_node_unref (node);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
GskSlNode *
|
||||
|
||||
@@ -41,7 +41,7 @@ struct _GskSlNodeClass {
|
||||
GskSpvWriter *writer);
|
||||
};
|
||||
|
||||
GskSlNode * gsk_sl_node_parse_function_definition (GskSlScope *scope,
|
||||
GskSlNode * gsk_sl_node_parse_statement (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc);
|
||||
|
||||
GskSlNode * gsk_sl_node_ref (GskSlNode *node);
|
||||
|
||||
@@ -20,10 +20,12 @@
|
||||
|
||||
#include "gskslprogramprivate.h"
|
||||
|
||||
#include "gskslfunctionprivate.h"
|
||||
#include "gskslnodeprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslscopeprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
struct _GskSlProgram {
|
||||
@@ -59,7 +61,48 @@ gsk_sl_program_class_init (GskSlProgramClass *klass)
|
||||
static void
|
||||
gsk_sl_program_init (GskSlProgram *program)
|
||||
{
|
||||
program->scope = gsk_sl_scope_new (NULL);
|
||||
program->scope = gsk_sl_scope_new (NULL, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_program_parse_declaration (GskSlProgram *program,
|
||||
GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlType *type;
|
||||
GskSlFunction *function;
|
||||
const GskSlToken *token;
|
||||
char *name;
|
||||
|
||||
type = gsk_sl_type_new_parse (preproc);
|
||||
if (type == NULL)
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, program);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Expected a function name");
|
||||
gsk_sl_type_unref (type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
name = g_strdup (token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, program);
|
||||
|
||||
function = gsk_sl_function_new_parse (scope,
|
||||
preproc,
|
||||
type,
|
||||
name);
|
||||
if (function)
|
||||
program->functions = g_slist_append (program->functions, function);
|
||||
|
||||
gsk_sl_type_unref (type);
|
||||
g_free (name);
|
||||
|
||||
return function != NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -67,26 +110,16 @@ gsk_sl_program_parse (GskSlProgram *program,
|
||||
GskSlPreprocessor *preproc)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
gboolean result = TRUE;
|
||||
gboolean success = TRUE;
|
||||
|
||||
for (token = gsk_sl_preprocessor_get (preproc);
|
||||
!gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
|
||||
token = gsk_sl_preprocessor_get (preproc))
|
||||
{
|
||||
GskSlNode *node = gsk_sl_node_parse_function_definition (program->scope, preproc);
|
||||
|
||||
if (node)
|
||||
{
|
||||
program->functions = g_slist_append (program->functions, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlNode *) program);
|
||||
result = FALSE;
|
||||
}
|
||||
success &= gsk_sl_program_parse_declaration (program, program->scope, preproc);
|
||||
}
|
||||
|
||||
return result;
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -105,7 +138,7 @@ gsk_sl_program_print (GskSlProgram *program,
|
||||
{
|
||||
if (l != program->functions || program->declarations != NULL)
|
||||
g_string_append (string, "\n");
|
||||
gsk_sl_node_print (l->data, string);
|
||||
gsk_sl_function_print (l->data, string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "gskslscopeprivate.h"
|
||||
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslvariableprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -30,12 +31,14 @@ struct _GskSlScope
|
||||
|
||||
GskSlScope *parent;
|
||||
GSList *children;
|
||||
GskSlType *return_type;
|
||||
|
||||
GHashTable *variables;
|
||||
};
|
||||
|
||||
GskSlScope *
|
||||
gsk_sl_scope_new (GskSlScope *parent)
|
||||
gsk_sl_scope_new (GskSlScope *parent,
|
||||
GskSlType *return_type)
|
||||
{
|
||||
GskSlScope *scope;
|
||||
|
||||
@@ -47,6 +50,8 @@ gsk_sl_scope_new (GskSlScope *parent)
|
||||
scope->parent = parent;
|
||||
parent->children = g_slist_prepend (parent->children, scope);
|
||||
}
|
||||
if (return_type)
|
||||
scope->return_type = gsk_sl_type_ref (return_type);
|
||||
scope->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gsk_sl_variable_unref);
|
||||
|
||||
return scope;
|
||||
@@ -81,10 +86,18 @@ gsk_sl_scope_unref (GskSlScope *scope)
|
||||
for (l = scope->children; l; l = l->next)
|
||||
((GskSlScope *) l->data)->parent = NULL;
|
||||
g_slist_free (scope->children);
|
||||
if (scope->return_type)
|
||||
gsk_sl_type_unref (scope->return_type);
|
||||
|
||||
g_slice_free (GskSlScope, scope);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_scope_get_return_type (const GskSlScope *scope)
|
||||
{
|
||||
return scope->return_type;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_scope_add_variable (GskSlScope *scope,
|
||||
GskSlVariable *variable)
|
||||
|
||||
@@ -25,11 +25,14 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlScope * gsk_sl_scope_new (GskSlScope *parent);
|
||||
GskSlScope * gsk_sl_scope_new (GskSlScope *parent,
|
||||
GskSlType *return_type);
|
||||
|
||||
GskSlScope * gsk_sl_scope_ref (GskSlScope *scope);
|
||||
void gsk_sl_scope_unref (GskSlScope *scope);
|
||||
|
||||
GskSlType * gsk_sl_scope_get_return_type (const GskSlScope *scope);
|
||||
|
||||
void gsk_sl_scope_add_variable (GskSlScope *scope,
|
||||
GskSlVariable *variable);
|
||||
GskSlVariable * gsk_sl_scope_lookup_variable (GskSlScope *scope,
|
||||
|
||||
Reference in New Issue
Block a user