Click here to Skip to main content
Click here to Skip to main content
Go to top

Pseudo Code Modeling Language

, 7 Aug 2008
Rate this:
Please Sign up or sign in to vote.
Describes a short hand modeling language for specifying and rendering .NET code models quickly and easily.

Background

I very often have an idea of what my model will be from the start, or want to play with some model ideas early on in design. Since I already have model ideas bouncing around in my head, I want to express them as fast as possible. Most modeling tools, like UML, don't let you express models as quickly as I would like. UML is great for visualizing models, and is especially helpful in communicating models. But, UML diagrams generally require some time and effort to build. In some cases, it seems like it would be just as fast to write the code. I would much rather have a faster modeling tool, and just generate class diagrams from existing code or assemblies or other artifacts. I personally view UML as a presentation tool more than a design tool.

Now, when I say 'model', what I mean is entities and relationships. And, in the .NET world, on the most basic level, that equates to types and their properties. In the early phases of design, I'm most interested in what types will be needed, what information those entities will hold, and what kinds of relationships they have with each other. With this information alone, you have what you need to start designing databases and middle ware.

Through the years in my quest for a fast design tool, I've experimented with several tool ideas for specifying models to generate code from. From using a specific XML schema for specifying models, to graphical tools much like UML. But, they all left me thinking that writing code was still faster and more natural to me as a programmer. In the end, the tool I've found the most useful, is something like the demo project presented here.

Normally, when you hear "code generation", you think about template tools like CodeSmith, or you think about tools like tier generators that take existing artifacts as input (like XML and database) and produce a fairly rigid output. This project is a different kind of tool. This is a modeling tool that simply allows you to specify a model quicker and easier than you could through full code or with graphic tools. It does this by making a few assumptions (which we'll get to), and the output is not intended to necessarily be final, but more of a boiler plate starting point.

Introduction

Pseudo code is a very light weight simple language that allows basic entity relationship information to be expressed in a concise format that is very similar to languages we already use. It is parsed to build a model, which can then be rendered to other languages like C#, VB, XML schema, Java, SQL, or just about any language that can represent ER structure. The demo app is a simplified example of this, which allows you to express classes, interfaces, structs, and enums, with properties and indexers.

Pseudo code's syntax is very similar to that of C#. One of the main differences (besides the limited scope) is that much like defining members on interfaces, you don't provide any implementation details. Also, given that one of the main goals of this tool is to provide modeling speed, many keywords have single character shortcuts, very similar to the way that UML diagrams abbreviate members for display. As an example, like the way that UML presents it, you can use "+" to mean public. The language supports full keywords as well as their shortcuts, so you can use the shortcuts you remember and are most comfortable with, but are not required to. Once you get used to using them, they can add considerable speed to your modeling.

The Syntax

At the beginning of a Pseudo script, you can include using directives.

using System.IO;

The using keyword has the shortcut "u", so you can express the same thing with this:

u System.IO;

Each script can have a namespace declaration after any using statements. The namespace keyword has the shortcut "ns". Unlike C#, since there can only be one namespace declared for the document, it's followed by a semi-colon, and doesn't encase types in a code block. It can be used like this:

using System.IO;
namespace My.Stuff;

// or

u System.IO;
ns My.Stuff;

which specifies that the output will include a using statement for System.IO, and all types specified in the script will be in the namespace My.Stuff.

Type Declarations

Defining types is very similar to C#. You optionally specify type modifiers (which all have shortcuts inspired by UML class diagrams), you use the type keywords or shortcuts (class or c, struct or s, interface or i, enum or e), you give it a type name, an optional parent and/or implemented interfaces, and a code block.

public class Thing : object, IThing {
}

protected struct DataType {
}

internal interface IThing {
}

// or

+c Thing : object, IThing {
}
#s DataType {
}
*i IThing {
}

Enums are specified virtually the same way they are in C#, the only differences are the ability to use the modifier shortcuts, and the enum type shortcuts. There are three enum type shortcuts, one basic and two special cases. The basic enum "e" generates an enum with no explicit values (unless you specify values in the script, which you can do). There is a shortcut for a "valued enum", "ev", which generates sequential explicit values for the enum's members. And, there is a shortcut for a "flags enum", "ef", which generates bit mask explicit values for the enum's members.

As an example, the following Pseudo script...

+e BasicEnum {
  One, Two, Three
}
+ev ValuedEnum {
  One, Two, Three
}
+ef FlagsEnum {
  One, Two, Three
}

would generate C# like this:

public enum BasicEnum {
  One,
  Two,
  Three
}

public enum ValuedEnum {
  One = 0,
  Two = 1,
  Three = 2
}

[Flags]
public enum FlagsEnum {
  One = 1,
  Two = 2,
  Three = 4
}

The idea for modifier shortcuts came from the way UML displays modifiers in class diagrams, some of which should be familiar to UML users (public = "+", private = "-", protected = "#"). However, since .NET uses several modifiers that UML doesn't recognize, I've used other special characters for them. The full list of modifiers and shortcuts for types and members is as follows:

Member Declarations

