Angel \”Java\” Lopez on Blog

September 13, 2011

AjScript: Javascript-Alike interpreter in C# (2) Expressions

Previous Post

As in other interpreters, one key piece is the Expression, something to evaluate during the execution of a program. In AjScript (repository) I have an IExpression:

public interface IExpression
{
    object Evaluate(IContext context);
}

These are the implemented expression in current solution:

A simple expression, ConstantExpression:

public class ConstantExpression : IExpression
{
    private object value;
    public ConstantExpression(object value)
    {
        this.value = value;
    }
    public object Value { get { return this.value; } }
    public object Evaluate(IContext context)
    {
        return this.value;
    }
}

A bit more interesting, VariableExpression, given a name, and a context, returns the value of a named variable:

public class VariableExpression : IExpression
{
    private string name;
    public VariableExpression(string name)
    {
        this.name = name;
    }
    public string Name { get { return this.name; } }
    public object Evaluate(IContext context)
    {
        return context.GetValue(this.name);
    }
}

Sometimes, an expression has one or two parameters. I have UnaryExpression, BinaryExpression as abstract class. The BinaryExpression code:

public abstract class BinaryExpression : IExpression
{
    private IExpression leftExpression;
    private IExpression rigthExpression;
    public BinaryExpression(IExpression left, IExpression right)
    {
        this.leftExpression = left;
        this.rigthExpression = right;
    }
    public IExpression LeftExpression { get { return this.leftExpression; } }
    public IExpression RightExpression { get { return this.rigthExpression; } }
    public abstract object Apply(object leftValue, object rightValue);
    public object Evaluate(IContext context)
    {
        object leftValue = this.leftExpression.Evaluate(context);
        object rightValue = this.rigthExpression.Evaluate(context);
        return this.Apply(leftValue, rightValue);
    }
}

Note that the Apply method is abstract. A concrete implementation:

using Microsoft.VisualBasic.CompilerServices;
public class ConcatenateExpression : BinaryExpression
{
    public ConcatenateExpression(IExpression left, IExpression right)
        : base(left, right)
    {
    }
    public override object Apply(object leftValue, object rightValue)
    {
        if (leftValue == null)
            leftValue = string.Empty;
        if (rightValue == null)
            rightValue = string.Empty;
        return Operators.ConcatenateObject(leftValue, rightValue);
    }
}

I'm a lazy programmer: note the use of Visual Basic Operators. I could write a custom implementation. I have all the tests in place to refactor this expression.

I didn't write all expressions at once. An example: I wrote Context class using tests, and then the VariableExpression class using tests. Then I added variable support in Parser, and evaluates simple expressions that use constants and variables. I use this pattern many times: add a new base class (Context, Function…), add a new expression, improve lexer/parser to support the new expression, use the expression in code tests, etc.

Upcoming topics: commands, function implementation, closures, hoisting, native objects. And AjScript examples.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

September 12, 2011

AjScript: Javascript-Alike interpreter in C# (1) Base Interface

Filed under: .NET, AjScript, C Sharp, JavaScript, Open Source Projects, Programming Languages — ajlopez @ 11:12 am

Next Post

I’m working on implementing a C# interpreter of AjScript: a Javascript-alike language. The code in progress is published at:

https://github.com/ajlopez/AjScript

Initially it was at my AjCodeKatas project in Google Code, but now I prefer GitHub: it able me to have more projects. Google Code has a limit in the number of projects, so I was forced to put little projects in the AjCodeKata. Now, GitHub frees me from that limitation. And GitHub with its public forks and pull request has its charm.

The idea is to have an interpreter with the “good parts” of Javascript. I should discuss with myself about inheritance support. But a key point that it supports is: access to native .NET objects. You can write var obj = new System.IO.DirectoryInfo(‘.’) directly in AjScript. And you can invoke AjScript code from a .NET application.

But now, I will present the base interfaces of this interpreter. First, IObject, the interface that every AjScript object should implement:

 

public interface IObject
{
    IFunction Function { get; }
    object GetValue(string name);
    void SetValue(string name, object value);
    ICollection<string> GetNames();
    object Invoke(string name, object[] parameters);
    object Invoke(ICallable method, object[] parameters);
}

Interesting, every object has a Function property: that function is the “class” of the object, the function used in the new command.

To keep the variable names and their values, I have an IContext interface:

public interface IContext
{
    IContext RootContext { get; }
    ReturnValue ReturnValue { get; set;  }
    void SetValue(string name, object value);
    object GetValue(string name);
    void DefineVariable(string name);
}

Note that a context could have a parent context, in order to support nested context. ReturnValue property is used to detect the return command that could have executed many levels inside the current execution.

Any AjScript method implements ICallable:

public interface ICallable
{
    int Arity { get; }
    IContext Context { get; }
    object Invoke(IContext context, object @this, object[] arguments);
}

Note that functions are IObject and ICallable but with the power of create a new object:

public interface IFunction : ICallable, IObject
{
    object NewInstance(object[] parameters);
}

Upcoming posts: examples, closures, native object management, lexer and parser, test and TDD (I wrote the interpreter using TDD, I have > 80% code coverage).

Pending work: implements Function with arguments, prototype with .constructor and other properties, typeof, Javascript original “classes” like Number and others, decide what features of Javascript are “in” and what ones are “out”. Suggestions?

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

The Shocking Blue Green Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 56 other followers