chomatter_lexer 0.0.1

A lexer for the Chomatter programming language
Documentation
#[cfg(test)]
mod lex_tests {
    use super::super::*;
    use commons::{EPrimitiveToken::*, *};

    struct BeginEndModel(String, usize, usize);
    struct ExpressionModel(String, usize, usize);
    struct LexModel(String, Vec<EPrimitiveToken>);

    fn assert_tokens(input: Vec<PrimitiveToken>, lexes: Vec<EPrimitiveToken>) {
        let mut i = 0;
        assert!(
            input.len() == lexes.len(),
            "Lengths are not equal\n-------------\n> {:?}\n|\n> {:?}\n---------\n",
            input
                .iter()
                .map(|t| t.kind.clone())
                .collect::<Vec<EPrimitiveToken>>(),
            lexes
        );
        for lex in lexes.clone() {
            assert_eq!(
                input[i].kind,
                lex,
                "\n-------------\n> {:?}\n|\n> {:?}\n---------\n",
                input
                    .iter()
                    .map(|t| t.kind.clone())
                    .collect::<Vec<EPrimitiveToken>>(),
                lexes
            );
            i += 1;
        }
    }

    #[test]
    fn tget_identifier() {
        let datas = vec![
            BeginEndModel(String::from("abc"), 0, 3),
            BeginEndModel(String::from("abc:"), 0, 3),
        ];

        for data in datas {
            let result = get_identifier(&data.0, &0, &mut data.0.chars().count());
            assert_eq!(
                result.unwrap(),
                Segment {
                    begin: data.1,
                    count: data.2,
                },
            );
        }
    }

    #[test]
    fn tget_end_of_params() {
        let datas = vec![
            BeginEndModel("(x, y)".to_string(), 0, 5),
            BeginEndModel("(sub(x, y), y)".to_string(), 0, 13),
            BeginEndModel("sub(x, y), y)".to_string(), 0, 0),
            BeginEndModel("(\"status)\", 1)".to_string(), 0, 13),
        ];
        for data in datas {
            let result = get_end_of_params(&data.0, &data.1, &data.0.chars().count());
            assert_eq!(result, data.2);
        }
    }

    #[test]
    fn end_of_string() {
        let datas = vec![
            ExpressionModel("\"Não é\"".to_string(), 0, 6),
            ExpressionModel("\"Hello World!\"".to_string(), 0, 13),
            ExpressionModel("\"ab#{\"c\"}de\" {}".to_string(), 0, 11),
            ExpressionModel("\"ab#{\"c #{\"\\\"x\\\"\"}\"}de\" {}".to_string(), 0, 22),
        ];
        for data in datas {
            let result = get_end_of_string(&data.0, &data.1, &data.0.chars().count());
            assert_eq!(result, data.2, "Failed on {}", data.0);
        }
    }

    #[test]
    fn tget_expression() {
        let datas = vec![
            ExpressionModel("\"Hello World!\"".to_string(), 0, 14),
            ExpressionModel("\"ab#{\"c\"}de\" {}".to_string(), 0, 12),
            ExpressionModel("24".to_string(), 0, 2),
            ExpressionModel("24, 43".to_string(), 0, 2),
            ExpressionModel("24 + 43".to_string(), 0, 7),
            ExpressionModel("24+add(x, y)+43".to_string(), 0, 15),
            ExpressionModel("24+add(sub(x, y), y)+43".to_string(), 0, 23),
            ExpressionModel("24+player.stats().hp+43".to_string(), 0, 23),
            ExpressionModel("24+player.stats(\")\")+43".to_string(), 0, 23),
            ExpressionModel("player".to_string(), 0, 6),
            ExpressionModel("player:".to_string(), 0, 6),
            ExpressionModel("\"oi\" ".to_string(), 0, 4),
            ExpressionModel("\"oi\" {x=1}".to_string(), 0, 4),
            ExpressionModel("\"oi\" {x=1}".to_string(), 0, 4),
            ExpressionModel("add(x,y)".to_string(), 0, 8),
            ExpressionModel("add(x,y)\n".to_string(), 0, 8),
            ExpressionModel("add(x,y)\n  x += 1\n".to_string(), 0, 8),
        ];

        for data in datas {
            let result = get_expression(&data.0.to_string(), &0, &data.0.chars().count());

            if let Some(result) = result {
                assert_eq!(result.begin, data.1);
                assert_eq!(result.count, data.2, "'{}'", data.0);
            } else {
                assert!(false);
            }
        }
    }

