1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

add execute & get_integer

This commit is contained in:
mat 2022-04-17 14:40:26 -05:00
parent 82ed6baea5
commit 10cd1733cb
9 changed files with 82 additions and 39 deletions

View file

@ -67,7 +67,6 @@ impl<S: Any + Clone> ArgumentBuilder<S> {
}
pub fn build(self) -> CommandNode<S> {
println!("building {:?}", self);
CommandNode {
value: self.value,

View file

@ -1,5 +1,8 @@
use super::argument_builder::{ArgumentBuilder, ArgumentBuilderType};
use crate::{parsers::Parser, string_reader::StringReader};
use crate::{
exceptions::command_syntax_exception::CommandSyntaxException, parsers::Parser,
string_reader::StringReader,
};
use std::{any::Any, fmt::Debug, rc::Rc};
/// An argument node type. The `T` type parameter is the type of the argument,
@ -17,7 +20,7 @@ impl Argument {
}
}
pub fn parse(&self, reader: &mut StringReader) -> Option<Rc<dyn Any>> {
pub fn parse(&self, reader: &mut StringReader) -> Result<Rc<dyn Any>, CommandSyntaxException> {
self.parser.parse(reader)
}
}

View file

@ -142,4 +142,9 @@ impl<S: Any + Clone> CommandContext<S> {
pub fn has_nodes(&self) -> bool {
return !self.nodes.is_empty();
}
pub fn argument(&self, name: &str) -> Option<Rc<dyn Any>> {
let argument = self.arguments.get(name);
argument.map(|a| a.result.clone())
}
}

View file

@ -5,7 +5,6 @@ use crate::{
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
},
parse_results::ParseResults,
string_range::StringRange,
string_reader::StringReader,
tree::CommandNode,
};
@ -28,10 +27,8 @@ impl<S: Any + Clone> CommandDispatcher<S> {
}
pub fn register(&mut self, node: ArgumentBuilder<S>) {
println!("register {:#?}", node);
let build = Rc::new(RefCell::new(node.build()));
self.root.borrow_mut().add_child(&build);
// println!("build: {:#?}", build);
}
pub fn parse(&self, command: StringReader, source: S) -> ParseResults<S> {
@ -142,7 +139,6 @@ impl<S: Any + Clone> CommandDispatcher<S> {
})
}
let best_potential = potentials.into_iter().next().unwrap();
println!("chosen {:#?}", best_potential);
return Ok(best_potential);
}
@ -153,10 +149,14 @@ impl<S: Any + Clone> CommandDispatcher<S> {
})
}
pub fn execute(&self, input: StringReader, source: S) -> Result<i32, CommandSyntaxException> {
let parse = self.parse(input, source);
Self::execute_parsed(parse)
}
/// Executes a given pre-parsed command.
pub fn execute(parse: ParseResults<S>) -> Result<i32, CommandSyntaxException> {
pub fn execute_parsed(parse: ParseResults<S>) -> Result<i32, CommandSyntaxException> {
if parse.reader.can_read() {
println!("can read from reader {}", parse.reader.cursor);
if parse.exceptions.len() == 1 {
return Err(parse.exceptions.values().next().unwrap().clone());
}
@ -169,7 +169,6 @@ impl<S: Any + Clone> CommandDispatcher<S> {
BuiltInExceptions::DispatcherUnknownArgument.create_with_context(&parse.reader)
);
}
println!("a");
let mut result = 0i32;
let mut successful_forks = 0;
let mut forked = false;

View file

@ -6,17 +6,17 @@ use super::command_syntax_exception::CommandSyntaxException;
#[derive(Clone, PartialEq)]
pub enum BuiltInExceptions {
DoubleTooSmall { found: usize, min: usize },
DoubleTooBig { found: usize, max: usize },
DoubleTooSmall { found: f64, min: f64 },
DoubleTooBig { found: f64, max: f64 },
FloatTooSmall { found: usize, min: usize },
FloatTooBig { found: usize, max: usize },
FloatTooSmall { found: f32, min: f32 },
FloatTooBig { found: f32, max: f32 },
IntegerTooSmall { found: usize, min: usize },
IntegerTooBig { found: usize, max: usize },
IntegerTooSmall { found: i32, min: i32 },
IntegerTooBig { found: i32, max: i32 },
LONGTooSmall { found: usize, min: usize },
LONGTooBig { found: usize, max: usize },
LongTooSmall { found: i64, min: i64 },
LongTooBig { found: i64, max: i64 },
LiteralIncorrect { expected: String },
@ -65,10 +65,10 @@ impl fmt::Debug for BuiltInExceptions {
write!(f, "Integer must not be more than {}, found {}", max, found)
}
BuiltInExceptions::LONGTooSmall { found, min } => {
BuiltInExceptions::LongTooSmall { found, min } => {
write!(f, "Long must not be less than {}, found {}", min, found)
}
BuiltInExceptions::LONGTooBig { found, max } => {
BuiltInExceptions::LongTooBig { found, max } => {
write!(f, "Long must not be more than {}, found {}", max, found)
}

View file

@ -18,7 +18,7 @@ mod tests {
use crate::{
builder::{literal_argument_builder::literal, required_argument_builder::argument},
dispatcher::CommandDispatcher,
parsers::integer,
parsers::{get_integer, integer},
};
struct CommandSourceStack {
@ -36,7 +36,7 @@ mod tests {
dispatcher.register(
literal("foo")
.then(argument("bar", integer()).executes(|c| {
// println!("Bar is {}", get_integer(c, "bar"));
println!("Bar is {:?}", get_integer(c, "bar"));
2
}))
.executes(|c| {
@ -45,11 +45,8 @@ mod tests {
}),
);
let parse = dispatcher.parse("foo 123".to_string().into(), source);
println!(
"{}",
CommandDispatcher::<Rc<CommandSourceStack>>::execute(parse).unwrap()
);
// assert_eq!(dispatcher.execute("foo bar", source), 2);
let parse = dispatcher.parse("foo 123".into(), source.clone());
assert_eq!(CommandDispatcher::<_>::execute_parsed(parse).unwrap(), 2);
assert_eq!(dispatcher.execute("foo".into(), source).unwrap(), 1);
}
}

View file

@ -1,21 +1,56 @@
use std::{any::Any, marker::PhantomData, rc::Rc};
use crate::string_reader::StringReader;
use crate::{
context::CommandContext,
exceptions::{
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
},
string_reader::StringReader,
};
pub trait Parser {
fn parse(&self, reader: &mut StringReader) -> Option<Rc<dyn Any>>;
fn parse(&self, reader: &mut StringReader) -> Result<Rc<dyn Any>, CommandSyntaxException>;
}
#[derive(Default)]
struct Integer {
pub minimum: Option<i32>,
pub maximum: Option<i32>,
}
struct Integer {}
impl Parser for Integer {
fn parse(&self, reader: &mut StringReader) -> Option<Rc<dyn Any>> {
fn parse(&self, reader: &mut StringReader) -> Result<Rc<dyn Any>, CommandSyntaxException> {
let start = reader.cursor;
let result = reader.read_int();
// TODO: check min and max
Some(Rc::new(result))
let result = reader.read_int()?;
if let Some(minimum) = self.minimum {
if result < minimum {
return Err(BuiltInExceptions::IntegerTooSmall {
found: result,
min: minimum,
}
.create_with_context(reader));
}
}
if let Some(maximum) = self.maximum {
if result > maximum {
return Err(BuiltInExceptions::IntegerTooBig {
found: result,
max: maximum,
}
.create_with_context(reader));
}
}
Ok(Rc::new(result))
}
}
pub fn integer() -> impl Parser {
Integer {}
Integer::default()
}
pub fn get_integer<S: Any + Clone>(context: &CommandContext<S>, name: &str) -> Option<i32> {
context
.argument(name)
.unwrap()
.downcast_ref::<i32>()
.map(|x| *x)
}

View file

@ -18,6 +18,14 @@ impl From<String> for StringReader {
Self { string, cursor: 0 }
}
}
impl From<&str> for StringReader {
fn from(string: &str) -> Self {
Self {
string: string.to_string(),
cursor: 0,
}
}
}
impl StringReader {
pub fn string(&self) -> &str {

View file

@ -67,8 +67,6 @@ impl<S: Any + Clone> CommandNode<S> {
pub fn get_relevant_nodes(&self, input: &mut StringReader) -> Vec<Rc<RefCell<CommandNode<S>>>> {
let literals = self.literals();
println!("get relevant nodes {:?} literals={:?}", self, literals);
if literals.len() > 0 {
let cursor = input.cursor();
while input.can_read() && input.peek() != ' ' {
@ -220,7 +218,6 @@ impl<S: Any + Clone> Debug for CommandNode<S> {
impl<S: Any + Clone> Default for CommandNode<S> {
fn default() -> Self {
println!("making default node");
Self {
value: ArgumentBuilderType::Literal(Literal::default()),