Wednesday, June 25, 2008

AbcExplorationLib: Starting an open source project

A couple of months ago I started working on a F# library to read and write ActionScript Byte Code (ABC) files based on the ActionScript Virtual Machine 2 (AVM2) Overview document. I though this was a great opportunity to learn more about both F# and ActionScript.

Although the library is still pretty incomplete, I'll continue the development as an open source project. The project is called AbcExplorationLib and is hosted in CodePlex .

Inspiration for this library comes from excellent bytecode manipulation libraries such as BCEL, ASM, Cecil or System.Reflection.Emit.

When completed this library could be used as part of a complied code analysis tool or as part of the back end of a experimental compiler.

An example of using this library to load a compiled script and print all the names of the opcodes is the following:

let loadedFile =
using(new BinaryReader(new FileStream("",FileMode.Open)))
(fun aInput -> AbcFile.ReadFrom(aInput))

let loadedScript =

(fun (x:AbcFileInstruction) -> printf "%s\n" x.Name)

An example for generating a "Hello world" program:

let abcFileCreator = AbcFileCreator()
let cpCreator = abcFileCreator.ConstantPoolCreator

let instructions =
[| GetLocal0 ;
PushScope ;
PushString(cpCreator.AddString( "Hola!"));
CallProperty(cpCreator.GetMultiname([|""|],"print"),1) ;
CoerceA ;
SetLocal_1 ;
GetLocal1 ;
ReturnValue ;

let code = ConvertToByteArray(instructions)

let script =
AvmMethod( "",
Some (
0, 2, 2, 1, 2,


let fileRep = abcFileCreator.CreateFile()

using (new BinaryWriter(new FileStream("",FileMode.Create))) (fun f -> fileRep.WriteTo(f))

As you can see this is the part that requires more work! :) .

Future posts will cover the progress of this library.

Monday, June 9, 2008

Using F# option types in C#

This post shows a small example of how to use F# option type instances in C#.

Option types

The F# option type provides a very nice way for defining variables that can may or may not hold a value. For example, in the following class definition, the description field is optional .

type Product(name : string, description : string option) =

member this.Name
with get() = name

member this.Description
with get() = description


F# Optional types are constructed using the Some and None constructors. For example:

let p1 = Product("Foo",Some "A description")
let p2 = Product("Goo",None)

Optional types are available in many functional languages, for example: Haskell's Maybe, Scala's Option, OCaml's option, among others.

Using option types in C#

Manipulating a option instance from C# requires some considerations since it is defined in F# as a discriminated union. Some useful documentation on how to manipulate discriminated unions from C# includes: Creating and Consuming F# discriminated unions from F#'s manual and this entry from the hubFS.

An instance of the class defined above can be created in C# like this:

Product p = new Product("Foo", Option<string>.Some("A description"));
Product p2 = new Product("Goo", Option<string>.None);

As shown here the Option<A> class (defined in Microsoft.FSharp.Core) provide static methods to construct both cases of the discriminated union.

Several techniques can be used to verify if an instance of Option<A> was created with Some or None. For example, there are static methods called get_IsNone or get_Some which can be used as follows:

if (Option<string>.get_IsNone(p.Description))
if (Option<string>.get_IsSome(p.Description))

Another alternative is to use the GetTag method as follows:

if(Option<string>.GetTag(p.Description) == Option<string>.tag_Some) {

Extension methods

C# extension methods can be used to avoid calling static methods on the Option<A> class. For example:

static class Utility
public static bool IsSome(this Option<string> option)
return Option<string>.get_IsSome(option);

public static bool IsNone(this Option<string> option)
return Option<string>.get_IsNone(option);

Having these extension methods the code could be changed to:

if (p.Description.IsSome())

if (p2.Description.IsSome())

C# extension methods could also be implemented directly in F# . This could be accomplished by applying the System.Runtime.CompilerServices.ExtensionAttribute attribute. For example:

module Methods =

let Exists(opt : string option) =
match opt with
| Some _ -> true
| None -> false

This method could be used in C# only by adding the namespace (using using) to the file where it will be used.

if (p2.Description.Exists())

Sunday, June 1, 2008

Creating a simple AIR/Flex UI for a Snobol program

This post presents a little experiment for communicating an Snobol program with an AIR/Flex interface using HTTP.

This post is inspired by the Put a Flex UI On Your Application article by Bruce Eckel.

The example

The example that will be presented is a simple form showing sudo attempts recorded in the /var/log/auth.log log in a Linux box.

A simple program written in Snobol4 using CSnobol4 is used to extract the entries from auth.log . A AIR/Flex program is used to display the data. Both programs are communicated using HTTP.

Although there are several ways to communicate a AIR application with a server side element, HTTP was chosen because of its simplicity to implement in Snobol.

Simple HTTP in Snobol

A way to answer simple HTTP GET method requests from Snobol was required. This requires the creation of a server socket to answer requests. Luckly CSnobol4 includes a nice example for creating a server socket (snolib/serv.sno) using the SERV_LISTEN function. Having this element it was very simple to implement the GET method support.

serverPort = 8080
SLOOP FD = SERV_LISTEN("inet", "stream", serverPort) :F(LERR)

INPUT(.NET, 9, "UWT", "/dev/fd/" FD) :F(IERR)

OUTPUT = "Accepting request "


LINE "GET " GetStringPat $ getString " HTTP/" NUMBER "." NUMBER :F(LERR)

getString ARB "username=" ARB $ requestedUserName ("&" | RPOS(0))

OUTPUT = "Requesting SUDOS for user: " requestedUserName


NET = "HTTP/1.1 200 OK" CRLF
NET = "Server: SNOBOL4/1.1 (Linux)" CRLF
NET = "Content-Type: text/xml" CRLF

Extracting the data

The data extraction process is presented in the following code.

LetterL = "abcdefghijklmnopqrstuvwxyz"
Digit = "0123456789"
DirectorySeparator = "/"
GetQuerySeparator = "?"
EscapeChar = "%.&="

GetStringChar = LetterU LetterL Digit DirectorySeparator EscapeChar GetQuerySeparator

GetStringPat = SPAN(GetStringChar)


NET = "<sudosdata>"

LETTER = LetterU LetterL
USERNAMECHAR = Digit LetterU LetterL


USER requestedUserName :F(READLINE)

NET = "<sudo><date>" month " " day "</date><user>" USER "</user><command>" COMMAND "</command></sudo>" :(READLINE)


NET = "</sudosdata>" :S(END)

The answer is formated as XML.

The Interface Code

The interface is a very simple program containing a text input to filter the query for a specify user. The useful HTTPService component is used to get the data from the Snobol program.

The Flex part of the program is the following:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx=""
title="Sudos Test">
import flash.utils.Dictionary;
private function callQuery():void {
<mx:Label text="Sudos" />
<mx:TextInput id="userName" />
<mx:Button label="Query!" click="callQuery()"/>
<mx:DataGrid id="data" dataProvider="{request.lastResult.sudosdata.sudo}">
<mx:DataGridColumn headerText="date" dataField="date"/>
<mx:DataGridColumn headerText="user" dataField="user"/>
<mx:DataGridColumn headerText="command" dataField="command"/>

<mx:HTTPService id="request" url="http://localhost:8080"
<mx:request xmlns="">

How it looks

An example of running these programs is the following:

Code for this post can be found here.