Giter Site home page Giter Site logo

expressions's People

Contributors

apgapg avatar dsyrstad avatar rbellens avatar shyndman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

expressions's Issues

Power function

The power function "^" doesn't return the correct answer.

Also, this is what I get when using a double.
Class 'double' has no instance method '^'

How do I use the power function?

Set in context

i need help please
how implement set "=" in Map context

carriage return in expression ?

it looks like having a carriage return in an expression does not work, has there been any consideration around an option to allow carriage returns ? this is mainly to allow a more complicated expression to be formatted ... so not crazy important ... but hey we software types tend to like formatting :)

Handle assignment expressions

I was trying a simple expression as follows but it keeps throwing errors -
`
void example_2() {
// Parse expression:
var expression = Expression.parse("person.name='John'");
var context = {'person': Person('Jane')};
final evaluator = const MyEvaluator();
var r = evaluator.eval(expression, context);
}

class Person {
String name;
Person(this.name);
Map<String, dynamic> toJson() => {'name': name};
}

class MyEvaluator extends ExpressionEvaluator {
const MyEvaluator();
@OverRide
dynamic evalMemberExpression(
MemberExpression expression, Map<String, dynamic> context) {
var object = eval(expression.object, context).toJson();
return object[expression.property.name];
}
}
The exception I get is as follows - Unhandled exception:
end of input expected at 1:12
#0 Failure.value (package:petitparser/src/context/failure.dart:13:18)
#1 Expression.parse (package:expressions/src/expressions.dart:32:55)
#2 example_2 (file:///Users/khurrammahmood/StudioProjects/expressions/example/expressions_example.dart:29:31)
#3 main (file:///Users/khurrammahmood/StudioProjects/expressions/example/expressions_example.dart:6:3)
#4 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:283:19)
#5 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

`

What if I want to use a special match expression

I'm glad to provide this plug-in, but when I use this plug-in, my expression may contain some special characters and chinese, such as the '$测试'. Does this plug-in support of this writing method?

This is the code I wrote

 Expression expression = Expression.parse('\$测试');

  var context = {
    '\$测试': 1,
  };
  
  final evaluator = const ExpressionEvaluator();
  var r = evaluator.eval(expression, context);
  print(r);


But I got such a mistake

E/flutter ( 4910): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: end of input expected at 1:2
E/flutter ( 4910): #0      Failure.value (package:petitparser/src/context/failure.dart:15:18)
E/flutter ( 4910): #1      Expression.parse (package:expressions/src/expressions.dart:33:55)
E/flutter ( 4910): #2      main (package:test_demo/test_function.dart:25:38)
E/flutter ( 4910): #3      _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:231:25)
E/flutter ( 4910): #4      _rootRun (dart:async/zone.dart:1190:13)
E/flutter ( 4910): #5      _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter ( 4910): #6      _runZoned (dart:async/zone.dart:1630:10)
E/flutter ( 4910): #7      runZonedGuarded (dart:async/zone.dart:1618:12)
E/flutter ( 4910): #8      _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:223:5)
E/flutter ( 4910): #9      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter ( 4910): #10     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter ( 4910): 

So how do I call it? If I don't support this way of writing, I think I will consider using English

type 'Null' is not a subtype of type 'Function'

var callee = eval(expression.callee, context);

add a null check here.

if value of callee evaluates to null then it throws an exception stating type 'Null' is not a subtype of type 'Function'

as of now i've handled it in our project by explicitly checking callee value in this way


final callee = eval(expression.callee, context);
    if (callee == null) {
      return;
    }
    return evalCallExpression(expression, context);

Update pubspec.yaml "petitparser" to 3.0.0

Hello.
Thanks for your amazing package!
I've got an issue when using your package together with any package that requires xml 3.7.0 . For example, any of aws sdk packages .
To reproduce it, add in pubspec.yaml following dependencies:

dependencies:
  expressions: ^0.1.2
  aws_sns_api: ^0.0.2

and try to run flutter pub get. You will get an error:

Because every version of aws_sns_api depends on shared_aws_api ^0.1.0 which depends on xml ^3.7.0, every version of aws_sns_api requires xml ^3.7.0.
And because xml >=3.7.0 depends on petitparser ^3.0.0, every version of aws_sns_api requires petitparser ^3.0.0.


And because expressions 0.1.2 depends on petitparser ^2.0.0 and no versions of expressions match >0.1.2 <0.2.0, aws_sns_api is incompatible with expressions ^0.1.2.

