Sign in to follow this  
AlexanderMorou

Action Translation

Recommended Posts

Hello, Fairly (very) new to GameDev.Net, so if this is the wrong place, please let me know. I'm writing a CodeDOM wrapper in C# with the aim of eventually utilizing the user's data and translating it into code accordingly. For those who aren't familiar with the CodeDOM, it is a Document Object Model for working with a 'code'-based document. It's a high-level intermediate format that can be used to generate scripts for compilation or other needs (such as designers that generate code to aid their setup, and doubling as a way to translate that data into the program itself without any need for another few steps, since it's already in the appropriate format when it's done.) In the proposed model, the various parts of the game would function off of Actions. Actions would be specific and the code they yield would be based upon their individual design. They're intended to be able to allow nesting, but that is also based upon the individual type of action. The trigger (invoke/launch point) for the actions would be the fixed part of the system, and would vary based upon the type of game the person is making (Basically I would code various common behavioral models. The basis for those would be the different types of games.) Right now it's mostly theoretical, however I have the CodeDOM wrapper going pretty well. Using it, I was able to write an Expression Builder, which links groups of expression parts together, such as [method invoke/reference]/Property/field/indexer or event reference(s). I figure the biggest thing holding back a large scale project like this would be the maintainability of the code you write the translation system in. CodeDOM is one of the ugliest, most verbose, and irritating Document Models I've ever used. In it, you build expressions by linking together a large series of instantiations such as:
CodeTypeReferenceExpression consoleRefExp = new CodeTypeReferenceExpression(typeof(Console));
mainMethod.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(consoleRefExp, "WriteLine", new CodePrimitiveExpression("Welcome to the generated test project."))));
Which translates into:
System.Console.WriteLine("Welcome to the generated test project.");
As you can tell it's not very friendly. Presently with the Wrapper and Expressions system, the same is done like so:
mainMethod.CallMethod(ConsoleExp.WriteLine((StringExp.__arg)(Expression)"Welcome to the generated test project."));
The reason for the unusual cast on the StringExp is the 'Expression' class auto-wraps primitives, and due to the fact that all types wrapped in the original library auto-wrap normal expressions, ambiguity occurs without the cast. Though casting to resolve ambiguities is a minor trade-off in my opinion. The reason the types in the calls are translated into wrapped versions is obvious: you're referring to the state of code, as opposed to the literal invoke of the method itself; I needed to wrap the parameters in order to preserve the signatures as well as correctly translate the data passed through the parameters. Does anyone else here know of a more appropriate way to simplify the generation process further, or would doing so be likely to cause functionality quirks (similar to the need to cast due to ambiguity)? I was sent here by another forum that thought the project details were more appropriate for a development website as opposed to a game enthusiast website.

Share this post


Link to post
Share on other sites
www.codeproject.com has a wealth of articles about the CodeDOM, and I believe you might find what you need. In any case, good luck with your project. CodeDOM is a real PITA. :|

Edit: What about translating user actions into MSIL? A slightly more advanced approach, however I find it much easier to implement.

Share this post


Link to post
Share on other sites
Yes they do, they have one such project called ReFly which wraps the CodeDOM similarly to how I have; however, I'm aiming for a more functional variant that has a even more naturalistic coding habits such as the Expression Library wrapper. The point of a wrapper is to put it to work, and in wrapping the Code DOM there's a lot you can have it do for you. ReFly was the spark that got me started on my own variant of the CodeDOM Wrapper. I talked to Johnathan de Halleux, the author, and he said one of the largest flaws with CodeDOM is the usage (he's a Microsoft Researcher, working on an interesting project called Pex)

One thing I've done is looked at the disassembly of hand-written code and adapted the results to the CodeDOM wrapper. The Enumeration statement in the wrapper works this way:
for (IEnumerator @__enumerator = arguments.GetEnumerator(); @__enumerator.MoveNext();
)
{
string @__current = ((string)(@__enumerator.Current));
Console.WriteLine(@__current);
}


Which was from:
//Get an enumerator for the arguments.
IEnumeratorStatement argumentEnum = mainMethod.Enumerate(arguments.GetReference(), CodeDOMGeneratorHelper.GetTypeReference(typeof(string)));
//Write the argument
argumentEnum.CallMethod(ConsoleExp.WriteLine((StringExp.__arg)(Expression)argumentEnum.CurrentMember.GetReference()));


Later on I'll add switches and large-groupings of conditional statements (if and else with nested if on the end, if (...) {...} else if (...2) {...}) While I'm far on the CodeDOM project, I have a lot of functionality I can still add.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this