fixes #150; next steps for proper unsigned support
This commit is contained in:
parent
2e2650c708
commit
8ef48a34e5
7 changed files with 44 additions and 34 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
20
doc/tut1.txt
20
doc/tut1.txt
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
5
todo.txt
5
todo.txt
|
|
@ -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!
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue