Split module and function defines.

This commit is contained in:
James Harton 2018-09-09 14:15:57 +12:00
parent c166f66ac6
commit c32adf0838
14 changed files with 184 additions and 601 deletions

View file

@ -1,4 +1,4 @@
use ast::{def::Define, expression::Expression}; use ast::{define_function::DefineFunction, expression::Expression};
use grammar::Rule; use grammar::Rule;
use pest::iterators::Pair; use pest::iterators::Pair;
use pest::Span; use pest::Span;
@ -11,7 +11,7 @@ pub struct Block<'a> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Inner<'a> { pub enum Inner<'a> {
Define(Define<'a>), DefineFunction(DefineFunction<'a>),
Expression(Expression<'a>), Expression(Expression<'a>),
} }
@ -23,7 +23,7 @@ impl<'a> From<Pair<'a, Rule>> for Block<'a> {
let body = pair let body = pair
.into_inner() .into_inner()
.map(|p| match p.as_rule() { .map(|p| match p.as_rule() {
Rule::def => Inner::Define(Define::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!(),
}) })
@ -37,9 +37,9 @@ impl<'a> From<Pair<'a, Rule>> for Block<'a> {
} }
impl<'a> Inner<'a> { impl<'a> Inner<'a> {
fn define(&self) -> Option<&Define<'a>> { fn define_function(&self) -> Option<&DefineFunction<'a>> {
match self { match self {
Inner::Define(ref inner) => Some(&inner), Inner::DefineFunction(ref inner) => Some(&inner),
_ => None, _ => None,
} }
} }

View file

@ -1,56 +0,0 @@
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
use grammar::Rule;
use pest::iterators::Pairs;
use pest::Span;
#[derive(Debug, Clone)]
pub struct Impl<'a> {
pub span: Span<'a>,
pub name: TypeName<'a>,
pub fields: Vec<(ArgumentName<'a>, Expression<'a>)>,
}
impl<'a> From<Pairs<'a, Rule>> for Impl<'a> {
fn from(mut pairs: Pairs<'a, Rule>) -> Self {
let pair = pairs.next().unwrap();
let span = pair.clone().into_span();
let type_name = get_type_name(pairs.clone());
let fields = get_fields(pairs);
Impl {
span: span,
name: type_name,
fields: fields,
}
}
}
impl<'a> Impl<'a> {
pub fn name(&self) -> &str {
&self.name.name
}
pub fn fields(&self) -> &Vec<(ArgumentName<'a>, Expression<'a>)> {
&self.fields
}
}
fn get_type_name<'a>(pairs: Pairs<'a, Rule>) -> TypeName {
let pair = pairs
.filter(|p| p.as_rule() == Rule::type_name)
.next()
.unwrap();
TypeName::from(pair)
}
fn get_fields<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expression<'a>)> {
pairs
.filter(|p| p.as_rule() == Rule::argument_pair)
.map(|p| {
let mut pairs = p.into_inner();
let arg_name = pairs.next().unwrap();
let value = pairs.next().unwrap();
(ArgumentName::from(arg_name), Expression::from(value))
})
.collect()
}

View file

@ -1,56 +0,0 @@
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
use grammar::Rule;
use pest::iterators::Pairs;
use pest::Span;
#[derive(Debug, Clone)]
pub struct Trait<'a> {
pub span: Span<'a>,
pub name: TypeName<'a>,
pub fields: Vec<(ArgumentName<'a>, Expression<'a>)>,
}
impl<'a> From<Pairs<'a, Rule>> for Trait<'a> {
fn from(mut pairs: Pairs<'a, Rule>) -> Self {
let pair = pairs.next().unwrap();
let span = pair.clone().into_span();
let type_name = get_type_name(pairs.clone());
let fields = get_fields(pairs);
Trait {
span: span,
name: type_name,
fields: fields,
}
}
}
impl<'a> Trait<'a> {
pub fn name(&self) -> &str {
&self.name.name
}
pub fn fields(&self) -> &Vec<(ArgumentName<'a>, Expression<'a>)> {
&self.fields
}
}
fn get_type_name<'a>(pairs: Pairs<'a, Rule>) -> TypeName<'a> {
let pair = pairs
.filter(|p| p.as_rule() == Rule::type_name)
.next()
.unwrap();
TypeName::from(pair)
}
fn get_fields<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expression<'a>)> {
pairs
.filter(|p| p.as_rule() == Rule::argument_pair)
.map(|p| {
let mut pairs = p.into_inner();
let arg_name = pairs.next().unwrap();
let value = pairs.next().unwrap();
(ArgumentName::from(arg_name), Expression::from(value))
})
.collect()
}

