JTokenToRuntimeObject static method
Implementation
static RuntimeObject? JTokenToRuntimeObject(dynamic token) {
if (token is int || token is double || token is bool) {
return Value.create(token);
}
if (token is String) {
var str = token;
// String Value
var firstChar = str[0];
if (firstChar == '^') {
return StringValue(str.substring(1));
} else if (firstChar == '\n' && str.length == 1) {
return StringValue('\n');
}
// Glue
if (str == '<>') {
return Glue();
}
// Control commands (would looking up in a hash set be faster?)
for (var i = 0; i < controlCommandNames.length; ++i) {
var cmdName = controlCommandNames[i];
if (str == cmdName) {
return ControlCommand(CommandType.values[i]);
}
}
// Native functions
// "^" conflicts with the way to identify strings, so now
// we know it's not a string, we can convert back to the proper
// symbol for the operator.
if (str == 'L^') str = '^';
if (NativeFunctionCall.callExistsWithName(str)) {
return NativeFunctionCall.callWithName(str);
}
// Pop
if (str == '->->') {
return ControlCommand.PopTunnel();
} else if (str == '~ret') {
return ControlCommand.PopFunction();
}
// Void
if (str == 'void') {
return RuntimeVoid();
}
}
if (token is Map<String, dynamic>) {
var obj = token;
dynamic propValue;
// Divert target value to path
propValue = obj['^->'];
if (propValue != null) {
return DivertTargetValue(Path(propValue as String));
}
// VariablePointerValue
propValue = obj['^var'];
if (propValue != null) {
var varPtr = VariablePointerValue(obj['^var'] as String);
propValue = obj['ci'];
if (propValue != null) {
varPtr.contextIndex = propValue as int;
}
return varPtr;
}
// Divert
var isDivert = false;
var pushesToStack = false;
var divPushType = PushPopType.Function;
var external = false;
propValue = obj['->'];
if (propValue != null) {
isDivert = true;
} else {
propValue = obj['f()'];
if (propValue != null) {
isDivert = true;
pushesToStack = true;
divPushType = PushPopType.Function;
} else {
propValue = obj['->t->'];
if (propValue != null) {
isDivert = true;
pushesToStack = true;
divPushType = PushPopType.Tunnel;
} else {
propValue = obj['x()'];
if (propValue != null) {
isDivert = true;
external = true;
pushesToStack = false;
divPushType = PushPopType.Function;
}
}
}
}
if (isDivert) {
var divert = Divert();
divert.pushesToStack = pushesToStack;
divert.stackPushType = divPushType;
divert.isExternal = external;
var target = propValue.toString();
propValue = obj['var'];
if (propValue != null) {
divert.variableDivertName = target;
} else {
divert.targetPathString = target;
}
propValue = obj['c'];
divert.isConditional = obj['c'] ?? false;
if (external) {
propValue = obj['exArgs'];
if (propValue != null) {
divert.externalArgs = obj['exArgs'] as int;
}
}
return divert;
}
// Choice
propValue = obj['*'];
if (propValue != null) {
var choice = ChoicePoint();
choice.pathStringOnChoice = propValue.toString();
propValue = obj['flg'];
if (propValue != null) {
choice.flags = obj['flg'] as int;
}
return choice;
}
// Variable reference
propValue = obj['VAR?'];
if (propValue != null) {
return VariableReference(propValue.toString());
} else {
propValue = obj['CNT?'];
if (propValue != null) {
var readCountVarRef = VariableReference();
readCountVarRef.pathStringForCount = propValue.toString();
return readCountVarRef;
}
}
// Variable assignment
var isVarAss = false;
var isGlobalVar = false;
propValue = obj['VAR='];
if (propValue != null) {
isVarAss = true;
isGlobalVar = true;
} else {
propValue = obj['temp='];
if (propValue != null) {
isVarAss = true;
isGlobalVar = false;
}
}
if (isVarAss) {
var varName = propValue.toString();
propValue = obj['re'];
bool isNewDecl = propValue == null;
var varAss = VariableAssignment(varName, isNewDecl);
varAss.isGlobal = isGlobalVar;
return varAss;
}
// Legacy Tag with text
propValue = obj['#'];
if (propValue != null) {
return Tag(obj['#'].toString());
}
// List value
propValue = obj['list'];
// List value
if (propValue != null) {
var listContent = Map<String, dynamic>.from(propValue);
var rawList = InkList();
propValue = obj['origins'];
if (propValue != null) {
var namesAsObjs = List<String>.from(propValue);
rawList.setInitialOriginNames(namesAsObjs);
}
listContent.forEach((key, value) {
var item = InkListItem.fullName(key);
var val = value;
rawList[item] = val;
});
return ListValue(rawList);
}
// Used when serialising save state only
if (obj['originalChoicePath'] != null) {
return JObjectToChoice(obj);
}
}
// Array is always a Runtime.Container
if (token is List<dynamic>) {
return JArrayToContainer(token);
}
if (token == null) return null;
throw Exception('Failed to convert token to runtime object: $token');
}