Pull to refresh

Вычисление выражений на Nemerle и Mono.

Reading time2 min
Views1.5K
За weekend на хабре появились три статьи по разбору математических выражений: Компилятор выражений, Парсер математических выражений и Вычисление значения выражения и один комментарий, в котором код на прологе по краткости и выразительности рвет примеры в этих статьях.

Ниже я покажу, как использовать стандартные средства платформы и языка для достижения того же результата, а именно вычислению выражений.

На конференции PDC2008 Anders Hejlsberg сделал доклад, в котором проследил эволюцию языка C#. Он рассмотрел уже существующие версии и сделал обзор будущих: в 4ой версии разработчиков ждет возможность разбавить строгую систему типов возможностями из динамических языков, а к пятой версии компилятор будет полностью переписан под управляемый код, и его можно будет использовать как сервис (compiler as a service).

Для тех программистов, которые мечтают опробовать эту идеологию (compiler as a service) уже сейчас, будет приятной новостью то, что они могут это сделать. Дело в том, что компилятор nemerle написан на nemerle, и его можно использовать как простую библиотеку. Стоит так же отметить то, что в этом случае в процессе его работы не будет создано на диске никаких файлов, только если Вы не хотите обратного. Ниже — пример кода, который использует компилятор как библиотеку и который эффективно решает проблему разбора/вычислений выражений=)

using System;

using System.Console;
using Nemerle.Evaluation.Evaluator;

module Program
{
  Main() : void
  {
    def function = EvaluateExpression("x => x + 1.0") :> double->double;
    WriteLine(function(2.0));
  }
}


Думаю, что любому программисту, владеющим C# этот код понятен, отдельно отмечу только, что module — синоним static class, double->double — тип функции, аналог Func<double,double>, а using System.Console раскрывает System.Console так, что его статические методы «превращаются» в глобальные функции/процедуры, то есть вызов WriteLine(function(2.0)) это на самом деле вызов Console.WriteLine(function(2.0)).

Другой возможностью попробовать будущее на вкус является платформа mono. Я долго ждал выхода версии 2.2 и удивлен, что на хабре про её выход еще никто не написал. Мои ожидания были основаны на заметке, которую Miguel De Icaza опубликовал в своем блоге в сентябре, в нем он анонсировал, что в следующей версии mono (теперь она уже текущая) добавиться REPL, который в свою очередь основан на идеологии compiler as service. Ниже — код на C# под mono, аналогичный коду на Nemerle:

using System;
using Mono.CSharp;

public class Program
{
  public static void Main(string[] args)
  {
    var function =
      Evaluator.Evaluate ("new System.Converter<double,double>(x=>x+1.0);")
      as Converter<double,double>;
    Console.WriteLine(function(2.0));
  }
}


P.S.
Отдельно хочется отметить, то что и Nemerle, и Mono являются open source проектами. Эту особенность я использовал при создании этой заметки, а именно, исчерпывающей документации по использования compile as a service в Nemerle и Mono я не нашел, но зато быстро смог найти всю интересующую меня информацию, изучая исходные коды.
Tags:
Hubs:
Total votes 21: ↑20 and ↓1+19
Comments15

Articles