Skip to content

Commit

Permalink
loosen type restrictions for join block
Browse files Browse the repository at this point in the history
  • Loading branch information
dragazo committed Sep 22, 2023
1 parent e5eee59 commit d6bddb8
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Process<'gc, C, S> {
VariadicOp::StrCat => |_, _, values| {
let mut acc = String::new();
for item in values {
acc.push_str(item.to_string()?.as_ref());
core::fmt::write(&mut acc, format_args!("{item}")).unwrap();
}
Ok(Rc::new(acc).into())
},
Expand Down
74 changes: 45 additions & 29 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,42 +676,58 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> GetType for Value<'gc, C, S> {
}
}

#[derive(Clone, Copy)]
enum FormatStyle {
Debug, Display,
}
impl<C: CustomTypes<S>, S: System<C>> fmt::Debug for Value<'_, C, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn print<'gc, C: CustomTypes<S>, S: System<C>>(value: &Value<'gc, C, S>, cache: &mut BTreeSet<Identity<'gc, C, S>>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match value {
Value::Bool(x) => write!(f, "{x}"),
Value::Number(x) => write!(f, "{x}"),
Value::String(x) => write!(f, "{:?}", x.as_str()),
Value::Closure(x) => write!(f, "{:?}", &*x.borrow()),
Value::Entity(x) => write!(f, "{:?}", &*x.borrow()),
Value::Native(x) => write!(f, "{:?}", &**x),
Value::Image(x) => write!(f, "[Image {:?}]", Rc::as_ptr(x)),
Value::Audio(x) => write!(f, "[Audio {:?}]", Rc::as_ptr(x)),
Value::List(x) => {
let identity = value.identity();
if !cache.insert(identity) { return write!(f, "[...]") }

let x = x.borrow();
write!(f, "[")?;
for (i, val) in x.iter().enumerate() {
print(val, cache, f)?;
if i != x.len() - 1 { write!(f, ",")? }
}
write!(f, "]")?;

debug_assert!(cache.contains(&identity));
cache.remove(&identity);
Ok(())
format_value(self, f, FormatStyle::Debug)
}
}
impl<C: CustomTypes<S>, S: System<C>> fmt::Display for Value<'_, C, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
format_value(self, f, FormatStyle::Display)
}
}
fn format_value<C: CustomTypes<S>, S: System<C>>(value: &Value<'_, C, S>, f: &mut fmt::Formatter<'_>, style: FormatStyle) -> fmt::Result {
fn print<'gc, C: CustomTypes<S>, S: System<C>>(value: &Value<'gc, C, S>, f: &mut fmt::Formatter<'_>, style: FormatStyle, cache: &mut BTreeSet<Identity<'gc, C, S>>) -> fmt::Result {
match value {
Value::Bool(x) => write!(f, "{x}"),
Value::Number(x) => write!(f, "{x}"),
Value::String(x) => match style {
FormatStyle::Debug => write!(f, "{:?}", x.as_str()),
FormatStyle::Display => write!(f, "{}", x.as_str()),
}
Value::Closure(x) => write!(f, "{:?}", &*x.borrow()),
Value::Entity(x) => write!(f, "{:?}", &*x.borrow()),
Value::Native(x) => write!(f, "{:?}", &**x),
Value::Image(x) => write!(f, "[Image {:?}]", Rc::as_ptr(x)),
Value::Audio(x) => write!(f, "[Audio {:?}]", Rc::as_ptr(x)),
Value::List(x) => {
let identity = value.identity();
if !cache.insert(identity) { return write!(f, "[...]") }

let x = x.borrow();
write!(f, "[")?;
for (i, val) in x.iter().enumerate() {
print(val, f, style, cache)?;
if i != x.len() - 1 { write!(f, ",")? }
}
write!(f, "]")?;

debug_assert!(cache.contains(&identity));
cache.remove(&identity);
Ok(())
}
}
let mut cache = Default::default();
let res = print(self, &mut cache, f);
if res.is_ok() { debug_assert_eq!(cache.len(), 0); }
res
}
let mut cache = Default::default();
let res = print(value, f, style, &mut cache);
if res.is_ok() { debug_assert_eq!(cache.len(), 0); }
res
}

