# # SYS/CLASS.D - The system core class hierarchy # # This file holds our core class hierarchy and internal function # tie-ins. It is actually fairly straightforward. Remember that # type name visibility is not based on the class hierarchy but instead # based on semantic visibility. We add a bunch of typedefs to make # it easy and main.d imports us "as self" so our top-level ids can # be accessed directly. # # We use type refinement to shortcut operator & cast procedure # refinement. By creating a "T" type and using it to declare # the procedures, we need only refine "T" in subclasses to # automatically refine the support procedures. The internal tie-ins # take it from there. # # Note that && and || are not operators, they are language constructs, # so you will not see them here. # # We have to match int, bool, and generic pointer types to their # internal equivalents. See __internal_void, __internal_int, # __internal_bool, and __internal_ptr. # public internal interface Numeric { # T can be refined in subclasses, automatically causing procedures # using it to be regenerated for each subclass. # public typedef Numeric _t; # we have an internal binding capable of casting core numeric types # to a boolean. # public internal pure cast bool __cast_bool(_t rhs); public internal pure cast Numeric __cast_numeric(_t rhs); public internal pure operator "!" bool __not(_t rhs); public internal pure operator "+" _t __pos(_t rhs); public internal pure operator "-" _t __neg(_t rhs); public internal pure operator "+" _t __add(_t lhs, _t rhs); public internal pure operator "-" _t __sub(_t lhs, _t rhs); public internal pure operator "*" _t __mul(_t lhs, _t rhs); public internal pure operator "/" _t __div(_t lhs, _t rhs); public internal pure operator "==" bool __eqeq(_t lhs, _t rhs); public internal pure operator "!=" bool __noteq(_t lhs, _t rhs); public internal pure operator "<=" bool __lteq(_t lhs, _t rhs); public internal pure operator ">=" bool __gteq(_t lhs, _t rhs); public internal pure operator "<" bool __lt(_t lhs, _t rhs); public internal pure operator ">" bool __gt(_t lhs, _t rhs); public internal operator "+=" lvalue _t __addeq(lvalue _t lhs, _t rhs); public internal operator "-=" lvalue _t __subeq(lvalue _t lhs, _t rhs); public internal operator "*=" lvalue _t __muleq(lvalue _t lhs, _t rhs); public internal operator "/=" lvalue _t __diveq(lvalue _t lhs, _t rhs); public __storage(0) data; } # note that 'void' and other numeric subclasses are not placed in Numeric's # namespace. If you want to be able to do 'Numeric.void' you have to # 'typedef void void;' inside the Numeric class definition above. Note # that this creates a loop in the resolver which it can handle, but it # might slow down the resolution stage of the interpreter/compiler. # public internal subclass void from Numeric { refine typedef void _t; } public internal subclass bool from Numeric { refine typedef bool _t; refine __storage(1) data; } public internal subinterface Integral from Numeric { refine typedef Integral _t; typedef Integral _u; # RHS can be different for shifts public internal pure operator "~" _t __inv(_t rhs); public internal operator "++" lvalue _t __plpl(lvalue _t rhs); public internal operator "--" lvalue _t __mimi(lvalue _t rhs); public internal pure operator "%" _t __mod(_t lhs, _t rhs); public internal pure operator "&" _t __and(_t lhs, _t rhs); public internal pure operator "|" _t __or(_t lhs, _t rhs); public internal pure operator "^" _t __xor(_t lhs, _t rhs); public internal pure operator "<<" _t __lshift(_t lhs, _u rhs); public internal pure operator ">>" _t __rshift(_t lhs, _u rhs); public internal operator "&=" lvalue _t __andeq(lvalue _t lhs, _t rhs); public internal operator "|=" lvalue _t __oreq(lvalue _t lhs, _t rhs); public internal operator "<<=" lvalue _t __lshifteq(lvalue _t lhs, _u rhs); public internal operator ">>=" lvalue _t __rshifteq(lvalue _t lhs, _u rhs); # Atomic ops (future) # #public internal void atomic_add(lvalue _t lhs, _t value); #public internal void atomic_set(lvalue_t lhs, _t value); #public internal void atomic_clear(lvalue_t lhs, _t value); #public internal _t atomic_fetchadd(lvalue_t lhs, _t value); #public internal _t atomic_cmpxchg(lvalue_t lhs, _t match, _t value); } public internal subinterface SInteger from Integral { refine typedef SInteger _t; } public internal subinterface UInteger from Integral { refine typedef UInteger _t; } public internal subclass int8_t from SInteger { refine typedef int8_t _t; refine __storage(1) data; } public internal subclass int16_t from SInteger { refine typedef int16_t _t; refine __storage(2) data; } public internal subclass int32_t from SInteger { refine typedef int32_t _t; refine __storage(4) data; } public internal subclass int64_t from SInteger { refine typedef int64_t _t; refine __storage(8) data; } public internal subclass int128_t from SInteger { refine typedef int128_t _t; refine __storage(16) data; } public internal subclass uint8_t from UInteger { refine typedef uint8_t _t; refine __storage(1) data; } public internal subclass uint16_t from UInteger { refine typedef uint16_t _t; refine __storage(2) data; } public internal subclass uint32_t from UInteger { refine typedef uint32_t _t; refine __storage(4) data; } public internal subclass uint64_t from UInteger { refine typedef uint64_t _t; refine __storage(8) data; } public internal subclass uint128_t from UInteger { refine typedef uint128_t _t; refine __storage(16) data; } public internal subinterface Float from Numeric { refine typedef Float _t; public global const _t epsilon; public internal pure _t pow(_t val, _t exp); public internal pure _t exp(_t val); public internal pure _t exp2(_t val); public internal pure _t expm1(_t val); public internal pure _t log(_t val); public internal pure _t log1p(_t val); public internal pure _t log2(_t val); public internal pure _t log10(_t val); public internal pure int ilogb(_t val); public internal pure (_t, int) frexp(_t val); public internal pure _t sin(_t val); public internal pure _t cos(_t val); public internal pure _t tan(_t val); public internal pure _t asin(_t val); public internal pure _t acos(_t val); public internal pure _t atan(_t val); public internal pure _t atan2(_t y, _t x); public internal pure _t sinh(_t val); public internal pure _t cosh(_t val); } public internal subclass float32_t from Float { refine typedef float32_t _t; refine public global const _t epsilon = 1.19209290E-07F; refine __storage(4) data; } public internal subclass float64_t from Float { refine typedef float64_t _t; refine public global const _t epsilon = 2.2204460492503131E-16D; refine __storage(8) data; } public internal subclass float128_t from Float { refine typedef float128_t _t; refine public global const _t epsilon = 1.0842021724855044340E-19X; refine __storage(16) data; } #float32_t epsilon_32 = 1.19209290E-07F; #float64_t epsilon_64; #float128_t epsilon_128; # Pointers. A pointer is not a class, it is a pointer to a class, but we # still need to define operators on it and that is done right # here. We hack a special meaning for 'internal' operators # which pass and return void * (XXX). All pointers must match the # lhs. public internal interface Pointer { public typedef void @_t; public internal method void new(size_t count = 1); public internal method size_t lockcount(); public internal operator "++" lvalue _t __ptr_plpl(lvalue _t lhs); public internal operator "--" lvalue _t __ptr_mimi(lvalue _t lhs); public internal pure operator "+" _t __ptr_add(_t lhs, Integral rhs); public internal pure operator "-" _t __ptr_sub(_t lhs, Integral rhs); public internal pure operator "-" intptr_t __ptr_ptr_sub(_t lhs, _t rhs); public internal operator "+=" lvalue _t __ptr_pluseq(lvalue _t lhs, Integral rhs); public internal operator "-=" lvalue _t __ptr_minuseq(lvalue _t lhs, Integral rhs); # Pointers can be cast to integers, but not the other way. # public internal pure cast Integral __cast_ptr(_t rhs); # internal2 allows either side to be a void * (e.g. NULL) # public internal internal2 operator "==" bool __ptr_eqeq(_t lhs, _t rhs); public internal internal2 operator "!=" bool __ptr_noteq(_t lhs, _t rhs); public internal internal2 operator "<" bool __ptr_lt(_t lhs, _t rhs); public internal internal2 operator "<=" bool __ptr_lteq(_t lhs, _t rhs); public internal internal2 operator ">" bool __ptr_gt(_t lhs, _t rhs); public internal internal2 operator ">=" bool __ptr_gteq(_t lhs, _t rhs); } # These definitions are hardwired into the symbol table and allowed to # deviate from normal naming restrictions for types. They exist to # make code more readable. However, UNLIKE C, Rune hardwires these names # to specific definitions. In Rune, an 'int' is *always* a signed 32 bit # field. In Rune, a 'char' is *always* an unsigned 32 bit value (which is # different from C). Note that we do not try to mimic all of C, so things # like 'short' are simply not legal Rune (use int16_t instead). # public typedef uint8_t char; public typedef int32_t int; public typedef int64_t long; public typedef uint32_t uint; public typedef uint64_t ulong; public typedef float32_t float; public typedef float64_t double; public typedef float128_t ldouble; # These are special 'locked' internal tie-ins and cannot be changed. # In particular, intptr_t and off_t are always 64 bit signed quantities. # Rune will optimize pointer operations that are cast to int or passed as # int, and most people will not ever need to use the intptr_t type. # # Rune explicitly implements size_t as signed and provides usize_t if an # unsigned size_t-width integer is desired. Rune also explicitly does NOT # implement ssize_t. That is, we want programmers to use 'size_t' and to # know that it is signed, and not create confusion mixing size_t and ssize_t. # # XXX allow 32 or 64 bit selection # public internal typedef int64_t intptr_t; public internal typedef uint64_t uintptr_t; public internal typedef int64_t off_t; public internal typedef intptr_t size_t; # size_t is signed in rune public typedef uintptr_t usize_t; # These types are designed for nominal portability between systems, and # are also for the most part signed in order to allow for in-band values # and deltas. # public typedef int pid_t; public typedef long time_t; public typedef long uid_t; public typedef long gid_t; public typedef long ino_t; public typedef uint16_t mode_t; public typedef uint32_t dev_t; # Boolean constants # public const bool TRUE = (1 == 1); public const bool FALSE = (1 == 2); /* for very large values of 1 */ # These are special internal tie-ins # #public internal typedef void __internal_void; #public internal typedef bool __internal_bool; #public internal typedef int8_t __internal_int8; #public internal typedef uint8_t __internal_uint8; #public internal typedef int16_t __internal_int16; #public internal typedef uint16_t __internal_uint16; #public internal typedef int32_t __internal_int32; #public internal typedef uint32_t __internal_uint32; #public internal typedef int64_t __internal_int64; #public internal typedef uint64_t __internal_uint64; # #public internal typedef float32_t __internal_float32; #public internal typedef float64_t __internal_float64; #public internal typedef float128_t __internal_float128; # #public internal typedef Pointer __internal_pointer; #public internal typedef intptr_t __internal_intptr; #public internal typedef uintptr_t __internal_uintptr; #public internal typedef off_t __internal_off; #public internal typedef size_t __internal_size; # #public internal typedef Numeric __internal_numeric; #public internal typedef Integral __internal_integral; #public internal typedef SInteger __internal_sinteger; #public internal typedef UInteger __internal_uinteger;