Merge: Byte data type
authorJean Privat <jean@pryen.org>
Sat, 30 May 2015 00:37:01 +0000 (20:37 -0400)
committerJean Privat <jean@pryen.org>
Sat, 30 May 2015 00:37:01 +0000 (20:37 -0400)
As discussed in #1267, we need a Byte data type to manipulate low-level data as numerics instead of how it is done for now using chars.

This PR will serve as base for future updates, notably related to #1370 which will introduce a way to express Bytes in their literal form.

Pull-Request: #1403
Reviewed-by: Romain Chanoir <chanoir.romain@courrier.uqam.ca>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Jean Privat <jean@pryen.org>

18 files changed:
lib/standard/kernel.nit
lib/standard/string.nit
lib/standard/string_nit.c
lib/standard/string_nit.h
src/compiler/abstract_compiler.nit
src/compiler/separate_compiler.nit
src/ffi/java.nit
src/interpreter/naive_interpreter.nit
src/model/model.nit
src/nitni/nitni_base.nit
src/rapid_type_analysis.nit
tests/sav/nitg-e/fixme/base_gen_reassign_alt4.res
tests/sav/nitg-e/fixme/base_gen_reassign_alt5.res
tests/sav/nitg-e/fixme/base_gen_reassign_alt6.res
tests/sav/nituml_args3.res
tests/sav/nituml_args4.res
tests/sav/test_byte.res [new file with mode: 0644]
tests/test_byte.nit [new file with mode: 0644]

index ffd684a..c596bb3 100644 (file)
@@ -275,6 +275,12 @@ interface Numeric
        #     assert 5.to_f         != 5 # Float and Int are not equals
        fun to_f: Float is abstract
 
+       # The byte equivalent of `self`
+       #
+       #     assert (-1).to_b == 0xFF.to_b
+       #     assert (1.9).to_b == 1.to_b
+       fun to_b: Byte is abstract
+
        # Is this the value of zero in its domain?
        fun is_zero: Bool do return self == zero
 
@@ -344,6 +350,7 @@ universal Float
 
        redef fun to_i is intern
        redef fun to_f do return self
+       redef fun to_b is intern
 
        redef fun zero do return 0.0
        redef fun value_of(val) do return val.to_f
@@ -402,6 +409,110 @@ universal Float
        end
 end
 
+# Native bytes.
+# Same as a C `unsigned char`
+universal Byte
+       super Discrete
+       super Numeric
+
+       redef type OTHER: Byte
+
+       redef fun successor(i) do return self + i.to_b
+       redef fun predecessor(i) do return self - i.to_b
+
+       redef fun object_id is intern
+       redef fun hash do return self.to_i
+       redef fun ==(i) is intern
+       redef fun !=(i) is intern
+       redef fun output is intern
+
+       redef fun <=(i) is intern
+       redef fun <(i) is intern
+       redef fun >=(i) is intern
+       redef fun >(i) is intern
+       redef fun +(i) is intern
+
+       # On an Byte, unary minus will return `(256 - self) % 256`
+       #
+       #     assert -(1.to_b) == 0xFF.to_b
+       #     assert -(0.to_b) == 0x00.to_b
+       redef fun - is intern
+       redef fun -(i) is intern
+       redef fun *(i) is intern
+       redef fun /(i) is intern
+
+       # Modulo of `self` with `i`.
+       #
+       # Finds the remainder of division of `self` by `i`.
+       #
+       #     assert 5.to_b % 2.to_b            == 1.to_b
+       #     assert 10.to_b % 2.to_b           == 0.to_b
+       fun %(i: Byte): Byte is intern
+
+       redef fun zero do return 0.to_b
+       redef fun value_of(val) do return val.to_b
+
+       # `i` bits shift fo the left (aka <<)
+       #
+       #     assert 5.to_b.lshift(1)    == 10.to_b
+       fun lshift(i: Int): Byte is intern
+
+       # alias of `lshift`
+       fun <<(i: Int): Byte do return lshift(i)
+
+       # `i` bits shift fo the right (aka >>)
+       #
+       #     assert 5.to_b.rshift(1)    == 2.to_b
+       fun rshift(i: Int): Byte is intern
+
+       # alias of `rshift`
+       fun >>(i: Int): Byte do return rshift(i)
+
+       redef fun to_i is intern
+       redef fun to_f is intern
+       redef fun to_b do return self
+
+       redef fun distance(i) do return (self - i).to_i
+
+       redef fun <=>(other)
+       do
+               if self < other then
+                       return -1
+               else if other < self then
+                       return 1
+               else
+                       return 0
+               end
+       end
+
+       redef fun is_between(c, d)
+       do
+               if self < c or d < self then
+                       return false
+               else
+                       return true
+               end
+       end
+
+       redef fun max(other)
+       do
+               if self < other then
+                       return other
+               else
+                       return self
+               end
+       end
+
+       redef fun min(c)
+       do
+               if c < self then
+                       return c
+               else
+                       return self
+               end
+       end
+end
+
 # Native integer numbers.
 # Correspond to C int.
 universal Int