View file

@ -1,56 +0,0 @@
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
use grammar::Rule;
use pest::iterators::Pairs;
use pest::Span;
#[derive(Debug, Clone)]
pub struct Type<'a> {
pub span: Span<'a>,
pub name: TypeName<'a>,
pub fields: Vec<(ArgumentName<'a>, Expression<'a>)>,
}
impl<'a> From<Pairs<'a, Rule>> for Type<'a> {
fn from(mut pairs: Pairs<'a, Rule>) -> Self {
let pair = pairs.next().unwrap();
let span = pair.clone().into_span();
let type_name = get_type_name(pairs.clone());
let fields = get_fields(pairs);
Type {
span: span,
name: type_name,
fields: fields,
}
}
}
impl<'a> Type<'a> {
pub fn name(&self) -> &str {
&self.name.name
}
pub fn fields(&self) -> &Vec<(ArgumentName<'a>, Expression<'a>)> {
&self.fields
}
}
fn get_type_name<'a>(pairs: Pairs<'a, Rule>) -> TypeName {
let pair = pairs
.filter(|p| p.as_rule() == Rule::type_name)
.next()
.unwrap();
TypeName::from(pair)
}
fn get_fields<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expression<'a>)> {
pairs
.filter(|p| p.as_rule() == Rule::argument_pair)
.map(|p| {
let mut pairs = p.into_inner();
let arg_name = pairs.next().unwrap();
let value = pairs.next().unwrap();
(ArgumentName::from(arg_name), Expression::from(value))
})
.collect()
}

View file