Simplified depencency tree:
| _ shared_aws_api ^0.1.0
| ___xml ^3.7.0
| _____petitparser ^3.0.0

| _expressions ^0.1.2
| ___petitparser ^2.0.0

2.0.0 not match with 3.0.0

Parsing RegEx as a variable in an Expression.

I'm looking to parse out a string containing regex to an expression:

Expression expression = Expression.parse(s);

This fails with end of input expected if the RegEx contains \ or ' and there seems to be no way to escape these characters.

Change precedence of Operations

Hi,

I have overwritten the binary operator ^ to be the power function. (I want it to be a BinaryOperator and not just a simple function like pow(2, 4)) This works great, but it still has the low precedence of the XOR operator. To fix this I was thinking to overwrite the ExpressionParser but this feels hacky and wrong since this is not part of the public library.
Is there a better way of going about this?

Use of async evaluator

Hi, I see you are using Stream approach to support async.
My take towards async was to extend every method with async and put await just. before eval statement everywhere.

See below:

import 'package:expressions/expressions.dart';

class AsyncExpressionEvaluator {
  const AsyncExpressionEvaluator();

  dynamic eval(Expression expression, Map<String, dynamic> context) async {
    if (expression == null) {
      throw ArgumentError.notNull('expression');
    }
    if (expression is Literal) {
      return await evalLiteral(expression, context);
    }
    if (expression is Variable) {
      return await evalVariable(expression, context);
    }
    if (expression is ThisExpression) {
      return await evalThis(expression, context);
    }
    if (expression is MemberExpression) {
      return await evalMemberExpression(expression, context);
    }
    if (expression is IndexExpression) {
      return await evalIndexExpression(expression, context);
    }
    if (expression is CallExpression) {
      return await evalCallExpression(expression, context);
    }
    if (expression is UnaryExpression) {
      return await evalUnaryExpression(expression, context);
    }
    if (expression is BinaryExpression) {
      return await evalBinaryExpression(expression, context);
    }
    if (expression is ConditionalExpression) {
      return await evalConditionalExpression(expression, context);
    }
    throw ArgumentError("Unknown expression type '${expression.runtimeType}'");
  }

  dynamic evalLiteral(
    Literal literal,
    Map<String, dynamic> context,
  ) async {
    var value = literal.value;
    if (value is List) {
      return await Future.wait(
          value.map((e) async => await eval(e, context)).toList());
    }
    if (value is Map) {
      return value.map((key, value) {
        final mKey = eval(key, context);
        final mValue = eval(value, context);
        return MapEntry(mKey, mValue);
      });
    }
    return value;
  }

  dynamic evalVariable(Variable variable, Map<String, dynamic> context) {
    return context[variable.identifier.name];
  }

  dynamic evalThis(ThisExpression expression, Map<String, dynamic> context) {
    return context['this'];
  }

  dynamic evalMemberExpression(
      MemberExpression expression, Map<String, dynamic> context) {
    throw UnsupportedError('Member expressions not supported');
  }

  dynamic evalIndexExpression(
      IndexExpression expression, Map<String, dynamic> context) async {
    return (await eval(
      expression.object,
      context,
    ))[await eval(
      expression.index,
      context,
    )];
  }

  dynamic evalCallExpression(
      CallExpression expression, Map<String, dynamic> context) async {
    var callee = await eval(expression.callee, context);
    final arguments = [];
    for (final e in expression.arguments) {
      arguments.add(await eval(e, context));
    }
    return await Function.apply(callee, arguments);
  }

  dynamic evalUnaryExpression(
      UnaryExpression expression, Map<String, dynamic> context) async {
    var argument = await eval(expression.argument, context);
    switch (expression.operator) {
      case '-':
        return -argument;
      case '+':
        return argument;
      case '!':
        return !argument;
      case '~':
        return ~argument;
    }
    throw ArgumentError('Unknown unary operator ${expression.operator}');
  }

