VALをより忠実な挙動にした
This commit is contained in:
@@ -403,8 +403,6 @@ class BuiltinFunction
|
|||||||
p.popFront();
|
p.popFront();
|
||||||
if(p.empty) return 0;
|
if(p.empty) return 0;
|
||||||
//enforce(!p.empty, bailOut());
|
//enforce(!p.empty, bailOut());
|
||||||
if (std.ascii.toLower(p.front) == 'i')
|
|
||||||
goto case 'i';
|
|
||||||
if(p.empty) return 0;
|
if(p.empty) return 0;
|
||||||
//enforce(!p.empty, bailOut());
|
//enforce(!p.empty, bailOut());
|
||||||
break;
|
break;
|
||||||
@@ -413,23 +411,6 @@ class BuiltinFunction
|
|||||||
if(p.empty) return 0;
|
if(p.empty) return 0;
|
||||||
//enforce(!p.empty, bailOut());
|
//enforce(!p.empty, bailOut());
|
||||||
break;
|
break;
|
||||||
case 'i': case 'I':
|
|
||||||
p.popFront();
|
|
||||||
if(p.empty) return 0;
|
|
||||||
//enforce(!p.empty, bailOut());
|
|
||||||
if (std.ascii.toLower(p.front) == 'n')
|
|
||||||
{
|
|
||||||
p.popFront();
|
|
||||||
if(p.empty) return 0;
|
|
||||||
if(std.ascii.toLower(p.front) == 'f')
|
|
||||||
{
|
|
||||||
// 'inf'
|
|
||||||
p.popFront();
|
|
||||||
result = sign ? -Target.infinity : Target.infinity;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto default;
|
|
||||||
default: {}
|
default: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,19 +565,6 @@ class BuiltinFunction
|
|||||||
}
|
}
|
||||||
else // not hex
|
else // not hex
|
||||||
{
|
{
|
||||||
if (std.ascii.toUpper(p.front) == 'N' && !startsWithZero)
|
|
||||||
{
|
|
||||||
// nan
|
|
||||||
if(!((p.popFront(), !p.empty && std.ascii.toUpper(p.front) == 'A') &&
|
|
||||||
(p.popFront(), !p.empty && std.ascii.toUpper(p.front) == 'N'))) return 0;
|
|
||||||
//enforce((p.popFront(), !p.empty && std.ascii.toUpper(p.front) == 'A')
|
|
||||||
// && (p.popFront(), !p.empty && std.ascii.toUpper(p.front) == 'N'),
|
|
||||||
// new ConvException("error converting input to floating point"));
|
|
||||||
// skip past the last 'n'
|
|
||||||
p.popFront();
|
|
||||||
result = typeof(result).nan;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sawDigits = startsWithZero;
|
bool sawDigits = startsWithZero;
|
||||||
|
|
||||||
@@ -713,39 +681,103 @@ class BuiltinFunction
|
|||||||
result = (sign) ? -ldval : ldval;
|
result = (sign) ? -ldval : ldval;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
static bool tryParse(Target, Source)(ref Source s, uint radix, out Target result)
|
||||||
|
if (isSomeChar!(ElementType!Source) &&
|
||||||
|
isIntegral!Target && !is(Target == enum))
|
||||||
|
{
|
||||||
|
if (!(radix >= 2 && radix <= 36))
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
import core.checkedint : mulu, addu;
|
||||||
|
|
||||||
|
immutable uint beyond = (radix < 10 ? '0' : 'a'-10) + radix;
|
||||||
|
|
||||||
|
Target v = 0;
|
||||||
|
bool atStart = true;
|
||||||
|
|
||||||
|
for (; !s.empty; s.popFront())
|
||||||
|
{
|
||||||
|
uint c = s.front;
|
||||||
|
if (c < '0')
|
||||||
|
break;
|
||||||
|
if (radix < 10)
|
||||||
|
{
|
||||||
|
if (c >= beyond)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (c > '9')
|
||||||
|
{
|
||||||
|
c |= 0x20;//poorman's tolower
|
||||||
|
if (c < 'a' || c >= beyond)
|
||||||
|
break;
|
||||||
|
c -= 'a'-10-'0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool overflow = false;
|
||||||
|
auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow);
|
||||||
|
if (overflow || nextv > Target.max)
|
||||||
|
goto Loverflow;
|
||||||
|
v = cast(Target) nextv;
|
||||||
|
|
||||||
|
atStart = false;
|
||||||
|
}
|
||||||
|
if (atStart)
|
||||||
|
goto Lerr;
|
||||||
|
result = v;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Loverflow:
|
||||||
|
result = 0;
|
||||||
|
return false;
|
||||||
|
Lerr:
|
||||||
|
result = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
static double VAL(wstring str)
|
static double VAL(wstring str)
|
||||||
{
|
{
|
||||||
try
|
munch(str, " ");
|
||||||
|
if(str.length > 2 && str[0..2] == "&H")
|
||||||
{
|
{
|
||||||
if(str.empty) return 0;
|
int r;
|
||||||
if(str.length > 2 && str[0..2] == "&H")
|
str = str[2..$];
|
||||||
|
if (tryParse!(int, wstring)(str, 16, r))
|
||||||
{
|
{
|
||||||
return str[2..$].to!int(16);
|
if (!str.empty)
|
||||||
|
return 0;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
if(str.length > 2 && str[0..2] == "&B")
|
|
||||||
{
|
|
||||||
return str[2..$].to!int(2);
|
|
||||||
}
|
|
||||||
munch(str, " ");
|
|
||||||
if(str.empty) return 0;
|
|
||||||
/*
|
|
||||||
wchar c = str[0];
|
|
||||||
if((c > '9' || c < '0') && (c != '-' && c != '+' && c != '.'))
|
|
||||||
return 0;*/
|
|
||||||
double val;
|
|
||||||
if(tryParse(str, val))
|
|
||||||
return val;
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
//例外は遅い
|
}
|
||||||
//TryParse欲しい...
|
|
||||||
//double val = str.to!double;
|
|
||||||
//return val;
|
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
if(str.length > 2 && str[0..2] == "&B")
|
||||||
{
|
{
|
||||||
return 0;//toriaezu
|
int r;
|
||||||
|
str = str[2..$];
|
||||||
|
if (tryParse!(int, wstring)(str, 2, r))
|
||||||
|
{
|
||||||
|
if (!str.empty)
|
||||||
|
return 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
double val;
|
||||||
|
if(tryParse(str, val) && str.empty)
|
||||||
|
return val;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
static nothrow double FLOOR(double val)
|
static nothrow double FLOOR(double val)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user