Parsing correctly yay

This commit is contained in:
greg 2017-12-01 02:16:28 -08:00
parent 1dae4443cd
commit 787b6d51a4
1 changed files with 60 additions and 39 deletions

View File

@ -1,6 +1,7 @@
use itertools::Itertools; use itertools::Itertools;
use schala_lib::{ProgrammingLanguageInterface, EvalOptions, ReplOutput}; use schala_lib::{ProgrammingLanguageInterface, EvalOptions, ReplOutput};
use std::iter::Peekable; use std::iter::Peekable;
use std::vec::IntoIter;
use std::str::Chars; use std::str::Chars;
pub struct Rukka { } pub struct Rukka { }
@ -20,10 +21,22 @@ impl ProgrammingLanguageInterface for Rukka {
fn evaluate_in_repl(&mut self, input: &str, _eval_options: &EvalOptions) -> ReplOutput { fn evaluate_in_repl(&mut self, input: &str, _eval_options: &EvalOptions) -> ReplOutput {
let mut output = ReplOutput::default(); let mut output = ReplOutput::default();
match parse(input).and_then(|x| eval(x)) { let sexps = match read(input) {
Ok(s) => output.add_output(s), Err(err) => {
Err(e) => output.add_output(format!("Error: {}", e)) output.add_output(format!("Error: {}", err));
return output;
},
Ok(sexps) => sexps
}; };
let mut text = String::new();
for (i, sexp) in sexps.into_iter().enumerate() {
match eval(sexp) {
Ok(result) => text.push_str(&format!("{}: {}", i, result)),
Err(err) => text.push_str(&format!("{} Error: {}", i, err)),
}
}
output.add_output(text);
output output
} }
} }
@ -32,13 +45,17 @@ fn eval(ast: Sexp) -> Result<String, String> {
Ok(format!("{:?}", ast)) Ok(format!("{:?}", ast))
} }
fn parse(input: &str) -> Result<Sexp, String> { fn read(input: &str) -> Result<Vec<Sexp>, String> {
let mut iter: Peekable<Chars> = input.chars().peekable(); let mut chars: Peekable<Chars> = input.chars().peekable();
let output = read_sexp(&mut iter); let mut tokens = tokenize(&mut chars).into_iter().peekable();
match iter.next() { let mut sexps = Vec::new();
None => output, loop {
Some(c) => Err(format!("Expected end of input, got {}", c)), sexps.push(parse(&mut tokens)?);
if let None = tokens.peek() {
break;
}
} }
Ok(sexps)
} }
#[derive(Debug)] #[derive(Debug)]
@ -49,51 +66,55 @@ enum Token {
} }
fn tokenize(input: &mut Peekable<Chars>) -> Vec<Token> { fn tokenize(input: &mut Peekable<Chars>) -> Vec<Token> {
use self::Token::*;
let mut tokens = Vec::new(); let mut tokens = Vec::new();
loop { loop {
match input.peek().map(|x| *x) { match input.next() {
None => break, None => break,
Some('(') => tokens.push(LParen), Some('(') => tokens.push(LParen),
Some(')') => tokens.push(RParen), Some(')') => tokens.push(RParen),
Some(c) if c.is_whitespace() => { tokens.next(); continue }, Some(c) if c.is_whitespace() => continue,
Some(c) => { Some(c) => {
let mut sym = String::new();
sym.push(c);
loop {
match input.peek().map(|x| *x) {
Some('(') | Some(')') | None => break,
Some(c) if c.is_whitespace() => break,
Some(c) => {
sym.push(c);
input.next();
}
}
}
tokens.push(Symbol(sym));
} }
} }
} }
tokens
} }
fn read_sexp(input: &mut Peekable<Chars>) -> Result<Sexp, String> { fn parse(tokens: &mut Peekable<IntoIter<Token>>) -> Result<Sexp, String> {
if input.next() != Some('(') { use self::Token::*;
return Err(format!("Expected '('")); match tokens.next() {
Some(Symbol(s)) => Ok(Sexp::Atom(AtomT::Symbol(s))),
Some(LParen) => parse_sexp(tokens),
Some(RParen) => Err(format!("Unexpected ')'")),
None => Err(format!("Unexpected end of input")),
} }
let mut v = Vec::new();
loop {
let c = input.peek().map(|x| *x);
match c {
Some(')') | None => break,
Some('(') => v.push(read_sexp(input)?),
Some(c) if c.is_whitespace() => { input.next(); continue; },
Some(c) => v.push(read_sym(input)?)
}
}
if input.next() != Some(')') {
return Err(format!("Expected ')'"));
}
Ok(Sexp::List(v))
} }
fn read_sym(input: &mut Peekable<Chars>) -> Result<Sexp, String> { fn parse_sexp(tokens: &mut Peekable<IntoIter<Token>>) -> Result<Sexp, String> {
let mut sym = String::new(); use self::Token::*;
let mut vec = Vec::new();
loop { loop {
sym.push(input.next().unwrap()); match tokens.peek() {
match input.peek().map(|x| *x) { None => return Err(format!("Unexpected end of input")),
Some('(') | Some(')') | None => break, Some(&RParen) => { tokens.next(); break},
Some(c) if c.is_whitespace() => break, _ => vec.push(parse(tokens)?),
_ => continue,
} }
} }
Ok(Sexp::Atom(AtomT::Symbol(sym))) Ok(Sexp::List(vec))
} }
#[derive(Debug)] #[derive(Debug)]
@ -109,8 +130,8 @@ enum AtomT {
} }
#[derive(Debug)] #[derive(Debug)]
struct List<'a> { struct PointerList<'a> {
next: Option<&'a List<'a>>, next: Option<&'a PointerList<'a>>,
data: usize data: usize
} }