  dynamic evalBinaryExpression(
      BinaryExpression expression, Map<String, dynamic> context) async {
    var left = await eval(expression.left, context);
    var right = await eval(expression.right, context);
    switch (expression.operator) {
      case '||':
        return left || await right;
      case '&&':
        return left && right;
      case '|':
        return left | right;
      case '^':
        return left ^ right;
      case '&':
        return left & right;
      case '==':
        return left == right;
      case '!=':
        return left != right;
      case '<=':
        return left <= right;
      case '>=':
        return left >= right;
      case '<':
        return left < right;
      case '>':
        return left > right;
      case '<<':
        return left << right;
      case '>>':
        return left >> right;
      case '+':
        return left + right;
      case '-':
        return left - right;
      case '*':
        return left * right;
      case '/':
        return left / right;
      case '%':
        return left % right;
    }
    throw ArgumentError(
        'Unknown operator ${expression.operator} in expression');
  }

  dynamic evalConditionalExpression(
      ConditionalExpression expression, Map<String, dynamic> context) async {
    final test = await eval(expression.test, context);
    return test
        ? await eval(expression.consequent, context)
        : await eval(expression.alternate, context);
  }
}

min/max function support

Hi,

I have expressions that look like min(MAIN_rPowerBattery, 0) * (-1), with a context of {MAIN_rPowerBattery: 0.86}, but I always get the following error:

flutter: ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: │ type 'Null' is not a subtype of type 'Function'
flutter: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
flutter: │ #0   ExpressionEvaluator.evalCallExpression (package:expressions/src/evaluator.dart:120:27)
flutter: │ #1   ExpressionEvaluator.eval (package:expressions/src/evaluator.dart:66:14)
flutter: │ #2   ExpressionEvaluator.evalBinaryExpression (package:expressions/src/evaluator.dart:143:16)
flutter: │ #3   ExpressionEvaluator.eval (package:expressions/src/evaluator.dart:72:14)
flutter: │ #4   _calculate (package:app/ui/charts/chart_math.dart:91:31)
flutter: │ #5   calculateResult.<anonymous closure> (package:app/ui/charts/chart_math.dart:53:28)
flutter: │ #6   ListExtensions.mapIndexed (package:collection/src/list_extensions.dart:144:20)
flutter: │ #7   _SyncStarIterator.moveNext (dart:async-patch/async_patch.dart:710:21)

It seems that it somehow expects a function mapping for min, or something similar. I suppose that expressions doesn't support the min/max function?

Is there a way to make min/max functions inside expressions work?

showing exponential number instead full number. please show full number.

Read the below code and understand for large number calculation of multiplications.

// Multiplies str1 and str2, and prints result.
multiply(num1, num2) {
var len1 = num1.length;
var len2 = num2.length;
if (len1 == 0 || len2 == 0) {
return "0";
}

// will keep the result number in vector
// in reverse order
var result = List.filled(len1 + len2, 0);

// Below two indexes are used to
// find positions in result.
var i_n1 = 0;
var i_n2 = 0;

// Go from right to left in num1
for (var i = len1 - 1; i > -1; i--) {
var carry = 0;
final n1 = (num1[i]).codeUnits[0] - 48;

// To shift position to left after every
// multiplication of a digit in num2
i_n2 = 0;

// Go from right to left in num2
for (var j = len2 - 1; j > -1; j--) {
  // Take current digit of second number
  final n2 = (num2[j]).codeUnits[0] - 48;

  // Multiply with current digit of first number
  // and add result to previously stored result
  // at current position.
  final summ = n1 * n2 + result[i_n1 + i_n2] + carry;

  // Carry for next iteration
  carry = (summ / 10).floor();

  // Store result
  result[i_n1 + i_n2] = summ % 10;

  i_n2 += 1;
}

// store carry in next cell
if (carry > 0) {
  result[i_n1 + i_n2] += carry;
}
// To shift position to left after every
// multiplication of a digit in num1.
i_n1 += 1;

// print(result)

}
// ignore '0's from the right
var i = result.length - 1;
while (i >= 0 && result[i] == 0) {
i -= 1;
}

// If all were '0's - means either both or
// one of num1 or num2 were '0'
if (i == -1) {
return "0";
}

// generate the result string
var s = "";
while (i >= 0) {
s += String.fromCharCode(result[i] + 48);
i -= 1;
}

return s;
}

void main() {
// Driver code
var str1 = "1235421415454545454545454544";
var str2 = "1714546546546545454544548544544545";

if ((str1[0] == '-' || str2[0] == '-') &&
(str1[0] != '-' || str2[0] != '-')) {
print("-");
}

if (str1[0] == '-' && str2[0] != '-') {
str1.substring(1);
} else if (str1[0] != '-' && str2[0] == '-') {
str2.substring(1);
} else if (str1[0] == '-' && str2[0] == '-') {
str1.substring(1);
str2.substring(1);
}
print(multiply(str1, str2));
}

