public string ToString(Gears context) { if (IsObjPtr) { if (context != null) { return(AsObject(context).ToString()); } return($"objPtr(@{AsObjPtr.ToString()})"); } else if (IsBool) { return(AsBool ? "true" : "false"); } else if (IsNil) { return("nil"); } else if (IsNumber) { return(_Value.ToString()); } else { throw new Exception("Unknown GearsValue type!"); } }
public bool TryGetField(Gears vm, object wrappedObject, ulong name, out GearsValue value) { if (_Fields.TryGetValue(name, out FieldInfo fieldInfo)) { if (IsNumeric(fieldInfo.FieldType)) { double fieldValue = Convert.ToDouble(fieldInfo.GetValue(wrappedObject)); value = new GearsValue(fieldValue); return(true); } else if (fieldInfo.FieldType == typeof(bool)) { bool fieldValue = Convert.ToBoolean(fieldInfo.GetValue(wrappedObject)); value = fieldValue ? GearsValue.TrueValue : GearsValue.FalseValue; return(true); } else if (fieldInfo.FieldType == typeof(string)) { if (!(fieldInfo.GetValue(wrappedObject) is string fieldValue)) { value = GearsValue.NilValue; } else { value = GearsValue.CreateObjPtr(vm.HeapAddObject(new GearsObjString(fieldValue))); } return(true); } else if (fieldInfo.FieldType.IsSubclassOf(typeof(object))) { if (!(fieldInfo.GetValue(wrappedObject) is object wrappedFieldObject)) { value = GearsValue.NilValue; } else { value = GearsValue.CreateObjPtr(vm.HeapAddObject(new GearsObjInstanceNative(vm, wrappedFieldObject))); } return(true); }
public void SetField(Gears context, object wrappedObject, ulong name, GearsValue value) { if (_Fields.TryGetValue(name, out FieldInfo fieldInfo)) { if (value.IsNumber) { if (!IsNumeric(fieldInfo.FieldType)) { throw new GearsRuntimeException($"Attempted to set {WrappedType.Name}.{fieldInfo.Name} to numeric value."); } try { fieldInfo.SetValue(wrappedObject, Convert.ChangeType((double)value, fieldInfo.FieldType)); return; } catch (Exception e) { throw new GearsRuntimeException($"Error setting {WrappedType.Name}.{fieldInfo.Name} to {(double)value}: {e.Message}"); } } else if (value.IsNil && fieldInfo.FieldType == typeof(string)) { fieldInfo.SetValue(wrappedObject, null); return; } else if (fieldInfo.FieldType == typeof(bool) && value.IsBool) { fieldInfo.SetValue(wrappedObject, value.IsTrue); return; } else if (value.IsObjPtr) { GearsObj obj = value.AsObject(context); if (fieldInfo.FieldType == typeof(string) && obj is GearsObjString objString) { fieldInfo.SetValue(wrappedObject, objString.Value); return; } } } else if (_Properties.TryGetValue(name, out PropertyInfo propertyInfo)) { if (!propertyInfo.GetSetMethod().IsPublic) { throw new GearsRuntimeException($"Unsupported reference: Native class {WrappedType.Name} does not have a public set method for '{BitString.GetBitStr(name)}'."); } if (value.IsNumber) { if (!IsNumeric(propertyInfo.PropertyType)) { throw new GearsRuntimeException($"Attempted to set {WrappedType.Name}.{propertyInfo.Name} to numeric value."); } try { propertyInfo.SetValue(wrappedObject, Convert.ChangeType((double)value, propertyInfo.PropertyType), null); return; } catch (Exception e) { throw new GearsRuntimeException($"Error setting {WrappedType.Name}.{propertyInfo.Name} to {(double)value}: {e.Message}"); } } else if (value.IsNil && propertyInfo.PropertyType == typeof(string)) { propertyInfo.SetValue(wrappedObject, null, null); return; } else if (propertyInfo.PropertyType == typeof(bool) && value.IsBool) { propertyInfo.SetValue(wrappedObject, value.IsTrue, null); return; } else if (value.IsObjPtr) { GearsObj obj = value.AsObject(context); if (propertyInfo.PropertyType == typeof(string) && obj is GearsObjString objString) { propertyInfo.SetValue(wrappedObject, objString.Value, null); return; } } } throw new GearsRuntimeException($"Unsupported native conversion: Error setting {WrappedType.Name}.{BitString.GetBitStr(name)} to {value}."); }
public GearsObj AsObject(Gears context) => context.HeapGetObject(AsObjPtr); // todo: fix with reference to context's heap...
public bool IsObjType <T>(Gears context) where T : GearsObj => IsObjPtr && AsObject(context) is T;