Advertisement

Real literals

Started by September 28, 2005 12:25 PM
5 comments, last by Deyja 19 years, 2 months ago
Suppose I declare a variable of double (or float).

double x;
I can assign any numeric value to that:

x = 5;
x = 5.13143;
However, I can't use the "e" literals, i.e.:

x = 1.531e5;
x = 0.3813e-7;
Does Angelscript not support these type of literals?
It should work, at least it was implemented to work. I'll need to look into it.

I seem to remember that you mentioned that you're using Deyja's preprocessor. If so, please verify that AngelScript really receives the real number as one token.



AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
I can guarantee it doesn't! Give me a run down of exactly what this format looks like in all possible forms and I'll make it work.
What AngelScript accepts is this:

[0-9]+('.'[0-9]+(('e'|'E')('-'|'+')?[0-9])?'f'?)?


Where + means 1 or more occurrances, and ? means 0 or 1 occurrances.

Examples:

00.00.0f0.0e00.0e0f0.0e+0f0.0e-0f0.0E00.0E-0... etc


C/C++ accepts a few more variants. I know that C++ allow you to skip the 0 before the decimal point, also I believe that C++ accepts 'd' and 'D' as well as 'e' and 'E'.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Ah, regexy. /\D+\.\D+[eEdD][+-]?\D+f?/
Okay, I got it working.

In the file lex.cpp, replace the function
static char* parseFloatingPoint(char* start, char* end, Lexem& out){	out.value += *start;	while (true)	{		++start;		if (start == end) return start;		if (!isNumber(*start))		{			if (*start == 'f') //f postfix transforms literal from type double to float.			{				out.value += *start;				return ++start;			}			else return start;		} 		else 		{			out.value += *start;		}	}}


with

static char* parseFloatingPoint(char* start, char* end, Lexem& out){	out.value += *start;	while (true)	{		++start;		if (start == end) return start;		if (*start == 'f') //f postfix is part of float, but terminates it.		{			out.value += 'f';			return ++start;		}		if (*start == 'e' // real literal; exponent follows.			|| *start == 'E'			|| *start == 'd'			|| *start == 'D')		{ 			out.value += 'e';			++start; if (start == end) return start;			if (*start == '-' || *start == '+' || isNumber(*start))			{				out.value += *start;			} else return start;			while (true)			{				++start; if (start == end) return start;				if (*start == 'f')				{					out.value += 'f';					return ++start;				}				if (!isNumber(*start)) return start;				out.value += *start;			}		}		if (!isNumber(*start)) return start;		out.value += *start;	}}


Note that, though angelscript only supports e and E, this code supports d and D as well. Angelscript will only ever see e, no matter which you actually use.
Advertisement
Just to clear up why this sort of thing happens in the first place; my preprocessor tends to produce output like this..
void cml_player_command(){string cp=GetParameterString();string cw=PopFirstWord(cp);Object player=GetActiveObject();Object room;GetObject(room,Location(player));Send(GetActiveObject(),"<Debug command parsing. ");while(true){Send(GetActiveObject(),"[Looking for command '"+cw+"'. ");if(cp.length()==0&&HasKey(player,"$player_command_"+cw)){Send(GetActiveObject(),"Found on player.]\n");AsyncCall(GetValue(player,"$player_command_"+cw),player,player,cp);return;}else if(cp.length()>0&&HasKey(player,"$player_string_command_"+cw)){Send(GetActiveObject(),"Found on player.]\n");AsyncCall(GetValue(player,"$player_string_command_"+cw),player,player,cp);return;}else if(cp.length()==0&&HasKey(room,"$world_command_"+cw)){Send(GetActiveObject(),"Found on room.]\n");AsyncCall(GetValue(room,"$world_command_"+cw),player,room,cp);return;}else if(cp.length()>0&&HasKey(room,"$world_string_command_"+cw)){Send(GetActiveObject(),"Found on room.]\n");AsyncCall(GetValue(room,"$world_string_command_"+cw),player,room,cp);return;}string rest;Object obj;if(ml_parse_object_ex(cp,player,rest,obj,0,false)){Send(GetActiveObject(),"[Found matching object.]");if(rest.length()==0&&Location(obj)==GetName(player)&&HasKey(obj,"$INVENTORY_COMMAND_"+cw)){Send(GetActiveObject()," Found in inventory.]\n");AsyncCall(GetValue(obj,"$inventory_command_"+cw),player,obj,rest);return;}else if(rest.length()>0&&Location(obj)==GetName(player)&&HasKey(obj,"$INVENTORY_STRING_COMMAND_"+cw)){Send(GetActiveObject()," Found in inventory.]\n");AsyncCall(GetValue(obj,"$inventory_STRING_command_"+cw),player,obj,rest);return;}else if(rest.length()==0&&HasKey(obj,"$ROOM_COMMAND_"+cw)){Send(GetActiveObject()," Found in room.]\n");AsyncCall(GetValue(obj,"$room_command_"+cw),player,obj,rest);return;}else if(rest.length()>0&&HasKey(obj,"$ROOM_STRING_COMMAND_"+cw)){Send(GetActiveObject()," Found in room.]\n");AsyncCall(GetValue(obj,"$room_STRING_command_"+cw),player,obj,rest);return;}}Send(GetActiveObject()," Command Not Found.]");string co=PopFirstWord(cp);if(co.length()==0){Send(GetActiveObject(),"\nHuh?\n");return;}cw+="_"+co;}}

Just enough whitespace to keep the meaning of the program from changing, and still give helpfull error messages. What happened was '0.0e0f' was changed to '0.0 e 0 f', because the preprocessor thought that the e was an identifier, the 0 was a whole new number, and the f was another identifier.

This topic is closed to new replies.

Advertisement