1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
//! The Interpreter design pattern example module
//!
//! The interpreter is a function that is fed a series of arrays containing
//! integer tokens.  Each token represents a single word or punctuation mark.
//! The interpreter converts that array of tokens to an actual sentence by
//! interpreting the meaning of the tokens.
//! 
//! This is a very simple interpreter that handles the first token in a special
//! way and supports punctuation.  It is an example of a linear interpreter
//! where tokens can appear in any order (it's up to the creator of the token
//! list to make sure the outcome makes any sense).
//!
//! Accessed through the interpreter_exercise() function.
//-----------------------------------------------------------------------------
pub mod interpreter_interpreter;
//-----------------------------------------------------------------------------
use interpreter_interpreter::{InterpreterConstants, interpreter_interpret};
//-----------------------------------------------------------------------------
/// Represents the sentence: "What do you say to that?"
const SENTENCE_TOKENS0: &'static [usize] = &[ 39, 18, 17, 27,  2,  7, InterpreterConstants::QUESTION as usize, InterpreterConstants::EOL as usize ];
/// Represents the sentence: "Will you be the one to be there?"
const SENTENCE_TOKENS1: &'static [usize] = &[ 32, 17,  1,  0, 34,  2,   1,  37, InterpreterConstants::QUESTION as usize, InterpreterConstants::EOL as usize ];
/// Represents the sentence: "Would you have a will to do that?"
const SENTENCE_TOKENS2: &'static [usize] = &[ 36, 17,  8,  5, 32,  2,  18,   7, InterpreterConstants::QUESTION as usize, InterpreterConstants::EOL as usize ];
/// Represents the sentence: "For not you I would not be in this."
const SENTENCE_TOKENS3: &'static [usize] = &[ 11, 12, 17,  9, 36, 12,   1,   6,  20, InterpreterConstants::PERIOD as usize, InterpreterConstants::EOL as usize ];
/// Represents the sentence: "We say that but would you say it?"
const SENTENCE_TOKENS4: &'static [usize] = &[ 26, 27,  7, 21, 36, 17,  27,  10, InterpreterConstants::QUESTION as usize, InterpreterConstants::EOL as usize ];
/// Represents the sentence: "By her will we will do it."
const SENTENCE_TOKENS5: &'static [usize] = &[ 23, 28, 32, 26, 32, 18,  10, InterpreterConstants::PERIOD as usize, InterpreterConstants::EOL as usize ];
/// A list of pre-defined token lists.  Each token list represents a single
/// sentence constructed from the 40 most common words in the English language.
/// I don't use all 40 words, though; that would be silly.
const _SENTENCE_TOKEN_LISTS: &'static [&'static [usize]; 6] = &[
    &SENTENCE_TOKENS0,
    &SENTENCE_TOKENS1,
    &SENTENCE_TOKENS2,
    &SENTENCE_TOKENS3,
    &SENTENCE_TOKENS4,
    &SENTENCE_TOKENS5,
];
//-----------------------------------------------------------------------------
/// Helper function to convert a list of integers to a string representation.
///
/// # Parameters
/// - tokens
///
///   Array of integers to work with.  Assumed to be terminated with a -1 (EOL).
///
/// # Returns
/// Returns a string representation of the integer list.
fn _tokens_to_string(tokens: &[usize]) -> String {
    let mut buffer = String::new();
    buffer.push('[');
    let mut index = 0;
    while tokens[index] != (InterpreterConstants::EOL as usize) {
        buffer.push_str(&format!("{:3}", tokens[index]));
        if tokens[index + 1] != (InterpreterConstants::EOL as usize)
        {
            buffer.push_str(", ");
        }
        index += 1;
    }
    buffer.push(']');
    return buffer;
}
//-----------------------------------------------------------------------------
/// Example of using the "Interpreter" design pattern.
/// 
/// The interpreter is a function that is fed a series of arrays containing
/// integer tokens.  Each token represents a single word or punctuation mark.
/// The interpreter converts that array of tokens to an actual sentence by
/// interpreting the meaning of the tokens.
/// 
/// This is a very simple interpreter that handles the first token in a special
/// way and supports punctuation.  It is an example of a linear interpreter
/// where tokens can appear in any order (it's up to the creator of the token
/// list to make sure the outcome makes any sense).
/// 
/// The output shows the token list followed by the sentence produced
/// from the tokens.
// ! [Using Interpreter in Rust]
pub fn interpreter_exercise() -> Result<(), String> {
    println!("");
    println!("Interpreter Exercise");
    for sentence_index in 0.._SENTENCE_TOKEN_LISTS.len() {
        let token_list = _SENTENCE_TOKEN_LISTS[sentence_index];
        let tokens_as_string = _tokens_to_string(token_list);
        let sentence = interpreter_interpret(token_list);
        // 50 is a magic number corresponding to the longest token list
        // expressed as a string.  Derived empirically.  It makes the
        // output easier to, er, interpret.
        println!("  {:-50} ==> \"{}\"", tokens_as_string, sentence);
    }
    println!("  Done.");
    Ok(())
}
// ! [Using Interpreter in Rust]