    #[test]
    fn tlex() {
        let tests = vec![
            LexModel("case ep1".to_string(), vec![Keyword, Space, Expression]),
            LexModel(
                "case ep1:".to_string(),
                vec![Keyword, Space, Expression, Colon],
            ),
            LexModel(
                "case ep1:\n".to_string(),
                vec![Keyword, Space, Expression, Colon, EndLine],
            ),
            LexModel(
                "  case ep1:\n".to_string(),
                vec![Indent, Keyword, Space, Expression, Colon, EndLine],
            ),
            LexModel(
                "    case ep1:\n".to_string(),
                vec![Indent, Indent, Keyword, Space, Expression, Colon, EndLine],
            ),
            LexModel(
                "case ep1:\n  cla:".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon,
                ],
            ),
            LexModel(
                "case ep1:\n  cla:\n".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon, EndLine,
                ],
            ),
            LexModel(
                "case ep1:\n  cla: \"test\" {x=1, y=2}".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon, Space,
                    Expression, Space, Attributes,
                ],
            ),
            LexModel(
                "case ep1:\n  cla: \"test\" {x=1, y=2}\n".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon, Space,
                    Expression, Space, Attributes, EndLine,
                ],
            ),
            LexModel(
                "case ep1:\n  cla: \"test\" {x=1, y=2}\n  jump ep1".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon, Space,
                    Expression, Space, Attributes, EndLine, Indent, Keyword, Space, Expression,
                ],
            ),
            LexModel(
                "case ep1:\n  cla: \"test\" {x=1, y=2}\n  jump ep1\n".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon, Space,
                    Expression, Space, Attributes, EndLine, Indent, Keyword, Space, Expression,
                    EndLine,
                ],
            ),
            LexModel(
                "case ep1:\n  cla: \"test\" {x=1, y=2}\n  jump ep1\n  call ep1\n".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon, Space,
                    Expression, Space, Attributes, EndLine, Indent, Keyword, Space, Expression,
                    EndLine, Indent, Keyword, Space, Expression, EndLine,
                ],
            ),
            LexModel(
                "case ep1:\n  new question:".to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Keyword, Space, Expression,
                    Colon,
                ],
            ),
            LexModel(
                "case ep1:\n  do question:\n    nar: \"My Question?\" {sleep=1}\n    \"Yes\":\n      nar: \"Ok\"\n    \"No\":\n      nar: \"Bad\"\n"
                    .to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Keyword, Space, Expression,
                    Colon, EndLine, Indent, Indent, Expression, Colon, Space, Expression, Space,
                    Attributes, EndLine, Indent, Indent, Expression, Colon, EndLine, Indent, Indent, Indent, Expression, Colon, Space, Expression, EndLine, Indent, Indent, Expression, Colon, EndLine, Indent, Indent, Indent, Expression, Colon, Space, Expression, EndLine,
                ],
            ),
            LexModel(
              "function increase()".to_string(),
              vec![
                  Keyword, Space, Expression
              ],
            ),
            LexModel(
              "return".to_string(),
              vec![
                  Keyword
              ],
            ),
            LexModel(
              "return x".to_string(),
              vec![
                  Keyword, Space, Expression
              ],
            ),
            LexModel(
              "continue".to_string(),
              vec![
                  Keyword
              ],
            ),
            LexModel(
              "break".to_string(),
              vec![
                  Keyword
              ],
            ),
            LexModel(
              "new nar:\n  name: \"Story Teller\"\n".to_string(),
              vec![
                  Keyword, Space, Expression, Colon, EndLine, Indent, Expression, Colon, Space, Expression, EndLine
              ],
            ),
            LexModel(
              "x = 1".to_string(),
              vec![
                  Expression
              ],
            ),
            LexModel(
              "x = 1 + 2".to_string(),
              vec![
                  Expression
              ],
            ),

            LexModel(
              "if x == 1".to_string(),
              vec![
                  Keyword, Space, Expression
              ],
            ),
            LexModel(
              "else if x == 1".to_string(),
              vec![
                  Keyword, Space, Keyword, Space, Expression
              ],
            ),
            LexModel(
              "default nar.mood = 5".to_string(),
              vec![
                  Keyword, Space, Expression
              ],
            ),
            LexModel(
              "\"oi #{\"xd\"}\"".to_string(),
              vec![
                   Expression
              ],
            ),
            LexModel(
                "case ep1:# ignore\n  do question:\n    nar: \"My Question?\" {sleep=1}# oi\n    \"Yes\":\n      nar: \"Ok\"\n    \"No\":\n      nar: \"Bad\"# oi\n"
                    .to_string(),
                vec![
                    Keyword, Space, Expression, Colon, EndLine, Indent, Keyword, Space, Expression,
                    Colon, EndLine, Indent, Indent, Expression, Colon, Space, Expression, Space,
                    Attributes, EndLine, Indent, Indent, Expression, Colon, EndLine, Indent, Indent, Indent, Expression, Colon, Space, Expression, EndLine, Indent, Indent, Expression, Colon, EndLine, Indent, Indent, Indent, Expression, Colon, Space, Expression, EndLine,
                ],
            ),
        ];

        for test in tests {
            let tokens = lex(&test.0);

            assert_tokens(tokens, test.1);
        }
    }
}