Skip to content

Commit

Permalink
Trying to let the lexer deal with indentation somewhat elegantly #56
Browse files Browse the repository at this point in the history
  • Loading branch information
mverleg committed May 21, 2018
1 parent c6ec834 commit 97f7f30
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 15 deletions.
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ These instructions were tested on Ubuntu 18.4 (using Bash). It should also work
cargo test --all
cargo run --bin mango-cli
or to build a fast, release-mode native binary:
.. code:: bash
RUSTFLAGS="-C target-cpu=native" cargo build --release
* To deploy the web version in release mode:

.. code:: bash
Expand Down
21 changes: 12 additions & 9 deletions src/mango/io/fortest/fromstr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use mango::io::typ::Reader;
use mango::io::typ::ReaderResult;
use mango::io::util::REXCACHE;

/// Implementation of [Reader] that reads from a pre-provided string.
Expand All @@ -15,19 +16,21 @@ impl StringReader {
}

impl Reader for StringReader {
fn equals(&mut self, text: &str) -> bool {
if &self.code[self.index..self.index + text.len()] == text {
self.index += text.len();
return true;
}
false
}
// fn equals(&mut self, texts: Vec<&str>) -> ReaderResult {
// for text in texts {
// if &self.code[self.index..self.index + text.len()] == text {
// self.index += text.len();
// return ReaderResult::Match(self.code[self.index..self.index + text.len()])
// }
// }
// ReaderResult::NoMatch()
// }

fn matches(&mut self, subpattern: &str) -> Option<String> {
fn matches(&mut self, subpattern: &str) -> ReaderResult {
REXCACHE.with(|rl| {
let mut rexlib = rl.borrow_mut();
let rex = rexlib.make_or_get(subpattern);
});
Option::None // TODO
ReaderResult::NoMatch() // TODO
}
}
12 changes: 10 additions & 2 deletions src/mango/io/typ.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
// TODO: I should perhaps separate the splitting that happens here from the actual reading

pub enum ReaderResult {
Match(String),
NoMatch(),
EOF(),
}

/// A reader represents a source 'file', which may be a file, webpage, string, ...
pub trait Reader {
/// Checks whether the `text` is found starting from the current position.
fn equals(&mut self, text: &str) -> bool;
// fn equals(&mut self, texts: Vec<&str>) -> ReaderResult;

/// Checks whether the code from the current position matches a regex pattern.
fn matches(&mut self, subpattern: &str) -> Option<String>;
fn matches(&mut self, subpattern: &str) -> ReaderResult;
}

pub trait Writer {
Expand Down
59 changes: 59 additions & 0 deletions src/mango/lexing/code_lexer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use mango::io::typ::Reader;
use mango::io::typ::ReaderResult::*;
use mango::lexing::typ::Lexer;
use mango::lexing::typ::MaybeToken;
use mango::token::special::UnlexableToken;
use mango::token::tokens::ParenthesisCloseToken;
use mango::token::tokens::ParenthesisOpenToken;
use mango::token::Tokens;
use mango::util::codeparts::Keyword;
use std::collections::VecDeque;

pub struct CodeLexer<'r> {
reader: &'r mut Reader,
indent: i32,
// This is unfortunate, would not be needed with 'yield' but is now for indents
buffer: VecDeque<Tokens>,
}

impl<'r> CodeLexer<'r> {
fn new(reader: &'r mut Reader) -> Self {
CodeLexer {
reader,
indent: 0,
buffer: VecDeque::with_capacity(16),
}
}
}

impl<'r> Lexer<'r> for CodeLexer<'r> {
fn lex(&mut self) -> MaybeToken {
// If there is a buffer due to indentation or continuations, return from that.
if !self.buffer.is_empty() {
return MaybeToken::Token(self.buffer.pop_front().unwrap());
}
if let Match(word) = self.reader.matches("\\.\\.\\.") {
// Line continuation has no token, it just continues on the next line.
if let Match(word) = self.reader.matches("\\n\\r?") {
// There should always be a newline after continuations, so that they can be ignored together.
} else if let Match(word) = self.reader.matches("[^\\n]*\\n\\r?") {
return MaybeToken::Token(Tokens::Unlexable(UnlexableToken::new(word)));
} else {
// TODO: I don't know yet how to deal with continuation followed by end of file
panic!()
}
}
// Indentation done; do the rest of lexing.
if let Match(word) = self.reader.matches("(") {
return MaybeToken::Token(Tokens::ParenthesisOpen(ParenthesisOpenToken::new()));
}
if let Match(word) = self.reader.matches(")") {
return MaybeToken::Token(Tokens::ParenthesisClose(ParenthesisCloseToken::new()));
}

// TODO: a lot more

// TODO: specify the unlexable word
return MaybeToken::Token(Tokens::Unlexable(UnlexableToken::new("TODO".to_owned())));
}
}
1 change: 1 addition & 0 deletions src/mango/lexing/comment_lexer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

4 changes: 4 additions & 0 deletions src/mango/lexing/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
pub mod typ;

pub mod code_lexer;

pub mod comment_lexer;
15 changes: 15 additions & 0 deletions src/mango/lexing/typ.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use mango::io::typ::Reader;
use mango::token::Tokens;

pub enum MaybeToken {
Token(Tokens),
End(),
}

pub trait Lexer<'r> {
// /// Create a new lexer from a reader instance.
// fn new(reader: &'r mut Reader) -> Self;

/// Every call to lex returns a token until the end of the input.
fn lex(&mut self) -> MaybeToken;
}
6 changes: 3 additions & 3 deletions src/mango/token/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
mod tokens;
pub mod tokens;
pub use self::tokens::*;

mod special;
pub mod special;
pub use self::special::*;

mod collect;
pub mod collect;
pub use self::collect::Token;
pub use self::collect::Tokens;

Expand Down
2 changes: 1 addition & 1 deletion src/mango/token/special/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mod unlexable;
pub mod unlexable;
pub use self::unlexable::UnlexableToken;

0 comments on commit 97f7f30

Please sign in to comment.