@@ -459,6 +570,7 @@ universal Int
 
        redef fun to_i do return self
        redef fun to_f is intern
+       redef fun to_b is intern
 
        redef fun distance(i)
        do
index ff46e46..b02ff9b 100644 (file)
@@ -2035,6 +2035,26 @@ redef class Bool
        end
 end
 
+redef class Byte
+       # C function to calculate the length of the `NativeString` to receive `self`
+       private fun byte_to_s_len: Int is extern "native_byte_length_str"
+
+       # C function to convert an nit Int to a NativeString (char*)
+       private fun native_byte_to_s(nstr: NativeString, strlen: Int) is extern "native_byte_to_s"
+
+       # Displayable byte in its hexadecimal form (0x..)
+       #
+       #     assert 1.to_b.to_s       == "0x01"
+       #     assert (-123).to_b.to_s  == "0x85"
+       redef fun to_s do
+               var nslen = byte_to_s_len
+               var ns = new NativeString(nslen + 1)
+               ns[nslen] = '\0'
+               native_byte_to_s(ns, nslen + 1)
+               return ns.to_s_with_length(nslen)
+       end
+end
+
 redef class Int
 
        # Wrapper of strerror C function
index 686d6be..050ab95 100644 (file)
@@ -20,3 +20,13 @@ long native_int_length_str(long recv){
 void native_int_to_s(long recv, char* str, long buflen){
        snprintf(str, buflen, "%ld", recv);
 }
+
+// Returns the length of `recv` as a `char*` (excluding the null character)
+long native_byte_length_str(unsigned char recv){
+       return snprintf(NULL, 0, "0x%02x", recv);
+}
+
+// Byte to NativeString method
+void native_byte_to_s(unsigned char recv, char* str, long buflen){
+       snprintf(str, buflen, "0x%02x", recv);
+}
index f33580f..c1c7818 100644 (file)
@@ -15,5 +15,7 @@
 
 long native_int_length_str(long recv);
 void native_int_to_s(long recv, char* str, long buflen);
+long native_byte_length_str(unsigned char recv);
+void native_byte_to_s(unsigned char recv, char* str, long buflen);
 
 #endif
index 8d3f7db..259c597 100644 (file)
@@ -1455,6 +1455,14 @@ abstract class AbstractCompilerVisitor
                return res
        end
 
+       # Generate a byte value
+       fun byte_instance(value: Byte): RuntimeVariable
+       do
+               var t = mmodule.byte_type
+               var res = new RuntimeVariable("((unsigned char){value.to_s})", t, t)
+               return res
+       end
+
        # Generate a char value
        fun char_instance(value: Char): RuntimeVariable
        do
@@ -1838,6 +1846,8 @@ redef class MClassType
                        return "char"
                else if mclass.name == "Float" then
                        return "double"
+               else if mclass.name == "Byte" then
+                       return "unsigned char"
                else if mclass.name == "NativeString" then
                        return "char*"
                else if mclass.name == "NativeArray" then
@@ -1868,6 +1878,8 @@ redef class MClassType
                        return "c"
                else if mclass.name == "Float" then
                        return "d"
+               else if mclass.name == "Byte" then
+                       return "b"
                else if mclass.name == "NativeString" then
                        return "str"
                else if mclass.name == "NativeArray" then
@@ -2098,6 +2110,9 @@ redef class AMethPropdef
                        else if pname == "to_f" then
                                v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
                                return true
+                       else if pname == "to_b" then
+                               v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+                               return true
                        else if pname == "ascii" then
                                v.ret(v.new_expr("{arguments[0]}", ret.as(not null)))
                                return true
@@ -2141,6 +2156,69 @@ redef class AMethPropdef
                                v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
                                return true
                        end
+               else if cname == "Byte" then
+                       if pname == "output" then
+                               v.add("printf(\"%x\\n\", {arguments.first});")
+                               return true
+                       else if pname == "object_id" then
+                               v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
+                               return true
+                       else if pname == "+" then
+                               v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "-" then
+                               v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "unary -" then
+                               v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+                               return true
+                       else if pname == "unary +" then
+                               v.ret(arguments[0])
+                               return true
+                       else if pname == "*" then
+                               v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "/" then
+                               v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "%" then
+                               v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "lshift" then
+                               v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "rshift" then
+                               v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "==" then
+                               v.ret(v.equal_test(arguments[0], arguments[1]))
+                               return true
+                       else if pname == "!=" then
+                               var res = v.equal_test(arguments[0], arguments[1])
+                               v.ret(v.new_expr("!{res}", ret.as(not null)))
+                               return true
+                       else if pname == "<" then
+                               v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == ">" then
+                               v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "<=" then
+                               v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == ">=" then
+                               v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+                               return true
+                       else if pname == "to_i" then
+                               v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+                               return true
+                       else if pname == "to_f" then
+                               v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+                               return true
+                       else if pname == "ascii" then
+                               v.ret(v.new_expr("{arguments[0]}", ret.as(not null)))
+                               return true
+                       end
                else if cname == "Bool" then
                        if pname == "output" then
                                v.add("printf({arguments.first}?\"true\\n\":\"false\\n\");")
@@ -2209,6 +2287,9 @@ redef class AMethPropdef
                        else if pname == "to_i" then
                                v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
                                return true
+                       else if pname == "to_b" then
+                               v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+                               return true
                        end
                else if cname == "NativeString" then
                        if pname == "[]" then
index 7231bbb..31a4f20 100644 (file)
@@ -252,7 +252,7 @@ class SeparateCompiler
        do
                # Collect all bas box class
                # FIXME: this is not completely fine with a separate compilation scheme
-               for classname in ["Int", "Bool", "Char", "Float", "NativeString", "Pointer"] do
+               for classname in ["Int", "Bool", "Byte", "Char", "Float", "NativeString", "Pointer"] do
                        var classes = self.mainmodule.model.get_mclasses_by_name(classname)
                        if classes == null then continue
                        assert classes.length == 1 else print classes.join(", ")
index 41c9c26..3f2a21e 100644 (file)
@@ -483,6 +483,7 @@ redef class MClassType
                if mclass.name == "Char" then return "char"
                if mclass.name == "Int" then return "long"
                if mclass.name == "Float" then return "double"
+               if mclass.name == "Byte" then return "byte"
                return super
        end
 
@@ -494,6 +495,7 @@ redef class MClassType
                if mclass.name == "Char" then return "jchar"
                if mclass.name == "Int" then return "jlong"
                if mclass.name == "Float" then return "jdouble"
+               if mclass.name == "Byte" then return "jbyte"
                return super
        end
 
@@ -553,6 +555,7 @@ redef class MClassType
                if mclass.name == "Char" then return "C"
                if mclass.name == "Int" then return "J"
                if mclass.name == "Float" then return "D"
+               if mclass.name == "Byte" then return "B"
                return super
        end
 
@@ -565,6 +568,7 @@ redef class MClassType
                if mclass.name == "Char" then return "Char"
                if mclass.name == "Int" then return "Long"
                if mclass.name == "Float" then return "Double"
+               if mclass.name == "Byte" then return "Byte"
                return super
        end
 end
index 9708f3f..3626d33 100644 (file)
@@ -207,6 +207,15 @@ class NaiveInterpreter
                return instance
        end
 
+       # Return the byte instance associated with `val`.
+       fun byte_instance(val: Byte): Instance
+       do
+               var t = mainmodule.byte_type
+               var instance = new PrimitiveInstance[Byte](t, val)
+               init_instance_primitive(instance)
+               return instance
+       end
+
        # Return the char instance associated with `val`.
        fun char_instance(val: Char): Instance
        do
@@ -632,6 +641,10 @@ abstract class Instance
        # else aborts
        fun to_f: Float do abort
 
+       # Return the integer value if the instance is a byte.
+       # else aborts
+       fun to_b: Byte do abort
+
        # The real value encapsulated if the instance is primitive.
        # Else aborts.
        fun val: nullable Object do abort
@@ -677,6 +690,8 @@ class PrimitiveInstance[E]
        redef fun to_i do return val.as(Int)
 
        redef fun to_f do return val.as(Float)
+
+       redef fun to_b do return val.as(Byte)
 end
 
 # Information about local variables in a running method
@@ -867,6 +882,8 @@ redef class AMethPropdef
                                return v.char_instance(args[0].to_i.ascii)
                        else if pname == "to_f" then
                                return v.float_instance(args[0].to_i.to_f)
+                       else if pname == "to_b" then
+                               return v.byte_instance(args[0].to_i.to_b)
                        else if pname == "lshift" then
                                return v.int_instance(args[0].to_i.lshift(args[1].to_i))
                        else if pname == "rshift" then
@@ -894,6 +911,50 @@ redef class AMethPropdef
                        else if pname == "strerror_ext" then
                                return v.native_string_instance(recvval.strerror)
                        end
+               else if cname == "Byte" then
+                       var recvval = args[0].to_b
+                       if pname == "unary -" then
+                               return v.byte_instance(-args[0].to_b)
+                       else if pname == "unary +" then
+                               return args[0]
+                       else if pname == "+" then
+                               return v.byte_instance(args[0].to_b + args[1].to_b)
+                       else if pname == "-" then
+                               return v.byte_instance(args[0].to_b - args[1].to_b)
+                       else if pname == "*" then
+                               return v.byte_instance(args[0].to_b * args[1].to_b)
+                       else if pname == "%" then
+                               return v.byte_instance(args[0].to_b % args[1].to_b)
+                       else if pname == "/" then
+                               return v.byte_instance(args[0].to_b / args[1].to_b)
+                       else if pname == "<" then
+                               return v.bool_instance(args[0].to_b < args[1].to_b)
+                       else if pname == ">" then
+                               return v.bool_instance(args[0].to_b > args[1].to_b)
+                       else if pname == "<=" then
+                               return v.bool_instance(args[0].to_b <= args[1].to_b)
+                       else if pname == ">=" then
+                               return v.bool_instance(args[0].to_b >= args[1].to_b)
+                       else if pname == "<=>" then
+                               return v.int_instance(args[0].to_b <=> args[1].to_b)
+                       else if pname == "to_f" then
+                               return v.float_instance(args[0].to_b.to_f)
+                       else if pname == "to_i" then
+                               return v.int_instance(args[0].to_b.to_i)
+                       else if pname == "lshift" then
+                               return v.byte_instance(args[0].to_b.lshift(args[1].to_i))
+                       else if pname == "rshift" then
+                               return v.byte_instance(args[0].to_b.rshift(args[1].to_i))
+                       else if pname == "byte_to_s_len" then
+                               return v.int_instance(recvval.to_s.length)
+                       else if pname == "native_byte_to_s" then
+                               var s = recvval.to_s
+                               var srecv = args[1].val.as(Buffer)
+                               srecv.clear
+                               srecv.append(s)
+                               srecv.add('\0')
+                               return null
+                       end
                else if cname == "Char" then
                        var recv = args[0].val.as(Char)
                        if pname == "ascii" then
@@ -937,6 +998,8 @@ redef class AMethPropdef
                                return v.bool_instance(recv >= args[1].to_f)
                        else if pname == "to_i" then
                                return v.int_instance(recv.to_i)
+                       else if pname == "to_b" then
+                               return v.byte_instance(recv.to_b)
                        else if pname == "cos" then
                                return v.float_instance(args[0].to_f.cos)
                        else if pname == "sin" then
index 94f11f2..908cb60 100644 (file)
@@ -206,6 +206,9 @@ redef class MModule
        # The primitive type `Int`
        var int_type: MClassType = self.get_primitive_class("Int").mclass_type is lazy
 
+       # The primitive type `Byte`
+       var byte_type: MClassType = self.get_primitive_class("Byte").mclass_type is lazy
+
        # The primitive type `Char`
        var char_type: MClassType = self.get_primitive_class("Char").mclass_type is lazy
 
index a1f49a7..7cf6bbc 100644 (file)
@@ -92,6 +92,7 @@ redef class MClassType
                if name == "Char" then return "char"
                if name == "Float" then return "double"
                if name == "Int" then return "long"
+               if name == "Byte" then return "unsigned char"
                if name == "NativeString" then return "char*"
                if mclass.kind == extern_kind then
                        var ctype = mclass.ctype
@@ -107,6 +108,7 @@ redef class MClassType
                if name == "Char" then return "char"
                if name == "Float" then return "double"
                if name == "Int" then return "long"
+               if name == "Byte" then return "unsigned char"
                if name == "NativeString" then return "char*"
                if mclass.kind == extern_kind then return "void*"
                return "struct nitni_instance *"
index 8e5565c..bcd9f8e 100644 (file)
@@ -213,6 +213,7 @@ class RapidTypeAnalysis
                force_alive("Float")
                force_alive("Char")
                force_alive("Pointer")
+               force_alive("Byte")
 
                while not todo.is_empty do
                        var mmethoddef = todo.shift
index f1d9e06..d65304c 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:426)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:537)
 11
 21
 31
