[gtk+/wip/otte/shader: 45/56] gsksl: Add an error enum



commit 19b511bbc53851be41085bca0e6303ea937b6bb0
Author: Benjamin Otte <otte redhat com>
Date:   Wed Sep 27 17:11:01 2017 +0200

    gsksl: Add an error enum
    
    And specify the correct error value whenever an error is emitted.

 gsk/gskslcompiler.c            |    3 +
 gsk/gskslcompiler.h            |   23 +++++++
 gsk/gskslexpression.c          |  132 +++++++++++++++++++++++-----------------
 gsk/gskslfunction.c            |    8 +-
 gsk/gskslnode.c                |   19 +++---
 gsk/gskslpointertype.c         |   34 +++++-----
 gsk/gskslpreprocessor.c        |   21 +++---
 gsk/gskslpreprocessorprivate.h |   31 +++++++--
 gsk/gskslprogram.c             |   13 ++--
 gsk/gsksltokenizer.c           |    6 +-
 gsk/gsksltype.c                |    2 +-
 11 files changed, 178 insertions(+), 114 deletions(-)
---
diff --git a/gsk/gskslcompiler.c b/gsk/gskslcompiler.c
index 757867c..bec37d5 100644
--- a/gsk/gskslcompiler.c
+++ b/gsk/gskslcompiler.c
@@ -31,6 +31,9 @@ struct _GskSlCompiler {
   GHashTable *defines;
 };
 
+G_DEFINE_QUARK (gsk-sl-compiler-error-quark, gsk_sl_compiler_error)
+G_DEFINE_QUARK (gsk-sl-compiler-warning-quark, gsk_sl_compiler_warning)
+
 G_DEFINE_TYPE (GskSlCompiler, gsk_sl_compiler, G_TYPE_OBJECT)
 
 static void
diff --git a/gsk/gskslcompiler.h b/gsk/gskslcompiler.h
index 94c2763..4a23007 100644
--- a/gsk/gskslcompiler.h
+++ b/gsk/gskslcompiler.h
@@ -27,11 +27,34 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+  GSK_SL_COMPILER_ERROR_CONSTANT,
+  GSK_SL_COMPILER_ERROR_DECLARATION,
+  GSK_SL_COMPILER_ERROR_PREPROCESSOR,
+  GSK_SL_COMPILER_ERROR_SCOPE,
+  GSK_SL_COMPILER_ERROR_SYNTAX,
+  GSK_SL_COMPILER_ERROR_TOKENIZER,
+  GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
+  GSK_SL_COMPILER_ERROR_UNSUPPORTED,
+} GskSlCompilerError;
+
+typedef enum {
+  GSK_SL_COMPILER_WARNING_SHADOW
+} GskSlCompilerWarning;
+
+#define GSK_SL_COMPILER_ERROR (gsk_sl_compiler_error_quark ())
+#define GSK_SL_COMPILER_WARNING (gsk_sl_compiler_warning_quark ())
+
 #define GSK_TYPE_SL_COMPILER (gsk_sl_compiler_get_type ())
 
 G_DECLARE_FINAL_TYPE (GskSlCompiler, gsk_sl_compiler, GSK, SL_COMPILER, GObject)
 
 GDK_AVAILABLE_IN_3_92
+GQuark                  gsk_sl_compiler_error_quark             (void);
+GDK_AVAILABLE_IN_3_92
+GQuark                  gsk_sl_compiler_warning_quark           (void);
+
+GDK_AVAILABLE_IN_3_92
 GskSlCompiler *         gsk_sl_compiler_new                     (void);
 
 GDK_AVAILABLE_IN_3_92
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 2e9f765..4a6be24 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -269,8 +269,9 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
     {
       if (stream)
         {
-          gsk_sl_preprocessor_error (stream, "Operand types %s and %s do not share compatible scalar types.",
-                                             gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "Operand types %s and %s do not share compatible scalar types.",
+                                     gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
         }
       return NULL;
     }
@@ -284,7 +285,8 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
               if (gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (gsk_sl_type_get_index_type 
(rtype)))
                 {
                   if (stream)
-                    gsk_sl_preprocessor_error (stream, "Matrices to multiplication have incompatible 
dimensions.");
+                    gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                               "Matrices to multiplication have incompatible dimensions.");
                   return NULL;
                 }
               return gsk_sl_type_get_matrix (scalar,
@@ -304,7 +306,8 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
               else
                 {
                   if (stream)
-                    gsk_sl_preprocessor_error (stream, "Matrix types %s and %s have different size.",
+                    gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                               "Matrix types %s and %s have different size.",
                                                gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
                   return NULL;
                 }
@@ -317,7 +320,8 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
               if (gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (rtype))
                 {
                   if (stream)
-                    gsk_sl_preprocessor_error (stream, "Matrix column count doesn't match vector length.");
+                    gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                               "Matrix column count doesn't match vector length.");
                   return NULL;
                 }
               return gsk_sl_type_get_vector (scalar, gsk_sl_type_get_length (gsk_sl_type_get_index_type 
(ltype)));
@@ -325,7 +329,8 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
           else
             {
               if (stream)
-                gsk_sl_preprocessor_error (stream, "Cannot perform arithmetic operation between matrix and 
vector.");
+                gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                           "Cannot perform arithmetic operation between matrix and vector.");
               return NULL;
             }
         }
@@ -338,7 +343,8 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
       else
         {
           if (stream)
-            gsk_sl_preprocessor_error (stream, "Right operand is incompatible type for arithemtic 
operation.");
+            gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                       "Right operand is incompatible type for arithemtic operation.");
           return NULL;
         }
     }
