fixes #150; next steps for proper unsigned support

This commit is contained in:
Araq 2012-07-03 00:59:36 +02:00
commit 8ef48a34e5
7 changed files with 44 additions and 34 deletions

View file

@ -390,7 +390,8 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
var dest = skipTypes(n.typ, abstractVarRange) var dest = skipTypes(n.typ, abstractVarRange)
var source = skipTypes(n.sons[1].typ, abstractVarRange) var source = skipTypes(n.sons[1].typ, abstractVarRange)
case dest.kind case dest.kind
of tyInt..tyInt64, tyEnum, tyChar, tyBool, tyUInt..tyUInt64: of tyInt..tyInt64, tyEnum, tyChar, tyBool, tyUInt8..tyUInt32:
# we don't include uint and uint64 here as these are no ordinal types ;-)
if not isOrdinalType(source): if not isOrdinalType(source):
# XXX int64 -> float conversion? # XXX int64 -> float conversion?
result = transformSons(c, n) result = transformSons(c, n)

View file

@ -140,9 +140,10 @@ proc skipTypes(t: PType, kinds: TTypeKinds): PType =
result = t result = t
while result.kind in kinds: result = lastSon(result) while result.kind in kinds: result = lastSon(result)
proc isOrdinalType(t: PType): bool = proc isOrdinalType(t: PType): bool =
assert(t != nil) assert(t != nil)
result = (t.Kind in {tyChar, tyInt..tyInt64, tyUInt..tyUInt64, tyBool, tyEnum}) or # caution: uint, uint64 are no ordinal types!
result = t.Kind in {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum} or
(t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and (t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and
isOrdinalType(t.sons[0]) isOrdinalType(t.sons[0])
@ -532,10 +533,10 @@ proc lastOrd(t: PType): biggestInt =
of tyUInt: of tyUInt:
if platform.intSize == 4: result = 0xFFFFFFFF if platform.intSize == 4: result = 0xFFFFFFFF
else: result = 0x7FFFFFFFFFFFFFFF'i64 else: result = 0x7FFFFFFFFFFFFFFF'i64
of tyUInt8: result = 0x7F # XXX: Fix these of tyUInt8: result = 0xFF
of tyUInt16: result = 0x7FFF of tyUInt16: result = 0xFFFF
of tyUInt32: result = 0x7FFFFFFF of tyUInt32: result = 0xFFFFFFFF
of tyUInt64: result = 0x7FFFFFFFFFFFFFFF'i64 of tyUInt64: result = -1
of tyEnum: of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym) assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
result = t.n.sons[sonsLen(t.n) - 1].sym.position result = t.n.sons[sonsLen(t.n) - 1].sym.position

View file

@ -343,7 +343,7 @@ defined. The suffix starting with an apostrophe ('\'') is called a
unless the literal contains a dot or ``E|e`` in which case it is of unless the literal contains a dot or ``E|e`` in which case it is of
type ``float``. For notational convenience the apostrophe of a type suffix type ``float``. For notational convenience the apostrophe of a type suffix
is optional if it is not ambiguous (only hexadecimal floating point literals is optional if it is not ambiguous (only hexadecimal floating point literals
can be ambiguous). with a type suffix can be ambiguous).
The type suffixes are: The type suffixes are:
@ -504,7 +504,8 @@ Ordinal types
than the largest value gives a checked runtime or static error. than the largest value gives a checked runtime or static error.
Integers, bool, characters and enumeration types (and subranges of these Integers, bool, characters and enumeration types (and subranges of these
types) belong to ordinal types. types) belong to ordinal types. For reasons of simplicity of implementation
the types ``uint`` and ``uint64`` are no ordinal types.
Pre-defined integer types Pre-defined integer types
@ -514,19 +515,35 @@ These integer types are pre-defined:
``int`` ``int``
the generic signed integer type; its size is platform dependent and has the the generic signed integer type; its size is platform dependent and has the
same size as a pointer. This type should be used in general. An integer same size as a pointer. This type should be used in general. An integer
literal that has no type suffix is of this type. literal that has no type suffix is of this type.
intXX intXX
additional signed integer types of XX bits use this naming scheme additional signed integer types of XX bits use this naming scheme
(example: int16 is a 16 bit wide integer). (example: int16 is a 16 bit wide integer).
The current implementation supports ``int8``, ``int16``, ``int32``, ``int64``. The current implementation supports ``int8``, ``int16``, ``int32``, ``int64``.
Literals of these types have the suffix 'iXX. Literals of these types have the suffix 'iXX.
``uint``
the generic `unsigned integer`:idx: type; its size is platform dependent and
has the same size as a pointer. An integer literal with the type
suffix ``'u`` is of this type.
uintXX
additional signed integer types of XX bits use this naming scheme
(example: uint16 is a 16 bit wide unsigned integer).
The current implementation supports ``uint8``, ``uint16``, ``uint32``,
``uint64``. Literals of these types have the suffix 'uXX.
Unsigned operations all wrap around; they cannot lead to over- or
underflow errors.
There are no `unsigned integer`:idx: types, only `unsigned operations`:idx: In addition to the usual arithmetic operators for signed and unsigned integers
that treat their arguments as unsigned. Unsigned operations all wrap around; (``+ - *`` etc.) there are also operators that formally work on *signed*
they cannot lead to over- or underflow errors. Unsigned operations use the integers but treat their arguments as *unsigned*: They are mostly provided
``%`` suffix as convention: for backwards compatibility with older versions of the language that lacked
unsigned integer types. These unsigned operations for signed integers use
the ``%`` suffix as convention:
====================== ====================================================== ====================== ======================================================
operation meaning operation meaning

View file

@ -846,9 +846,8 @@ object on the heap, so there is a trade-off to be made here.
Integers Integers
-------- --------
Nimrod has these integer types built-in: ``int int8 int16 int32 int64``. These Nimrod has these integer types built-in:
are all signed integer types, there are no `unsigned integer`:idx: types, only ``int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64``.
`unsigned operations`:idx: that treat their arguments as unsigned.
The default integer type is ``int``. Integer literals can have a *type suffix* The default integer type is ``int``. Integer literals can have a *type suffix*
to mark them to be of another integer type: to mark them to be of another integer type:
@ -859,6 +858,7 @@ to mark them to be of another integer type:
x = 0 # x is of type ``int`` x = 0 # x is of type ``int``
y = 0'i8 # y is of type ``int8`` y = 0'i8 # y is of type ``int8``
z = 0'i64 # z is of type ``int64`` z = 0'i64 # z is of type ``int64``
u = 0'u # u is of type ``uint``
Most often integers are used for counting objects that reside in memory, so Most often integers are used for counting objects that reside in memory, so
``int`` has the same size as a pointer. ``int`` has the same size as a pointer.
@ -871,19 +871,7 @@ arguments as *unsigned*. For `arithmetic bit shifts`:idx: ordinary
multiplication or division can be used. multiplication or division can be used.
Unsigned operations all wrap around; they cannot lead to over- or underflow Unsigned operations all wrap around; they cannot lead to over- or underflow
errors. Unsigned operations use the ``%`` suffix as convention: errors.
====================== ======================================================
operation meaning
====================== ======================================================
``a +% b`` unsigned integer addition
``a -% b`` unsigned integer subtraction
``a *% b`` unsigned integer multiplication
``a /% b`` unsigned integer division
``a %% b`` unsigned integer modulo operation
``a <% b`` treat ``a`` and ``b`` as unsigned and compare
``a <=% b`` treat ``a`` and ``b`` as unsigned and compare
====================== ======================================================
`Automatic type conversion`:idx: is performed in expressions where different `Automatic type conversion`:idx: is performed in expressions where different
kinds of integer types are used. However, if the type conversion kinds of integer types are used. However, if the type conversion

View file

@ -18,7 +18,7 @@ type
type # WinNT.h -- Defines the 32-Bit Windows types and constants type # WinNT.h -- Defines the 32-Bit Windows types and constants
SHORT* = int16 SHORT* = int16
LONG* = int LONG* = int32
# UNICODE (Wide Character) types # UNICODE (Wide Character) types
PWCHAR* = PWideChar PWCHAR* = PWideChar
LPWCH* = PWideChar LPWCH* = PWideChar

View file

@ -15,7 +15,7 @@ const
type type
THandle* = int THandle* = int
LONG* = int LONG* = int32
WINBOOL* = int32 WINBOOL* = int32
DWORD* = int32 DWORD* = int32
HDC* = THandle HDC* = THandle

View file

@ -1,7 +1,10 @@
version 0.9.0 version 0.9.0
============= =============
- finish support for unsigned ints - finish support for unsigned ints:
- document new type conversion rules
- test codegen
- provide ``$`` for unsigned ints
Debug GC session: Debug GC session:
- test sequence of closures; especially that the GC does not leak for those! - test sequence of closures; especially that the GC does not leak for those!