@ -1,316 +0,0 @@
mod deffunction;
mod defimpl;
mod deftrait;
mod deftype;
use self::deffunction::Function;
use self::defimpl::Impl;
use self::deftrait::Trait;
use self::deftype::Type;
use grammar::Rule;
use pest::iterators::Pair;
use pest::Span;
#[derive(Debug, Clone)]
pub struct Define<'a> {
pub span: Span<'a>,
pub inner: DefineWhat<'a>,
}
#[derive(Debug, Clone)]
pub enum DefineWhat<'a> {
Type(Type<'a>),
Trait(Trait<'a>),
Impl(Impl<'a>),
Function(Function<'a>),
}
impl<'a> Define<'a> {
pub fn is_type(&self) -> bool {
match self.inner {
DefineWhat::Type(_) => true,
_ => false,
}
}
pub fn is_trait(&self) -> bool {
match self.inner {
DefineWhat::Trait(_) => true,
_ => false,
}
}
pub fn is_impl(&self) -> bool {
match self.inner {
DefineWhat::Impl(_) => true,
_ => false,
}
}
pub fn is_function(&self) -> bool {
match self.inner {
DefineWhat::Function(_) => true,
_ => false,
}
}
pub fn type_(&self) -> Option<&Type<'a>> {
match self.inner {
DefineWhat::Type(ref inner) => Some(&inner),
_ => None,
}
}
pub fn trait_(&self) -> Option<&Trait<'a>> {
match self.inner {
DefineWhat::Trait(ref inner) => Some(&inner),
_ => None,
}
}
pub fn impl_(&self) -> Option<&Impl<'a>> {
match self.inner {
DefineWhat::Impl(ref inner) => Some(&inner),
_ => None,
}
}
pub fn function(&self) -> Option<&Function<'a>> {
match self.inner {
DefineWhat::Function(ref inner) => Some(&inner),
_ => None,
}
}
}
impl<'a> From<Pair<'a, Rule>> for Define<'a> {
fn from(pair: Pair<'a, Rule>) -> Self {
assert_eq!(pair.as_rule(), Rule::def);
let span = pair.clone().into_span();
let pairs = pair.into_inner();
let first_rule = pairs.clone().next().unwrap().as_rule();
let inner = match first_rule {
Rule::def_impl => DefineWhat::Impl(Impl::from(pairs)),
Rule::def_private => DefineWhat::Function(Function::from(pairs)),
Rule::def_public => DefineWhat::Function(Function::from(pairs)),
Rule::def_static => DefineWhat::Function(Function::from(pairs)),
Rule::def_trait => DefineWhat::Trait(Trait::from(pairs)),
Rule::def_type => DefineWhat::Type(Type::from(pairs)),
_ => unreachable!(),
};
Define {
span: span,
inner: inner,
}
}
}
#[cfg(test)]
mod test {
use super::deffunction::FunctionType;
use super::*;
use grammar::parse_str;
#[test]
fn def_static() {
let result = parse_str("defstatic marty", Rule::file);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_static());
assert!(fun.fields().is_empty());
}
#[test]
fn def_static_with_type() {
let result = parse_str("defstatic <McFly> marty", Rule::def_test);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_static());
assert!(fun.fields().is_empty());
assert_eq!(fun.return_type().unwrap().name(), "McFly");
}
#[test]
fn def_static_with_type_and_arguments() {
let result = parse_str(
"defstatic <McFly> marty date_of_birth: Date",
Rule::def_test,
);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_static());
assert_eq!(fun.return_type().unwrap().name(), "McFly");
let (ref arg_name, ref arg_value) = fun.fields()[0];
assert_eq!(arg_name.name(), "date_of_birth");
assert_eq!(
arg_value.literal().unwrap().type_name().unwrap().name(),
"Date"
);
}
#[test]
fn def_private() {
let result = parse_str("defp marty", Rule::def_test);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_private());
assert!(fun.return_type().is_none());
assert!(fun.fields().is_empty());
}
#[test]
fn def_private_with_type() {
let result = parse_str("defp <McFly> marty", Rule::def_test);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_private());
assert_eq!(fun.return_type().unwrap().name(), "McFly");
assert!(fun.fields().is_empty());
}
#[test]
fn def_private_with_type_and_arguments() {
let result = parse_str("defp <McFly> marty date_of_birth: Date", Rule::def_test);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_private());
assert_eq!(fun.return_type().unwrap().name(), "McFly");
let (ref arg_name, ref arg_value) = fun.fields()[0];
assert_eq!(arg_name.name(), "date_of_birth");
assert_eq!(
arg_value.literal().unwrap().type_name().unwrap().name(),
"Date"
);
}
#[test]
fn def_public() {
let result = parse_str("def marty", Rule::def_test);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_public());
assert!(fun.return_type().is_none());
assert!(fun.fields().is_empty())
}
#[test]
fn def_public_with_type() {
let result = parse_str("def <McFly> marty", Rule::def_test);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_public());
assert_eq!(fun.return_type().unwrap().name(), "McFly");
assert!(fun.fields().is_empty())
}
#[test]
fn def_public_with_type_and_arguments() {
let result = parse_str("def <McFly> marty date_of_birth: Date", Rule::def_test);
let def = Define::from(result);
let fun = def.function().unwrap();
assert_eq!(fun.name(), "marty");
assert!(fun.is_public());
assert_eq!(fun.return_type().unwrap().name(), "McFly");
let (ref arg_name, ref arg_value) = fun.fields()[0];
assert_eq!(arg_name.name(), "date_of_birth");
assert_eq!(
arg_value.literal().unwrap().type_name().unwrap().name(),
"Date"
);
}
#[test]
fn def_type_with_no_fields() {
let result = parse_str("deftype Delorean", Rule::def_test);
let def = Define::from(result);
let ty = def.type_().unwrap();
assert_eq!(ty.name(), "Delorean");
assert!(ty.fields().is_empty());
}
#[test]
fn def_type_with_fields() {
let result = parse_str("deftype Delorean speed: Integer", Rule::def_test);
let def = Define::from(result);
let ty = def.type_().unwrap();
assert_eq!(ty.name(), "Delorean");
let (ref arg_name, ref arg_value) = ty.fields()[0];
assert_eq!(arg_name.name(), "speed");
assert_eq!(
arg_value.literal().unwrap().type_name().unwrap().name(),
"Integer"
);
}
#[test]
fn def_trait_with_no_fields() {
let result = parse_str("deftrait TimeMachine", Rule::def_test);
let def = Define::from(result);
let tr = def.trait_().unwrap();
assert_eq!(tr.name(), "TimeMachine");
assert!(tr.fields().is_empty());
}
#[test]
fn def_trait_with_fields() {
let result = parse_str("deftrait TimeMachine year: Integer", Rule::def_test);
let def = Define::from(result);
let tr = def.trait_().unwrap();
assert_eq!(tr.name(), "TimeMachine");
let (ref arg_name, ref arg_value) = tr.fields()[0];
assert_eq!(arg_name.name(), "year");
assert_eq!(
arg_value.literal().unwrap().type_name().unwrap().name(),
"Integer"
);
}
#[test]
fn def_impl_with_fields() {
let result = parse_str("defimpl TimeMachine for: Delorean", Rule::def_test);
let def = Define::from(result);
let im = def.impl_().unwrap();
assert_eq!(im.name(), "TimeMachine");
let (ref arg_name, ref arg_value) = im.fields()[0];
assert_eq!(arg_name.name(), "for");
assert_eq!(
arg_value.literal().unwrap().type_name().unwrap().name(),
"Delorean"
);
}
#[test]
fn def_type_with_body() {
let result = parse_str(
"deftype Delorean speed: Integer, as: ->
defstatic <Delorean> new as: ->
Delorean { speed: 0 }
end
end",
Rule::def_test,
);
let def = Define::from(result);
let ty = def.type_().unwrap();
assert_eq!(ty.name(), "Delorean");
let (ref arg_name, ref arg_value) = ty.fields()[0];
assert_eq!(arg_name.name(), "speed");
assert_eq!(
arg_value.literal().unwrap().type_name().unwrap().name(),
"Integer"
);
let (ref arg_name, ref arg_value) = ty.fields()[1];
assert_eq!(arg_name.name(), "as");
assert!(arg_value.is_block());
}
}

