🎉 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!

Preprocessor 0.4

Started by
3 comments, last by Deyja 18 years, 10 months ago
I've just put in the preprocessor, and I'm thrilled with it! It works wonderfully for what we are using it for (simple defines and simple macros). Great job! Just a couple of questions:
Quote: NEW IN 0.4 LineNumberTranslator - Use this class to resolve line numbers in the final preprocessed script to the original file and line. Client code creates a LineNumberTranslator object and passes it to Preprocessor::preprocess. After preprocessing, the members ResolveOriginalFile and ResolveOriginalLine of LineNumberTranslator can be used to resolve original file and line information.
Are there any example on how to use this exactly? Since Angelscript outputs the errors directly, how does one Resolve*() to gather the resolve the line numbers? Are you processing the error output? I'm curious about the macro syntax you chose. Being from a C/C++ background, I'm more used to:

#define macro(x, y) (x + y)
but it has to be done as

#define macro #(x, y) (x+y)
Not that I mind the latter. Just curious about your choice.
Advertisement
There should be the version 0.5 released now too you should try.
Yes. 0.5 has a few bug fixes. You should definitly use it.

First, the easy one. I choose the #define macro #(parms) syntax because of whitespace. My parser cannot tell the difference between #define macro(parms) and #define macro (parms). Allowing it to do so - by having the lexer generate 'whitespace' tokens instead of just ignoring them - would require me to rewrite most of the parser. It's actually somewhat more friendly this way. For example, you don't need to start a directive right at the begining of the line.

And the hard one; this is perhaps best shown by example. You need to write a asIOutputStream that changes the filename/line number before outputting. Like I said, example...

#include <boost/regex.hpp>#include <boost/lexical_cast.hpp>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);		}	}};ErrorTranslator as_error_stream;Preprocessor::VectorOutStream VOS;		bool error = false;Preprocessor::preprocess(script,*file_source,VOS,*error_stream,&LNT);


If you then use as_error_stream in asIScriptEngine::build, it will modify the error messages and re-emit them.
Quote: Original post by Rain Dog
There should be the version 0.5 released now too you should try.

Right. I am using 0.5. I only quoted the release notes for 0.4 since that is where the line number translater was introduced. Thanks for the suggestion.
Also keep in mind that the 'column' value is almost never correct. This is because A) Angelscript counts tab's as a single column, where as your IDE counts it as several, and B) The preprocessor strips extraneous whitespace anyway.

This topic is closed to new replies.

Advertisement