🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

A suggestion...

Started by
7 comments, last by Deyja 18 years, 2 months ago
Hope the AngelScript can built in the #include and others preprocess keywords. But the first important is #include. because now, if we want to include other files, we must use the 3rd preprocess library. But it have a colud not resolved problem that is the included code will replaced the source code, so the compiler reported message will give us a incorrect line number and source file name :(
Advertisement
My preprocessor already handles that. It has an interface you can use to get the original file and line number back using the line number angelscript gives you.
If you don't need all the feature's of Deyja's excellent preprocessor, then I've written an article that shows how to implement the #include feature in a very easy way.

Using #include with AngelScript

AngelScript itself will not have the #include feature built-in, because AngelScript doesn't deal with file loading, by design.

I think I'll write a sample for the SDK that implements the technique in the above article. That way it will be easier for people to find it.

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

Witchlord, I have an idea of #include (or similar) directive. How about making it a hookable event? That is, allow the user to hook in a function for #include's and let the user deal with the source loading him/herself?

Perhaps to avoid the notion of a preprocessor directive, it could be a keyword, such as 'using'. On encountering the statement, say:

using Common;

the compiler would invoke a callback function (if defined), say with the signature:
int f(const char *szModuleName, char *szSource)

where the function is expected to resolve the module (in this case "Common") from the given name and update the given source buffer, returning the length of the source, or, say, -1 on failure to resolve the module name.

The implementation for module resolution would remain entirely in the hands of the user and could be anything from loading a source file from disk, extracting it from an archive or loading it from a BLOB object within a database. On the other hand it would also save the user from having to implement or use a third party pre-processor. The 'using' keyword could also be made smarter by ensuring that only the first of multiple invocations for the same module is done, much like what happens when using #pragma once with #include.

I believe virtually all users of Angelscript need a mechanism for modularising their scripts at some stage and although I do understand that mixing in pre-processor functionality would pollute the design, I think my proposition is a reasonable compromise.

Your thoughts?
tIDE Tile Map Editorhttp://tide.codeplex.com
Actually... that's exactly how my preprocessor does it. You have to give it an instance of a 'file source' class. I'm probably going to be releasing the preprocessor again soon, along with all sorts of other nice stuff. :)
hey deyja, i've finally managed to include your preprocessor in my engine. it's gr8 ! i'm actually working on it to give this a better interface, cleaning up some messy code (i don't understand that namespace frenzy u are using in the cpps...) and integrate better with angelscript interface, let it support UTF-8 characters (for not english like me is a need) and more directives like #else. anyway is very very useful. thanx !
the only thing that i don't know how to use is the LineNumberTranslator class (which isn't in the docs), and how to let it interact with asIOutputStream to reconvert back a compiler error's line and file... that means that i have to parse the angelscript error string ? ouch... lord please give us that errorStruct and we'll live in peace... eheh ;)
I'll think about the possibility of using a callback function for implementing something like #include (or using) in the scripts. It's not a bad idea at all.

I'll also work on that error struct, or whatever it will be. It's on my to-do list already. I can't say when it will be done though, maybe for the next release, maybe not.

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

I'm actually using a simple regex to extract the line number from the error string. I've got it wrapped up inside a special asIOutputStream.

Here it is, cut out of my project.
Preprocessor::OutStream* error_stream = 0;	Preprocessor::LineNumberTranslator LNT;		std::string regex_expression = "^([a-zA-Z._\\/]+)[[:space:]]+\\((\\d+)";	boost::regex expression(regex_expression);	bool ParseErrorMessage(std::string& msg, int& num)	{		std::string::const_iterator start, end;		start = msg.begin();		end = msg.end();		boost::match_results<std::string::const_iterator> results;		boost::match_flag_type flags = boost::match_default;		if (!boost::regex_search(start, end, results, expression, flags)) return false;		std::string num_str = std::string(results[2].first, results[2].second);		msg = std::string(results[0].second,end);		num = boost::lexical_cast<int>(num_str);		return true;	}	class ErrorTranslator: public asIOutputStream	{	public:		virtual void Write(const char* text)		{			//Parse error message...			if (!error_stream) return;			int lnumber;			std::string msgtext = std::string(text);			if (ParseErrorMessage(msgtext,lnumber))			{				(*error_stream) << LNT.ResolveOriginalFile(lnumber) << " ("					<< LNT.ResolveOriginalLine(lnumber)	<< msgtext;			} else {				(*error_stream) << std::string(text);			}		}	};


I pass an 'error translator' to angelscript before compiling, and LNT is passed to and filled by the preprocessor.
As for your other comments on it, I'll try and address them all.

Quote: i'm actually working on it to give this a better interface


I'd recommend wrapping it rather than changing it. I've got a pretty simple 'load script' function myself. Also keep in mind that the messy 'file source' abstraction is for users who are doing things like loading files from archives and that sort of thing; the same reason angelscript doesn't load files itself.

Quote: cleaning up some messy code (i don't understand that namespace frenzy u are using in the cpps...)


A namespace without a name is 'anonymous'. It's equivilant to declaring stuff static; all it does is resolve multiply-defined symbol errors from the linker. Also, be really careful inside the lexer. Maintaining char*s in there drove me nuts. I've meant to rewrite it, but havn't bothered because it works now, and it's been fairly easy to hack in changes so far. The biggest change it needs is to support parameters to macros in the same syntax as C/C++ (without that extra # it requires now) and to preserve as much whitespace as possible so that the column numbers in angelscript's error messages still come out right.

Quote: and integrate better with angelscript interface


My original version actually called asScriptEngine::addScriptSection directly, giving each file it's own section. This made angelscript's error messages come out correctly; I suspect this was sort of what Witchlord originally intended script sections for. That had other issues, though.

Quote: let it support UTF-8 characters (for not english like me is a need)


I ignored unicode on purpose. Or rather, I just didn't bother with it.

Quote: and more directives like #else.


This should be fairly simple. It can already be simulated by using an ifdef for one block, and ifndef for the other.

This topic is closed to new replies.

Advertisement