evaluateGetElem method
Implementation
EvaluateExprOutput evaluateGetElem(EvaluateExprInput input) {
final path = input.path;
final get = evaluateExpr(EvaluateExprInput(
path: pathAppendKey(path, "get"),
defs: input.defs,
expr: input.expr.obj["get"]));
if (get.status != EvaluateExprOutput_Status.OK) {
return get;
}
final from = evaluateExpr(EvaluateExprInput(
path: pathAppendKey(path, "from"),
defs: input.defs,
expr: input.expr.obj["from"]));
if (from.status != EvaluateExprOutput_Status.OK) {
return from;
}
switch (from.value.type) {
case Type.TYPE_STR:
if (get.value.type != Type.TYPE_NUM) {
return _errorUnexpectedType(
pathAppendKey(path, "get"), [Type.TYPE_NUM], get.value.type);
}
if (!valueCanInt(get.value)) {
return _errorArithmeticError(pathAppendKey(path, "get"),
"index ${get.value.num} is not an integer");
}
final pos = get.value.num.toInt();
final fromChars = from.value.str.characters;
if (pos < 0 || pos >= fromChars.length) {
return _errorIndexOutOfBounds(
pathAppendKey(path, "get"), 0, fromChars.length, pos);
}
return EvaluateExprOutput(
value: Value(
type: Type.TYPE_STR,
str: fromChars.characterAt(pos).toString()));
case Type.TYPE_ARR:
if (get.value.type != Type.TYPE_NUM) {
return _errorUnexpectedType(
pathAppendKey(path, "get"), [Type.TYPE_NUM], get.value.type);
}
if (!valueCanInt(get.value)) {
return _errorArithmeticError(pathAppendKey(path, "get"),
"index ${get.value.num} is not an integer");
}
final pos = get.value.num.toInt();
if (pos < 0 || pos >= from.value.arr.length) {
return _errorIndexOutOfBounds(
pathAppendKey(path, "get"), 0, from.value.arr.length, pos);
}
return EvaluateExprOutput(value: from.value.arr[pos]);
case Type.TYPE_OBJ:
if (get.value.type != Type.TYPE_STR) {
return _errorUnexpectedType(
pathAppendKey(path, "get"), [Type.TYPE_STR], get.value.type);
}
final pos = get.value.str;
final val = from.value.obj[pos];
if (val == null) {
return _errorKeyNotFound(
pathAppendKey(path, "get"), from.value.obj.keys.toList(), pos);
}
return EvaluateExprOutput(value: from.value.obj[pos]);
default:
return _errorUnexpectedType(pathAppendKey(path, "from"),
[Type.TYPE_STR, Type.TYPE_ARR, Type.TYPE_OBJ], from.value.type);
}
}