impl<'gc, C: CustomTypes<S>, S: System<C>> From<bool> for Value<'gc, C, S> { fn from(v: bool) -> Self { Value::Bool(v) } }
impl<'gc, C: CustomTypes<S>, S: System<C>> From<Number> for Value<'gc, C, S> { fn from(v: Number) -> Self { Value::Number(v) } }
impl<'gc, C: CustomTypes<S>, S: System<C>> From<Rc<String>> for Value<'gc, C, S> { fn from(v: Rc<String>) -> Self { Value::String(v) } }
Expand Down
1 change: 1 addition & 0 deletions src/test/blocks/explicit-to-string-cvt.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<blocks app="NetsBlox 1.33.3, http://netsblox.org" version="1.33.3"><block-definition collabId="item_0" s="main" type="reporter" category="custom"><header></header><code></code><translations></translations><inputs></inputs><script><block collabId="item_2" s="doDeclareVariables"><list><l>c</l></list></block><block collabId="item_5" s="doSetVar"><l>c</l><block collabId="item_4" s="reportNewList"><list></list></block></block><block collabId="item_10" s="doAddToList"><block collabId="item_12" s="reportJoinWords"><list><l>hello </l><l>world</l><l> 1</l></list></block><block collabId="item_11" var="c"/></block><block collabId="item_14" s="doAddToList"><block collabId="item_14_1" s="reportJoinWords"><list><l>hello </l><l>67</l><l> 2</l></list></block><block collabId="item_14_2" var="c"/></block><block collabId="item_17" s="doAddToList"><block collabId="item_17_1" s="reportJoinWords"><list><l>hello </l><block collabId="item_19" s="reportVariadicSum"><list><l>67</l><l>2</l></list></block><l> 3</l></list></block><block collabId="item_17_2" var="c"/></block><block collabId="item_23" s="doAddToList"><block collabId="item_23_1" s="reportJoinWords"><list><l>hello </l><block collabId="item_25" s="reportBoolean"><l><bool>true</bool></l></block><l> 4</l></list></block><block collabId="item_23_2" var="c"/></block><block collabId="item_27" s="doAddToList"><block collabId="item_27_1" s="reportJoinWords"><list><l>hello </l><block collabId="item_27_3" s="reportBoolean"><l><bool>false</bool></l></block><l> 5</l></list></block><block collabId="item_27_2" var="c"/></block><block collabId="item_30" s="doAddToList"><block collabId="item_30_1" s="reportJoinWords"><list><l>hello </l><block collabId="item_32" s="reportNewList"><list></list></block><l> 6</l></list></block><block collabId="item_30_2" var="c"/></block><block collabId="item_33" s="doAddToList"><block collabId="item_33_1" s="reportJoinWords"><list><l>hello </l><block collabId="item_33_3" s="reportNewList"><list><l>test</l></list></block><l> 7</l></list></block><block collabId="item_33_2" var="c"/></block><block collabId="item_35" s="doAddToList"><block collabId="item_35_1" s="reportJoinWords"><list><l>hello </l><block collabId="item_35_3" s="reportNewList"><list><l>test</l><l>more</l></list></block><l> 8</l></list></block><block collabId="item_35_2" var="c"/></block><block collabId="item_37" s="doAddToList"><block collabId="item_37_1" s="reportJoinWords"><list><l>hello </l><block collabId="item_39" s="reportNumbers"><l>1</l><l>4</l></block><l> 9</l></list></block><block collabId="item_37_2" var="c"/></block><block collabId="item_1" s="doReport"><block collabId="item_9" var="c"/></block></script></block-definition></blocks>
26 changes: 26 additions & 0 deletions src/test/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,32 @@ fn test_proc_list_json() {
});
}

#[test]
fn test_proc_explicit_to_string_cvt() {
let system = Rc::new(StdSystem::new_sync(BASE_URL.to_owned(), None, Config::default(), UtcOffset::UTC));
let (mut env, _) = get_running_proc(&format!(include_str!("templates/generic-static.xml"),
globals = "",
fields = "",
funcs = include_str!("blocks/explicit-to-string-cvt.xml"),
methods = "",
), Settings::default(), system);

run_till_term(&mut env, |mc, _, res| {
let expect = Value::from_json(mc, json!([
"hello world 1",
"hello 67 2",
"hello 69 3",
"hello true 4",
"hello false 5",
"hello [] 6",
"hello [test] 7",
"hello [test,more] 8",
"hello [1,2,3,4] 9",
])).unwrap();
assert_values_eq(&res.unwrap().0.unwrap(), &expect, 1e-5, "explicit tostr");
});
}

#[test]
fn test_proc_signed_zero() {
let system = Rc::new(StdSystem::new_sync(BASE_URL.to_owned(), None, Config::default(), UtcOffset::UTC));
Expand Down

0 comments on commit d6bddb8

Please sign in to comment.