Tue, 14 Aug 2012 01:54:17 +0300
Added floating point support for the most part. However, decimals are somehow lost during a cast..
commands.cxx | file | annotate | diff | comparison | revisions | |
parser.cxx | file | annotate | diff | comparison | revisions | |
scriptreader.cxx | file | annotate | diff | comparison | revisions |
--- 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;
--- 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<word> (DH_PUSHSTRINGINDEX); b->Write<word> (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<word> (DH_PUSHNUMBER); + b->Write<word> (static_cast<word> ((val > 0) ? val : -val)); + if (val < 0) + b->Write<word> (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<float> (static_cast<word> (val)); + if (val != check) + ParserWarning ("floating point number %f loses precision (-> %f)", val, check); + } } }
--- 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