fixes #150; next steps for proper unsigned support

This commit is contained in:
Araq
2012-07-03 00:59:36 +02:00
parent 2e2650c708
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 source = skipTypes(n.sons[1].typ, abstractVarRange)
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):
# XXX int64 -> float conversion?
result = transformSons(c, n)

View File

@@ -140,9 +140,10 @@ proc skipTypes(t: PType, kinds: TTypeKinds): PType =
result = t
while result.kind in kinds: result = lastSon(result)
proc isOrdinalType(t: PType): bool =
proc isOrdinalType(t: PType): bool =
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
isOrdinalType(t.sons[0])
@@ -532,10 +533,10 @@ proc lastOrd(t: PType): biggestInt =
of tyUInt:
if platform.intSize == 4: result = 0xFFFFFFFF
else: result = 0x7FFFFFFFFFFFFFFF'i64
of tyUInt8: result = 0x7F # XXX: Fix these
of tyUInt16: result = 0x7FFF
of tyUInt32: result = 0x7FFFFFFF
of tyUInt64: result = 0x7FFFFFFFFFFFFFFF'i64
of tyUInt8: result = 0xFF
of tyUInt16: result = 0xFFFF
of tyUInt32: result = 0xFFFFFFFF
of tyUInt64: result = -1
of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
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
type ``float``. For notational convenience the apostrophe of a type suffix
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:
@@ -504,7 +504,8 @@ Ordinal types
than the largest value gives a checked runtime or static error.
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
@@ -514,19 +515,35 @@ These integer types are pre-defined:
``int``
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
literal that has no type suffix is of this type.
literal that has no type suffix is of this type.
intXX
additional signed integer types of XX bits use this naming scheme
(example: int16 is a 16 bit wide integer).
The current implementation supports ``int8``, ``int16``, ``int32``, ``int64``.
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:
that treat their arguments as unsigned. Unsigned operations all wrap around;
they cannot lead to over- or underflow errors. Unsigned operations use the
``%`` suffix as convention:
In addition to the usual arithmetic operators for signed and unsigned integers
(``+ - *`` etc.) there are also operators that formally work on *signed*
integers but treat their arguments as *unsigned*: They are mostly provided
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

View File

@@ -846,9 +846,8 @@ object on the heap, so there is a trade-off to be made here.
Integers
--------
Nimrod has these integer types built-in: ``int int8 int16 int32 int64``. These
are all signed integer types, there are no `unsigned integer`:idx: types, only
`unsigned operations`:idx: that treat their arguments as unsigned.
Nimrod has these integer types built-in:
``int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64``.
The default integer type is ``int``. Integer literals can have a *type suffix*
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``
y = 0'i8 # y is of type ``int8``
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
``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.
Unsigned operations all wrap around; they cannot lead to over- or underflow
errors. Unsigned operations use the ``%`` suffix as convention:
====================== ======================================================
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
====================== ======================================================
errors.
`Automatic type conversion`:idx: is performed in expressions where different
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
SHORT* = int16
LONG* = int
LONG* = int32
# UNICODE (Wide Character) types
PWCHAR* = PWideChar
LPWCH* = PWideChar

View File

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

View File

@@ -1,7 +1,10 @@
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:
- test sequence of closures; especially that the GC does not leak for those!