@@ -351,8 +357,9 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
               if (gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (gsk_sl_type_get_index_type 
(rtype)))
                 {
                   if (stream)
-                    gsk_sl_preprocessor_error (stream, "Vector length for %s doesn't match row count for %s",
-                                                       gsk_sl_type_get_name (ltype), gsk_sl_type_get_name 
(rtype));
+                    gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                               "Vector length for %s doesn't match row count for %s",
+                                               gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
                   return NULL;
                 }
               return gsk_sl_type_get_vector (scalar, gsk_sl_type_get_length (rtype));
@@ -360,7 +367,7 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
           else
             {
               if (stream)
-                gsk_sl_preprocessor_error (stream, "Cannot perform arithmetic operation between vector and 
matrix.");
+                gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Cannot perform arithmetic operation 
between vector and matrix.");
               return NULL;
             }
         }
@@ -369,8 +376,9 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
           if (gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (rtype))
             {
               if (stream)
-                gsk_sl_preprocessor_error (stream, "Vector operands %s and %s to arithmetic operation have 
different length.",
-                                                   gsk_sl_type_get_name (ltype), gsk_sl_type_get_name 
(rtype));
+                gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                           "Vector operands %s and %s to arithmetic operation have different 
length.",
+                                           gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
               return NULL;
             }
           return gsk_sl_type_get_vector (scalar, gsk_sl_type_get_length (ltype));
@@ -383,7 +391,8 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
       else
         {
           if (stream)
-            gsk_sl_preprocessor_error (stream, "Right operand is incompatible type for arithemtic 
operation.");
+            gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                       "Right operand is incompatible type for arithemtic operation.");
           return NULL;
         }
     }
@@ -407,14 +416,14 @@ gsk_sl_expression_arithmetic_type_check (GskSlPreprocessor *stream,
       else
         {
           if (stream)
-            gsk_sl_preprocessor_error (stream, "Right operand is incompatible type for arithemtic 
operation.");
+            gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand is incompatible type for 
arithemtic operation.");
           return NULL;
         }
     }
   else
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Left operand is incompatible type for arithemtic operation.");
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Left operand is incompatible type for arithemtic 
operation.");
       return NULL;
     }
 }
