Skip to content

Commit a9efebb

Browse files
committed
Added parsing API
1 parent 9120b8d commit a9efebb

File tree

8 files changed

+122
-28
lines changed

8 files changed

+122
-28
lines changed

expression-js/src/context.rs

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
use std::iter;
12
use std::rc::Rc;
2-
use wasm_bindgen::{
3-
JsValue,
4-
UnwrapThrowExt,
5-
prelude::*
6-
};
3+
use wasm_bindgen::{JsValue, UnwrapThrowExt, prelude::*};
74
use wasm_bindgen::__rt::WasmRefCell;
85
use expression::error::*;
96
use expression::Object;
7+
use expression::Value;
8+
use expression::parse;
9+
use expression::parse::literal::Literal;
1010
use crate::DataSource;
1111

1212
#[wasm_bindgen(js_name=Context)]
@@ -104,7 +104,7 @@ pub(crate) fn value_to_js_object(value: Object) -> Option<JsValue> {
104104
JsValue::from(key_map)
105105
},
106106
Object::Nothing => JsValue::null(),
107-
Object::Function(function) => JsClosure::new(move |args| -> JsValue {
107+
Object::Function(function) => JsClosure::new(move |_args| -> JsValue {
108108
wasm_bindgen::throw_str("Fuck you");
109109
function(vec![])
110110
.map(value_to_js_object)
@@ -161,8 +161,8 @@ impl Context {
161161
unimplemented!("Use the `pushOperator` function instead");
162162
}
163163

164-
#[wasm_bindgen(js_name = evaluate)]
165-
pub fn evaluate(&self, expression: js_sys::JsString, cx: JsValue) -> JsValue {
164+
#[wasm_bindgen(js_name = evaluateStr)]
165+
pub fn evaluate_str(&self, expression: js_sys::JsString, cx: JsValue) -> JsValue {
166166
let Some(expr) = expression.as_string() else {
167167
wasm_bindgen::throw_str("Expression could not be cast to native string");
168168
};
@@ -192,6 +192,52 @@ impl Context {
192192
wasm_bindgen::throw_str("Unable to convert result back into JS");
193193
}
194194
}
195+
196+
#[wasm_bindgen(js_name="parseStr")]
197+
pub fn parse_str(&self, expr: String) -> Vec<Token> {
198+
fn flatten(token: &mut Value) -> Option<Vec<Token>> {
199+
match token {
200+
Value::Expression(parse::expression::Expression { operator, ref mut operands }) if operands.len() > 0 => {
201+
let (first, rest) = operands.split_first_mut()?;
202+
203+
Some(flatten(first)?
204+
.into_iter()
205+
.chain(iter::once(Token::new(operator.clone(), TokenType::Operator)))
206+
.chain(rest
207+
.into_iter()
208+
.filter_map(flatten)
209+
.flat_map(|i| i))
210+
.collect())
211+
},
212+
Value::Expression(parse::expression::Expression { operator, .. }) => Some(vec![Token::new(operator.clone(), TokenType::Operator)]),
213+
Value::Literal(lit) => Some(vec![match lit {
214+
Literal::Name(name) => Token::new(name.clone(), TokenType::Name),
215+
Literal::String(str) => Token::new(str.clone(), TokenType::String),
216+
Literal::Number(num) => Token::new(format!("{}", num), TokenType::Num),
217+
Literal::Address(addr) => Token::new(format!("{{{content}}}", content=addr.query), TokenType::Address),
218+
}]),
219+
Value::Call(parse::call::Call { name, arguments }) => {
220+
Some(flatten(name)?
221+
.into_iter()
222+
.chain(iter::once(Token::new("(".to_owned(), TokenType::LParen)))
223+
.chain(arguments
224+
.iter_mut()
225+
.filter_map(flatten)
226+
.flat_map(|i| i))
227+
.chain(iter::once(Token::new(")".to_owned(), TokenType::RParen)))
228+
.collect())
229+
},
230+
Value::Access(_) => Some(vec![]),
231+
Value::List(_) => Some(vec![]),
232+
Value::AssociativeArray(_) => Some(vec![])
233+
}
234+
}
235+
236+
flatten(&mut match self.cx.parse(&expr) {
237+
Ok(value) => value,
238+
Err(err) => wasm_bindgen::throw_str(&format!("{:#?}", err))
239+
}).unwrap_or(vec![])
240+
}
195241
}
196242

197243
#[wasm_bindgen]
@@ -205,4 +251,50 @@ impl JsClosure {
205251
closure: Closure::new(|| {})
206252
}
207253
}
254+
}
255+
256+
257+
#[wasm_bindgen]
258+
pub struct Token {
259+
#[wasm_bindgen(js_name="type")]
260+
pub token_type: TokenType,
261+
token: String,
262+
// #[wasm_bindgen(js_name="tokenOffset")]
263+
// pub token_start: usize,
264+
}
265+
266+
#[wasm_bindgen]
267+
impl Token {
268+
#[wasm_bindgen]
269+
pub fn token(&self) -> String {
270+
self.token.clone()
271+
}
272+
}
273+
274+
impl Token {
275+
pub fn new(token: impl AsRef<str>, r#type: TokenType) -> Self {
276+
Self {
277+
token_type: r#type,
278+
token: token.as_ref().to_owned(),
279+
}
280+
}
281+
}
282+
283+
#[derive(Clone, Copy)]
284+
#[wasm_bindgen]
285+
pub enum TokenType {
286+
Name,
287+
Operator,
288+
LParen,
289+
LBracket,
290+
LBrace,
291+
RParen,
292+
RBracket,
293+
RBrace,
294+
Dot,
295+
Comma,
296+
Num,
297+
String,
298+
Bool,
299+
Address
208300
}

expression-js/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ mod operator;
22
mod context;
33
mod datasource;
44

5+
use wasm_bindgen::prelude::wasm_bindgen;
6+
// use expression
57
pub use crate::datasource::*;
68
pub use crate::context::*;
79
pub use crate::operator::*;

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub use crate::eval::*;
1616
pub use crate::eval::context::*;
1717
pub use crate::parse::literal::Address;
1818
pub use crate::parse::literal::Column;
19+
pub use crate::parse::value::Value;
1920

2021
/// # Data Source
2122
/// A datasource which responds to queries.

src/parse/associative_array.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::parse::{parser, ParseContext};
88
use crate::parse::value::value_parser;
99

1010
#[derive(Debug, PartialEq)]
11-
pub(crate) struct AssociativeArray {
12-
pub(crate) items: Vec<(Key, Value)>
11+
pub struct AssociativeArray {
12+
pub items: Vec<(Key, Value)>
1313
}
1414

1515
impl AssociativeArray {

src/parse/call.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ use crate::{
1010
use crate::parse::literal::Literal;
1111

1212
#[derive(Debug, PartialEq)]
13-
pub(crate) struct Call {
14-
pub(crate) name: Box<Value>,
15-
pub(crate) arguments: Vec<Value>
13+
pub struct Call {
14+
pub name: Box<Value>,
15+
pub arguments: Vec<Value>
1616
}
1717

1818
impl Call {

src/parse/expression.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use alloc::{
77
};
88

99
#[derive(Debug, PartialEq)]
10-
pub(crate) struct Expression {
11-
pub(crate) operands: Vec<Value>,
12-
pub(crate) operator: String,
10+
pub struct Expression {
11+
pub operands: Vec<Value>,
12+
pub operator: String,
1313
}
1414

1515
impl Expression {

src/parse/list.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::{
88
};
99

1010
#[derive(Debug, PartialEq)]
11-
pub(crate) struct List {
12-
pub(crate) items: Vec<Value>
11+
pub struct List {
12+
pub items: Vec<Value>
1313
}
1414

1515
impl List {

src/parse/mod.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
pub(crate) mod key;
2-
pub(crate) mod call;
3-
pub(crate) mod access;
4-
pub(crate) mod list;
5-
pub mod literal; // TODO: pub(crate)
6-
pub(crate) mod associative_array;
7-
pub(crate) mod expression;
8-
pub(crate) mod value;
9-
pub(crate) mod test;
1+
pub mod key;
2+
pub mod call;
3+
pub mod access;
4+
pub mod list;
5+
pub mod literal;
6+
pub mod associative_array;
7+
pub mod expression;
8+
pub mod value;
9+
pub mod test;
1010

1111
use crate::{
1212
error::*,
@@ -43,7 +43,6 @@ pub(crate) mod objects {
4343
pub(crate) use crate::parse::value::Value;
4444
}
4545

46-
4746
pub struct ParseContext(Rc<ContextInner>);
4847

4948
impl ParseContext {

0 commit comments

Comments
 (0)