Wednesday, June 15, 2005

UsUnit + UCPP

Well I laid my plans for a VS.Net Package aside for a while, kept getting annoying errors outside my source code. I'm been working on a UnrealScript Unit Testing Framework, somewhat similar to DUnit and JUnit. It's called UsUnit. It's almost done, but UnrealScript doesn't allow me to do certain cool things (like point out what check() failed). For this I started to create a PreProcessor for UnrealScript: UCPP

UCPP stands for UnrealScript (Class|Code) PreProcessor, the extention for UnrealScript classes is .uc so therefor UCPP, I'm not sure what the 'c' stands for. So far I've implemented quite some useful features:

  • #define NAME VALUE
  • #if EXPR (#else) #endif
  • UpperCase words in the code are replaced with thier definition according to a previous #define statement
The expression in the #if is quite extensive, simple boolean evaluations and some basic math functions.

But my current problem is with defining function macros:

#define DUMMY(a,b) DoSomething(a, b)

DUMMY("bla", 12345) -> DoSomething("bla", 12345);
I'm having problems to create a nice way to implement this feature. I don't want the definition list to be depended on a parser, but how do I process the definition to replace the arguments. a should be replace, but aa or "a" shouldn't be replaced. A simple replace text routine won't work. I could write an event
OnParseArguments(args: array of string; func: string; var OffsetList: TListOfSomeSort)
the argument names as specified in the name; this is simple to parse
the function part of the definition
Will contain the positions of the of the argument names in the function string; length isn't required since it's known.
The user will then have to assign a function to this event that will do the real parsing. However, this doesn't solve the magic entities in the macro definition (e.g. # and ##).But I guess that can be hacked in to the offset list in someway. Or I can add self and give direct access to the object that is actually being parsed.
The function definition only needs to be parsed the first time it's used. I can throw an exception when a definition can not be parsed because the event is not assigned.