Skip to content
This repository has been archived by the owner on Jun 11, 2021. It is now read-only.

Latest commit

 

History

History
82 lines (71 loc) · 6.39 KB

index.md

File metadata and controls

82 lines (71 loc) · 6.39 KB

Metaprogramming

Metaprogramming API provided by .NEXT library allows to generate and execute code in runtime. Code generation object model is language agnostic so developer can use it from any .NET programming language. From design point of view, metaprogramming capabilities built on top of LINQ Expressions without direct usage of IL generator. This increases portability of the library between different .NET implementations. All custom expressions introduced by Metaprogramming libary are reducible into predefined set of LINQ Expressions.

Warning

Xamarin.iOS supports only interpretation of Expression Trees without Just-in-Time Compilation. Since the iPhone's kernel prevents an application from generating code dynamically Mono on the iPhone does not support any form of dynamic code generation. Check out this article for more information. As a result, the code generated using .NEXT Metaprogramming library demonstrates significantly slower performance on iOS.

Metaprogramming library extends LINQ Expression with the following features:

All these extensions are compatible with Expression class.

Additionally, .NEXT Metaprogramming library replaces limit of C# Expression Trees where only single-line lambda expression is allowed.

Important

Despite of rich set of Metaprogramming API, a few limits still exist. These restrictions dictated by internal design of LINQ Expression. The first, overloaded operators with in parameter modifier cannot be resolved. The second, ref return and ref locals are not supported.

Concept

The code construction based on the following concepts:

  • Dynamic Construction of Expressions
  • Code Generator provides methods for adding statement such as method calls, assignment, loops, if-then-else statement etc.
  • Expression Builder provides extension methods for constructing expressions

Code expressions from .NET library heavily extended with additional expression types:

  • using Expression represents using statement from C#
  • lock Expression represents lock statement from C#
  • await Expression represents await operator from C#
  • String Interpolation Expression represents interpolated string
  • for-in Expression represents foreach loop from C#
  • while Expression represents while and do-while loops from C#
  • for Expression represents for loop from C#
  • Element Access Expression represents index-based access to individual elements of the collection or string
  • Slice Expression represents range of elements in arbitrary collection or string

The lexical scope is enclosed by multi-line lambda function. The body of such function contains the code for generation of expressions and statements.

using DotNext.Linq.Expressions;
using System;
using System.Linq.Expressions;
using static DotNext.Metaprogramming.CodeGenerator;

Func<long, long> fact = Lambda<Func<long, long>>(fun => 
{
    var arg = fun[0];    //declares access to lambda parameter
    //if-then-else expression
    If((Expression)(arg.AsDynamic() > 1L))
        .Then(arg.AsDynamic() * fun.Invoke(arg.AsDynamic() - 1L))  //recursive invocation of the current lambda function
        .Else(arg)  //else branch
        .OfType<long>()
    .End();
    //declare local variable of type long
    var local = DeclareVariable<long>("local");
    //assignment
    Assign(local, -arg.AsDynamic());  //equivalent is the assignment statement local = -arg
    //try-catch
    Try(() => 
    {
        Return(10.Const());    //return from lambda function
    })
    .Finally(() => //finally block
    {  
        //method call Console.WriteLine(local);
        CallStatic(typeof(Console), nameof(Console.WriteLine), local);
    })
    .End(); //end of try block
}).Compile();

Statement construction methods from CodeGenerator mimic syntax of C# programming language that improves maintainability of the code.