Added floating point support for the most part. However, decimals are somehow lost during a cast..

Tue, 14 Aug 2012 01:54:17 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Tue, 14 Aug 2012 01:54:17 +0300
changeset 54
8cc91ef94754
parent 53
9ef7e549391f
child 55
173956c1ac27

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

mercurial