View file

@ -4,12 +4,12 @@ use pest::iterators::{Pair, Pairs};
use pest::Span; use pest::Span;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Function<'a> { pub struct DefineFunction<'a> {
pub span: Span<'a>, span: Span<'a>,
pub name: FunctionName<'a>, fn_name: FunctionName<'a>,
pub return_type: Option<TypeName<'a>>, rt_type: Option<TypeName<'a>>,
pub fn_type: FunctionType, fn_type: FunctionType,
pub fields: Vec<(ArgumentName<'a>, Expression<'a>)>, fields: Vec<(ArgumentName<'a>, Expression<'a>)>,
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -25,13 +25,13 @@ pub struct FunctionName<'a> {
pub name: String, pub name: String,
} }
impl<'a> Function<'a> { impl<'a> DefineFunction<'a> {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
&self.name.name &self.fn_name.name
} }
pub fn return_type(&self) -> Option<&TypeName<'a>> { pub fn return_type(&self) -> Option<&TypeName<'a>> {
match self.return_type { match self.rt_type {
Some(ref type_name) => Some(&type_name), Some(ref type_name) => Some(&type_name),
None => None, None => None,
} }
@ -63,20 +63,22 @@ impl<'a> Function<'a> {
} }
} }
impl<'a> From<Pairs<'a, Rule>> for Function<'a> { impl<'a> From<Pair<'a, Rule>> for DefineFunction<'a> {
fn from(mut pairs: Pairs<'a, Rule>) -> Self { fn from(pair: Pair<'a, Rule>) -> Self {
let pair = pairs.next().unwrap(); assert_eq!(pair.as_rule(), Rule::def_function);
let span = pair.clone().into_span(); let span = pair.clone().into_span();
let fn_type = FunctionType::from(pair); let mut pairs = pair.into_inner();
let fn_type = FunctionType::from(pairs.next().unwrap());
let rt_type = get_return_type(pairs.clone()); let rt_type = get_return_type(pairs.clone());
let name = get_name(pairs.clone()); let name = get_name(pairs.clone());
let arguments = get_arguments(pairs); let arguments = get_arguments(pairs);
Function { DefineFunction {
span: span, span: span,
name: name, fn_name: name,
fn_type: fn_type, fn_type: fn_type,
return_type: rt_type, rt_type: rt_type,
fields: arguments, fields: arguments,
} }
} }

