make character_literal stricter support more method return types, support
authorJürg Billeter <j@bitron.ch>
Sun, 3 Sep 2006 06:25:18 +0000 (06:25 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sun, 3 Sep 2006 06:25:18 +0000 (06:25 +0000)
2006-09-03  Jürg Billeter  <j@bitron.ch>

* vala/scanner.l: make character_literal stricter
* vala/valacodegenerator.vala: support more method return types,
  support unicode character literals
* vala/valacharacterliteral.vala: validate input, add get_char method

svn path=/trunk/; revision=123

vala/ChangeLog
vala/vala/scanner.l
vala/vala/valacharacterliteral.vala
vala/vala/valacodegenerator.vala

index aa6f2c0..28177c0 100644 (file)
@@ -1,3 +1,10 @@
+2006-09-03  Jürg Billeter  <j@bitron.ch>
+
+       * vala/scanner.l: make character_literal stricter
+       * vala/valacodegenerator.vala: support more method return types,
+         support unicode character literals
+       * vala/valacharacterliteral.vala: validate input, add get_char method
+
 2006-09-02  Jürg Billeter  <j@bitron.ch>
 
        * vala/parser.y, vala/valacodecontext.vala,
index a6b366c..e6c17ea 100644 (file)
@@ -56,7 +56,7 @@ simple_escape_sequence                \\[\'\"\?\\abfnrtv]
 hexadecimal_escape_sequence    \\x{hex_digit}{hex_digit}?{hex_digit}?{hex_digit}?
 character                      ({single_character}|{simple_escape_sequence})
 string_literal_character       ({single_string_literal_character}|{simple_escape_sequence})
-character_literal              \'{character}*\'
+character_literal              \'{character}+\'
 string_literal                 \"{string_literal_character}*\"
 integer_literal                        ({decimal_integer_literal}|{hexadecimal_integer_literal}|{octal_integer_literal}){integer_suffix}?
 literal                                ({integer_literal}|{real_literal}|{character_literal}|{string_literal})
index ea97323..dc1e779 100644 (file)
@@ -29,7 +29,20 @@ public class Vala.CharacterLiteral : Literal {
        /**
         * The literal value.
         */
-       public string! value { get; set construct; }
+       public string! value {
+               get {
+                       return _value;
+               }
+               set construct {
+                       _value = value;
+                       
+                       if (!value.validate () || (value.len () != 3 && value.next_char ().get_char () != '\\')) {
+                               error = true;
+                       }
+               }
+       }
+       
+       private string! _value;
 
        /**
         * Creates a new character literal.
@@ -41,9 +54,24 @@ public class Vala.CharacterLiteral : Literal {
        public construct (string! c, SourceReference source) {
                value = c;
                source_reference = source;
+
+               if (error) {
+                       Report.error (source_reference, "invalid character literal");
+               }
        }
        
        public override void accept (CodeVisitor! visitor) {
                visitor.visit_character_literal (this);
        }
+       
+       /**
+        * Returns the unicode character value this character literal
+        * represents.
+        *
+        * @return unicode character value
+        */
+       public uint get_char () {
+               // FIXME: unichar return type
+               return (uint) value.next_char ().get_char ();
+       }
 }
index 365ce2e..4598e52 100644 (file)
@@ -63,10 +63,16 @@ public class Vala.CodeGenerator : CodeVisitor {
        private int next_temp_var_id = 0;
 
        TypeReference bool_type;
+       TypeReference char_type;
+       TypeReference unichar_type;
+       TypeReference short_type;
+       TypeReference ushort_type;
        TypeReference int_type;
        TypeReference uint_type;
        TypeReference long_type;
        TypeReference ulong_type;
+       TypeReference int64_type;
+       TypeReference uint64_type;
        TypeReference string_type;
        TypeReference float_type;
        TypeReference double_type;
@@ -92,6 +98,18 @@ public class Vala.CodeGenerator : CodeVisitor {
                bool_type = new TypeReference ();
                bool_type.data_type = (DataType) root_symbol.lookup ("bool").node;
 
+               char_type = new TypeReference ();
+               char_type.data_type = (DataType) root_symbol.lookup ("char").node;
+
+               unichar_type = new TypeReference ();
+               unichar_type.data_type = (DataType) root_symbol.lookup ("unichar").node;
+
+               short_type = new TypeReference ();
+               short_type.data_type = (DataType) root_symbol.lookup ("short").node;
+               
+               ushort_type = new TypeReference ();
+               ushort_type.data_type = (DataType) root_symbol.lookup ("ushort").node;
+
                int_type = new TypeReference ();
                int_type.data_type = (DataType) root_symbol.lookup ("int").node;
                
@@ -104,6 +122,12 @@ public class Vala.CodeGenerator : CodeVisitor {
                ulong_type = new TypeReference ();
                ulong_type.data_type = (DataType) root_symbol.lookup ("ulong").node;
 
+               int64_type = new TypeReference ();
+               int64_type.data_type = (DataType) root_symbol.lookup ("int64").node;
+               
+               uint64_type = new TypeReference ();
+               uint64_type.data_type = (DataType) root_symbol.lookup ("uint64").node;
+               
                float_type = new TypeReference ();
                float_type.data_type = (DataType) root_symbol.lookup ("float").node;
 
@@ -943,9 +967,21 @@ public class Vala.CodeGenerator : CodeVisitor {
                        
                        if (ret_type.is_reference_type ()) {
                                ccheck.add_argument (new CCodeConstant ("NULL"));
-                       } else if (ret_type.name == "bool") {
+                       } else if (ret_type == bool_type.data_type) {
                                ccheck.add_argument (new CCodeConstant ("FALSE"));
-                       } else if (ret_type.name == "int" || ret_type.name == "long" || ret_type.name == "double" || ret_type.name == "float" || ret_type.name == "uint" || ret_type.name == "ulong" || ret_type is Enum || ret_type is Flags) {
+                       } else if (ret_type == char_type.data_type ||
+                                  ret_type == unichar_type.data_type ||
+                                  ret_type == short_type.data_type ||
+                                  ret_type == ushort_type.data_type ||
+                                  ret_type == int_type.data_type ||
+                                  ret_type == uint_type.data_type ||
+                                  ret_type == long_type.data_type ||
+                                  ret_type == ulong_type.data_type ||
+                                  ret_type == int64_type.data_type ||
+                                  ret_type == uint64_type.data_type ||
+                                  ret_type == double_type.data_type ||
+                                  ret_type == float_type.data_type ||
+                                  ret_type is Enum || ret_type is Flags) {
                                ccheck.add_argument (new CCodeConstant ("0"));
                        } else {
                                Report.error (method_node.source_reference, "not supported return type for runtime type checks");
@@ -1910,7 +1946,11 @@ public class Vala.CodeGenerator : CodeVisitor {
        }
 
        public override void visit_character_literal (CharacterLiteral! expr) {
-               expr.ccodenode = new CCodeConstant (expr.value);
+               if (expr.get_char () >= 0x20 && expr.get_char () < 0x80) {
+                       expr.ccodenode = new CCodeConstant (expr.value);
+               } else {
+                       expr.ccodenode = new CCodeConstant ("%uU".printf (expr.get_char ()));
+               }
        }
 
        public override void visit_integer_literal (IntegerLiteral! expr) {