summaryrefslogtreecommitdiff
path: root/src/prelude.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-08-16 22:14:27 +0200
committerLaurenz <laurmaedje@gmail.com>2020-08-16 22:39:21 +0200
commit30f16bbf6431ca0c174ca0a1abaa6a13ef50ab06 (patch)
treef5a5c0adad15840ebe24b39e77ff467862067c91 /src/prelude.rs
parent9f6137d8a829fe8f34554623495fa620252a0184 (diff)
Add Value type and replace dyn-nodes with call-exprs 🏗
- In addition to syntax trees there are now `Value`s, which syntax trees can be evaluated into (e.g. the tree is `5+5` and the value is `10`) - Parsing is completely pure, function calls are not parsed into nodes, but into simple call expressions, which are resolved later - Functions aren't dynamic nodes anymore, but simply functions which receive their arguments as a table and the layouting context - Functions may return any `Value` - Layouting is powered by functions which return the new `Commands` value, which informs the layouting engine what to do - When a function returns a non-`Commands` value, the layouter simply dumps the value into the document in monospace
Diffstat (limited to 'src/prelude.rs')
-rw-r--r--src/prelude.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/prelude.rs b/src/prelude.rs
new file mode 100644
index 00000000..214b00c8
--- /dev/null
+++ b/src/prelude.rs
@@ -0,0 +1,37 @@
+//! A prelude for building custom functions.
+
+pub use crate::compute::value::*;
+pub use crate::layout::prelude::*;
+pub use crate::layout::Commands;
+pub use crate::layout::Command::{self, *};
+pub use crate::style::*;
+pub use crate::syntax::parsing::parse;
+pub use crate::syntax::span::{Pos, Span, SpanVec, Spanned};
+pub use crate::syntax::tree::*;
+pub use crate::{Pass, Feedback};
+pub use super::*;
+
+/// Extra methods on `Option`s used for function argument parsing.
+pub trait OptionExt<T>: Sized {
+ /// Call `f` with `val` if this is `Some(val)`.
+ fn with(self, f: impl FnOnce(T));
+
+ /// Report an error about a missing argument with the given name and span if
+ /// the option is `None`.
+ fn or_missing(self, span: Span, arg: &str, f: &mut Feedback) -> Self;
+}
+
+impl<T> OptionExt<T> for Option<T> {
+ fn with(self, f: impl FnOnce(T)) {
+ if let Some(val) = self {
+ f(val);
+ }
+ }
+
+ fn or_missing(self, span: Span, arg: &str, f: &mut Feedback) -> Self {
+ if self.is_none() {
+ error!(@f, span, "missing argument: {}", arg);
+ }
+ self
+ }
+}