C::Blocks Advent Day 1

In the tradition of the Perl Advent Calendar, I have decided to write an Advent Calendar for C::Blocks, which is in pre-Beta. My plan is to release a new treat each day about the C::Blocks library. Today we will begin with the basics: what it is and how it works.

It is very easy to inject regular expressions into Perl code. This is one of the reasons Perl is commonly used for text processing. One of the aims of C::Blocks is to make it equally easy to inject C code into your Perl code.

Check out the following simple program, a minor modification from the SYNOPSIS:

use strict;
use warnings;
use C::Blocks;
use C::Blocks::PerlAPI; # for printf

print "Merry Christmas world! from Perl\n";
cblock {
    printf("Merry Christmas world! from C::Blocks\n");
}
print "... and a happy new year!\n";

If you run that, you will get:

$ perl merry-christmas-world.pl
Merry Christmas world! from Perl
Merry Christmas world! from C::Blocks
... and a happy new year!

The interesting bit here is the code within the cblock. That is real C code. It calls the well-known C function printf to produce its message. That code gets compiled into a little function that is inserted into your Perl’s OP tree at that precise location so that when your Perl script runs, it executes your C code exactly where you had it in your file.

Let’s take a look at a more interesting example. In C, a string is just an array of chars, and an array is mostly interchangeable with a pointer. So, I can build a collection of greetings as an array of char *. Since zero is a valid pointer, and since no real data will ever live at that location, I can terminate a list in an array with a null pointer to signal the end. Here’s an example that uses this:

use strict;
use warnings;
use C::Blocks;
use C::Blocks::PerlAPI; # for printf

print "Merry Christmas world! from Perl\n";
cblock {
    char * greetings[] = {
        "Merry Christmas",
        "Froehliche Weihnachten",
        "Joyeux Noel",
        "Buon Natale",
        "Feliz Navidad",
        "Kuwa na Krismasi njema",
        "Bada Din Mubarak Ho",
        0
    };
    for (char ** phrase = greetings; *phrase; phrase++) {
        printf("%s world! from C::Blocks\n", *phrase);
    }
}
print "... and a happy new year!\n";

When run, this produces:

$ perl merry-christmas-world.pl
Merry Christmas world! from Perl
Merry Christmas world! from C::Blocks
Froehliche Weihnachten world! from C::Blocks
Joyeux Noel world! from C::Blocks
Buon Natale world! from C::Blocks
Feliz Navidad world! from C::Blocks
Kuwa na Krismasi njema world! from C::Blocks
Bada Din Mubarak Ho world! from C::Blocks
... and a happy new year!

Furthermore, If you run it, you will notice that it runs “instantly”, almost as instantly as any other Perl script. This is because C::Blocks utilizes a very fast compiler which can produce executable machine code in RAM without writing to the file system. The compilation is so fast that you don’t notice it, which is one of the redeeming qualities of a good scripting language.

So, C::Blocks lets you “script” in C by simply weaving in little blocks of C code within your Perl. It does a whole lot more, but we’ll get to that as Advent progresses.

CAVEATS

Why did I include C::Blocks::PerlAPI in these scripts? C by itself does not have printf, you have to incorporate stdio.h into your code to get it. Perl’s C API includes the main parts of the standard C library, including stdio.h and printf, so I haven’t had a pressing need to implement C::Blocks::stdio.

C::Blocks Advent Day 1 2 3 4 5 6 7 8 9 10 11 12 13

1 Comment

David Mertens++.

Leave a comment

About David Mertens

user-pic This is my blog about numerical computing with Perl.