Bug Vanquisher

9 June 2007

Runtime Code Generation in C++ 5

Filed under: C++ — Tanveer Badar @ 3:34 PM

Sorry for such a long discontinuity in posts related to CppCodeProvider. I have been really busy and barely had time to do anything apart from my project. Till last time, we have discussed type support in CppCodeProvider. Also, I am sorry about the bout of C++ I am having recently. I really annoys me to stick to one topic too but it had to be finished sooner or later.

You cannot use a type without statements and expressions. Apart from types, a language is entirely built from expressions and statements. C++ has a rich support for expressions, which are the topic of this post.

Since it is possible to mix any type of expression with any other from compiler’s point of view, all expressions derive from one base class Expression. Let’s begin from the simplest of expressions, a literal expression. A literal is represented by PrimitiveExpression which is built from a string. Next, consider integral compile time constants. They are encapsulated by IntegralExpression. This expression is currently only used in case labels, although it is possible to use it in non-type template parameters too.

When adding namespaces and classes to the mix, we need some way to resolve an identifier to its scope, for this we need ScopeResolutionExpression. A ScopeResolutionExpression expression can take one argument, for global identifiers or two arguments; one string and second another ScopeResolutionExpression to refer to one particular scope. Then, consider how to reference a variable declaration in code, and for similar purposes argument reference. For these, ArgumentReference and VariableReference are provided which respectively allow you to refer to an argument or variable defined previously. We can also refer to a function for function pointers, so there is a MethodReference too. A MethodReference can refer to any function. Therefore, there are smarts built into writetext to handle the special cases of free standing and member functions.

In order to allocate objects on heap, you can use NewExpression and its corresponding DeleteExpression. A NewExpression can be an array new or a scalar new. It can allocate a multi-dimensional array variable. In case of scalar new, it calls the constructor with the given number of arguments. A DeleteExpression can be a scalar delete or an array delete, with the difference given by member function Array.

We also need casts to change from one type to another. Cast expression takes another expression which will be cast to another type, the target type and type of cast to apply to given expression. Possible types of casts are c-style casts, reinterpret_cast, dynamic_cast, static_cast and const_cast.

No discussion of expressions is complete without expressions with operators. A BinaryExpression takes two other expressions and an operator Type to apply infix to the given expressions. All types of binary operators can be given. Similarly, UnaryExpression allows us to apply a unary operator to some variable. There are two types of unary expressions. PrefixExpresison applies any of the prefix operators to the given expression and PostfixExpression applies any of the postfix operators to the given expression. It is possible to provide names of some operators instead of their types as defined in the standard.

We can change precedence of operators by applying parenthesis with the help of ParenthesizedExpression to an expression and producing a new expression. This class takes an Expression as argument and surrounds it with parenthesis. Another handy expression in the conditional operator. This operator is provided in the class ConditionalExpression. This class takes three expressions and uses the first one to decide between the last two expressions to presents as result.

To cover exceptions, a ThrowExpression is also provided. Since we can throw an object or rethrow a previous exception, it is possible to instantiate ThrowExpression without any argument to realize rethrowing a previous exception.

A function call qualifies as an expression. A MethodInvoke takes a reference to either a Function or a MemberFunction. Second argument is an Expression which will be used as the object reference for the MemberFunction call or in place of function name for Function. For the MemberFunction, it is possible to specify whether the object is a reference or a pointer. Argument list is accessible through Arguments( ).

Next time, it will be statements.

1 Comment »

  1. […] is, here are some links which explain it in much more details: part 1, part 2, part 3, part 4, part 5 and part […]

    Pingback by Major Changes in CPPCodeProvider « Bug Vanquisher — 4 November 2007 @ 7:02 PM

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: