diff --git a/sample/handle.pl.xml b/sample/handle.pl.xml
new file mode 100644
index 0000000..f1ce811
--- /dev/null
+++ b/sample/handle.pl.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/error.rs b/src/error.rs
index 78e0293..ba7d666 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -17,7 +17,7 @@ pub struct MissingAttribute(pub &'static str, pub &'static str);
impl fmt::Display for MissingAttribute {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "missing '{}' child in '{}' node", self.1, self.0)
+ write!(f, "missing '{}' attribute in '{}' node", self.1, self.0)
}
}
@@ -118,3 +118,14 @@ impl fmt::Display for UnknownVariable {
}
impl Error for UnknownVariable {}
+
+#[derive(Clone, Debug)]
+pub struct InaccessibleFile(pub String);
+
+impl fmt::Display for InaccessibleFile {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "unable to access file '{}'", self.0)
+ }
+}
+
+impl Error for InaccessibleFile {}
diff --git a/src/instruction.rs b/src/instruction.rs
index 745841e..43fe269 100644
--- a/src/instruction.rs
+++ b/src/instruction.rs
@@ -43,6 +43,7 @@ pub enum Instruction {
},
Each(String, Box, Vec),
While(Box, Vec),
+ Handle(Vec, Vec, String),
}
impl Instruction {
@@ -230,6 +231,19 @@ impl Instruction {
util::find_node(&node, "do").ok_or(MissingChild("while", "from"))?,
)?,
),
+ "handle" => Instruction::Handle(
+ Instruction::from_children(
+ util::find_node(&node, "try").ok_or(MissingChild("handle", "try"))?,
+ )?,
+ Instruction::from_children(
+ util::find_node(&node, "catch").ok_or(MissingChild("handle", "try"))?,
+ )?,
+ util::find_node(&node, "catch")
+ .ok_or(MissingChild("handle", "try"))?
+ .attribute("variable")
+ .ok_or(MissingAttribute("catch", "variable"))?
+ .to_string(),
+ ),
tag => Err(format!("unknown tag '{}'", tag))?,
})
}
@@ -698,6 +712,18 @@ impl Instruction {
}
None
}
+ Instruction::Handle(try_block, catch_block, variable) => {
+ for ins in try_block {
+ if let Err(e) = ins.run(ctx, globals) {
+ ctx.assign(variable.clone(), Value::String(e.to_string()));
+ for ins in catch_block {
+ ins.run(ctx, globals)?;
+ }
+ break;
+ }
+ }
+ None
+ }
}
} else {
None
diff --git a/src/stl.rs b/src/stl.rs
index 8396105..8dec93b 100644
--- a/src/stl.rs
+++ b/src/stl.rs
@@ -1,3 +1,5 @@
+use crate::error::InaccessibleFile;
+
use super::error::{BadArgumentCount, InvalidArgument};
use super::{Context, Value};
use std::cell::RefCell;
@@ -232,12 +234,12 @@ fn write_file(vals: Vec) -> Result