index f1d9e06..d65304c 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:426)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:537)
 11
 21
 31
index f1d9e06..d65304c 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:426)
+Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/standard/kernel.nit:537)
 11
 21
 31
index fd2ef3c..1e16616 100644 (file)
@@ -36,7 +36,7 @@ Cloneable [
 Object -> Cloneable [dir=back arrowtail=open style=dashed];
 
 Numeric [
- label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
+ label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ to_b(): Byte\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
 ]
 Comparable -> Numeric [dir=back arrowtail=open style=dashed];
 
@@ -50,6 +50,12 @@ Float [
 ]
 Numeric -> Float [dir=back arrowtail=open style=dashed];
 
+Byte [
+ label = "{Byte||+ %(i: Byte): Byte\l+ lshift(i: Int): Byte\l+ \<\<(i: Int): Byte\l+ rshift(i: Int): Byte\l+ \>\>(i: Int): Byte\l}"
+]
+Discrete -> Byte [dir=back arrowtail=open style=dashed];
+Numeric -> Byte [dir=back arrowtail=open style=dashed];
+
 Int [
  label = "{Int||+ %(i: Int): Int\l+ lshift(i: Int): Int\l+ \<\<(i: Int): Int\l+ rshift(i: Int): Int\l+ \>\>(i: Int): Int\l+ ascii(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
 ]
index 43e3f9e..74c96da 100644 (file)
@@ -36,7 +36,7 @@ Cloneable [
 Object -> Cloneable [dir=back arrowtail=open style=dashed];
 
 Numeric [
- label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
+ label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ to_b(): Byte\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
 ]
 Comparable -> Numeric [dir=back arrowtail=open style=dashed];
 
@@ -50,6 +50,12 @@ Float [
 ]
 Numeric -> Float [dir=back arrowtail=open style=dashed];
 
+Byte [
+ label = "{Byte||+ %(i: Byte): Byte\l+ lshift(i: Int): Byte\l+ \<\<(i: Int): Byte\l+ rshift(i: Int): Byte\l+ \>\>(i: Int): Byte\l}"
+]
+Discrete -> Byte [dir=back arrowtail=open style=dashed];
+Numeric -> Byte [dir=back arrowtail=open style=dashed];
+
 Int [
  label = "{Int||+ %(i: Int): Int\l+ lshift(i: Int): Int\l+ \<\<(i: Int): Int\l+ rshift(i: Int): Int\l+ \>\>(i: Int): Int\l+ ascii(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
 ]
diff --git a/tests/sav/test_byte.res b/tests/sav/test_byte.res
new file mode 100644 (file)
index 0000000..256f8b1
--- /dev/null
@@ -0,0 +1,5 @@
+0xff
+0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+0xff
+0x01
+0x85
diff --git a/tests/test_byte.nit b/tests/test_byte.nit
new file mode 100644 (file)
index 0000000..97e9bde
--- /dev/null
@@ -0,0 +1,28 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+var b = 0xFF.to_b
+
+print b
+
+var a = new Array[Byte]
+
+for i in [0 .. 0xFF] do a.push i.to_b
+
+print a.join(", ")
+
+print ((-1).to_b)
+
+print 1.to_b
+print((-123).to_b)