Skip to content

Repository files navigation

NFun. Expressions Evaluator for .NET

To install NFun, run the following command in the Package Manager Console:

PM> Install-Package NFun 

What is the NFun?

This is an expression evaluator or a mini-script language for .net. It supports working with mathematical expressions as well as with collections, strings, hi-order functions and structures. NFun is quite similar to NCalc but with a rich type system and linq support. See the 'How to / specifications' section for details

Nfun can perform simple evaluations

doubled=Funny.Calc<double>(" 2 * 10 + 1 ")// 21 boolb=Funny.Calc<bool>("false and (2 > 1)")// false// 'age' and 'name' are properties from input 'User' model stringuserAlias=Funny.Calc<User,string>("if(age < 18) name else 'Mr. {name}' ",inputUser)

as well as complex, with multiple composite inputs and outputs

// Evaluate many values and set them into 'Person' object's properties // inputs and outputs 'age', 'cars' and 'birthYear' are properties of 'Person' object varpersonModel=newPerson(birthYear:2000);Funny.CalcContext(@"  age = 2022 - birthYear  cars = [ { name = 'lada', cost = 1200, power = 102 }, { name = 'camaro', cost = 5000, power = 275 } ] ",personModel);Assert.Equal(22,personModel.Age);Assert.Equal(2,personModel.Cars.Count());Assert.Equal(1200,personModel.Cars[0].Cost);

Low-level hardcore API is also supported

varruntime=Funny.Hardcore.Build("y = 2x+1");runtime["x"].Value=42;//Write input dataruntime.Run();//Run scriptvarresult=runtime["y"].Value //collect resultsConsole.WriteLine("Script contains these variables:"
foreach(varvariablein runtime.Variables)
Console.WriteLine("{variable.Name}:{variable.Type} {variable.IsOutput?"[OUTPUT]":"[INPUT]"}");

Key features

  • Arithmetic, Bitwise, Discreet operators
# Arithmetic operators: + - * / % // ** y1=2*(x//2+1) / (x%3-1)**0.5+3x# Bitwise: ~ | & ^ << >> y2= (x|y&0xF0FF<<2) ^0x1234# Discreet: and or not > >= < <= == !=y3=xandfalseornot (y>0)
  • If-expression
simple=if (x>0) xelseif (x==0) 0else-1complex=if (age>18)
if (weight>100) 1if (weight>50) 2else3if (age>16) 0else-1
  • User functions and generic arithmetics
sum3(a,b,c) =a+b+cr:real=sum3(1,2,3)
i:int=sum3(1,2,3)
  • Array, string, numbers, structs and hi-order fun support
out= {
name='etaK'.reverse()
values= [0xFF0F, 2_000_000, 0b100101]
items= [1,2,3].map(rule'item {it}')
}
  • Strict type system and type-inference algorithm
y=2xz:int=y*xm:real[] = [1,2,3].map(ruleit/2)
  • Double or decimal arithmetics
  • Syntax and semantic customization
  • Built-in functions
  • Comments
  • Optional types, type narrowing, named types, etc...

How to

API - guide and examples

Syntax - guide and examples

Built in functions


Boring specification is better than no specification

Boring specification: Basics

Boring specification: Operators

Boring specification: Arrays

Boring specification: Texts (Strings)

Boring specification: Structs

Boring specification: Rules (Anonymous functions)

Boring specification: Types

Boring specification: Optional types

Boring specification: Named types

Boring specification: Math sugar