Merge branch 'master' into lets-invent-a-linter
This commit is contained in:
commit
e5a2bc1291
30 changed files with 329 additions and 451 deletions
|
@ -1,11 +1,16 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ArgumentName<'a> {
|
pub struct ArgumentName<'a> {
|
||||||
pub span: Span<'a>,
|
span: Span<'a>,
|
||||||
pub name: String,
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for ArgumentName<'a> {
|
||||||
|
const RULE: Rule = Rule::argument_keyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for ArgumentName<'a> {
|
impl<'a> From<Pair<'a, Rule>> for ArgumentName<'a> {
|
||||||
|
@ -31,13 +36,10 @@ impl<'a> ArgumentName<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn argument_name() {
|
fn argument_name() {
|
||||||
let pair = parse_str("marty_mcfly:", Rule::argument_keyword);
|
let argument_name = ArgumentName::parse("marty_mcfly:").unwrap();
|
||||||
let argument_name = ArgumentName::from(pair);
|
assert_eq!(argument_name.name(), "marty_mcfly");
|
||||||
|
|
||||||
assert_eq!(argument_name.name, "marty_mcfly");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::expression::Expression;
|
use ast::expression::Expression;
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -9,6 +10,10 @@ pub struct Array<'a> {
|
||||||
values: Vec<Expression<'a>>,
|
values: Vec<Expression<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Array<'a> {
|
||||||
|
const RULE: Rule = Rule::array;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Array<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Array<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::array);
|
assert_eq!(pair.as_rule(), Rule::array);
|
||||||
|
@ -32,12 +37,10 @@ impl<'a> Array<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn array_of_ints() {
|
fn array_of_ints() {
|
||||||
let result = parse_str("[1, 2, 3]", Rule::array);
|
let array = Array::parse("[1, 2, 3]").unwrap();
|
||||||
let array = Array::from(result);
|
|
||||||
let mut value = 0;
|
let mut value = 0;
|
||||||
for expr in array.values() {
|
for expr in array.values() {
|
||||||
value = value + 1;
|
value = value + 1;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::into_span::IntoSpan;
|
use ast::into_span::IntoSpan;
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -9,6 +10,10 @@ pub struct Atom<'a> {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Atom<'a> {
|
||||||
|
const RULE: Rule = Rule::atom;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Atom<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Atom<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
|
@ -62,12 +67,10 @@ impl<'a> IntoSpan<'a> for Atom<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn atom() {
|
fn atom() {
|
||||||
let pair = parse_str(":marty_mcfly", Rule::atom);
|
let atom = Atom::parse(":marty_mcfly").unwrap();
|
||||||
let atom = Atom::from(pair);
|
|
||||||
assert_eq!(atom.name(), "marty_mcfly");
|
assert_eq!(atom.name(), "marty_mcfly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::{define_function::DefineFunction, expression::Expression};
|
use ast::{define_function::DefineFunction, expression::Expression};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -15,6 +16,10 @@ pub enum Inner<'a> {
|
||||||
Expression(Expression<'a>),
|
Expression(Expression<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Block<'a> {
|
||||||
|
const RULE: Rule = Rule::block;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Block<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Block<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::block);
|
assert_eq!(pair.as_rule(), Rule::block);
|
||||||
|
@ -26,8 +31,7 @@ impl<'a> From<Pair<'a, Rule>> for Block<'a> {
|
||||||
Rule::def_function => Inner::DefineFunction(DefineFunction::from(p)),
|
Rule::def_function => Inner::DefineFunction(DefineFunction::from(p)),
|
||||||
Rule::expression => Inner::Expression(Expression::from(p)),
|
Rule::expression => Inner::Expression(Expression::from(p)),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
}).collect();
|
||||||
.collect();
|
|
||||||
|
|
||||||
Block {
|
Block {
|
||||||
span: span,
|
span: span,
|
||||||
|
@ -61,19 +65,16 @@ impl<'a> Block<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_empty() {
|
fn block_empty() {
|
||||||
let pair = parse_str("-> end", Rule::block_test);
|
let block = Block::parse("-> end").unwrap();
|
||||||
let block = Block::from(pair);
|
|
||||||
assert!(block.body().is_empty());
|
assert!(block.body().is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_single() {
|
fn block_single() {
|
||||||
let pair = parse_str("-> 123 end", Rule::block_test);
|
let block = Block::parse("-> 123 end").unwrap();
|
||||||
let block = Block::from(pair);
|
|
||||||
assert_eq!(block.body().len(), 1);
|
assert_eq!(block.body().len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
block.body()[0]
|
block.body()[0]
|
||||||
|
@ -90,15 +91,13 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_multi() {
|
fn block_multi() {
|
||||||
let pair = parse_str(
|
let block = Block::parse(
|
||||||
"->
|
"->
|
||||||
:marty
|
:marty
|
||||||
:doc
|
:doc
|
||||||
:einstein
|
:einstein
|
||||||
end",
|
end",
|
||||||
Rule::block_test,
|
).unwrap();
|
||||||
);
|
|
||||||
let block = Block::from(pair);
|
|
||||||
assert_eq!(block.body().len(), 3);
|
assert_eq!(block.body().len(), 3);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
block.body()[0]
|
block.body()[0]
|
||||||
|
@ -137,8 +136,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_with_function_define() {
|
fn block_with_function_define() {
|
||||||
let pair = parse_str("-> def marty? end", Rule::block);
|
let block = Block::parse("-> def marty? end").unwrap();
|
||||||
let block = Block::from(pair);
|
|
||||||
assert_eq!(block.body()[0].define_function().unwrap().name(), "marty?");
|
assert_eq!(block.body()[0].define_function().unwrap().name(), "marty?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -8,6 +9,10 @@ pub struct Boolean<'a> {
|
||||||
value: bool,
|
value: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Boolean<'a> {
|
||||||
|
const RULE: Rule = Rule::boolean;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Boolean<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Boolean<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::boolean);
|
assert_eq!(pair.as_rule(), Rule::boolean);
|
||||||
|
@ -44,19 +49,16 @@ impl<'a> Boolean<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn boolean_true() {
|
fn boolean_true() {
|
||||||
let pair = parse_str("true", Rule::boolean);
|
let b = Boolean::parse("true").unwrap();
|
||||||
let b = Boolean::from(pair);
|
|
||||||
assert!(b.value());
|
assert!(b.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn boolean_false() {
|
fn boolean_false() {
|
||||||
let pair = parse_str("false", Rule::boolean);
|
let b = Boolean::parse("false").unwrap();
|
||||||
let b = Boolean::from(pair);
|
|
||||||
assert!(!b.value());
|
assert!(!b.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use ast::call::{message::Message, receiver::Receiver};
|
use ast::call::{message::Message, receiver::Receiver};
|
||||||
use ast::expression::Expression;
|
use ast::expression::Expression;
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -12,6 +13,10 @@ pub struct Call<'a> {
|
||||||
arguments: Vec<Expression<'a>>,
|
arguments: Vec<Expression<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Call<'a> {
|
||||||
|
const RULE: Rule = Rule::call;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Call<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Call<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::call);
|
assert_eq!(pair.as_rule(), Rule::call);
|
||||||
|
@ -53,13 +58,10 @@ impl<'a> Call<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::{parse_str, Rule};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call_no_arg() {
|
fn call_no_arg() {
|
||||||
let result = parse_str("delorean.accelerate()", Rule::call);
|
let call = Call::parse("delorean.accelerate()").unwrap();
|
||||||
let call = Call::from(result);
|
|
||||||
|
|
||||||
assert_eq!(call.receiver().name(), "delorean");
|
assert_eq!(call.receiver().name(), "delorean");
|
||||||
assert_eq!(call.message().name(), "accelerate");
|
assert_eq!(call.message().name(), "accelerate");
|
||||||
assert_eq!(call.arguments().len(), 0);
|
assert_eq!(call.arguments().len(), 0);
|
||||||
|
@ -67,10 +69,8 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call_with_arg() {
|
fn call_with_arg() {
|
||||||
let result = parse_str("delorean.accelerate(88)", Rule::call);
|
let call = Call::parse("delorean.accelerate(88)").unwrap();
|
||||||
let call = Call::from(result);
|
|
||||||
let ref arg = call.arguments[0];
|
let ref arg = call.arguments[0];
|
||||||
|
|
||||||
assert_eq!(call.receiver().name(), "delorean");
|
assert_eq!(call.receiver().name(), "delorean");
|
||||||
assert_eq!(call.message().name(), "accelerate");
|
assert_eq!(call.message().name(), "accelerate");
|
||||||
assert_eq!(arg.literal().unwrap().integer().unwrap().value(), 88);
|
assert_eq!(arg.literal().unwrap().integer().unwrap().value(), 88);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -8,6 +9,10 @@ pub struct Message<'a> {
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Message<'a> {
|
||||||
|
const RULE: Rule = Rule::call_message;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Message<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Message<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::call_message);
|
assert_eq!(pair.as_rule(), Rule::call_message);
|
||||||
|
@ -31,12 +36,10 @@ impl<'a> Message<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::{parse_str, Rule};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn message() {
|
fn message() {
|
||||||
let result = parse_str("marty_mcfly", Rule::call_message);
|
let node = Message::parse("marty_mcfly").unwrap();
|
||||||
let node = Message::from(result);
|
|
||||||
assert_eq!(node.name(), "marty_mcfly");
|
assert_eq!(node.name(), "marty_mcfly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -8,6 +9,10 @@ pub struct Receiver<'a> {
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Receiver<'a> {
|
||||||
|
const RULE: Rule = Rule::call_receiver;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Receiver<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Receiver<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::call_receiver);
|
assert_eq!(pair.as_rule(), Rule::call_receiver);
|
||||||
|
@ -31,12 +36,10 @@ impl<'a> Receiver<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::{parse_str, Rule};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn receiver() {
|
fn receiver() {
|
||||||
let result = parse_str("marty_mcfly", Rule::call_receiver);
|
let node = Receiver::parse("marty_mcfly").unwrap();
|
||||||
let node = Receiver::from(result);
|
|
||||||
assert_eq!(node.name(), "marty_mcfly");
|
assert_eq!(node.name(), "marty_mcfly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
|
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -10,6 +11,10 @@ pub struct Constructor<'a> {
|
||||||
fields: Vec<(ArgumentName<'a>, Expression<'a>)>,
|
fields: Vec<(ArgumentName<'a>, Expression<'a>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Constructor<'a> {
|
||||||
|
const RULE: Rule = Rule::constructor;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Constructor<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Constructor<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::constructor);
|
assert_eq!(pair.as_rule(), Rule::constructor);
|
||||||
|
@ -48,12 +53,10 @@ impl<'a> Constructor<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constructor() {
|
fn constructor() {
|
||||||
let pair = parse_str("Delorean { speed: 88 }", Rule::constructor);
|
let constructor = Constructor::parse("Delorean { speed: 88 }").unwrap();
|
||||||
let constructor = Constructor::from(pair);
|
|
||||||
assert_eq!(constructor.type_name().name(), "Delorean");
|
assert_eq!(constructor.type_name().name(), "Delorean");
|
||||||
let (ref arg_name, ref arg_value) = constructor.fields()[0];
|
let (ref arg_name, ref arg_value) = constructor.fields()[0];
|
||||||
assert_eq!(arg_name.name(), "speed");
|
assert_eq!(arg_name.name(), "speed");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
|
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::{Pair, Pairs};
|
use pest::iterators::{Pair, Pairs};
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -26,6 +27,10 @@ pub struct FunctionName<'a> {
|
||||||
predicate: bool,
|
predicate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for DefineFunction<'a> {
|
||||||
|
const RULE: Rule = Rule::def_function;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> DefineFunction<'a> {
|
impl<'a> DefineFunction<'a> {
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
&self.fn_name.name
|
&self.fn_name.name
|
||||||
|
@ -125,8 +130,7 @@ fn get_arguments<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expressio
|
||||||
let arg_name = pairs.next().unwrap();
|
let arg_name = pairs.next().unwrap();
|
||||||
let value = pairs.next().unwrap();
|
let value = pairs.next().unwrap();
|
||||||
(ArgumentName::from(arg_name), Expression::from(value))
|
(ArgumentName::from(arg_name), Expression::from(value))
|
||||||
})
|
}).collect()
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for FunctionType {
|
impl<'a> From<Pair<'a, Rule>> for FunctionType {
|
||||||
|
@ -143,12 +147,10 @@ impl<'a> From<Pair<'a, Rule>> for FunctionType {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn name_only() {
|
fn name_only() {
|
||||||
let pair = parse_str("def marty", Rule::def_function);
|
let fun = DefineFunction::parse("def marty").unwrap();
|
||||||
let fun = DefineFunction::from(pair);
|
|
||||||
assert!(fun.is_public());
|
assert!(fun.is_public());
|
||||||
assert!(!fun.is_predicate());
|
assert!(!fun.is_predicate());
|
||||||
assert_eq!(fun.name(), "marty");
|
assert_eq!(fun.name(), "marty");
|
||||||
|
@ -156,8 +158,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn name_with_predicate() {
|
fn name_with_predicate() {
|
||||||
let pair = parse_str("def marty?", Rule::def_function);
|
let fun = DefineFunction::parse("def marty?").unwrap();
|
||||||
let fun = DefineFunction::from(pair);
|
|
||||||
assert!(fun.is_public());
|
assert!(fun.is_public());
|
||||||
assert!(fun.is_predicate());
|
assert!(fun.is_predicate());
|
||||||
assert_eq!(fun.name(), "marty?");
|
assert_eq!(fun.name(), "marty?");
|
||||||
|
@ -165,8 +166,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn with_return_type() {
|
fn with_return_type() {
|
||||||
let pair = parse_str("def <McFly> marty", Rule::def_function);
|
let fun = DefineFunction::parse("def <McFly> marty").unwrap();
|
||||||
let fun = DefineFunction::from(pair);
|
|
||||||
assert!(fun.is_public());
|
assert!(fun.is_public());
|
||||||
assert!(!fun.is_predicate());
|
assert!(!fun.is_predicate());
|
||||||
assert_eq!(fun.name(), "marty");
|
assert_eq!(fun.name(), "marty");
|
||||||
|
@ -175,8 +175,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn with_arguments() {
|
fn with_arguments() {
|
||||||
let pair = parse_str("def marty family: McFly, car: Delorean", Rule::def_function);
|
let fun = DefineFunction::parse("def marty family: McFly, car: Delorean").unwrap();
|
||||||
let fun = DefineFunction::from(pair);
|
|
||||||
assert!(fun.is_public());
|
assert!(fun.is_public());
|
||||||
assert!(!fun.is_predicate());
|
assert!(!fun.is_predicate());
|
||||||
assert_eq!(fun.name(), "marty");
|
assert_eq!(fun.name(), "marty");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
|
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::{Pair, Pairs};
|
use pest::iterators::{Pair, Pairs};
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -60,6 +61,10 @@ impl<'a> From<Pair<'a, Rule>> for ModuleType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for DefineModule<'a> {
|
||||||
|
const RULE: Rule = Rule::def_module;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for DefineModule<'a> {
|
impl<'a> From<Pair<'a, Rule>> for DefineModule<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::def_module);
|
assert_eq!(pair.as_rule(), Rule::def_module);
|
||||||
|
@ -87,43 +92,37 @@ fn get_arguments<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expressio
|
||||||
let arg_name = pairs.next().unwrap();
|
let arg_name = pairs.next().unwrap();
|
||||||
let value = pairs.next().unwrap();
|
let value = pairs.next().unwrap();
|
||||||
(ArgumentName::from(arg_name), Expression::from(value))
|
(ArgumentName::from(arg_name), Expression::from(value))
|
||||||
})
|
}).collect()
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn type_name_only() {
|
fn type_name_only() {
|
||||||
let pair = parse_str("deftype Marty", Rule::def_module);
|
let module = DefineModule::parse("deftype Marty").unwrap();
|
||||||
let module = DefineModule::from(pair);
|
|
||||||
assert!(module.is_type());
|
assert!(module.is_type());
|
||||||
assert_eq!(module.type_name().name(), "Marty");
|
assert_eq!(module.type_name().name(), "Marty");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trait_name_only() {
|
fn trait_name_only() {
|
||||||
let pair = parse_str("deftrait Marty", Rule::def_module);
|
let module = DefineModule::parse("deftrait Marty").unwrap();
|
||||||
let module = DefineModule::from(pair);
|
|
||||||
assert!(module.is_trait());
|
assert!(module.is_trait());
|
||||||
assert_eq!(module.type_name().name(), "Marty");
|
assert_eq!(module.type_name().name(), "Marty");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn impl_name_only() {
|
fn impl_name_only() {
|
||||||
let pair = parse_str("defimpl Marty", Rule::def_module);
|
let module = DefineModule::parse("defimpl Marty").unwrap();
|
||||||
let module = DefineModule::from(pair);
|
|
||||||
assert!(module.is_implementation());
|
assert!(module.is_implementation());
|
||||||
assert_eq!(module.type_name().name(), "Marty");
|
assert_eq!(module.type_name().name(), "Marty");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn type_with_fields() {
|
fn type_with_fields() {
|
||||||
let pair = parse_str("deftype Delorean speed: Integer", Rule::def_module);
|
let module = DefineModule::parse("deftype Delorean speed: Integer").unwrap();
|
||||||
let module = DefineModule::from(pair);
|
|
||||||
assert!(module.is_type());
|
assert!(module.is_type());
|
||||||
assert_eq!(module.type_name().name(), "Delorean");
|
assert_eq!(module.type_name().name(), "Delorean");
|
||||||
let (ref arg_name, ref arg_value) = module.fields()[0];
|
let (ref arg_name, ref arg_value) = module.fields()[0];
|
||||||
|
|
|
@ -3,6 +3,7 @@ use ast::{
|
||||||
unary::Unary,
|
unary::Unary,
|
||||||
};
|
};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -21,6 +22,10 @@ pub enum Inner<'a> {
|
||||||
Unary(Unary<'a>),
|
Unary(Unary<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Expression<'a> {
|
||||||
|
const RULE: Rule = Rule::expression;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Expression<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Expression<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::expression);
|
assert_eq!(pair.as_rule(), Rule::expression);
|
||||||
|
@ -159,20 +164,17 @@ impl<'a> Expression<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block() {
|
fn block() {
|
||||||
let pair = parse_str("-> 123 end", Rule::expression);
|
let expr = Expression::parse("-> 123 end").unwrap();
|
||||||
let expr = Expression::from(pair);
|
|
||||||
assert!(expr.is_block());
|
assert!(expr.is_block());
|
||||||
assert_eq!(expr.block().unwrap().body().len(), 1);
|
assert_eq!(expr.block().unwrap().body().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call() {
|
fn call() {
|
||||||
let pair = parse_str("marty.mcfly()", Rule::expression);
|
let expr = Expression::parse("marty.mcfly()").unwrap();
|
||||||
let expr = Expression::from(pair);
|
|
||||||
assert!(expr.is_call());
|
assert!(expr.is_call());
|
||||||
assert_eq!(expr.call().unwrap().receiver().name(), "marty");
|
assert_eq!(expr.call().unwrap().receiver().name(), "marty");
|
||||||
assert_eq!(expr.call().unwrap().message().name(), "mcfly");
|
assert_eq!(expr.call().unwrap().message().name(), "mcfly");
|
||||||
|
@ -180,8 +182,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infix() {
|
fn infix() {
|
||||||
let pair = parse_str("123 * 234", Rule::expression);
|
let expr = Expression::parse("123 * 234").unwrap();
|
||||||
let expr = Expression::from(pair);
|
|
||||||
assert!(expr.is_infix());
|
assert!(expr.is_infix());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expr.infix()
|
expr.infix()
|
||||||
|
@ -209,16 +210,14 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn literal() {
|
fn literal() {
|
||||||
let pair = parse_str("123", Rule::expression);
|
let expr = Expression::parse("123").unwrap();
|
||||||
let expr = Expression::from(pair);
|
|
||||||
assert!(expr.is_literal());
|
assert!(expr.is_literal());
|
||||||
assert_eq!(expr.literal().unwrap().integer().unwrap().value(), 123);
|
assert_eq!(expr.literal().unwrap().integer().unwrap().value(), 123);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unary() {
|
fn unary() {
|
||||||
let pair = parse_str("!123", Rule::expression);
|
let expr = Expression::parse("!123").unwrap();
|
||||||
let expr = Expression::from(pair);
|
|
||||||
assert!(expr.is_unary());
|
assert!(expr.is_unary());
|
||||||
assert!(expr.unary().unwrap().op().is_logical_not());
|
assert!(expr.unary().unwrap().op().is_logical_not());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::define_module::DefineModule;
|
use ast::define_module::DefineModule;
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -9,6 +10,10 @@ pub struct File<'a> {
|
||||||
modules: Vec<DefineModule<'a>>,
|
modules: Vec<DefineModule<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for File<'a> {
|
||||||
|
const RULE: Rule = Rule::file;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for File<'a> {
|
impl<'a> From<Pair<'a, Rule>> for File<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::file);
|
assert_eq!(pair.as_rule(), Rule::file);
|
||||||
|
@ -32,12 +37,10 @@ impl<'a> File<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn file() {
|
fn file() {
|
||||||
let pair = parse_str("deftype Marty", Rule::file);
|
let file = File::parse("deftype Marty").unwrap();
|
||||||
let file = File::from(pair);
|
|
||||||
assert_eq!(file.modules().len(), 1);
|
assert_eq!(file.modules().len(), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -9,6 +10,10 @@ pub struct Float<'a> {
|
||||||
value: f64,
|
value: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Float<'a> {
|
||||||
|
const RULE: Rule = Rule::float;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Float<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Float<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::float);
|
assert_eq!(pair.as_rule(), Rule::float);
|
||||||
|
@ -33,19 +38,16 @@ impl<'a> Float<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn float_zero_zero() {
|
fn float_zero_zero() {
|
||||||
let pair = parse_str("0.0", Rule::float);
|
let flt = Float::parse("0.0").unwrap();
|
||||||
let flt = Float::from(pair);
|
|
||||||
assert_eq!(flt.value, 0.0);
|
assert_eq!(flt.value, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn float_123_123() {
|
fn float_123_123() {
|
||||||
let pair = parse_str("123.123", Rule::float);
|
let flt = Float::parse("123.123").unwrap();
|
||||||
let flt = Float::from(pair);
|
|
||||||
assert_eq!(flt.value, 123.123);
|
assert_eq!(flt.value, 123.123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -9,6 +10,10 @@ pub struct Integer<'a> {
|
||||||
pub value: u64,
|
pub value: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Integer<'a> {
|
||||||
|
const RULE: Rule = Rule::integer;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Integer<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Integer<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::integer);
|
assert_eq!(pair.as_rule(), Rule::integer);
|
||||||
|
@ -50,44 +55,38 @@ impl<'a> Integer<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_zero() {
|
fn integer_zero() {
|
||||||
let pair = parse_str("0", Rule::integer);
|
let int = Integer::parse("0").unwrap();
|
||||||
let int = Integer::from(pair);
|
|
||||||
assert_eq!(int.radix, 0);
|
assert_eq!(int.radix, 0);
|
||||||
assert_eq!(int.value, 0);
|
assert_eq!(int.value, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_binary() {
|
fn integer_binary() {
|
||||||
let pair = parse_str("0b10101", Rule::integer);
|
let int = Integer::parse("0b10101").unwrap();
|
||||||
let int = Integer::from(pair);
|
|
||||||
assert_eq!(int.radix, 2);
|
assert_eq!(int.radix, 2);
|
||||||
assert_eq!(int.value, 21);
|
assert_eq!(int.value, 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_octal() {
|
fn integer_octal() {
|
||||||
let pair = parse_str("0o76543210", Rule::integer);
|
let int = Integer::parse("0o76543210").unwrap();
|
||||||
let int = Integer::from(pair);
|
|
||||||
assert_eq!(int.radix, 8);
|
assert_eq!(int.radix, 8);
|
||||||
assert_eq!(int.value, 16434824);
|
assert_eq!(int.value, 16434824);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_decimal() {
|
fn integer_decimal() {
|
||||||
let pair = parse_str("9876543210", Rule::integer);
|
let int = Integer::parse("9876543210").unwrap();
|
||||||
let int = Integer::from(pair);
|
|
||||||
assert_eq!(int.radix, 10);
|
assert_eq!(int.radix, 10);
|
||||||
assert_eq!(int.value, 9876543210);
|
assert_eq!(int.value, 9876543210);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_hexadecimal() {
|
fn integer_hexadecimal() {
|
||||||
let pair = parse_str("0xfEdCbA9876543210", Rule::integer);
|
let int = Integer::parse("0xfEdCbA9876543210").unwrap();
|
||||||
let int = Integer::from(pair);
|
|
||||||
assert_eq!(int.radix, 16);
|
assert_eq!(int.radix, 16);
|
||||||
assert_eq!(int.value, 18364758544493064720);
|
assert_eq!(int.value, 18364758544493064720);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ use ast::{
|
||||||
type_name::TypeName, variable::Variable,
|
type_name::TypeName, variable::Variable,
|
||||||
};
|
};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -28,6 +29,10 @@ pub enum Inner<'a> {
|
||||||
Variable(Variable<'a>),
|
Variable(Variable<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Literal<'a> {
|
||||||
|
const RULE: Rule = Rule::literal;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Literal<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Literal<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::literal);
|
assert_eq!(pair.as_rule(), Rule::literal);
|
||||||
|
@ -231,92 +236,80 @@ impl<'a> Literal<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn array() {
|
fn array() {
|
||||||
let pair = parse_str("[1, 2, 3]", Rule::literal);
|
let lit = Literal::parse("[1, 2, 3]").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_array());
|
assert!(lit.is_array());
|
||||||
assert_eq!(lit.array().unwrap().values().len(), 3);
|
assert_eq!(lit.array().unwrap().values().len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map() {
|
fn map() {
|
||||||
let pair = parse_str("{a: 1, b: 2}", Rule::literal);
|
let lit = Literal::parse("{a: 1, b: 2}").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_map());
|
assert!(lit.is_map());
|
||||||
assert_eq!(lit.map().unwrap().values().len(), 2);
|
assert_eq!(lit.map().unwrap().values().len(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn atom() {
|
fn atom() {
|
||||||
let pair = parse_str(":marty_mcfly", Rule::literal);
|
let lit = Literal::parse(":marty_mcfly").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_atom());
|
assert!(lit.is_atom());
|
||||||
assert_eq!(lit.atom().unwrap().name(), "marty_mcfly");
|
assert_eq!(lit.atom().unwrap().name(), "marty_mcfly");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn boolean() {
|
fn boolean() {
|
||||||
let pair = parse_str("true", Rule::literal);
|
let lit = Literal::parse("true").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_boolean());
|
assert!(lit.is_boolean());
|
||||||
assert!(lit.boolean().unwrap().is_true());
|
assert!(lit.boolean().unwrap().is_true());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constructor() {
|
fn constructor() {
|
||||||
let pair = parse_str("Delorean { speed: 88 }", Rule::literal);
|
let lit = Literal::parse("Delorean { speed: 88 }").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_constructor());
|
assert!(lit.is_constructor());
|
||||||
assert_eq!(lit.constructor().unwrap().type_name().name(), "Delorean");
|
assert_eq!(lit.constructor().unwrap().type_name().name(), "Delorean");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn float() {
|
fn float() {
|
||||||
let pair = parse_str("123.456", Rule::literal);
|
let lit = Literal::parse("123.456").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_float());
|
assert!(lit.is_float());
|
||||||
assert_eq!(lit.float().unwrap().value(), 123.456);
|
assert_eq!(lit.float().unwrap().value(), 123.456);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer() {
|
fn integer() {
|
||||||
let pair = parse_str("123", Rule::literal);
|
let lit = Literal::parse("123").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_integer());
|
assert!(lit.is_integer());
|
||||||
assert_eq!(lit.integer().unwrap().value(), 123);
|
assert_eq!(lit.integer().unwrap().value(), 123);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn property() {
|
fn property() {
|
||||||
let pair = parse_str("@doc_brown", Rule::literal);
|
let lit = Literal::parse("@doc_brown").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_property());
|
assert!(lit.is_property());
|
||||||
assert_eq!(lit.property().unwrap().name(), "doc_brown");
|
assert_eq!(lit.property().unwrap().name(), "doc_brown");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn string() {
|
fn string() {
|
||||||
let pair = parse_str("\"Doc \\\"Emmet\\\" Brown\"", Rule::literal);
|
let lit = Literal::parse("\"Doc \\\"Emmet\\\" Brown\"").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_string());
|
assert!(lit.is_string());
|
||||||
assert_eq!(lit.string().unwrap().value(), "Doc \"Emmet\" Brown");
|
assert_eq!(lit.string().unwrap().value(), "Doc \"Emmet\" Brown");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn type_name() {
|
fn type_name() {
|
||||||
let pair = parse_str("MartyMcFly", Rule::literal);
|
let lit = Literal::parse("MartyMcFly").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_type_name());
|
assert!(lit.is_type_name());
|
||||||
assert_eq!(lit.type_name().unwrap().name(), "MartyMcFly");
|
assert_eq!(lit.type_name().unwrap().name(), "MartyMcFly");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn variable() {
|
fn variable() {
|
||||||
let pair = parse_str("marty_mcfly", Rule::literal);
|
let lit = Literal::parse("marty_mcfly").unwrap();
|
||||||
let lit = Literal::from(pair);
|
|
||||||
assert!(lit.is_variable());
|
assert!(lit.is_variable());
|
||||||
assert_eq!(lit.variable().unwrap().name(), "marty_mcfly");
|
assert_eq!(lit.variable().unwrap().name(), "marty_mcfly");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::{atom::Atom, expression::Expression, literal::Literal};
|
use ast::{atom::Atom, expression::Expression, literal::Literal};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -16,6 +17,10 @@ pub struct MapPair<'a> {
|
||||||
value: Box<Expression<'a>>,
|
value: Box<Expression<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Map<'a> {
|
||||||
|
const RULE: Rule = Rule::map;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Map<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Map<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::map);
|
assert_eq!(pair.as_rule(), Rule::map);
|
||||||
|
@ -71,12 +76,10 @@ impl<'a> Map<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn keyword_map() {
|
fn keyword_map() {
|
||||||
let pair = parse_str("{a: 1, b: 2}", Rule::map);
|
let map = Map::parse("{a: 1, b: 2}").unwrap();
|
||||||
let map = Map::from(pair);
|
|
||||||
|
|
||||||
let map_pair = &map.values()[0];
|
let map_pair = &map.values()[0];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -113,8 +116,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn expression_map() {
|
fn expression_map() {
|
||||||
let pair = parse_str("{ 1 : 2, 3 : 4 }", Rule::map);
|
let map = Map::parse("{ 1 : 2, 3 : 4 }").unwrap();
|
||||||
let map = Map::from(pair);
|
|
||||||
|
|
||||||
let map_pair = &map.values()[0];
|
let map_pair = &map.values()[0];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Operator<'a> {
|
pub struct Operator<'a> {
|
||||||
pub span: Span<'a>,
|
span: Span<'a>,
|
||||||
pub op: Op,
|
op: Op,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Operator<'a> {
|
||||||
|
const RULE: Rule = Rule::all_operators;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Operator<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Operator<'a> {
|
||||||
|
@ -194,27 +199,27 @@ impl<'a> Operator<'a> {
|
||||||
impl<'a> From<Pair<'a, Rule>> for Op {
|
impl<'a> From<Pair<'a, Rule>> for Op {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::multiply => Op::Multiply,
|
Rule::assign => Op::Assign,
|
||||||
Rule::divide => Op::Divide,
|
|
||||||
Rule::modulus => Op::Modulo,
|
|
||||||
Rule::plus => Op::Plus,
|
|
||||||
Rule::minus => Op::Minus,
|
|
||||||
Rule::shift_left => Op::ShiftLeft,
|
|
||||||
Rule::shift_right => Op::ShiftRight,
|
|
||||||
Rule::less_than => Op::LessThan,
|
|
||||||
Rule::less_than_or_equal => Op::LessThanOrEqual,
|
|
||||||
Rule::greater_than => Op::GreaterThan,
|
|
||||||
Rule::greater_than_or_equal => Op::GreaterThanOrEqual,
|
|
||||||
Rule::not_equal => Op::NotEqual,
|
|
||||||
Rule::equal => Op::Equal,
|
|
||||||
Rule::exponent => Op::Exponent,
|
|
||||||
Rule::logical_and => Op::LogicalAnd,
|
|
||||||
Rule::logical_or => Op::LogicalOr,
|
|
||||||
Rule::logical_not => Op::LogicalNot,
|
|
||||||
Rule::bitwise_and => Op::BitwiseAnd,
|
Rule::bitwise_and => Op::BitwiseAnd,
|
||||||
Rule::bitwise_or => Op::BitwiseOr,
|
Rule::bitwise_or => Op::BitwiseOr,
|
||||||
Rule::bitwise_xor => Op::BitwiseXor,
|
Rule::bitwise_xor => Op::BitwiseXor,
|
||||||
Rule::assign => Op::Assign,
|
Rule::divide => Op::Divide,
|
||||||
|
Rule::equal => Op::Equal,
|
||||||
|
Rule::exponent => Op::Exponent,
|
||||||
|
Rule::greater_than => Op::GreaterThan,
|
||||||
|
Rule::greater_than_or_equal => Op::GreaterThanOrEqual,
|
||||||
|
Rule::less_than => Op::LessThan,
|
||||||
|
Rule::less_than_or_equal => Op::LessThanOrEqual,
|
||||||
|
Rule::logical_and => Op::LogicalAnd,
|
||||||
|
Rule::logical_not => Op::LogicalNot,
|
||||||
|
Rule::logical_or => Op::LogicalOr,
|
||||||
|
Rule::minus => Op::Minus,
|
||||||
|
Rule::modulus => Op::Modulo,
|
||||||
|
Rule::multiply => Op::Multiply,
|
||||||
|
Rule::not_equal => Op::NotEqual,
|
||||||
|
Rule::plus => Op::Plus,
|
||||||
|
Rule::shift_left => Op::ShiftLeft,
|
||||||
|
Rule::shift_right => Op::ShiftRight,
|
||||||
_ => panic!("Node {:?} is not an operator", pair),
|
_ => panic!("Node {:?} is not an operator", pair),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,256 +228,131 @@ impl<'a> From<Pair<'a, Rule>> for Op {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::{parse_str, Rule};
|
|
||||||
|
|
||||||
mod operator {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiply() {
|
fn assign() {
|
||||||
let result = parse_str("*", Rule::all_operators);
|
let op = Operator::parse("=").unwrap();
|
||||||
assert_eq!(Op::Multiply, Operator::from(result).op)
|
assert!(op.is_assign());
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn divide() {
|
|
||||||
let result = parse_str("/", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Divide, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn modulus() {
|
|
||||||
let result = parse_str("%", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Modulo, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn plus() {
|
|
||||||
let result = parse_str("+", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Plus, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn minus() {
|
|
||||||
let result = parse_str("-", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Minus, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn shift_left() {
|
|
||||||
let result = parse_str("<<", Rule::all_operators);
|
|
||||||
assert_eq!(Op::ShiftLeft, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn shift_right() {
|
|
||||||
let result = parse_str(">>", Rule::all_operators);
|
|
||||||
assert_eq!(Op::ShiftRight, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn less_than() {
|
|
||||||
let result = parse_str("<", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LessThan, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn less_than_or_equal() {
|
|
||||||
let result = parse_str("<=", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LessThanOrEqual, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn greater_than() {
|
|
||||||
let result = parse_str(">", Rule::all_operators);
|
|
||||||
assert_eq!(Op::GreaterThan, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn greater_than_or_equal() {
|
|
||||||
let result = parse_str(">=", Rule::all_operators);
|
|
||||||
assert_eq!(Op::GreaterThanOrEqual, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn not_equal() {
|
|
||||||
let result = parse_str("!=", Rule::all_operators);
|
|
||||||
assert_eq!(Op::NotEqual, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn equal() {
|
|
||||||
let result = parse_str("==", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Equal, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn logical_and() {
|
|
||||||
let result = parse_str("&&", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LogicalAnd, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn logical_or() {
|
|
||||||
let result = parse_str("||", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LogicalOr, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn logical_not() {
|
|
||||||
let result = parse_str("!", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LogicalNot, Operator::from(result).op);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bitwise_and() {
|
fn bitwise_and() {
|
||||||
let result = parse_str("&", Rule::all_operators);
|
let op = Operator::parse("&").unwrap();
|
||||||
assert_eq!(Op::BitwiseAnd, Operator::from(result).op);
|
assert!(op.is_bitwise_and());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bitwise_or() {
|
fn bitwise_or() {
|
||||||
let result = parse_str("|", Rule::all_operators);
|
let op = Operator::parse("|").unwrap();
|
||||||
assert_eq!(Op::BitwiseOr, Operator::from(result).op);
|
assert!(op.is_bitwise_or());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bitwise_xor() {
|
fn bitwise_xor() {
|
||||||
let result = parse_str("^", Rule::all_operators);
|
let op = Operator::parse("^").unwrap();
|
||||||
assert_eq!(Op::BitwiseXor, Operator::from(result).op);
|
assert!(op.is_bitwise_xor());
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assign() {
|
|
||||||
let result = parse_str("=", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Assign, Operator::from(result).op);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mod op {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn multiply() {
|
|
||||||
let result = parse_str("*", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Multiply, Op::from(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn divide() {
|
fn divide() {
|
||||||
let result = parse_str("/", Rule::all_operators);
|
let op = Operator::parse("/").unwrap();
|
||||||
assert_eq!(Op::Divide, Op::from(result));
|
assert!(op.is_divide());
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn modulus() {
|
|
||||||
let result = parse_str("%", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Modulo, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn plus() {
|
|
||||||
let result = parse_str("+", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Plus, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn minus() {
|
|
||||||
let result = parse_str("-", Rule::all_operators);
|
|
||||||
assert_eq!(Op::Minus, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn shift_left() {
|
|
||||||
let result = parse_str("<<", Rule::all_operators);
|
|
||||||
assert_eq!(Op::ShiftLeft, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn shift_right() {
|
|
||||||
let result = parse_str(">>", Rule::all_operators);
|
|
||||||
assert_eq!(Op::ShiftRight, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn less_than() {
|
|
||||||
let result = parse_str("<", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LessThan, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn less_than_or_equal() {
|
|
||||||
let result = parse_str("<=", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LessThanOrEqual, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn greater_than() {
|
|
||||||
let result = parse_str(">", Rule::all_operators);
|
|
||||||
assert_eq!(Op::GreaterThan, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn greater_than_or_equal() {
|
|
||||||
let result = parse_str(">=", Rule::all_operators);
|
|
||||||
assert_eq!(Op::GreaterThanOrEqual, Op::from(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn not_equal() {
|
|
||||||
let result = parse_str("!=", Rule::all_operators);
|
|
||||||
assert_eq!(Op::NotEqual, Op::from(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn equal() {
|
fn equal() {
|
||||||
let result = parse_str("==", Rule::all_operators);
|
let op = Operator::parse("==").unwrap();
|
||||||
assert_eq!(Op::Equal, Op::from(result));
|
assert!(op.is_equal());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exponent() {
|
||||||
|
let op = Operator::parse("**").unwrap();
|
||||||
|
assert!(op.is_exponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn greater_than() {
|
||||||
|
let op = Operator::parse(">").unwrap();
|
||||||
|
assert!(op.is_greater_than());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn greater_than_or_equal() {
|
||||||
|
let op = Operator::parse(">=").unwrap();
|
||||||
|
assert!(op.is_greater_than_or_equal());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn less_than() {
|
||||||
|
let op = Operator::parse("<").unwrap();
|
||||||
|
assert!(op.is_less_than());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn less_than_or_equal() {
|
||||||
|
let op = Operator::parse("<=").unwrap();
|
||||||
|
assert!(op.is_less_than_or_equal());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn logical_and() {
|
fn logical_and() {
|
||||||
let result = parse_str("&&", Rule::all_operators);
|
let op = Operator::parse("&&").unwrap();
|
||||||
assert_eq!(Op::LogicalAnd, Op::from(result));
|
assert!(op.is_logical_and());
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn logical_or() {
|
|
||||||
let result = parse_str("||", Rule::all_operators);
|
|
||||||
assert_eq!(Op::LogicalOr, Op::from(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn logical_not() {
|
fn logical_not() {
|
||||||
let result = parse_str("!", Rule::all_operators);
|
let op = Operator::parse("!").unwrap();
|
||||||
assert_eq!(Op::LogicalNot, Op::from(result));
|
assert!(op.is_logical_not());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bitwise_and() {
|
fn logical_or() {
|
||||||
let result = parse_str("&", Rule::all_operators);
|
let op = Operator::parse("||").unwrap();
|
||||||
assert_eq!(Op::BitwiseAnd, Op::from(result));
|
assert!(op.is_logical_or());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bitwise_or() {
|
fn minus() {
|
||||||
let result = parse_str("|", Rule::all_operators);
|
let op = Operator::parse("-").unwrap();
|
||||||
assert_eq!(Op::BitwiseOr, Op::from(result));
|
assert!(op.is_minus());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bitwise_xor() {
|
fn modulus() {
|
||||||
let result = parse_str("^", Rule::all_operators);
|
let op = Operator::parse("%").unwrap();
|
||||||
assert_eq!(Op::BitwiseXor, Op::from(result));
|
assert!(op.is_modulo());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn assign() {
|
fn multiply() {
|
||||||
let result = parse_str("=", Rule::all_operators);
|
let op = Operator::parse("*").unwrap();
|
||||||
assert_eq!(Op::Assign, Op::from(result));
|
assert!(op.is_multiply());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn not_equal() {
|
||||||
|
let op = Operator::parse("!=").unwrap();
|
||||||
|
assert!(op.is_not_equal());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn plus() {
|
||||||
|
let op = Operator::parse("+").unwrap();
|
||||||
|
assert!(op.is_plus());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shift_left() {
|
||||||
|
let op = Operator::parse("<<").unwrap();
|
||||||
|
assert!(op.is_shift_left());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shift_right() {
|
||||||
|
let op = Operator::parse(">>").unwrap();
|
||||||
|
assert!(op.is_shift_right());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,11 @@ pub fn climb<'a>(pair: Pair<'a, Rule>) -> Expression<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
use parse::Parse;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn precedence_test() {
|
fn precedence_test() {
|
||||||
let result = parse_str("10 * 20 + 30", Rule::expression_test);
|
let expr = Expression::parse("10 * 20 + 30").unwrap();
|
||||||
let expr = Expression::from(result);
|
|
||||||
let infix0 = expr.infix().unwrap();
|
let infix0 = expr.infix().unwrap();
|
||||||
assert!(infix0.op().is_plus());
|
assert!(infix0.op().is_plus());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -8,6 +9,10 @@ pub struct Property<'a> {
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Property<'a> {
|
||||||
|
const RULE: Rule = Rule::property;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Property<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Property<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::property);
|
assert_eq!(pair.as_rule(), Rule::property);
|
||||||
|
@ -37,13 +42,10 @@ impl<'a> Property<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn property() {
|
fn property() {
|
||||||
let pair = parse_str("@marty_mcfly", Rule::property);
|
let property = Property::parse("@marty_mcfly").unwrap();
|
||||||
let property = Property::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(property.name(), "marty_mcfly");
|
assert_eq!(property.name(), "marty_mcfly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
use regex::{Captures, Regex};
|
use regex::{Captures, Regex};
|
||||||
|
@ -14,6 +15,10 @@ pub struct StringLiteral<'a> {
|
||||||
value: String,
|
value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for StringLiteral<'a> {
|
||||||
|
const RULE: Rule = Rule::string;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for StringLiteral<'a> {
|
impl<'a> From<Pair<'a, Rule>> for StringLiteral<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::string);
|
assert_eq!(pair.as_rule(), Rule::string);
|
||||||
|
@ -60,91 +65,70 @@ impl<'a> StringLiteral<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic() {
|
fn basic() {
|
||||||
let pair = parse_str(r#""hello world""#, Rule::string);
|
let value = StringLiteral::parse(r#""hello world""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "hello world");
|
assert_eq!(value.value(), "hello world");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn vartical_tab_escape() {
|
fn vartical_tab_escape() {
|
||||||
let pair = parse_str(r#""\v""#, Rule::string);
|
let value = StringLiteral::parse(r#""\v""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\u{000b}");
|
assert_eq!(value.value(), "\u{000b}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tab_escape() {
|
fn tab_escape() {
|
||||||
let pair = parse_str(r#""\t""#, Rule::string);
|
let value = StringLiteral::parse(r#""\t""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\t");
|
assert_eq!(value.value(), "\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn carriage_return_escape() {
|
fn carriage_return_escape() {
|
||||||
let pair = parse_str(r#""\r""#, Rule::string);
|
let value = StringLiteral::parse(r#""\r""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\r");
|
assert_eq!(value.value(), "\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn newline_escape() {
|
fn newline_escape() {
|
||||||
let pair = parse_str(r#""\n""#, Rule::string);
|
let value = StringLiteral::parse(r#""\n""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\n");
|
assert_eq!(value.value(), "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn formfeed_escape() {
|
fn formfeed_escape() {
|
||||||
let pair = parse_str(r#""\f""#, Rule::string);
|
let value = StringLiteral::parse(r#""\f""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\u{000c}");
|
assert_eq!(value.value(), "\u{000c}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn backspace_escape() {
|
fn backspace_escape() {
|
||||||
let pair = parse_str(r#""\b""#, Rule::string);
|
let value = StringLiteral::parse(r#""\b""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\u{0008}");
|
assert_eq!(value.value(), "\u{0008}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn alert_escape() {
|
fn alert_escape() {
|
||||||
let pair = parse_str(r#""\a""#, Rule::string);
|
let value = StringLiteral::parse(r#""\a""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\u{0007}");
|
assert_eq!(value.value(), "\u{0007}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unicode_escape() {
|
fn unicode_escape() {
|
||||||
let pair = parse_str(r#""\u26f5""#, Rule::string);
|
let value = StringLiteral::parse(r#""\u26f5""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(value.value(), "\u{26f5}");
|
assert_eq!(value.value(), "\u{26f5}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn backslash_escape() {
|
fn backslash_escape() {
|
||||||
let pair = parse_str(r#""\\""#, Rule::string);
|
let value = StringLiteral::parse(r#""\\""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
assert_eq!(value.value(), "\\");
|
assert_eq!(value.value(), "\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn doublequote_escape() {
|
fn doublequote_escape() {
|
||||||
let pair = parse_str(r#""\""""#, Rule::string);
|
let value = StringLiteral::parse(r#""\""""#).unwrap();
|
||||||
let value = StringLiteral::from(pair);
|
|
||||||
assert_eq!(value.value(), r#"""#);
|
assert_eq!(value.value(), r#"""#);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -8,6 +9,10 @@ pub struct TypeName<'a> {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for TypeName<'a> {
|
||||||
|
const RULE: Rule = Rule::type_name;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for TypeName<'a> {
|
impl<'a> From<Pair<'a, Rule>> for TypeName<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::type_name);
|
assert_eq!(pair.as_rule(), Rule::type_name);
|
||||||
|
@ -30,12 +35,10 @@ impl<'a> TypeName<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn name() {
|
fn name() {
|
||||||
let pair = parse_str("DocBrown", Rule::type_name);
|
let type_name = TypeName::parse("DocBrown").unwrap();
|
||||||
let type_name = TypeName::from(pair);
|
|
||||||
assert_eq!(type_name.name(), "DocBrown");
|
assert_eq!(type_name.name(), "DocBrown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use ast::{expression::Expression, operator::Operator};
|
use ast::{expression::Expression, operator::Operator};
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -10,6 +11,10 @@ pub struct Unary<'a> {
|
||||||
expression: Box<Expression<'a>>,
|
expression: Box<Expression<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Unary<'a> {
|
||||||
|
const RULE: Rule = Rule::unary;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Unary<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Unary<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::unary);
|
assert_eq!(pair.as_rule(), Rule::unary);
|
||||||
|
@ -41,12 +46,10 @@ impl<'a> Unary<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unary() {
|
fn unary() {
|
||||||
let result = parse_str("!123", Rule::unary);
|
let unary = Unary::parse("!123").unwrap();
|
||||||
let unary = Unary::from(result);
|
|
||||||
|
|
||||||
assert!(unary.op().is_logical_not());
|
assert!(unary.op().is_logical_not());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use grammar::Rule;
|
use grammar::Rule;
|
||||||
|
use parse::Parse;
|
||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
|
@ -8,6 +9,10 @@ pub struct Variable<'a> {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Parse<'a> for Variable<'a> {
|
||||||
|
const RULE: Rule = Rule::variable;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<Pair<'a, Rule>> for Variable<'a> {
|
impl<'a> From<Pair<'a, Rule>> for Variable<'a> {
|
||||||
fn from(pair: Pair<'a, Rule>) -> Self {
|
fn from(pair: Pair<'a, Rule>) -> Self {
|
||||||
assert_eq!(pair.as_rule(), Rule::variable);
|
assert_eq!(pair.as_rule(), Rule::variable);
|
||||||
|
@ -30,13 +35,10 @@ impl<'a> Variable<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use grammar::parse_str;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn variable() {
|
fn variable() {
|
||||||
let pair = parse_str("marty_mcfly", Rule::variable);
|
let variable = Variable::parse("marty_mcfly").unwrap();
|
||||||
let variable = Variable::from(pair);
|
|
||||||
|
|
||||||
assert_eq!(variable.name(), "marty_mcfly");
|
assert_eq!(variable.name(), "marty_mcfly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ boolean_false = @{ keyword_false }
|
||||||
boolean_true = @{ keyword_true }
|
boolean_true = @{ keyword_true }
|
||||||
braced = !{ "(" ~ newline* ~ expression ~ newline* ~ ")" }
|
braced = !{ "(" ~ newline* ~ expression ~ newline* ~ ")" }
|
||||||
constructor = !{ type_name ~ "{" ~ argument_list? ~ "}" }
|
constructor = !{ type_name ~ "{" ~ argument_list? ~ "}" }
|
||||||
literal = !{ constructor | array | map | float | integer | string | atom | property | variable | braced | boolean | type_name }
|
literal = !{ constructor | array | map | float | integer | string | atom | property | type_name | variable | braced | boolean }
|
||||||
property = ${ "@" ~ identifier }
|
property = ${ "@" ~ identifier }
|
||||||
unary = ${ unary_operator ~ expression }
|
unary = ${ unary_operator ~ expression }
|
||||||
variable = @{ identifier }
|
variable = @{ identifier }
|
||||||
|
@ -87,7 +87,7 @@ keyword_false = { "false" }
|
||||||
|
|
||||||
identifier_test = _{ soi ~ identifier ~ eoi }
|
identifier_test = _{ soi ~ identifier ~ eoi }
|
||||||
identifier = @{ !keyword ~ identifier_head ~ identifier_tail? }
|
identifier = @{ !keyword ~ identifier_head ~ identifier_tail? }
|
||||||
identifier_head = @{ 'a'..'z' | "_" }
|
identifier_head = @{ 'A'..'Z' | 'a'..'z' | "_" }
|
||||||
identifier_tail = @{ ('a'..'z' | 'A'..'Z' | "_" | '0'..'9')+ }
|
identifier_tail = @{ ('a'..'z' | 'A'..'Z' | "_" | '0'..'9')+ }
|
||||||
type_name = @{ !keyword ~ type_name_head ~ type_name_tail? }
|
type_name = @{ !keyword ~ type_name_head ~ type_name_tail? }
|
||||||
type_name_head = @{ 'A'..'Z' }
|
type_name_head = @{ 'A'..'Z' }
|
||||||
|
|
|
@ -6,16 +6,3 @@ pub struct Grammar;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
use pest::iterators::Pair;
|
|
||||||
use pest::Parser;
|
|
||||||
|
|
||||||
pub fn parse_str<'a>(source: &'a str, rule: Rule) -> Pair<'a, Rule> {
|
|
||||||
let result = Grammar::parse(rule, source);
|
|
||||||
if result.is_err() {
|
|
||||||
println!("{}", result.err().unwrap());
|
|
||||||
panic!("Parses without failure");
|
|
||||||
} else {
|
|
||||||
result.unwrap().next().unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use super::assert_parses_expression;
|
|
||||||
use grammar::{Grammar, Rule};
|
use grammar::{Grammar, Rule};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use grammar::{Grammar, Rule};
|
// use grammar::{Grammar, Rule};
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn binary_operators() {
|
// fn binary_operators() {
|
||||||
|
|
|
@ -16,4 +16,8 @@ mod parse;
|
||||||
|
|
||||||
pub use ast::*;
|
pub use ast::*;
|
||||||
pub use error::ParseError;
|
pub use error::ParseError;
|
||||||
pub use parse::parse_file;
|
pub use parse::Parse;
|
||||||
|
|
||||||
|
pub fn parse_file<'a>(source: &'a str) -> Result<File<'a>, ParseError<'a>> {
|
||||||
|
File::parse(source)
|
||||||
|
}
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
use ast::File;
|
|
||||||
use error::ParseError;
|
use error::ParseError;
|
||||||
use grammar::{Grammar, Rule};
|
use grammar::{Grammar, Rule};
|
||||||
use pest::{iterators::Pair, Parser};
|
use pest::{iterators::Pair, Parser};
|
||||||
|
|
||||||
pub fn parse_file<'a>(source: &'a str) -> Result<File<'a>, ParseError<'a>> {
|
pub trait Parse<'a, Node = Self>
|
||||||
run_parser(source, Rule::file).and_then(|p| Ok(File::from(p)))
|
where
|
||||||
}
|
Node: From<Pair<'a, Rule>>,
|
||||||
|
{
|
||||||
|
const RULE: Rule;
|
||||||
|
|
||||||
fn run_parser<'a>(source: &'a str, rule: Rule) -> Result<Pair<'a, Rule>, ParseError<'a>> {
|
fn parse(source: &'a str) -> Result<Node, ParseError<'a>> {
|
||||||
let result = Grammar::parse(rule, source);
|
let result = Grammar::parse(Self::RULE, source);
|
||||||
match result {
|
match result {
|
||||||
Ok(mut pairs) => Ok(pairs.next().unwrap()),
|
Ok(mut pairs) => Ok(Node::from(pairs.next().unwrap())),
|
||||||
Err(pest_error) => Err(ParseError::from(pest_error)),
|
Err(pest_error) => Err(ParseError::from(pest_error)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
Reference in a new issue