View file

@ -0,0 +1,61 @@
use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName};
use grammar::Rule;
use pest::iterators::{Pair, Pairs};
use pest::Span;
#[derive(Debug, Clone)]
pub struct DefineModule<'a> {
span: Span<'a>,
ty_name: TypeName<'a>,
mod_type: ModuleType,
fields: Vec<(ArgumentName<'a>, Expression<'a>)>,
}
#[derive(Debug, PartialEq, Clone)]
pub enum ModuleType {
Implementation,
Trait,
Type,
}
impl<'a> From<Pair<'a, Rule>> for ModuleType {
fn from(pair: Pair<'a, Rule>) -> Self {
match pair.as_rule() {
Rule::def_impl => ModuleType::Implementation,
Rule::def_trait => ModuleType::Trait,
Rule::def_type => ModuleType::Type,
_ => unreachable!(),
}
}
}
impl<'a> From<Pair<'a, Rule>> for DefineModule<'a> {
fn from(pair: Pair<'a, Rule>) -> Self {
assert_eq!(pair.as_rule(), Rule::def_module);
let span = pair.clone().into_span();
let mut pairs = pair.into_inner();
let mod_type = ModuleType::from(pairs.next().unwrap());
let type_name = TypeName::from(pairs.next().unwrap());
let fields = get_arguments(pairs);
DefineModule {
span: span,
ty_name: type_name,
mod_type: mod_type,
fields: fields,
}
}
}
fn get_arguments<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expression<'a>)> {
pairs
.filter(|p| p.as_rule() == Rule::argument_pair)
.map(|p| {
let mut pairs = p.into_inner();
let arg_name = pairs.next().unwrap();
let value = pairs.next().unwrap();
(ArgumentName::from(arg_name), Expression::from(value))
})
.collect()
}

View file

