Skip to content

Commit

Permalink
feat(runtime): support writable builtins
Browse files Browse the repository at this point in the history
  • Loading branch information
watcol committed Jul 26, 2022
1 parent 20a3354 commit 564c572
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 11 deletions.
29 changes: 18 additions & 11 deletions drake-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ use drake_types::ast::{
Expression, ExpressionKind, Literal, Pattern, PatternKind, Statement, StatementKind,
TableHeaderKind,
};
use drake_types::runtime::{Error, Kind, Snapshot, Table, Value};
use drake_types::runtime::{Builtin, Error, Kind, Snapshot, Table, Value};

#[derive(Clone, Debug, PartialEq)]
struct Environment<L> {
root: Table<L>,
builtin: Builtin,
current: Option<Current<L>>,
errors: Vec<Error<L>>,
}
Expand All @@ -22,6 +23,7 @@ impl<L> Default for Environment<L> {
fn default() -> Self {
Self {
root: Table::new(),
builtin: Builtin::default(),
current: None,
errors: Vec::new(),
}
Expand All @@ -30,9 +32,9 @@ impl<L> Default for Environment<L> {

impl<L: Clone> Environment<L> {
fn bind(&mut self, pattern: Pattern<L>, value: Value<L>) {
let (table, key) = match pattern.kind {
PatternKind::Key(key) => (
match self.current {
match pattern.kind {
PatternKind::Key(key) => {
let table = match self.current {
Some(ref mut cur) => match cur.value.as_mut_table() {
Some(table) => table,
None => {
Expand All @@ -41,9 +43,17 @@ impl<L: Clone> Environment<L> {
}
},
None => &mut self.root,
},
key,
),
};

if let Err(err) = table.insert(key, value) {
self.errors.push(err);
}
}
PatternKind::Builtin(key) => {
if let Err(err) = self.builtin.write(key, value) {
self.errors.push(err);
}
}
_ => {
self.errors.push(Error::NotSupported {
feature: "unknown pattern",
Expand All @@ -52,10 +62,6 @@ impl<L: Clone> Environment<L> {
return;
}
};

if let Err(err) = table.insert(key, value) {
self.errors.push(err);
}
}

fn header(
Expand Down Expand Up @@ -99,6 +105,7 @@ impl<L: Clone> Environment<L> {

Snapshot {
root: self.root,
builtin: self.builtin,
errors: self.errors,
}
}
Expand Down
47 changes: 47 additions & 0 deletions drake-types/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Types for runtimes
use crate::ast::{Key, KeyKind};
use alloc::string::String;
use alloc::vec;
use alloc::vec::Vec;
use core::ops::Range;
use hashbrown::HashMap;
Expand All @@ -9,6 +10,7 @@ use hashbrown::HashMap;
#[derive(Clone, Debug, PartialEq)]
pub struct Snapshot<L> {
pub root: Table<L>,
pub builtin: Builtin,
pub errors: Vec<Error<L>>,
}

Expand Down Expand Up @@ -71,6 +73,48 @@ pub struct Table<L> {
pub local: HashMap<String, Element<L>>,
}

#[derive(Clone, Debug, PartialEq, Default, Eq)]
pub struct Builtin {
output: Option<String>,
filetype: Option<String>,
}

impl Builtin {
pub fn write<L>(&mut self, key: Key<L>, value: Value<L>) -> Result<(), Error<L>> {
if key.kind != KeyKind::Normal {
return Err(Error::BuiltinNotFound { span: key.span });
}

match key.name.as_str() {
"output" => {
if let Value::String(s) = value {
self.output = Some(s);
Ok(())
} else {
Err(Error::KindMismatch {
expect: vec![Kind::String],
found: value.kind(),
span: key.span,
})
}
}
"filetype" => {
if let Value::String(s) = value {
self.filetype = Some(s);
Ok(())
} else {
Err(Error::KindMismatch {
expect: vec![Kind::String],
found: value.kind(),
span: key.span,
})
}
}
_ => Err(Error::BuiltinNotFound { span: key.span }),
}
}
}

impl<L> Default for Table<L> {
#[inline]
fn default() -> Self {
Expand Down Expand Up @@ -152,6 +196,9 @@ pub enum Error<L> {
found: Kind,
span: Range<L>,
},
BuiltinNotFound {
span: Range<L>,
},
UnallowedDefaultValue {
span: Range<L>,
},
Expand Down

0 comments on commit 564c572

Please sign in to comment.