public void Should_cast_function_params() { BracketOpenDefinition openBracket, logFn; GrammerDefinition listDelimeter; var language = new Language( logFn = new FunctionCallDefinition( name: "LOG", regex: @"[Ll]og\(", argumentTypes: new[] { typeof(double), typeof(double) }, expressionBuilder: args => Expression.Call(Type <int> .Method(x => Math.Log(0, 0)), args)), openBracket = new BracketOpenDefinition( name: "OPENBRACKET", regex: @"\("), listDelimeter = new ListDelimiterDefinition( name: "COMMA", regex: @"\,"), new BracketCloseDefinition( name: "CLOSEBRACKET", regex: @"\)", bracketOpenDefinitions: new[] { openBracket, logFn }, listDelimeterDefinition: listDelimeter), new OperandDefinition( name: "NUMBER", regex: @"\d+", expressionBuilder: x => Expression.Constant(int.Parse(x))), new GrammerDefinition(name: "WHITESPACE", regex: @"\s+", ignore: true) ); var expression = language.Parse <double>("Log(1024,2)"); Assert.Equal(10, expression.Compile()()); }
public void Should_run_single_param_functions() { BracketOpenDefinition openBracket, sinFn; var language = new Language( new OperatorDefinition( name: "PLUS", regex: @"\+", orderOfPrecedence: 10, paramaterPositions: new[] { RelativePosition.Left, RelativePosition.Right }, expressionBuilder: args => Expression.Add(args[0], args[1])), sinFn = new FunctionCallDefinition( name: "SIN", regex: @"sin\(", expressionBuilder: args => Expression.Call(typeof(Math).GetMethod("Sin"), args[0])), openBracket = new BracketOpenDefinition( name: "OPENBRACKET", regex: @"\("), new BracketCloseDefinition( name: "CLOSEBRACKET", regex: @"\)", bracketOpenDefinitions: new[] { openBracket, sinFn }), new OperandDefinition( name: "NUMBER", regex: @"\d*\.?\d+?", expressionBuilder: x => Expression.Constant(double.Parse(x))), new GrammerDefinition(name: "WHITESPACE", regex: @"\s+", ignore: true) ); var expression = language.Parse <double>("sin(1+2)+3"); Assert.Equal(3.14, expression.Compile()(), 2); }
public void Should_apply_brackets() { BracketOpenDefinition openBracket; var language = new Language( new OperatorDefinition( name: "PLUS", regex: @"\+", orderOfPrecedence: 1, paramaterPositions: new[] { RelativePosition.Left, RelativePosition.Right }, expressionBuilder: args => Expression.Add(args[0], args[1])), new OperatorDefinition( name: "MULTIPLY", regex: @"\*", orderOfPrecedence: 2, paramaterPositions: new[] { RelativePosition.Left, RelativePosition.Right }, expressionBuilder: args => Expression.Multiply(args[0], args[1])), openBracket = new BracketOpenDefinition( name: "OPENBRACKET", regex: @"\("), new BracketCloseDefinition( name: "CLOSEBRACKET", regex: @"\)", bracketOpenDefinition: openBracket), new OperandDefinition( name: "NUMBER", regex: @"\d*\.?\d+?", expressionBuilder: x => Expression.Constant(decimal.Parse(x))), new GrammerDefinition(name: "WHITESPACE", regex: @"\s+", ignore: true) ); var expression = language.Parse <decimal>("(1 + 2) * (3 + 5)"); Assert.Equal(24, expression.Compile()()); }
public ParserErrorTests() { BracketOpenDefinition openBracket, logFn, errorFn; GrammerDefinition listDelimeter; Language = new Language( new OperatorDefinition( name: "PLUS", regex: @"\+", orderOfPrecedence: 1, paramaterPositions: new[] { RelativePosition.Left, RelativePosition.Right }, expressionBuilder: args => Expression.Add(args[0], args[1])), new OperatorDefinition( name: "MULTIPLY", regex: @"\*", orderOfPrecedence: 1, paramaterPositions: new[] { RelativePosition.Left, RelativePosition.Right }, expressionBuilder: args => Expression.Multiply(args[0], args[1])), logFn = new FunctionCallDefinition( name: "LOG", regex: @"[Ll]og\(", argumentTypes: new[] { typeof(double), typeof(double) }, expressionBuilder: args => Expression.Call(Type <int> .Method(x => Math.Log(0, 0)), args)), errorFn = new FunctionCallDefinition( name: "ERROR", regex: @"error\(", argumentTypes: new[] { typeof(double), typeof(double) }, expressionBuilder: args => { throw new NotImplementedException("I am a function error"); }), openBracket = new BracketOpenDefinition( name: "OPENBRACKET", regex: @"\("), listDelimeter = new ListDelimiterDefinition( name: "COMMA", regex: @"\,"), new BracketCloseDefinition( name: "CLOSEBRACKET", regex: @"\)", bracketOpenDefinitions: new[] { openBracket, logFn, errorFn }, listDelimeterDefinition: listDelimeter), new OperandDefinition( name: "NUMBER", regex: @"\d*\.?\d+?", expressionBuilder: x => Expression.Constant(decimal.Parse(x))), new OperandDefinition( name: "POOP", regex: @"💩", expressionBuilder: x => { throw new NotImplementedException("I am an operand error"); }), new OperandDefinition( name: "STRING", regex: @"'.*?'", expressionBuilder: x => Expression.Constant(x)), new GrammerDefinition(name: "WHITESPACE", regex: @"\s+", ignore: true) ); }
/// <summary> /// Returns the definitions for brackets used within the language. /// </summary> /// <param name="functionCalls">The function calls in the language. (used as opening brackets)</param> /// <returns></returns> protected virtual IEnumerable <GrammerDefinition> BracketDefinitions(IEnumerable <FunctionCallDefinition> functionCalls) { BracketOpenDefinition openBracket; ListDelimiterDefinition delimeter; return(new GrammerDefinition[] { openBracket = new BracketOpenDefinition( name: "OPEN_BRACKET", regex: @"\("), delimeter = new ListDelimiterDefinition( name: "COMMA", regex: ","), new BracketCloseDefinition( name: "CLOSE_BRACKET", regex: @"\)", bracketOpenDefinitions: new[] { openBracket }.Concat(functionCalls), listDelimeterDefinition: delimeter) }); }
public void Should_run_two_param_functions() { BracketOpenDefinition openBracket, logFn; GrammerDefinition listDelimeter; var language = new Language( new OperatorDefinition( name: "PLUS", regex: @"\+", orderOfPrecedence: 1, paramaterPositions: new[] { RelativePosition.Left, RelativePosition.Right }, expressionBuilder: args => Expression.Add(args[0], args[1])), logFn = new FunctionCallDefinition( name: "LOG", regex: @"[Ll]og\(", expressionBuilder: args => Expression.Call(Type <int> .Method(x => Math.Log(0, 0)), args)), openBracket = new BracketOpenDefinition( name: "OPENBRACKET", regex: @"\("), listDelimeter = new ListDelimiterDefinition( name: "COMMA", regex: @"\,"), new BracketCloseDefinition( name: "CLOSEBRACKET", regex: @"\)", bracketOpenDefinitions: new[] { openBracket, logFn }, listDelimeterDefinition: listDelimeter), new OperandDefinition( name: "NUMBER", regex: @"\d*\.?\d+?", expressionBuilder: x => Expression.Constant(double.Parse(x))), new GrammerDefinition(name: "WHITESPACE", regex: @"\s+", ignore: true) ); var expression = language.Parse <double>("Log(1024,2) + 5"); Assert.Equal(15, expression.Compile()()); }