@ -1,4 +1,4 @@
use ast::def::Define; use ast::define_module::DefineModule;
use grammar::Rule; use grammar::Rule;
use pest::iterators::Pair; use pest::iterators::Pair;
use pest::Span; use pest::Span;
@ -6,7 +6,7 @@ use pest::Span;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct File<'a> { pub struct File<'a> {
span: Span<'a>, span: Span<'a>,
children: Vec<Define<'a>>, children: Vec<DefineModule<'a>>,
} }
impl<'a> From<Pair<'a, Rule>> for File<'a> { impl<'a> From<Pair<'a, Rule>> for File<'a> {
@ -14,7 +14,7 @@ impl<'a> From<Pair<'a, Rule>> for File<'a> {
assert_eq!(pair.as_rule(), Rule::file); assert_eq!(pair.as_rule(), Rule::file);
let span = pair.clone().into_span(); let span = pair.clone().into_span();
let children = pair.into_inner().map(|p| Define::from(p)).collect(); let children = pair.into_inner().map(|p| DefineModule::from(p)).collect();
File { File {
span: span, span: span,

View file

@ -5,7 +5,8 @@ mod block;
mod boolean; mod boolean;
mod call; mod call;
mod constructor; mod constructor;
mod def; mod define_function;
mod define_module;
mod expression; mod expression;
mod file; mod file;
mod float; mod float;
@ -27,7 +28,8 @@ pub use self::{
boolean::Boolean, boolean::Boolean,
call::{Call, Message, Receiver}, call::{Call, Message, Receiver},
constructor::Constructor, constructor::Constructor,
def::Define, define_function::DefineFunction,
define_module::DefineModule,
file::File, file::File,
float::Float, float::Float,
infix::Infix, infix::Infix,

View file

@ -13,7 +13,7 @@
// ## INPUTS // ## INPUTS
// #################################### // ####################################
file = _{ soi ~ def* ~ eoi } file = _{ soi ~ def_module* ~ eoi }
// #################################### // ####################################
@ -72,7 +72,7 @@ block_test = _{ soi ~ block ~ eoi }
block = @{ block_stabby ~ whitespace+ ~ (block_end | block_body) } block = @{ block_stabby ~ whitespace+ ~ (block_end | block_body) }
block_stabby = _{ "->" } block_stabby = _{ "->" }
block_body = _{ block_expression ~ (padded_newline+ ~ block_expression)* ~ whitespace* ~ block_end } block_body = _{ block_expression ~ (padded_newline+ ~ block_expression)* ~ whitespace* ~ block_end }
block_expression = _{ def | expression } block_expression = _{ def_function | expression }
block_end = _{ "end" ~ !identifier_tail } block_end = _{ "end" ~ !identifier_tail }
@ -128,7 +128,6 @@ argument_keyword = ${ identifier ~ ":" }
// ## DEFINES // ## DEFINES
// #################################### // ####################################
def_test = _{ soi ~ def ~ eoi }
def_fn_keyword = _{ def_static | def_private | def_public } def_fn_keyword = _{ def_static | def_private | def_public }
def_type_keyword = _{ def_trait | def_type | def_impl } def_type_keyword = _{ def_trait | def_type | def_impl }
def_keyword = _{ def_type_keyword | def_fn_keyword } def_keyword = _{ def_type_keyword | def_fn_keyword }
@ -141,9 +140,10 @@ def_impl = { "defimpl" }
def_name = ${ identifier ~ def_predicate? } def_name = ${ identifier ~ def_predicate? }
def_predicate = { "?" } def_predicate = { "?" }
def_return_type = { "<" ~ type_name ~ ">" } def_return_type = { "<" ~ type_name ~ ">" }
def_fn = _{ def_fn_keyword ~ def_return_type? ~ def_name ~ argument_list? } def_function = !{ def_fn_keyword ~ def_return_type? ~ def_name ~ argument_list? }
def_ty = _{ def_type_keyword ~ type_name ~ argument_list? } def_module = !{ def_type_keyword ~ type_name ~ argument_list? }
def = !{ def_ty | def_fn } def_function_test = _{ soi ~ def_function ~ eoi }
def_module_test = _{ soi ~ def_module ~ eoi }
// #################################### // ####################################

View file

@ -5,9 +5,9 @@ fn define_no_args() {
parses_to!( parses_to!(
parser: Grammar, parser: Grammar,
input: "def name", input: "def name",
rule: Rule::def_test, rule: Rule::def_function_test,
tokens: [ tokens: [
def(0, 8, [ def_function(0, 8, [
def_public(0, 3), def_public(0, 3),
def_name(4, 8, [identifier(4, 8)]) def_name(4, 8, [identifier(4, 8)])
]) ])
@ -20,9 +20,9 @@ fn define_return_type_no_args() {
parses_to!( parses_to!(
parser: Grammar, parser: Grammar,
input: "def <Marty> name", input: "def <Marty> name",
rule: Rule::def_test, rule: Rule::def_function_test,
tokens: [ tokens: [
def(0, 16, [ def_function(0, 16, [
def_public(0, 3), def_public(0, 3),
def_return_type(4, 11, [ def_return_type(4, 11, [
type_name(5, 10) type_name(5, 10)
@ -38,9 +38,9 @@ fn define_return_type_with_args() {
parses_to!( parses_to!(
parser: Grammar, parser: Grammar,
input: r#"def <Character> new_character name: String, as: 123"#, input: r#"def <Character> new_character name: String, as: 123"#,
rule: Rule::def_test, rule: Rule::def_function_test,
tokens: [ tokens: [
def(0, 51, [ def_function(0, 51, [
def_public(0, 3), def_public(0, 3),
def_return_type(4, 15, [ def_return_type(4, 15, [
type_name(5, 14) type_name(5, 14)
@ -72,9 +72,9 @@ fn define_with_args() {
parses_to!( parses_to!(
parser: Grammar, parser: Grammar,
input: r#"def new_character name: String, as: 123"#, input: r#"def new_character name: String, as: 123"#,
rule: Rule::def_test, rule: Rule::def_function_test,
tokens: [ tokens: [
def(0, 39, [ def_function(0, 39, [
def_public(0, 3), def_public(0, 3),
def_name(4, 17, [identifier(4, 17)]), def_name(4, 17, [identifier(4, 17)]),
argument_pair(18, 30, [ argument_pair(18, 30, [
@ -103,9 +103,9 @@ fn define_with_body() {
parses_to!( parses_to!(
parser: Grammar, parser: Grammar,
input: r#"defp marty as: -> 123 end"#, input: r#"defp marty as: -> 123 end"#,
rule: Rule::def_test, rule: Rule::def_function_test,
tokens: [ tokens: [
def(0, 25, [ def_function(0, 25, [
def_private(0, 4), def_private(0, 4),
def_name(5, 10, [identifier(5, 10)]), def_name(5, 10, [identifier(5, 10)]),
argument_pair(11, 25, [ argument_pair(11, 25, [
@ -132,9 +132,9 @@ fn define_constructor() {
input: "defstatic <Delorean> new as: -> input: "defstatic <Delorean> new as: ->
Delorean { speed: 0 } Delorean { speed: 0 }
end", end",
rule: Rule::def_test, rule: Rule::def_function_test,
tokens: [ tokens: [
def(0, 91, [ def_function(0, 91, [
def_static(0, 9), def_static(0, 9),
def_return_type(10, 20, [type_name(11, 19)]), def_return_type(10, 20, [type_name(11, 19)]),
def_name(21, 24, [identifier(21, 24)]), def_name(21, 24, [identifier(21, 24)]),
@ -170,9 +170,9 @@ fn define_function_with_predicate() {
parses_to!( parses_to!(
parser: Grammar, parser: Grammar,
input: "defp name?", input: "defp name?",
rule: Rule::def_test, rule: Rule::def_function_test,
tokens: [ tokens: [
def(0, 10, [ def_function(0, 10, [
def_private(0, 4), def_private(0, 4),
def_name(5, 10, [ def_name(5, 10, [
identifier(5, 9), identifier(5, 9),
@ -182,69 +182,3 @@ fn define_function_with_predicate() {
] ]
) )
} }
#[test]
fn def_trait_type_only() {
parses_to!(
parser: Grammar,
input: r#"deftrait Integer"#,
rule: Rule::def_test,
tokens: [
def(0, 16, [
def_trait(0, 8),
type_name(9, 16)
])
]
)
}
#[test]
fn def_trait_with_args() {
parses_to!(
parser: Grammar,
input: r#"deftrait Integer requires: [Addition, BitwiseAnd]"#,
rule: Rule::def_test,
tokens: [
def(0, 49, [
def_trait(0, 8),
type_name(9, 16),
argument_pair(17, 49, [
argument_keyword(17, 26, [
identifier(17, 25)
]),
expression(27, 49, [
literal(27, 49, [
array(27, 49, [
expression(28, 36, [literal(28, 36, [type_name(28, 36)])]),
expression(38, 48, [literal(38, 48, [type_name(38, 48)])])
])
])
])
])
])
]
)
}
#[test]
fn def_trait_with_body() {
parses_to!(
parser: Grammar,
input: r#"deftrait Result as: -> end"#,
rule: Rule::def_test,
tokens: [
def(0, 26, [
def_trait(0, 8),
type_name(9, 15),
argument_pair(16, 26, [
argument_keyword(16, 19, [
identifier(16, 18)
]),
expression(20, 26, [
block(20, 26)
])
])
])
]
)
}

View file

@ -0,0 +1,67 @@
use grammar::{Grammar, Rule};
#[test]
fn def_trait_type_only() {
parses_to!(
parser: Grammar,
input: r#"deftrait Integer"#,
rule: Rule::def_module_test,
tokens: [
def_module(0, 16, [
def_trait(0, 8),
type_name(9, 16)
])
]
)
}
#[test]
fn def_trait_with_args() {
parses_to!(
parser: Grammar,
input: r#"deftrait Integer requires: [Addition, BitwiseAnd]"#,
rule: Rule::def_module_test,
tokens: [
def_module(0, 49, [
def_trait(0, 8),
type_name(9, 16),
argument_pair(17, 49, [
argument_keyword(17, 26, [
identifier(17, 25)
]),
expression(27, 49, [
literal(27, 49, [
array(27, 49, [
expression(28, 36, [literal(28, 36, [type_name(28, 36)])]),
expression(38, 48, [literal(38, 48, [type_name(38, 48)])])
])
])
])
])
])
]
)
}
#[test]
fn def_trait_with_body() {
parses_to!(
parser: Grammar,
input: r#"deftrait Result as: -> end"#,
rule: Rule::def_module_test,
tokens: [
def_module(0, 26, [
def_trait(0, 8),
type_name(9, 15),
argument_pair(16, 26, [
argument_keyword(16, 19, [
identifier(16, 18)
]),
expression(20, 26, [
block(20, 26)
])
])
])
]
)
}

View file

@ -11,7 +11,7 @@ fn multi_def_with_args() {
", ",
rule: Rule::file, rule: Rule::file,
tokens: [ tokens: [
def(17, 66, [ def_module(17, 66, [
def_type(17, 24), def_type(17, 24),
type_name(25, 33), type_name(25, 33),
argument_pair(34, 48, [ argument_pair(34, 48, [
@ -23,7 +23,7 @@ fn multi_def_with_args() {
]) ])
]) ])
]), ]),
def(66, 115, [ def_module(66, 115, [
def_impl(66, 73), def_impl(66, 73),
type_name(74, 85), type_name(74, 85),
argument_pair(86, 99, [ argument_pair(86, 99, [
@ -50,11 +50,11 @@ fn multi_def_no_args() {
", ",
rule: Rule::file, rule: Rule::file,
tokens: [ tokens: [
def(17, 51, [ def_module(17, 51, [
def_type(17, 24), def_type(17, 24),
type_name(25, 33), type_name(25, 33),
]), ]),
def(51, 86, [ def_module(51, 86, [
def_impl(51, 58), def_impl(51, 58),
type_name(59, 70) type_name(59, 70)
]) ])

View file

@ -3,7 +3,8 @@ mod binary;
mod block; mod block;
mod call; mod call;
mod comment; mod comment;
mod def; mod def_function;
mod def_module;
mod file; mod file;
mod float; mod float;
mod identifier; mod identifier;