fxAssignment function
Run assignment expression and return the right side value.
expression: Assignment expression,eg: $a.b$=1+2+3
.
envValues: Environment values set. If the expression contains a variable $a.b$
. Then
you should give a values set like {"a": {"b": something}}
.
leftEnvs: Used for jsfxAssignment
in jsfx.dart
.
Implementation
dynamic fxAssignment(String expression, Map envValues,
{void Function(List<String>)? leftEnvs}) {
if (expression.isEmpty) {
return null;
}
var program = _parseProgram(content: expression);
var visitor = AstRuntimeVisitor();
var ast = program.accept(visitor);
var executor = DefaultAstRuntimeExecutor(onGetEnvValue: (envVar) {
if (envVar.startsWith('\$') && envVar.endsWith('\$')) {
var varStr = envVar.substring(1, envVar.length - 1);
return _parseEnvValue(varStr, envValues);
} else {
warn(tag: _tag, message: "Unkown environment variable: $envVar");
return null;
}
});
var runtimeNode = runtime.Program.fromAst(ast)!.body!;
if (runtimeNode is! runtime.AssignmentExpression ||
(runtimeNode.operator != '=' &&
runtimeNode.operator != '+=' &&
runtimeNode.operator != '-=' &&
runtimeNode.operator != '*=' &&
runtimeNode.operator != '/=' &&
runtimeNode.operator != '~/=' &&
runtimeNode.operator != '%=' &&
runtimeNode.operator != '&=' &&
runtimeNode.operator != '|=' &&
runtimeNode.operator != '^=' &&
runtimeNode.operator != '>>=' &&
runtimeNode.operator != '<<=')) {
error(tag: _tag, message: 'Unsupport assignment expression: $expression');
return null;
}
if (runtimeNode.left is! runtime.StringLiteral ||
!executor
.isEnvString((runtimeNode.left as runtime.StringLiteral).value)) {
warn(tag: _tag, message: 'Assignment left is not env variable');
return null;
}
var astContext = AstContext();
dynamic rightValue = executor.execute(astContext, runtimeNode.right);
var leftEnvVar = (runtimeNode.left as runtime.StringLiteral).value as String;
if (leftEnvVar.startsWith('\$') && leftEnvVar.endsWith('\$')) {
leftEnvVar = leftEnvVar.substring(1, leftEnvVar.length - 1);
} else {
warn(tag: _tag, message: 'Assignment left is not env variable');
return null;
}
var leftValue = _parseEnvValue(leftEnvVar, envValues);
var fields = leftEnvVar.split(".");
leftEnvs?.call(fields);
dynamic value = envValues;
for (var i = 0; i < fields.length - 1; i++) {
value = value[fields[i]];
}
if (rightValue != null) {
if (leftValue != null) {
switch (runtimeNode.operator) {
case '+=':
rightValue = leftValue + rightValue;
break;
case '-=':
rightValue = leftValue - rightValue;
break;
case '*=':
rightValue = leftValue * rightValue;
break;
case '%=':
rightValue = leftValue % rightValue;
break;
case '&=':
rightValue = leftValue & rightValue;
break;
case '|=':
rightValue = leftValue | rightValue;
break;
case '^=':
rightValue = leftValue ^ rightValue;
break;
case '>>=':
rightValue = leftValue >> rightValue;
break;
case '<<=':
rightValue = leftValue << rightValue;
break;
}
} else {
warn(tag: _tag, message: 'Assignment right side is null');
}
value[fields.last] = rightValue;
} else {
warn(tag: _tag, message: 'Assignment right side is null');
}
return rightValue;
}