For this example app, the only members supported are properties and indexers. And, for quick modeling, that's a good starting point. Though C# 3.0 has somewhat removed the tedium of typing property declarations and their private backing members with auto-implementing properties, Pseudo code will generate full properties with their associated private members without much input as well.

In Pseudo code, you declare a property, basically, as you would in an interface, or similar to C# 3.0's auto-implementing properties. You optionally provide modifiers (or shortcuts), a type, and a name. You can then also specify whether or not to include get and/or set accessors, by using "{g}" for read only, or "{s}" for write only, and you can also specify the private member's name if you wish, by following the declaration with a string enclosed in square brackets. If omitted, both get and set are included by default, and a private name is generated by default as well (this is where the assumptions come in). As a simple property example...

+c Thing {
  +string Name;
}

would generate the following C#:

public class Thing {
  private string name;
  public string Name {
    get { return this.name; }
    set { this.name = value; }
  }
}

To specify a read only property, you could say:

+c Thing {
  +string Name {g};
}

which would generate the following C#:

public class Thing {
  private string name;
  public string Name {
    get { return this.name; }
  }
}

To specify the private member's name, you could say:

+c Thing {
  +string Name [myName];
  +int ID {g} [myId];
}

would generate the following C#:

public class Thing {
  private string myName;
  private int myId;
  public string Name {
    get { return this.myName; }
    set { this.myName = value; }
  }
  public int ID {
    get { return this.myId; }
  }
}

Declaring an indexer is very similar to how you declare properties, with the obvious exception that you use the this keyword and provide parameters in square brackets, just like you do in C#. The following example...

+c Thing {
  +string this[int id];
}

would generate the following C#:

public class Thing {
  private string ndxr;

  public string this[int id] {
    get { return this.ndxr; }
    set { this.ndxr = value; }
  }
}

Of course, you probably don't want an indexer to have a single string backing it, but a place holder is generated since I have no idea what you are using an indexer for. In my experience, indexers aren't used that often, but they are so similar to properties it was easy to include them in this demo.

The Code

The Pseudo code parser was generated using Coco/R. In another article that used Coco/R (Simple CSS Parser), I discussed how Coco/R is used to build a parser. I won't rehash all that here since this article isn't about the parser, but you can get some information about it from that article if you are interested.

I chose not to use CodeDom for several reasons. Partly because, it's so painful to use, but primarily because, the only advantage to using it would be to allow the CodeProviders to do the rendering for me for C# and VB, which aren't the only languages I'm interested in rendering to. Because of this, I've created my own simple model.

The PseudoLib project contains the code model, the scanner and parser, and the builders that do the rendering. The model diagram is way too large to be displayed here in the article, but it's available in the source download. The builders have a very simple structure:

The parser has four events corresponding to the four delegates in the diagram. When a type has been completely recognized, the parser fires an event with a reference to the type that it built. The builders subscribe to those events, and collect the types the parser builds. Once the parser has finished, the builders then render the model objects to code. For this example app, there are three builders: for C#, VB.NET, and XSD. The rendering is done very simply by iterating through the gathered types and appending to a StringBuilder. Though this example implementation didn't take advantage of it, since we are writing our own renderers to use our own model, you can easily add options to these renderers to make them more customizable, such as excluding default comments, including flags for value types so you can test whether or not they have been explicitly set, indention, brace formatting, etc.

The Demo App

The demo application has three tabs. The first is for inputting Pseudo code. The "Code" menu has three items for rendering to C#, VB, and XSD. These menu items will invoke the corresponding builder which parses your Pseudo code, and renders the output to the second tab. The third tab displays the modifier and type shortcuts. The "File" menu, as you can imagine, allows you to save and open Pseudo scripts, as well as save output.

Parting Thoughts

This implementation is rather limited, only supporting properties and indexers and the non-customizable builders. My original implementation is a commercial product, so I obviously don't want to share the entire implementation. But, I did want to share the concept, and share a simple, still useful implementation, and get some exposure and feedback to the idea.

I've been using this tool for several years now, and I honestly don't know how I ever lived without it. The main argument I've heard for apprehension towards adopting this approach is that it requires learning another language. But, Pseudo code syntax is so C#-like that learning it, for the most part, only requires learning what parts of C# to omit. Couple that with the fact that expressing a model in Pseudo code takes about 15% of the time it would take to produce the equivalent C# by hand, and you've got some pretty compelling reasons to try it out.

I hope you find the concept interesting, and I hope you can find a use for the demo. Or even take the concept, develop your own tool, and run with it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

BoneSoft
Software Developer (Senior) BoneSoft Software
United States United States
I've been in software development for more than a decade now. Originally with ASP 2.0 and VB6. I worked in Japan for a year doing Java. And have been with C# ever since.
 
In 2005 I founded BoneSoft Software where I sell a small number of developer tools.
Group type: Organisation (No members)



Comments and Discussions

 
-- No messages --
Try changing the 'Date Filter' value
| Advertise | Privacy | Mobile
Web01 | 2.8.140921.1 | Last Updated 7 Aug 2008
Article Copyright 2008 by BoneSoft
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid