Well, it's an idea about programming language without a programming language.
Think about writing a script that generates assembly. It's doable. Sometimes it's even *almost* sane thing to do, eg. when working on spellchecker I've had a crazy idea about generating code that does dictionary lookup for a hardcoded word set (It's no rocket science, just compare, jump, compare, jump...). But it's so low level and not cross-platform.
I've done some C generation from Python several times (eg. to make last year's april fool's joke - it's on this blog). The problem is that C is often not flexible enough (GCC would choke on 100MB file for dictionary; TCO, call/cc and other fancy stuff is hard...). Not C, not assembly...
There is LLVM - a perfect target.
Moving on: a scripting language that would generate all this mess.
It should be very, very meta one. Like lisp, but with syntax. A pluggable one.
My idea is to write a language that would have pluggable lexer (one lexer would switch to another one when it would encounter some sequence of characters - think of reader macros on steroids), then a huge layer of macros (tons of macros. Like Nemerle). Add a lispy semantics on top of it (few orthogonal concepts that combine together nicely) and my evil plan is 10% complete.
You would be able to create literal syntax for your new, shiny DSL inside your script, then semantics that would generate optimal machine code for it and boom!
It would enable some crazy stuff. Think of all super-duper assertions library creator would be able to enforce compile time with it! You like that D enables you have optional purity control? You can add it to your script.
It wouldn't be general purpose tool (it would probably be to wired and demanding to do everyday work), but I can see applications where you have to be extremely fast (OS kernels, games) or you are very domain-specific stuff (think of all those code-generating tools like lex, bison, antlr).
More or less related things to do/blog about in future:
- DBus + gvim - a possible step towards an headless IDE
- Actor-based OS
Showing posts with label DSL. Show all posts
Showing posts with label DSL. Show all posts
Saturday, 15 November 2008
Monday, 14 January 2008
DSL for CppUnit tests
It's amazing what activities can one invent, just to have something to do but learn...
I've just written an external DSL to ease writing CppUnit tests. It's not finished, but it works.
There is one thing I particularly hate about CppUnit: you have to name every test in fixture at least twice - once when it's created, and another time when it's added to the suite. OK, it's C++, we don't have reflection to do this stuff automatically, preprocessor is to dumb to fix it too... but it still sucks. It's repetitive and error prone. And you can end with tests that are never called, because you have forgotten to add them to suite.
Blah. I think I'm clear.
I wanted to have something simple - generated code should be very similar to our source - tests bodies themselves should be just copied intro right places and so on. No full-blown C++ parsers... no C++ parser at all. Just something that is a little more than preprocessor macros.
And here it goes:
translates to
Simple as that.
Mercurial repo.
Time to finish this longish post before it took me more time to blog about it, than to actually write it...
cut!
My first post on my first blog is finished. Applause!
I've just written an external DSL to ease writing CppUnit tests. It's not finished, but it works.
There is one thing I particularly hate about CppUnit: you have to name every test in fixture at least twice - once when it's created, and another time when it's added to the suite. OK, it's C++, we don't have reflection to do this stuff automatically, preprocessor is to dumb to fix it too... but it still sucks. It's repetitive and error prone. And you can end with tests that are never called, because you have forgotten to add them to suite.
Blah. I think I'm clear.
I wanted to have something simple - generated code should be very similar to our source - tests bodies themselves should be just copied intro right places and so on. No full-blown C++ parsers... no C++ parser at all. Just something that is a little more than preprocessor macros.
And here it goes:
@includeHeaders
@beginFixture TestSum
Sum *sum;
@setUp {
sum = new Sum();
}
@tearDown {
delete sum;
}
@test "empty sum of nothing should be zero" {
CPPUNIT_ASSERT_EQUAL(0, sum->getResult());
}
@test "simple sum of 1+2+3" {
sum->add(1);
sum->add(2);
sum->add(3);
CPPUNIT_ASSERT_EQUAL(6, sum->getResult());
}
@endFixture
translates to
#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>
class TestSum: public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( TestSum );
CPPUNIT_TEST( empty_sum_of_nothing_should_be_zero );
CPPUNIT_TEST( simple_sum_of_1_2_3 );
CPPUNIT_TEST_SUITE_END();
public:
Sum *sum;
void setUp() {
sum = new Sum();
}
void tearDown() {
delete sum;
}
void empty_sum_of_nothing_should_be_zero() {
CPPUNIT_ASSERT_EQUAL(0, sum->getResult());
}
void simple_sum_of_1_2_3() {
sum->add(1);
sum->add(2);
sum->add(3);
CPPUNIT_ASSERT_EQUAL(6, sum->getResult());
}
};
Simple as that.
Mercurial repo.
Time to finish this longish post before it took me more time to blog about it, than to actually write it...
cut!
My first post on my first blog is finished. Applause!
Subscribe to:
Posts (Atom)