8
$\begingroup$

When putting several SymbolicC expressions in a list, they will usually be joined together with semicolons in the final generated code:

<< SymbolicC`

{CCall["g", 2], CCall["h", 3]} // ToCCodeString
g(2);
h(3);

This is true when pieces of code are given as strings too:

{"a=1", "b=2"} // ToCCodeString
a=1;
b=2;

But there are a few special construct that don't use the semicolon as separator, e.g. CBlock:

{CBlock[{"a=1"}], "b=2"} // ToCCodeString
{
a=1;
}
b=2;

I would like to be able to include bits of code as strings and not have them terminated by ;. For example, the following behaviour is undesirable:

{"{a=1;}", "b=2"} // ToCCodeString
{a=1;};
b=2;

How can I prevent semicolons from being added at the end of certain pieces of code?

Motivation:

  • It is just easier to type fixed bits of C code as a string than in terms of SymbolicC.

  • When working with C++, it becomes necessary to use strings as many C++ constructs cannot be represented in SymbolicC

$\endgroup$
6
$\begingroup$

To achieve this, we can define a new SymbolicC construct that won't get semicolons at the end. Let's call it CInlineCode.

We will need to provide translation rules for conversions to a string. This is done in terms of SymbolicC`GenerateCode (which is a slightly lower level version to ToCCodeString).

In general, translation rules are attached to GenerateCode and need to:

  • Translate anything inside the construct by recursively calling GenerateCode
  • Glue the resulting bits of strings together

We define our own CInlineCode:

Needs["SymbolicC`"]

GenerateCode[CInlineCode[arg_], opts : OptionsPattern[]] := GenerateCode[arg, opts]

Whether a construct uses ; as a separator is determined by the function SymbolicC`Private`IsCExpression. The default is no semicolon, so we don't actually need to do this for CInlineCode, but for the sake of completeness (and to show how we could force semicolons if we wanted to):

SymbolicC`Private`IsCExpression[ _CInlineCode ] := False (* change to True to force semicolon *)

Now we can do

{CInlineCode["{a=1;}"], "b=2"} // ToCCodeString
{a=1;}
b=2;

No more semicolon after }!


Needless to say relying on internal implementation details of a package is fragile, so this method might not work in future versions.

$\endgroup$
  • $\begingroup$ Admittedly, this is a very basic thing but I hope it'll save someone the trouble of going into the package file and figuring out how it works. It's also a very basic example of how to create new SymbolicC constructs. $\endgroup$ – Szabolcs Aug 11 '15 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.