mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 06:08:41 +01:00
WIP wren/core: Add DEF_NUM_CONSTANT (with Num::infinity and Num::nan). (#781)
* wren/vm: Add "wren_math.h". * wren/core: Add DEF_NUM_CONSTANT. * wren/core: Add `Num::infinity` constant. * wren/core: Add `Num::nan` constant.
This commit is contained in:
@ -9,6 +9,16 @@ Attempts to parse `value` as a decimal literal and return it as an instance of
|
||||
|
||||
It is a runtime error if `value` is not a string.
|
||||
|
||||
### Num.**infinity**
|
||||
|
||||
The value of &infinity;.
|
||||
|
||||
### Num.**nan**
|
||||
|
||||
One value representing a NaN.
|
||||
|
||||
Provides a default sane NaN number suitable for the vm internal values.
|
||||
|
||||
### Num.**pi**
|
||||
|
||||
The value of π.
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include "wren_common.h"
|
||||
#include "wren_core.h"
|
||||
#include "wren_math.h"
|
||||
#include "wren_primitive.h"
|
||||
#include "wren_value.h"
|
||||
|
||||
@ -596,10 +597,19 @@ DEF_PRIMITIVE(num_fromString)
|
||||
RETURN_NUM(number);
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE(num_pi)
|
||||
{
|
||||
RETURN_NUM(3.14159265358979323846);
|
||||
}
|
||||
// Defines a primitive on Num that calls infix [op] and returns [type].
|
||||
#define DEF_NUM_CONSTANT(name, value) \
|
||||
DEF_PRIMITIVE(num_##name) \
|
||||
{ \
|
||||
RETURN_NUM(value); \
|
||||
}
|
||||
|
||||
DEF_NUM_CONSTANT(infinity, INFINITY)
|
||||
DEF_NUM_CONSTANT(nan, WREN_DOUBLE_NAN)
|
||||
DEF_NUM_CONSTANT(pi, 3.14159265358979323846)
|
||||
|
||||
DEF_NUM_CONSTANT(largest, DBL_MAX)
|
||||
DEF_NUM_CONSTANT(smallest, DBL_MIN)
|
||||
|
||||
// Defines a primitive on Num that calls infix [op] and returns [type].
|
||||
#define DEF_NUM_INFIX(name, op, type) \
|
||||
@ -749,16 +759,6 @@ DEF_PRIMITIVE(num_sign)
|
||||
}
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE(num_largest)
|
||||
{
|
||||
RETURN_NUM(DBL_MAX);
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE(num_smallest)
|
||||
{
|
||||
RETURN_NUM(DBL_MIN);
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE(num_toString)
|
||||
{
|
||||
RETURN_VAL(wrenNumToString(vm, AS_NUM(args[0])));
|
||||
@ -1277,6 +1277,8 @@ void wrenInitializeCore(WrenVM* vm)
|
||||
|
||||
vm->numClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Num"));
|
||||
PRIMITIVE(vm->numClass->obj.classObj, "fromString(_)", num_fromString);
|
||||
PRIMITIVE(vm->numClass->obj.classObj, "infinity", num_infinity);
|
||||
PRIMITIVE(vm->numClass->obj.classObj, "nan", num_nan);
|
||||
PRIMITIVE(vm->numClass->obj.classObj, "pi", num_pi);
|
||||
PRIMITIVE(vm->numClass->obj.classObj, "largest", num_largest);
|
||||
PRIMITIVE(vm->numClass->obj.classObj, "smallest", num_smallest);
|
||||
|
||||
34
src/vm/wren_math.h
Normal file
34
src/vm/wren_math.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef wren_math_h
|
||||
#define wren_math_h
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// A union to let us reinterpret a double as raw bits and back.
|
||||
typedef union
|
||||
{
|
||||
uint64_t bits64;
|
||||
uint32_t bits32[2];
|
||||
double num;
|
||||
} WrenDoubleBits;
|
||||
|
||||
#define WREN_DOUBLE_QNAN_POS_MIN_BITS (UINT64_C(0x7FF8000000000000))
|
||||
#define WREN_DOUBLE_QNAN_POS_MAX_BITS (UINT64_C(0x7FFFFFFFFFFFFFFF))
|
||||
|
||||
#define WREN_DOUBLE_NAN (wrenDoubleFromBits(WREN_DOUBLE_QNAN_POS_MIN_BITS))
|
||||
|
||||
static inline double wrenDoubleFromBits(uint64_t bits)
|
||||
{
|
||||
WrenDoubleBits data;
|
||||
data.bits64 = bits;
|
||||
return data.num;
|
||||
}
|
||||
|
||||
static inline uint64_t wrenDoubleToBits(double num)
|
||||
{
|
||||
WrenDoubleBits data;
|
||||
data.num = num;
|
||||
return data.bits64;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -374,9 +374,7 @@ static inline uint32_t hashBits(uint64_t hash)
|
||||
static inline uint32_t hashNumber(double num)
|
||||
{
|
||||
// Hash the raw bits of the value.
|
||||
DoubleBits bits;
|
||||
bits.num = num;
|
||||
return hashBits(bits.bits64);
|
||||
return hashBits(wrenDoubleToBits(num));
|
||||
}
|
||||
|
||||
// Generates a hash code for [object].
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "wren_common.h"
|
||||
#include "wren_math.h"
|
||||
#include "wren_utils.h"
|
||||
|
||||
// This defines the built-in types and their core representations in memory.
|
||||
@ -613,14 +614,6 @@ typedef struct
|
||||
|
||||
#endif
|
||||
|
||||
// A union to let us reinterpret a double as raw bits and back.
|
||||
typedef union
|
||||
{
|
||||
uint64_t bits64;
|
||||
uint32_t bits32[2];
|
||||
double num;
|
||||
} DoubleBits;
|
||||
|
||||
// Creates a new "raw" class. It has no metaclass or superclass whatsoever.
|
||||
// This is only used for bootstrapping the initial Object and Class classes,
|
||||
// which are a little special.
|
||||
@ -854,9 +847,7 @@ static inline Value wrenObjectToValue(Obj* obj)
|
||||
static inline double wrenValueToNum(Value value)
|
||||
{
|
||||
#if WREN_NAN_TAGGING
|
||||
DoubleBits data;
|
||||
data.bits64 = value;
|
||||
return data.num;
|
||||
return wrenDoubleFromBits(value);
|
||||
#else
|
||||
return value.as.num;
|
||||
#endif
|
||||
@ -866,9 +857,7 @@ static inline double wrenValueToNum(Value value)
|
||||
static inline Value wrenNumToValue(double num)
|
||||
{
|
||||
#if WREN_NAN_TAGGING
|
||||
DoubleBits data;
|
||||
data.num = num;
|
||||
return data.bits64;
|
||||
return wrenDoubleToBits(num);
|
||||
#else
|
||||
Value value;
|
||||
value.type = VAL_NUM;
|
||||
|
||||
Reference in New Issue
Block a user