Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 39 additions & 46 deletions engine/src/scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,17 @@

let name = span(initial_input, input);

let field = scheme
.get(name)
.ok_or((LexErrorKind::UnknownIdentifier, name))?;
let field = if input.starts_with('(') {
scheme
.get_function(name)
.map(Identifier::Function)
.map_err(|_| (LexErrorKind::UnknownIdentifier, name))?
} else {
scheme
.get_field(name)
.map(Identifier::Field)
.map_err(|_| (LexErrorKind::UnknownIdentifier, name))?
};

Ok((field, input))
}
Expand Down Expand Up @@ -486,7 +494,7 @@
}

#[derive(Clone, Copy, Debug)]
enum SchemeItem {

Check warning on line 497 in engine/src/scheme.rs

View workflow job for this annotation

GitHub Actions / Test with -Zsanitizer=leak

enum `SchemeItem` is never used

Check warning on line 497 in engine/src/scheme.rs

View workflow job for this annotation

GitHub Actions / Test with -Zsanitizer=thread

enum `SchemeItem` is never used

Check failure on line 497 in engine/src/scheme.rs

View workflow job for this annotation

GitHub Actions / Test with miri

enum `SchemeItem` is never used

Check warning on line 497 in engine/src/scheme.rs

View workflow job for this annotation

GitHub Actions / Test with -Zsanitizer=address

enum `SchemeItem` is never used

Check failure on line 497 in engine/src/scheme.rs

View workflow job for this annotation

GitHub Actions / Documentation

enum `SchemeItem` is never used

Check failure on line 497 in engine/src/scheme.rs

View workflow job for this annotation

GitHub Actions / build

enum `SchemeItem` is never used
Field(usize),
Function(usize),
}
Expand Down Expand Up @@ -628,7 +636,8 @@
pub struct SchemeBuilder {
fields: Vec<FieldDefinition>,
functions: Vec<(IdentifierName, Box<dyn FunctionDefinition>)>,
items: HashMap<IdentifierName, SchemeItem, FnvBuildHasher>,
fields_map: HashMap<IdentifierName, usize, FnvBuildHasher>,
functions_map: HashMap<IdentifierName, usize, FnvBuildHasher>,

list_types: HashMap<Type, usize, FnvBuildHasher>,
lists: Vec<(Type, Box<dyn ListDefinition>)>,
Expand All @@ -648,23 +657,18 @@
ty: Type,
optional: bool,
) -> Result<(), IdentifierRedefinitionError> {
match self.items.entry(name) {
Entry::Occupied(entry) => match entry.get() {
SchemeItem::Field(_) => Err(IdentifierRedefinitionError::Field(
FieldRedefinitionError(entry.key().to_string()),
)),
SchemeItem::Function(_) => Err(IdentifierRedefinitionError::Function(
FunctionRedefinitionError(entry.key().to_string()),
)),
},
match self.fields_map.entry(name) {
Entry::Occupied(entry) => Err(IdentifierRedefinitionError::Field(
FieldRedefinitionError(entry.key().to_string()),
)),
Entry::Vacant(entry) => {
let index = self.fields.len();
self.fields.push(FieldDefinition {
name: entry.key().clone(),
ty,
optional,
});
entry.insert(SchemeItem::Field(index));
entry.insert(index);
Ok(())
}
}
Expand Down Expand Up @@ -694,20 +698,15 @@
name: N,
function: impl FunctionDefinition + 'static,
) -> Result<(), IdentifierRedefinitionError> {
match self.items.entry(name.as_ref().into()) {
Entry::Occupied(entry) => match entry.get() {
SchemeItem::Field(_) => Err(IdentifierRedefinitionError::Field(
FieldRedefinitionError(entry.key().to_string()),
)),
SchemeItem::Function(_) => Err(IdentifierRedefinitionError::Function(
FunctionRedefinitionError(entry.key().to_string()),
)),
},
match self.functions_map.entry(name.as_ref().into()) {
Entry::Occupied(entry) => Err(IdentifierRedefinitionError::Function(
FunctionRedefinitionError(entry.key().to_string()),
)),
Entry::Vacant(entry) => {
let index = self.functions.len();
self.functions
.push((entry.key().clone(), Box::new(function)));
entry.insert(SchemeItem::Function(index));
entry.insert(index);
Ok(())
}
}
Expand Down Expand Up @@ -851,26 +850,16 @@
}

impl<'s> Scheme {
/// Returns the [`identifier`](enum@Identifier) with the specified `name`.
pub(crate) fn get(&'s self, name: &str) -> Option<Identifier<'s>> {
self.inner.items.get(name).map(move |item| match *item {
SchemeItem::Field(index) => Identifier::Field(FieldRef {
scheme: self,
index,
}),
SchemeItem::Function(index) => Identifier::Function(FunctionRef {
scheme: self,
index,
}),
})
}

/// Returns the [`field`](struct@Field) with the specified `name`.
pub fn get_field(&'s self, name: &str) -> Result<FieldRef<'s>, UnknownFieldError> {
match self.get(name) {
Some(Identifier::Field(f)) => Ok(f),
_ => Err(UnknownFieldError),
}
self.inner
.fields_map
.get(name)
.map(move |item| FieldRef {
scheme: self,
index: *item,
})
.ok_or(UnknownFieldError)
}

/// Iterates over fields registered in the [`scheme`](struct@Scheme).
Expand All @@ -896,10 +885,14 @@

/// Returns the [`function`](struct@Function) with the specified `name`.
pub fn get_function(&'s self, name: &str) -> Result<FunctionRef<'s>, UnknownFunctionError> {
match self.get(name) {
Some(Identifier::Function(f)) => Ok(f),
_ => Err(UnknownFunctionError),
}
self.inner
.functions_map
.get(name)
.map(move |item| FunctionRef {
scheme: self,
index: *item,
})
.ok_or(UnknownFunctionError)
}

/// Iterates over functions registered in the [`scheme`](struct@Scheme).
Expand Down
Loading