@@ -430,34 +439,35 @@ gsk_sl_expression_bitwise_type_check (GskSlPreprocessor *stream,
   if (lscalar != GSK_SL_INT && lscalar != GSK_SL_UINT)
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Left operand %s is not an integer type.", gsk_sl_type_get_name 
(ltype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Left operand %s is not an integer type.", 
gsk_sl_type_get_name (ltype));
       return NULL;
     }
   rscalar = gsk_sl_type_get_scalar_type (ltype);
   if (rscalar != GSK_SL_INT && rscalar != GSK_SL_UINT)
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Right operand %s is not an integer type.", gsk_sl_type_get_name 
(rtype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand %s is not an integer type.", 
gsk_sl_type_get_name (rtype));
       return NULL;
     }
   if (!gsk_sl_type_is_scalar (ltype) && !gsk_sl_type_is_vector (ltype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Left operand %s is neither a scalar nor a vector.", 
gsk_sl_type_get_name (ltype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Left operand %s is neither a scalar nor a 
vector.", gsk_sl_type_get_name (ltype));
       return NULL;
     }
   if (!gsk_sl_type_is_scalar (rtype) && !gsk_sl_type_is_vector (rtype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Right operand %s is neither a scalar nor a vector.", 
gsk_sl_type_get_name (rtype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand %s is neither a scalar nor a 
vector.", gsk_sl_type_get_name (rtype));
       return NULL;
     }
   if (gsk_sl_type_is_vector (ltype) && gsk_sl_type_is_vector (rtype) &&
       gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (rtype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Vector operands %s and %s do not have the same length.",
-                                           gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                   "Vector operands %s and %s do not have the same length.",
+                                   gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
       return NULL;
     }
 
@@ -479,39 +489,39 @@ gsk_sl_expression_shift_type_check (GskSlPreprocessor *stream,
   if (lscalar != GSK_SL_INT && lscalar != GSK_SL_UINT)
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Left operand %s is not an integer type.", gsk_sl_type_get_name 
(ltype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Left operand %s is not an integer type.", 
gsk_sl_type_get_name (ltype));
       return FALSE;
     }
   rscalar = gsk_sl_type_get_scalar_type (ltype);
   if (rscalar != GSK_SL_INT && rscalar != GSK_SL_UINT)
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Right operand %s is not an integer type.", gsk_sl_type_get_name 
(rtype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand %s is not an integer type.", 
gsk_sl_type_get_name (rtype));
       return FALSE;
     }
   if (!gsk_sl_type_is_scalar (ltype) && !gsk_sl_type_is_vector (ltype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Left operand %s is neither a scalar nor a vector.", 
gsk_sl_type_get_name (ltype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Left operand %s is neither a scalar nor a 
vector.", gsk_sl_type_get_name (ltype));
       return FALSE;
     }
   if (!gsk_sl_type_is_scalar (rtype) && !gsk_sl_type_is_vector (rtype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Right operand %s is neither a scalar nor a vector.", 
gsk_sl_type_get_name (rtype));
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand %s is neither a scalar nor a 
vector.", gsk_sl_type_get_name (rtype));
       return FALSE;
     }
   if (gsk_sl_type_is_scalar (ltype) && gsk_sl_type_is_vector (rtype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Right operand to shift cannot be a vector if left operand is a 
scalar.");
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand to shift cannot be a vector if left 
operand is a scalar.");
       return FALSE;
     }
   if (gsk_sl_type_is_vector (ltype) && gsk_sl_type_is_vector (rtype) &&
       gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (rtype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Vector operands do not have the same length.");
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Vector operands do not have the same length.");
       return FALSE;
     }
 
@@ -526,25 +536,25 @@ gsk_sl_expression_relational_type_check (GskSlPreprocessor *stream,
   if (!gsk_sl_type_is_scalar (ltype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Left operand to relational operator is not a scalar.");
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Left operand to relational operator is not a 
scalar.");
       return NULL;
     }
   if (gsk_sl_type_get_scalar_type (ltype) == GSK_SL_BOOL)
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Left operand to relational operator must not be bool.");
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Left operand to relational operator must not be 
bool.");
       return NULL;
     }
   if (!gsk_sl_type_is_scalar (rtype))
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Right operand to relational operator is not a scalar.");
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand to relational operator is not a 
scalar.");
       return NULL;
     }
   if (gsk_sl_type_get_scalar_type (rtype) == GSK_SL_BOOL)
     {
       if (stream)
-        gsk_sl_preprocessor_error (stream, "Right operand to relational operator must not be bool.");
+        gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Right operand to relational operator must not be 
bool.");
       return NULL;
     }
 
@@ -1035,7 +1045,7 @@ gsk_sl_expression_parse_constructor_call (GskSlScope        *scope,
   token = gsk_sl_preprocessor_get (stream);
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
     {
-      gsk_sl_preprocessor_error (stream, "Expected opening \"(\" when calling constructor");
+      gsk_sl_preprocessor_error (stream, SYNTAX, "Expected opening \"(\" when calling constructor");
       gsk_sl_expression_unref ((GskSlExpression *) call);
       return NULL;
     }
@@ -1071,14 +1081,14 @@ gsk_sl_expression_parse_constructor_call (GskSlScope        *scope,
     types[i] = gsk_sl_expression_get_return_type (call->arguments[i]);
   if (!gsk_sl_function_matches (call->function, types, call->n_arguments, &error))
     {
-      gsk_sl_preprocessor_error (stream, "%s", error->message);
+      gsk_sl_preprocessor_emit_error (stream, TRUE, gsk_sl_preprocessor_get_location (stream), error);
       g_clear_error (&error);
       fail = TRUE;
     }
 
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
     {
-      gsk_sl_preprocessor_error (stream, "Expected closing \")\" after arguments.");
+      gsk_sl_preprocessor_error (stream, SYNTAX, "Expected closing \")\" after arguments.");
       gsk_sl_expression_unref ((GskSlExpression *) call);
       return NULL;
     }
@@ -1111,7 +1121,7 @@ gsk_sl_expression_parse_primary (GskSlScope        *scope,
         variable = gsk_sl_scope_lookup_variable (scope, token->str);
         if (variable == NULL)
           {
-            gsk_sl_preprocessor_error (stream, "No variable named \"%s\".", token->str);
+            gsk_sl_preprocessor_error (stream, DECLARATION, "No variable named \"%s\".", token->str);
             gsk_sl_preprocessor_consume (stream, NULL);
             return NULL;
           }
@@ -1213,7 +1223,7 @@ gsk_sl_expression_parse_primary (GskSlScope        *scope,
       }
 
     default:
-      gsk_sl_preprocessor_error (stream, "Expected an expression.");
+      gsk_sl_preprocessor_error (stream, SYNTAX, "Expected an expression.");
       gsk_sl_preprocessor_consume (stream, NULL);
       return NULL;
   }
@@ -1230,7 +1240,7 @@ gsk_sl_expression_parse_field_selection (GskSlScope        *scope,
 
   if (g_str_equal (name, "length"))
     {
-       gsk_sl_preprocessor_error (stream, ".length() is not implemented yet.");
+       gsk_sl_preprocessor_error (stream, UNSUPPORTED, ".length() is not implemented yet.");
        *success = FALSE;
        return expr;
     }
@@ -1252,7 +1262,7 @@ gsk_sl_expression_parse_field_selection (GskSlScope        *scope,
         }
       if (swizzle->name == G_N_ELEMENTS(swizzle_options))
         {
-          gsk_sl_preprocessor_error (stream, "Type %s has no member named \"%s\".", gsk_sl_type_get_name 
(type), name);
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Type %s has no member named \"%s\".", 
gsk_sl_type_get_name (type), name);
           gsk_sl_expression_unref ((GskSlExpression *) swizzle);
           *success = FALSE;
           return expr;
@@ -1264,23 +1274,25 @@ gsk_sl_expression_parse_field_selection (GskSlScope        *scope,
           const char *found = strchr (swizzle_options[swizzle->name], name[swizzle->length]);
           if (found == NULL)
             {
-              gsk_sl_preprocessor_error (stream, "Character '%c' is not valid for swizzle. Must be one of 
\"%s\".",
-                                                 name[swizzle->length], swizzle_options[swizzle->name]);
+              gsk_sl_preprocessor_error (stream, SYNTAX,
+                                         "Character '%c' is not valid for swizzle. Must be one of \"%s\".",
+                                         name[swizzle->length], swizzle_options[swizzle->name]);
               *success = FALSE;
               return (GskSlExpression *) swizzle;
             }
           swizzle->indexes[swizzle->length] = found - swizzle_options[swizzle->name];
           if (swizzle->indexes[swizzle->length] >= type_length)
             {
-              gsk_sl_preprocessor_error (stream, "Swizzle index '%c' not allowed for type %s",
-                                                 name[swizzle->length], gsk_sl_type_get_name (type));
+              gsk_sl_preprocessor_error (stream, SYNTAX,
+                                         "Swizzle index '%c' not allowed for type %s",
+                                         name[swizzle->length], gsk_sl_type_get_name (type));
               *success = FALSE;
               return (GskSlExpression *) swizzle;
             }
         }
       if (name[swizzle->length])
         {
-          gsk_sl_preprocessor_error (stream, "Too many swizzle options. A maximum of 4 characters are 
allowed.");
+          gsk_sl_preprocessor_error (stream, SYNTAX, "Too many swizzle options. A maximum of 4 characters 
are allowed.");
           *success = FALSE;
           return (GskSlExpression *) swizzle;
         }
@@ -1289,7 +1301,7 @@ gsk_sl_expression_parse_field_selection (GskSlScope        *scope,
     }
   else
     {
-      gsk_sl_preprocessor_error (stream, "Cannot select fields of type %s.", gsk_sl_type_get_name (type));
+      gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Type %s has no fields to select.", 
gsk_sl_type_get_name (type));
       *success = FALSE;
       return expr;
     }
@@ -1321,7 +1333,7 @@ gsk_sl_expression_parse_postfix (GskSlScope        *scope,
             }
           else
             {
-              gsk_sl_preprocessor_error (stream, "Expected an identifier to select a field.");
+              gsk_sl_preprocessor_error (stream, SYNTAX, "Expected an identifier to select a field.");
               success = FALSE;
               continue;
             }
@@ -1762,16 +1774,18 @@ gsk_sl_expression_parse_logical_and (GskSlScope        *scope,
       else if (!gsk_sl_type_can_convert (gsk_sl_type_get_scalar (GSK_SL_BOOL),
                                          gsk_sl_expression_get_return_type (operation->right)))
         {
-          gsk_sl_preprocessor_error (stream, "Right operand of && expression is not bool but %s",
-                                             gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(operation->right)));
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "Right operand of && expression is not bool but %s",
+                                     gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(operation->right)));
           gsk_sl_expression_ref (expression);
           gsk_sl_expression_unref ((GskSlExpression *) operation);
         }
       else if (!gsk_sl_type_can_convert (gsk_sl_type_get_scalar (GSK_SL_BOOL),
                                          gsk_sl_expression_get_return_type (expression)))
         {
-          gsk_sl_preprocessor_error (stream, "Left operand of && expression is not bool but %s",
-                                             gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(expression)));
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "Left operand of && expression is not bool but %s",
+                                     gsk_sl_type_get_name (gsk_sl_expression_get_return_type (expression)));
           expression = operation->right;
           gsk_sl_expression_ref (expression);
           gsk_sl_expression_unref ((GskSlExpression *) operation);
@@ -1816,16 +1830,18 @@ gsk_sl_expression_parse_logical_xor (GskSlScope        *scope,
       else if (!gsk_sl_type_can_convert (gsk_sl_type_get_scalar (GSK_SL_BOOL),
                                          gsk_sl_expression_get_return_type (operation->right)))
         {
-          gsk_sl_preprocessor_error (stream, "Right operand of ^^ expression is not bool but %s",
-                                             gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(operation->right)));
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "Right operand of ^^ expression is not bool but %s",
+                                     gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(operation->right)));
           gsk_sl_expression_ref (expression);
           gsk_sl_expression_unref ((GskSlExpression *) operation);
         }
       else if (!gsk_sl_type_can_convert (gsk_sl_type_get_scalar (GSK_SL_BOOL),
                                          gsk_sl_expression_get_return_type (expression)))
         {
-          gsk_sl_preprocessor_error (stream, "Left operand of ^^ expression is not bool but %s",
-                                             gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(expression)));
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "Left operand of ^^ expression is not bool but %s",
+                                     gsk_sl_type_get_name (gsk_sl_expression_get_return_type (expression)));
           expression = operation->right;
           gsk_sl_expression_ref (expression);
           gsk_sl_expression_unref ((GskSlExpression *) operation);
@@ -1870,16 +1886,18 @@ gsk_sl_expression_parse_logical_or (GskSlScope        *scope,
       else if (!gsk_sl_type_can_convert (gsk_sl_type_get_scalar (GSK_SL_BOOL),
                                          gsk_sl_expression_get_return_type (operation->right)))
         {
-          gsk_sl_preprocessor_error (stream, "Right operand of || expression is not bool but %s",
-                                             gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(operation->right)));
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "Right operand of || expression is not bool but %s",
+                                     gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(operation->right)));
           gsk_sl_expression_ref (expression);
           gsk_sl_expression_unref ((GskSlExpression *) operation);
         }
       else if (!gsk_sl_type_can_convert (gsk_sl_type_get_scalar (GSK_SL_BOOL),
                                          gsk_sl_expression_get_return_type (expression)))
         {
-          gsk_sl_preprocessor_error (stream, "Left operand of || expression is not bool but %s",
-                                             gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(expression)));
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "Left operand of || expression is not bool but %s",
+                                     gsk_sl_type_get_name (gsk_sl_expression_get_return_type (expression)));
           expression = operation->right;
           gsk_sl_expression_ref (expression);
           gsk_sl_expression_unref ((GskSlExpression *) operation);
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 16b0e60..8c1b58a 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -323,7 +323,7 @@ gsk_sl_function_new_parse (GskSlScope        *scope,
   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_preprocessor_error (preproc, SYNTAX, "Expected an openening \"(\"");
       gsk_sl_function_unref ((GskSlFunction *) function);
       return NULL;
     }
@@ -332,7 +332,7 @@ gsk_sl_function_new_parse (GskSlScope        *scope,
   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_preprocessor_error (preproc, SYNTAX, "Expected a closing \")\"");
       gsk_sl_function_unref ((GskSlFunction *) function);
       return NULL;
     }
@@ -347,7 +347,7 @@ gsk_sl_function_new_parse (GskSlScope        *scope,
 
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE))
     {
-      gsk_sl_preprocessor_error (preproc, "Expected an opening \"{\"");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected an opening \"{\"");
       gsk_sl_function_unref ((GskSlFunction *) function);
       return NULL;
     }
@@ -370,7 +370,7 @@ gsk_sl_function_new_parse (GskSlScope        *scope,
 
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE))
     {
-      gsk_sl_preprocessor_error (preproc, "Missing closing \"}\" at end.");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "Missing closing \"}\" at end.");
       gsk_sl_function_unref ((GskSlFunction *) function);
       return NULL;
     }
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index 2cc1e1a..7b3f961 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -275,9 +275,10 @@ gsk_sl_node_parse_declaration (GskSlScope        *scope,
           declaration->initial = gsk_sl_expression_parse_assignment (scope, stream);
           if (!gsk_sl_type_can_convert (type, gsk_sl_expression_get_return_type (declaration->initial)))
             {
-              gsk_sl_preprocessor_error (stream, "Cannot convert from initializer type %s to variable type 
%s",
-                                                 gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(declaration->initial)),
-                                                 gsk_sl_type_get_name (type));
+              gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                         "Cannot convert from initializer type %s to variable type %s",
+                                         gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(declaration->initial)),
+                                         gsk_sl_type_get_name (type));
               gsk_sl_node_unref ((GskSlNode *) declaration);
               return NULL;
             }
