From 77dac270a8a99f24a6fc0eb9e92256bcc07c586c Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 19 Aug 2020 20:49:01 +0200 Subject: =?UTF-8?q?Make=20compute=20functions=20possible=20=F0=9F=92=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ships with the amazing new `rgb` function! --- src/compute/scope.rs | 9 +-------- src/compute/table.rs | 41 +++++++++++++++++++++++++++++++---------- src/compute/value.rs | 45 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 20 deletions(-) (limited to 'src/compute') diff --git a/src/compute/scope.rs b/src/compute/scope.rs index 1c297fde..3ab56561 100644 --- a/src/compute/scope.rs +++ b/src/compute/scope.rs @@ -8,16 +8,14 @@ use super::value::FuncValue; /// A map from identifiers to functions. pub struct Scope { functions: HashMap, - fallback: FuncValue, } impl Scope { // Create a new empty scope with a fallback function that is invoked when no // match is found. - pub fn new(fallback: FuncValue) -> Self { + pub fn new() -> Self { Self { functions: HashMap::new(), - fallback, } } @@ -30,11 +28,6 @@ impl Scope { pub fn func(&self, name: &str) -> Option<&FuncValue> { self.functions.get(name) } - - /// Return the fallback function. - pub fn fallback(&self) -> &FuncValue { - &self.fallback - } } impl Debug for Scope { diff --git a/src/compute/table.rs b/src/compute/table.rs index e8c4b307..bb71d4f2 100644 --- a/src/compute/table.rs +++ b/src/compute/table.rs @@ -115,6 +115,17 @@ impl Table { self.lowest_free += 1; } + /// Iterator over all borrowed keys and values. + pub fn iter(&self) -> impl Iterator { + self.nums().map(|(&k, v)| (BorrowedKey::Num(k), v)) + .chain(self.strs().map(|(k, v)| (BorrowedKey::Str(k), v))) + } + + /// Iterate over all values in the table. + pub fn values(&self) -> impl Iterator { + self.nums().map(|(_, v)| v).chain(self.strs().map(|(_, v)| v)) + } + /// Iterate over the number key-value pairs. pub fn nums(&self) -> std::collections::btree_map::Iter { self.nums.iter() @@ -125,9 +136,16 @@ impl Table { self.strs.iter() } - /// Iterate over all values in the table. - pub fn values(&self) -> impl Iterator { - self.nums().map(|(_, v)| v).chain(self.strs().map(|(_, v)| v)) + /// Move into an owned iterator over owned keys and values. + pub fn into_iter(self) -> impl Iterator { + self.nums.into_iter().map(|(k, v)| (OwnedKey::Num(k), v)) + .chain(self.strs.into_iter().map(|(k, v)| (OwnedKey::Str(k), v))) + } + + /// Move into an owned iterator over all values in the table. + pub fn into_values(self) -> impl Iterator { + self.nums.into_iter().map(|(_, v)| v) + .chain(self.strs.into_iter().map(|(_, v)| v)) } /// Iterate over the number key-value pairs. @@ -139,12 +157,6 @@ impl Table { pub fn into_strs(self) -> std::collections::btree_map::IntoIter { self.strs.into_iter() } - - /// Move into an owned iterator over all values in the table. - pub fn into_values(self) -> impl Iterator { - self.nums.into_iter().map(|(_, v)| v) - .chain(self.strs.into_iter().map(|(_, v)| v)) - } } impl<'a, K, V> Index for Table @@ -168,7 +180,7 @@ impl Eq for Table {} impl PartialEq for Table { fn eq(&self, other: &Self) -> bool { - self.nums().eq(other.nums()) && self.strs().eq(other.strs()) + self.iter().eq(other.iter()) } } @@ -218,6 +230,15 @@ pub enum OwnedKey { Str(String), } +impl From> for OwnedKey { + fn from(key: BorrowedKey<'_>) -> Self { + match key { + BorrowedKey::Num(num) => Self::Num(num), + BorrowedKey::Str(string) => Self::Str(string.to_string()), + } + } +} + impl From for OwnedKey { fn from(num: u64) -> Self { Self::Num(num) diff --git a/src/compute/value.rs b/src/compute/value.rs index 32f2778b..c11a3d31 100644 --- a/src/compute/value.rs +++ b/src/compute/value.rs @@ -7,11 +7,11 @@ use std::rc::Rc; use fontdock::{FontStyle, FontWeight, FontWidth}; use crate::color::RgbaColor; -use crate::layout::{Commands, Dir, LayoutContext, SpecAlign}; +use crate::layout::{Command, Commands, Dir, LayoutContext, SpecAlign}; use crate::length::{Length, ScaleLength}; use crate::paper::Paper; use crate::syntax::span::{Span, Spanned}; -use crate::syntax::tree::SyntaxTree; +use crate::syntax::tree::{SyntaxTree, SyntaxNode}; use crate::syntax::Ident; use crate::{DynFuture, Feedback, Pass}; use super::table::{SpannedEntry, Table}; @@ -61,6 +61,47 @@ impl Value { } } +impl Spanned { + /// Transform this value into something layoutable. + /// + /// If this is already a command-value, it is simply unwrapped, otherwise + /// the value is represented as layoutable content in a reasonable way. + pub fn into_commands(self) -> Commands { + match self.v { + Value::Commands(commands) => commands, + Value::Tree(tree) => vec![Command::LayoutSyntaxTree(tree)], + + // Forward to each entry, separated with spaces. + Value::Table(table) => { + let mut commands = vec![]; + let mut end = None; + for entry in table.into_values() { + if let Some(last_end) = end { + let span = Span::new(last_end, entry.key.start); + commands.push(Command::LayoutSyntaxTree(vec![ + Spanned::new(SyntaxNode::Spacing, span) + ])); + } + + end = Some(entry.val.span.end); + commands.extend(entry.val.into_commands()); + } + commands + } + + // Format with debug. + val => vec![ + Command::LayoutSyntaxTree(vec![ + Spanned::new( + SyntaxNode::Text(format!("{:?}", val)), + self.span, + ) + ]) + ], + } + } +} + impl Debug for Value { fn fmt(&self, f: &mut Formatter) -> fmt::Result { use Value::*; -- cgit v1.2.3