Unable to parse expression in Flutter

Code:
Expression expression = Expression.parse("V1>50");

This code works fine in dart programs, but when I use it in Flutter, an exception occurs

Launching lib\main.dart on Android SDK built for x86 in debug mode...
Built build\app\outputs\apk\debug\app-debug.apk (31.1MB).
I/FlutterActivityDelegate( 3743): onResume setting current activity to this
E/flutter ( 3743): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter ( 3743): 'package:expressions/src/parser.dart': error: line 12 pos 23: file:///C:/Users/lenovo/AppData/Roaming/Pub/Cache/hosted/pub.flutter-io.cn/expressions-0.1.0/lib/src/parser.dart:12:23: Error: A value of type 'typedparser::Parserexpressions.core::UnaryExpression' can't be assigned to a variable of type 'typedparser::Parserexpressions.core::Literal'.
E/flutter ( 3743): Try changing the type of the left hand side, or casting the right hand side to 'typedparser::Parserexpressions.core::Literal'.
E/flutter ( 3743): token.set(literal|unaryExpression|variable); // ignore: argument_type_not_assignable
E/flutter ( 3743): ^
E/flutter ( 3743): token.set(literal|unaryExpression|variable); // ignore: argument_type_not_assignable
E/flutter ( 3743): ^
E/flutter ( 3743):
E/flutter ( 3743): #0 Expression._parser (package:expressions/src/expressions.dart:27:47)
E/flutter ( 3743): #1 Expression._parser (package:expressions/src/expressions.dart:27:33)
E/flutter ( 3743): #2 Expression.parse (package:expressions/src/expressions.dart:30:16)
E/flutter ( 3743): #3 main (file:///E:/MyWork/livebuilding/lib/main.dart:14:38)
E/flutter ( 3743): #4 _startIsolate. (dart:isolate/runtime/libisolate_patch.dart:279:19)
E/flutter ( 3743): #5 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:165:12)

image

test environment

image

Parse string methods.

Is there any way to parse string methods?

Everytime i try to use string methods that do not come from variables I get:

"Unhandled exception:
end of input expected at x:y"

Thanks for the excelent package.
Daniel

Concat function

I have an expression something like this.

var context = <String, dynamic>{
    a: '10',
    b: 'apples'
};

String expression = "(a=='10' ? 'ten' : 'other').concat('_').concat(b)";  // Expected output: 'ten_apples'

Is there any example how to do this?

Thanks for the awesome package!

Handle empty and contains

HI,

I need to handle expressions with empty, notempty, contains and notcontains.

How can I do this?

Escaping apostrophe in String

Hi,

I am trying to escape apostrophe in String but without success.
I tried preceding it with backlash or doubling but it is not working.

example:
Expression.parse("json.name == 'A\'B'");
is causing failure: end of input expected at ...

is it possible to include apostrophe in String ?

Call a method from object

I want to call a method from a self defined object. When I try to call the method, I got the following exception:
ExpressionEvaluatorException (ExpressionEvaluatorException: Access of member doMyMethod not supported for objects of type MyObject: have you defined a member accessor in the ExpressionEvaluator?)

Is it somehow possible or is it overall not supported?

Wrong answer

This library is great, but shows wrong answer when for this expression. "-4+4" should be 0 instead it shows 8.

Leading and trailing spaces throw errors with Expression.parse

Firstly, we love this package. It's been great for our app!

Issue is simple, if the expression has leading or trailing spaces, the parser throws an error:

import 'package:expressions/expressions.dart';
void main() {
  // Throws
  Expression.parse("myVar == false ");
  // Throws
  Expression.parse(" myVar == false ");
}

We simply run trim on our expressions before parsing, but thought it worth creating an issue.

Add Exponent operator

The exponent operator is very commonly used in geometry and algebra. At the moment one could add the function pow to the context when the expression is evaluated, however that makes the expression less readable.

I noticed that Dart itself doesn't support the ** operator like most languages, but i'd suggest using it in this case.

? in expression

Hello,

I asked a question about using methods in strings in the parser, and I was told to overwrite evalCallExpressions.

Now I am trying to evalutate methods with '?' in the end, and am having trouble to parse.
Another question is about ternary operators. Do you see any way to parse them?

Thanks for the help!
Daniel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.