@@ -320,7 +321,7 @@ gsk_sl_node_parse_statement (GskSlScope        *scope,
       break;
 
     case GSK_SL_TOKEN_EOF:
-      gsk_sl_preprocessor_error (preproc, "Unexpected end of document");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "Unexpected end of document");
       return NULL;
 
     case GSK_SL_TOKEN_CONST:
@@ -450,7 +451,7 @@ gsk_sl_node_parse_statement (GskSlScope        *scope,
 
         if (return_type == NULL)
           {
-            gsk_sl_preprocessor_error (preproc, "Cannot return from here.");
+            gsk_sl_preprocessor_error (preproc, SCOPE, "Cannot return from here.");
             gsk_sl_node_unref (node);
             node = NULL;
           }
@@ -458,7 +459,7 @@ gsk_sl_node_parse_statement (GskSlScope        *scope,
           {
             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_preprocessor_error (preproc, TYPE_MISMATCH,"Functions expectes a return value of type 
%s", gsk_sl_type_get_name (return_type));
                 gsk_sl_node_unref (node);
                 node = NULL;
               }
@@ -467,13 +468,13 @@ gsk_sl_node_parse_statement (GskSlScope        *scope,
           {
             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_preprocessor_error (preproc, TYPE_MISMATCH, "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,
+                gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH,
                                            "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));
@@ -512,7 +513,7 @@ gsk_sl_node_parse_statement (GskSlScope        *scope,
   token = gsk_sl_preprocessor_get (preproc);
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
     {
-      gsk_sl_preprocessor_error (preproc, "No semicolon at end of statement.");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of statement.");
       gsk_sl_node_unref (node);
       return NULL;
     }
diff --git a/gsk/gskslpointertype.c b/gsk/gskslpointertype.c
index 0b2fbbd..0fb6964 100644
--- a/gsk/gskslpointertype.c
+++ b/gsk/gskslpointertype.c
@@ -72,7 +72,7 @@ gsk_sl_decoration_list_add_simple (GskSlPreprocessor *preproc,
 {
   if (list->values[decoration].set)
     {
-      gsk_sl_preprocessor_error (preproc, "Duplicate qualifier.");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate qualifier.");
       return FALSE;
     }
 
@@ -96,7 +96,7 @@ gsk_sl_decoration_list_parse_assignment (GskSlPreprocessor *preproc,
   token = gsk_sl_preprocessor_get (preproc);
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
     {
-      gsk_sl_preprocessor_error (preproc, "Expected \"=\" sign to assign a value.");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected \"=\" sign to assign a value.");
       return FALSE;
     }
   gsk_sl_preprocessor_consume (preproc, NULL);
@@ -110,7 +110,7 @@ gsk_sl_decoration_list_parse_assignment (GskSlPreprocessor *preproc,
 
   if (value == NULL)
     {
-      gsk_sl_preprocessor_error (preproc, "Expression is not constant.");
+      gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression is not constant.");
       return FALSE;
     }
 
@@ -125,7 +125,7 @@ gsk_sl_decoration_list_parse_assignment (GskSlPreprocessor *preproc,
     }
   else
     {
-      gsk_sl_preprocessor_error (preproc, "Type of expression is not an integer type, but %s", 
gsk_sl_type_get_name (type));
+      gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Type of expression is not an integer type, but 
%s", gsk_sl_type_get_name (type));
       success = FALSE;
     }
   gsk_sl_value_free (value);
@@ -149,7 +149,7 @@ gsk_sl_decoration_list_parse_layout (GskSlPreprocessor *preproc,
 
       if (gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
         {
-          gsk_sl_preprocessor_error (preproc, "Expected layout identifier.");
+          gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
           success = FALSE;
           break;
         }
@@ -185,14 +185,14 @@ gsk_sl_decoration_list_parse_layout (GskSlPreprocessor *preproc,
             }
           else
             {
-              gsk_sl_preprocessor_error (preproc, "Unknown layout identifier.");
+              gsk_sl_preprocessor_error (preproc, UNSUPPORTED, "Unknown layout identifier.");
               gsk_sl_preprocessor_consume (preproc, NULL);
               success = FALSE;
             }
         }
       else
         {
-          gsk_sl_preprocessor_error (preproc, "Expected layout identifier.");
+          gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
           gsk_sl_preprocessor_consume (preproc, NULL);
           success = FALSE;
           continue;
@@ -231,7 +231,7 @@ gsk_sl_decoration_list_parse (GskSlScope        *scope,
         case GSK_SL_TOKEN_IN:
           if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
             {
-              gsk_sl_preprocessor_error (preproc, "\"in\" qualifier specified twice.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"in\" qualifier specified twice.");
               success = FALSE;
             }
           else
@@ -246,7 +246,7 @@ gsk_sl_decoration_list_parse (GskSlScope        *scope,
         case GSK_SL_TOKEN_OUT:
           if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
             {
-              gsk_sl_preprocessor_error (preproc, "\"out\" qualifier specified twice.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"out\" qualifier specified twice.");
               success = FALSE;
             }
           else
@@ -261,12 +261,12 @@ gsk_sl_decoration_list_parse (GskSlScope        *scope,
         case GSK_SL_TOKEN_INOUT:
           if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
             {
-              gsk_sl_preprocessor_error (preproc, "\"in\" qualifier already used.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"in\" qualifier already used.");
               success = FALSE;
             }
           else if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
             {
-              gsk_sl_preprocessor_error (preproc, "\"out\" qualifier already used.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"out\" qualifier already used.");
               success = FALSE;
             }
           else
@@ -302,12 +302,12 @@ gsk_sl_decoration_list_parse (GskSlScope        *scope,
         case GSK_SL_TOKEN_READONLY:
           if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
             {
-              gsk_sl_preprocessor_error (preproc, "\"readonly\" qualifier specified twice.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"readonly\" qualifier specified twice.");
               success = FALSE;
             }
           else if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
             {
-              gsk_sl_preprocessor_error (preproc, "\"writeonly\" qualifier already used.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"writeonly\" qualifier already used.");
               success = FALSE;
             }
           else
@@ -322,12 +322,12 @@ gsk_sl_decoration_list_parse (GskSlScope        *scope,
         case GSK_SL_TOKEN_WRITEONLY:
           if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
             {
-              gsk_sl_preprocessor_error (preproc, "\"readonly\" qualifier already used.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"readonly\" qualifier already used.");
               success = FALSE;
             }
           else if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
             {
-              gsk_sl_preprocessor_error (preproc, "\"writeonly\" qualifier specified twice.");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "\"writeonly\" qualifier specified twice.");
               success = FALSE;
             }
           else
@@ -344,7 +344,7 @@ gsk_sl_decoration_list_parse (GskSlScope        *scope,
           token = gsk_sl_preprocessor_get (preproc);
           if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
             {
-              gsk_sl_preprocessor_error (preproc, "Expected opening \"(\" after layout specifier");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected opening \"(\" after layout specifier");
               success = FALSE;
               break;
             }
@@ -355,7 +355,7 @@ gsk_sl_decoration_list_parse (GskSlScope        *scope,
           token = gsk_sl_preprocessor_get (preproc);
           if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
             {
-              gsk_sl_preprocessor_error (preproc, "Expected opening \"(\" after layout specifier");
+              gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected opening \"(\" after layout specifier");
               success = FALSE;
             }
           gsk_sl_preprocessor_consume (preproc, NULL);
diff --git a/gsk/gskslpreprocessor.c b/gsk/gskslpreprocessor.c
index b697124..b9d34c4 100644
--- a/gsk/gskslpreprocessor.c
+++ b/gsk/gskslpreprocessor.c
@@ -192,13 +192,13 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
           gsk_sl_preprocessor_clear_token (&pp);
           if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
             {
-              gsk_sl_preprocessor_error_full (preproc, &pp.location, "No variable after #define.");
+              gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No variable after 
#define.");
               gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
               return;
             }
           if (!gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
             {
-              gsk_sl_preprocessor_error_full (preproc, &pp.location, "Expected identifier after #define.");
+              gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Expected identifier 
after #define.");
               gsk_sl_preprocessor_clear_token (&pp);
             }
           else
@@ -206,7 +206,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
               GskSlDefine *define;
 
               if (g_hash_table_lookup (preproc->defines, pp.token.str))
-                gsk_sl_preprocessor_error_full (preproc, &pp.location, "\"%s\" redefined.", pp.token.str);
+                gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "\"%s\" redefined.", 
pp.token.str);
               
               define = gsk_sl_define_new (pp.token.str, NULL);
               gsk_sl_preprocessor_clear_token (&pp);
@@ -258,13 +258,13 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
           gsk_sl_preprocessor_clear_token (&pp);
           if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
             {
-              gsk_sl_preprocessor_error_full (preproc, &pp.location, "No variable after #undef.");
+              gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No variable after 
#undef.");
               gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
               return;
             }
           if (!gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
             {
-              gsk_sl_preprocessor_error_full (preproc, &pp.location, "Expected identifier after #undef.");
+              gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Expected identifier 
after #undef.");
               gsk_sl_preprocessor_clear_token (&pp);
             }
           else
@@ -273,7 +273,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
               
               if (!gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
                 {
-                  gsk_sl_preprocessor_error_full (preproc, &pp.location, "Expected newline after #undef.");
+                  gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Expected newline 
after #undef.");
                   gsk_sl_preprocessor_clear_token (&pp);
                 }
               else
@@ -290,13 +290,13 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
 #endif
       else
         {
-          gsk_sl_preprocessor_error_full (preproc, &pp.location, "Unknown preprocessor directive #%s.", 
pp.token.str);
+          gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Unknown preprocessor 
directive #%s.", pp.token.str);
           gsk_sl_preprocessor_clear_token (&pp);
         }
     }
   else
     {
-      gsk_sl_preprocessor_error_full (preproc, &pp.location, "Missing identifier for preprocessor 
directive.");
+      gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Missing identifier for 
preprocessor directive.");
       gsk_sl_preprocessor_clear_token (&pp);
     }
   
@@ -315,7 +315,7 @@ gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
     {
       if (!was_newline)
         {
-          gsk_sl_preprocessor_error (preproc, "Unexpected \"#\" - preprocessor directives must be at start 
of line.");
+          gsk_sl_preprocessor_error (preproc, SYNTAX, "Unexpected \"#\" - preprocessor directives must be at 
start of line.");
           gsk_sl_preprocessor_clear_token (pp);
         }
       else
@@ -375,8 +375,9 @@ gsk_sl_preprocessor_emit_error (GskSlPreprocessor     *preproc,
                                 const GskCodeLocation *location,
                                 const GError          *error)
 {
-  g_print ("%3zu:%2zu: error: %s\n",
+  g_print ("%3zu:%2zu: %s: %s\n",
            location->lines + 1, location->line_bytes,
+           fatal ? "warn" : "error",
            error->message);
 }
 
diff --git a/gsk/gskslpreprocessorprivate.h b/gsk/gskslpreprocessorprivate.h
index 9ac1265..8fcb429 100644
--- a/gsk/gskslpreprocessorprivate.h
+++ b/gsk/gskslpreprocessorprivate.h
@@ -19,8 +19,7 @@
 #ifndef __GSK_SL_PREPROCESSOR_PRIVATE_H__
 #define __GSK_SL_PREPROCESSOR_PRIVATE_H__
 
-#include <glib.h>
-
+#include "gskslcompilerprivate.h"
 #include "gsksltypesprivate.h"
 #include "gsksltokenizerprivate.h"
 
@@ -42,14 +41,14 @@ void                    gsk_sl_preprocessor_emit_error          (GskSlPreprocess
                                                                  const GskCodeLocation *location,
                                                                  const GError        *error);
 
-#define gsk_sl_preprocessor_error(preproc, ...) \
-  gsk_sl_preprocessor_error_full (preproc, gsk_sl_preprocessor_get_location (preproc), __VA_ARGS__)
+#define gsk_sl_preprocessor_error(preproc, type, ...) \
+  gsk_sl_preprocessor_error_full (preproc, type, gsk_sl_preprocessor_get_location (preproc), __VA_ARGS__)
 
-#define gsk_sl_preprocessor_error_full(preproc, location, ...) G_STMT_START{\
+#define gsk_sl_preprocessor_error_full(preproc, type, location, ...) G_STMT_START{\
   GError *error; \
 \
-  error = g_error_new (G_FILE_ERROR, \
-                       G_FILE_ERROR_FAILED, \
+  error = g_error_new (GSK_SL_COMPILER_ERROR, \
+                       GSK_SL_COMPILER_ERROR_ ## type, \
                        __VA_ARGS__); \
 \
   gsk_sl_preprocessor_emit_error (preproc, \
@@ -60,6 +59,24 @@ void                    gsk_sl_preprocessor_emit_error          (GskSlPreprocess
   g_error_free (error);\
 }G_STMT_END
 
+#define gsk_sl_preprocessor_warn(preproc, type, ...) \
+  gsk_sl_preprocessor_warn_full (preproc, type, gsk_sl_preprocessor_get_location (preproc), __VA_ARGS__)
+
+#define gsk_sl_preprocessor_warn_full(preproc, type, location, ...) G_STMT_START{\
+  GError *error; \
+\
+  error = g_error_new (GSK_SL_COMPILER_WARNING, \
+                       GSK_SL_COMPILER_WARNING_ ## type, \
+                       __VA_ARGS__); \
+\
+  gsk_sl_preprocessor_emit_error (preproc, \
+                                  FALSE, \
+                                  location, \
+                                  error); \
+\
+  g_error_free (error);\
+}G_STMT_END
+
 G_END_DECLS
 
 #endif /* __GSK_SL_PREPROCESSOR_PRIVATE_H__ */
diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c
index 90843dd..6b135ee 100644
--- a/gsk/gskslprogram.c
+++ b/gsk/gskslprogram.c
@@ -95,9 +95,10 @@ gsk_sl_program_parse_variable (GskSlProgram      *program,
 
       if (!gsk_sl_type_can_convert (type, gsk_sl_expression_get_return_type (initial)))
         {
-          gsk_sl_preprocessor_error (preproc, "Cannot convert from initializer type %s to variable type %s",
-                                              gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(initial)),
-                                              gsk_sl_type_get_name (type));
+          gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH,
+                                     "Cannot convert from initializer type %s to variable type %s",
+                                     gsk_sl_type_get_name (gsk_sl_expression_get_return_type (initial)),
+                                     gsk_sl_type_get_name (type));
           gsk_sl_expression_unref (initial);
           return NULL;
         }
@@ -111,7 +112,7 @@ gsk_sl_program_parse_variable (GskSlProgram      *program,
         }
       else 
         {
-          gsk_sl_preprocessor_error (preproc, "Initializer is not constant.");
+          gsk_sl_preprocessor_error (preproc, UNSUPPORTED, "Non-constant initializer are not supported 
yet.");
           return FALSE;
         }
 
@@ -120,7 +121,7 @@ gsk_sl_program_parse_variable (GskSlProgram      *program,
 
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
     {
-      gsk_sl_preprocessor_error (preproc, "No semicolon at end of variable declaration.");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of variable declaration.");
       return FALSE;
     }
   gsk_sl_preprocessor_consume (preproc, NULL);
@@ -173,7 +174,7 @@ gsk_sl_program_parse_declaration (GskSlProgram      *program,
     }
   else if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
     {
-      gsk_sl_preprocessor_error (preproc, "Expected a variable name");
+      gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected a variable name");
       gsk_sl_type_unref (type);
       return FALSE;
     }
diff --git a/gsk/gsksltokenizer.c b/gsk/gsksltokenizer.c
index e5a8c5d..c6f3639 100644
--- a/gsk/gsksltokenizer.c
+++ b/gsk/gsksltokenizer.c
@@ -19,7 +19,7 @@
 
 #include "gsksltokenizerprivate.h"
 
-#include "gskpixelshader.h"
+#include "gskslcompiler.h"
 
 #include <math.h>
 #include <string.h>
@@ -1370,8 +1370,8 @@ set_parse_error (GError     **error,
   g_assert (*error == NULL);
 
   va_start (args, format); 
-  *error = g_error_new_valist (G_FILE_ERROR,
-                               G_FILE_ERROR_FAILED,
+  *error = g_error_new_valist (GSK_SL_COMPILER_ERROR,
+                               GSK_SL_COMPILER_ERROR_TOKENIZER,
                                format,
                                args);
   va_end (args);
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index ba2765d..4126379 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -964,7 +964,7 @@ gsk_sl_type_new_parse (GskSlPreprocessor *stream)
       type = gsk_sl_type_ref (gsk_sl_type_get_matrix (GSK_SL_DOUBLE, 4, 4));
       break;
     default:
-      gsk_sl_preprocessor_error (stream, "Expected type specifier");
+      gsk_sl_preprocessor_error (stream, SYNTAX, "Expected type specifier");
       return NULL;
   }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]