From 787b6d51a4d5beba3c1a6671f0f88bdbe3e92343 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 1 Dec 2017 02:16:28 -0800 Subject: [PATCH] Parsing correctly yay --- src/rukka_lang/mod.rs | 99 ++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/src/rukka_lang/mod.rs b/src/rukka_lang/mod.rs index e92ca9d..c77c243 100644 --- a/src/rukka_lang/mod.rs +++ b/src/rukka_lang/mod.rs @@ -1,6 +1,7 @@ use itertools::Itertools; use schala_lib::{ProgrammingLanguageInterface, EvalOptions, ReplOutput}; use std::iter::Peekable; +use std::vec::IntoIter; use std::str::Chars; pub struct Rukka { } @@ -20,10 +21,22 @@ impl ProgrammingLanguageInterface for Rukka { fn evaluate_in_repl(&mut self, input: &str, _eval_options: &EvalOptions) -> ReplOutput { let mut output = ReplOutput::default(); - match parse(input).and_then(|x| eval(x)) { - Ok(s) => output.add_output(s), - Err(e) => output.add_output(format!("Error: {}", e)) + let sexps = match read(input) { + Err(err) => { + 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 } } @@ -32,13 +45,17 @@ fn eval(ast: Sexp) -> Result { Ok(format!("{:?}", ast)) } -fn parse(input: &str) -> Result { - let mut iter: Peekable = input.chars().peekable(); - let output = read_sexp(&mut iter); - match iter.next() { - None => output, - Some(c) => Err(format!("Expected end of input, got {}", c)), +fn read(input: &str) -> Result, String> { + let mut chars: Peekable = input.chars().peekable(); + let mut tokens = tokenize(&mut chars).into_iter().peekable(); + let mut sexps = Vec::new(); + loop { + sexps.push(parse(&mut tokens)?); + if let None = tokens.peek() { + break; + } } + Ok(sexps) } #[derive(Debug)] @@ -49,51 +66,55 @@ enum Token { } fn tokenize(input: &mut Peekable) -> Vec { + use self::Token::*; let mut tokens = Vec::new(); loop { - match input.peek().map(|x| *x) { + match input.next() { None => break, Some('(') => tokens.push(LParen), Some(')') => tokens.push(RParen), - Some(c) if c.is_whitespace() => { tokens.next(); continue }, + Some(c) if c.is_whitespace() => continue, 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) -> Result { - if input.next() != Some('(') { - return Err(format!("Expected '('")); +fn parse(tokens: &mut Peekable>) -> Result { + use self::Token::*; + 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) -> Result { - let mut sym = String::new(); +fn parse_sexp(tokens: &mut Peekable>) -> Result { + use self::Token::*; + let mut vec = Vec::new(); loop { - sym.push(input.next().unwrap()); - match input.peek().map(|x| *x) { - Some('(') | Some(')') | None => break, - Some(c) if c.is_whitespace() => break, - _ => continue, + match tokens.peek() { + None => return Err(format!("Unexpected end of input")), + Some(&RParen) => { tokens.next(); break}, + _ => vec.push(parse(tokens)?), } } - Ok(Sexp::Atom(AtomT::Symbol(sym))) + Ok(Sexp::List(vec)) } #[derive(Debug)] @@ -109,8 +130,8 @@ enum AtomT { } #[derive(Debug)] -struct List<'a> { - next: Option<&'a List<'a>>, +struct PointerList<'a> { + next: Option<&'a PointerList<'a>>, data: usize }