# HG changeset patch # User Teemu Piippo # Date 1344898457 -10800 # Node ID 8cc91ef9475431d62508365e406d4f75845698c8 # Parent 9ef7e549391f0e04dfd25e5da5d69f3ec53683eb Added floating point support for the most part. However, decimals are somehow lost during a cast.. diff -r 9ef7e549391f -r 8cc91ef94754 commands.cxx --- a/commands.cxx Tue Aug 14 00:59:39 2012 +0300 +++ b/commands.cxx Tue Aug 14 01:54:17 2012 +0300 @@ -77,7 +77,7 @@ r->MustNext (); comm->returnvalue = GetCommandType (r->token); if (comm->returnvalue == -1) - r->ParserError ("bad return value type `%s`", r->token.chars()); + r->ParserError ("bad return value type `%s` for command %s", r->token.chars(), comm->name.chars()); r->MustNext (":"); @@ -158,13 +158,9 @@ // ============================================================================ // Get command type by name int GetCommandType (str t) { - // "float" is for now just int. - // TODO: find out how BotScript floats work - // (are they real floats or fixed? how are they - // stored?) and add proper floating point number support. t = t.tolower(); return !t.compare ("int") ? TYPE_INT : - !t.compare ("float") ? TYPE_INT : + !t.compare ("float") ? TYPE_FLOAT : !t.compare ("str") ? TYPE_STRING : !t.compare ("void") ? TYPE_VOID : !t.compare ("bool") ? TYPE_INT : -1; diff -r 9ef7e549391f -r 8cc91ef94754 parser.cxx --- a/parser.cxx Tue Aug 14 00:59:39 2012 +0300 +++ b/parser.cxx Tue Aug 14 01:54:17 2012 +0300 @@ -848,6 +848,35 @@ b->Write (DH_PUSHSTRINGINDEX); b->Write (PushToStringTable (token.chars())); break; + case TYPE_FLOAT: { + str floatstring; + + MustNumber (true); + floatstring += token; + + // Go after the decimal point + if (!PeekNext ().compare(".")) { + MustNext ("."); + MustNumber (false); + floatstring += "."; + floatstring += token; + } + + // TODO: Casting float to word causes the decimal to be lost. + // Find a way to store the number without such loss. + float val = atof (floatstring); + b->Write (DH_PUSHNUMBER); + b->Write (static_cast ((val > 0) ? val : -val)); + if (val < 0) + b->Write (DH_UNARYMINUS); + + // TODO: Keep this check after decimal loss is fixed, but make + // it a real precision loss check. 55.5123 -> 55.512299, this + // should probably be warned of. + float check = static_cast (static_cast (val)); + if (val != check) + ParserWarning ("floating point number %f loses precision (-> %f)", val, check); + } } } diff -r 9ef7e549391f -r 8cc91ef94754 scriptreader.cxx --- a/scriptreader.cxx Tue Aug 14 00:59:39 2012 +0300 +++ b/scriptreader.cxx Tue Aug 14 01:54:17 2012 +0300 @@ -373,6 +373,12 @@ if (!fromthis) MustNext (); + str num = token; + if (!num.compare ("-")) { + MustNext (); + num += token; + } + // "true" and "false" are valid numbers if (!token.icompare ("true")) token = "1"; @@ -380,11 +386,13 @@ token = "0"; else { if (!token.isnumber()) - ParserError ("expected a number, got `%s`", token.chars()); + ParserError ("expected a number, got `%s`", num.chars()); str check; - check.appendformat ("%d", atoi (token)); + check.appendformat ("%d", atoi (num)); if (token.compare (check) != 0) - ParserWarning ("integer too large: %s -> %s", token.chars(), check.chars()); + ParserWarning ("integer too large: %s -> %s", num.chars(), check.chars()); + + token = num; } } \ No newline at end of file