Tag Archive for 'DSL'

How to peek inside Boo compiler - part 2

Here’s even shorter way of getting to see the Boo compiler in action with details:

  • Get yourself latest SharpDevelop (15MB)
  • Create new Boo project
  • Paste the code below and hit F5. It will print AST in XML to the console
import System
import Boo.Lang.Compiler.IO
import Boo.Lang.Compiler.Pipelines
import Boo.Lang.Compiler

script = """abstract class BaseWorkflow[of X]:
	abstract def Process(record as X):
		pass

class MyWorkflow(BaseWorkflow[of int]):
	def Process(record as int):
		print record"""

booC = BooCompiler()
booC.Parameters.Input.Add(StringInput("script", script))
booC.Parameters.Pipeline = ParseAndPrintXml()
booC.Parameters.Ducky = true 

context = booC.Run()

if context.GeneratedAssembly is null:
	print join(e for e in context.Errors, "\n")

print "Press any key to continue . . . "
Console.ReadKey(true)

It seems trivial so now, but this little snippet could’ve saved me a couple of hours this morning while I’ve been trying to implement custom DSL workflow around a generic base class.

How to peek inside the compiler pipeline of Boo

Learning how to implement custom DSL with Boo would have been extremely hard without some help from the Boo compiler itself. You just need to know where to look for it.

For example, you can use custom compiler steps to visualize Boo syntax tree between the transformations. Check out the Boo.Lang.Compiler.Steps namespace for:

  • PrintBoo - outputs the AST in Boo format
  • PrintAst - outputs the AST in text form
  • SerializeToXml - outputs all nodes in Xml

To use these steps, you just need to insert them in the desired spot of the compiler pipeline like:

this.Insert(3, new PrintAst());
this.Insert(4, new PrintBoo());

This is all nice already, but we can make this “print AST information” approach even more useful for us. Here’s the simplified recipe:

Continue reading ‘How to peek inside the compiler pipeline of Boo’

Fluent interface from Autofac IoC in DSL configuration

Fluent registration API from the Autofac inversion of control container is really addictive.

I’ve just found myself writing the code for the DSL prototype project, that has nothing to do with the IoC (yet), but has feel similar to the Autofac component registrations:

/// <summary>  Default compiler pipeline for this project  </summary>
public sealed class MyPipeline : CompileToFile
{
  public MyPipeline()
  {
    var provider = new BaseClassProviderOnRules();

    // compile all *.boo from Requests folder against BaseRequestWorkflow
    provider.Register<BaseRequestWorkflow>(“Requests”, “InitWorkflow”)
      .Importing(“Request.Core”);

    // compile all *.boo from Requests folder against BaseRequestDocumenter
    // and add “_Documenter” suffix to class names
    provider.Register<BaseRequestDocumenter>(“Requests”, “DescribeWorkflow”)
      .Naming(file => file + “_Documenter”)
      .Importing(“Request.Core”);

    provider.Register<BaseClass>(“Samples”, “InitializeMethod”);

    // customize the compiler pipeline
    Insert(1, new UseSymbolsStep());
    Insert(2, new MultiBaseClassCompilerStep(provider));
  }
}

What about extending xLim2 with DSL implementations?

As you can see from the overview article, the minimal development cost of implementing first Domain Specific Language in your solution is:

Cost(generic_DSL_framework) + Cost(specific_DSL_implementation)

where initial cost of generic DSL framework could be close to zero, if you reuse Boo compiler and Rhino.DSL. And the cost of specific DSL implementation normally revolves around writing the appropriate base class with all the syntax specifications.

Now, when you have all this in place, development cost of adding another DSL implementation to your solution (in the optimistic scenario) would just depend on creating yet another base class.

So, if it looks so easy for us to add different Domain Specific Languages to our information management solution, what could we do?

  • DSL for workflow definitions (WWF is just too heavy)
  • DSL for the complex security rules
  • Business rules DSL
  • DSL for specifying Smart Client UI composition for different user roles (composite web UI could reuse this, too)
  • Message routing rules

And remember, that you can compile these DSL implementations to .NET at build-time (this results in easier development) or at run-time (also adds flexibility of run-time configuration of the system).

Given all this efficient flexibility at low development cost (and possibly low maintenance costs), it is no wonder that Boo-based DSLs are being considered for the introduction into the architecture concept of building lightweight extensible information management systems.

Obviously, pros and cons of this step are yet to be researched, but I already could think of some big chunks of code, that could be thrown out of the existing xLim 2 implementations.

Overview of creating custom DSL with Boo

Here’s a short overview of creating custom DSL with Boo. It will serve as technical intro point to the Capture business requirements with Boo-based DSL series.

Basically, when we create custom DSL with Boo, we just add our own steps to the Boo compiler pipeline. These steps inform the compiler how to transform our DSL to valid Boo syntax. Then, the actual compilation steps kick off and compile the results into .NET code.

Since Boo syntax itself is also quite flexible and customizable, later on we can take advantage of this too and make our DSL even more expressive.

One of the transformation approaches (I think Ayende came up with it, although not 100% sure about that) works like this:

Continue reading ‘Overview of creating custom DSL with Boo’

Let’s integrate our DSL compiler into the build process

This is the second article in “Capture business requirements with the Boo-based DSL” series. We are just getting started on the series and will talk about simple way of integrating our DSL compiler into the build process of Visual Studio. This approach would simplify learning custom DSLs and could save some head-ache for anyone, who does not want to bother with on-the-fly compilation in the very beginning.

Normally any DSL scripts implemented via Boo could be used in two distinct ways:

  • Scripts that are distributed in the raw form and get compiled into .NET at run-time.
  • Scripts that get compiled into .NET within the main build and are distributed as assemblies.

First approach is more suitable for large and complex solutions. that could require on-the-fly configuration without recompiling the solution. For example, by editing files manually or automatically getting the update from the central update server (file monitoring could be established to recompile the files once the change is detected).

Advantages of this approach are obvious; disadvantages are:

Continue reading ‘Let’s integrate our DSL compiler into the build process’

Learning how to implement business workflows with DSL

Ok, writing your own DSL seems to be way too easy (so probably I’m missing a whole bunch of problems here).

Here’s the story:

In one project I have to set up a whole bunch of request workflows (workflow depends on the type of request), i.e.: cancel program request, retrieve approval to change conditions, submit question etc. Some steps of this workflow could happen within the Smart Client UI, others - within the Web interface, and some more - executed by the automation engine.

Since I’m tired of handcoding the workflows in .NET C#, I’ve turned to the SimpleStateMachine demo for the help. The actual SSM project seemed to be too heavy for me (reimplementing lightweight WWF is still too much), so I’ve just used it as a reference.

Continue reading ‘Learning how to implement business workflows with DSL’