From 0a087cd28bbee5fcdffbb9d49b0ba9f413ad7f92 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 24 Jan 2020 16:23:57 +0100 Subject: =?UTF-8?q?Reorganize=20modules=20=F0=9F=A7=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/syntax/scope.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/syntax/scope.rs (limited to 'src/syntax/scope.rs') diff --git a/src/syntax/scope.rs b/src/syntax/scope.rs new file mode 100644 index 00000000..2aae331d --- /dev/null +++ b/src/syntax/scope.rs @@ -0,0 +1,83 @@ +use std::collections::HashMap; +use std::fmt::{self, Debug, Formatter}; + +use crate::func::ParseFunc; +use super::func::FuncHeader; +use super::parsing::{ParseContext, Parsed}; +use super::span::Spanned; +use super::Model; + + +/// A map from identifiers to function parsers. +pub struct Scope { + parsers: HashMap>, + fallback: Box +} + +impl Scope { + /// Create a new empty scope with a fallback parser that is invoked when no + /// match is found. + pub fn new() -> Scope + where F: ParseFunc + Model + 'static { + Scope { + parsers: HashMap::new(), + fallback: parser::(()), + } + } + + /// Create a new scope with the standard functions contained. + pub fn with_std() -> Scope { + crate::library::std() + } + + /// Associate the given name with a type that is parseable into a function. + pub fn add(&mut self, name: &str) + where F: ParseFunc + Model + 'static { + self.add_with_meta::(name, ()); + } + + /// Add a parseable type with additional metadata that is given to the + /// parser (other than the default of `()`). + pub fn add_with_meta(&mut self, name: &str, metadata: ::Meta) + where F: ParseFunc + Model + 'static { + self.parsers.insert( + name.to_owned(), + parser::(metadata), + ); + } + + /// Return the parser with the given name if there is one. + pub fn get_parser(&self, name: &str) -> Result<&Parser, &Parser> { + self.parsers.get(name) + .map(|x| &**x) + .ok_or_else(|| &*self.fallback) + } + + /// Return the fallback parser. + pub fn get_fallback_parser(&self) -> &Parser { + &*self.fallback + } +} + +impl Debug for Scope { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "Scope ")?; + write!(f, "{:?}", self.parsers.keys()) + } +} + +/// A function which parses the source of a function into a model type which +/// implements [`Model`]. +type Parser = dyn Fn( + FuncHeader, + Option>, + ParseContext, +) -> Parsed>; + +fn parser(metadata: ::Meta) -> Box +where F: ParseFunc + Model + 'static { + Box::new(move |h, b, c| { + F::parse(h, b, c, metadata.clone()) + .map(|model| Box::new(model) as Box) + }) +} -- cgit v1.2.3