schala/src/rukka_lang/mod.rs

132 lines
3.0 KiB
Rust
Raw Normal View History

use itertools::Itertools;
use schala_lib::{ProgrammingLanguageInterface, EvalOptions, ReplOutput};
2017-11-29 01:45:29 -08:00
use std::iter::Peekable;
2017-12-01 02:16:28 -08:00
use std::vec::IntoIter;
2017-11-29 01:45:29 -08:00
use std::str::Chars;
pub struct Rukka { }
impl Rukka {
pub fn new() -> Rukka { Rukka { } }
}
impl ProgrammingLanguageInterface for Rukka {
fn get_language_name(&self) -> String {
"Rukka".to_string()
}
fn get_source_file_suffix(&self) -> String {
format!("rukka")
}
fn evaluate_in_repl(&mut self, input: &str, _eval_options: &EvalOptions) -> ReplOutput {
let mut output = ReplOutput::default();
2017-12-01 02:16:28 -08:00
let sexps = match read(input) {
Err(err) => {
output.add_output(format!("Error: {}", err));
return output;
},
Ok(sexps) => sexps
2017-11-29 01:45:29 -08:00
};
2017-12-01 02:16:28 -08:00
2017-12-01 02:36:52 -08:00
let output_str: String = sexps.into_iter().enumerate().map(|(i, sexp)| {
2017-12-01 02:16:28 -08:00
match eval(sexp) {
2017-12-01 02:36:52 -08:00
Ok(result) => format!("{}: {}", i, result),
Err(err) => format!("{} Error: {}", i, err),
2017-12-01 02:16:28 -08:00
}
2017-12-01 02:36:52 -08:00
}).intersperse(format!("\n")).collect();
output.add_output(output_str);
output
}
}
2017-11-27 00:57:26 -08:00
2017-11-28 03:37:16 -08:00
fn eval(ast: Sexp) -> Result<String, String> {
2017-11-29 02:08:30 -08:00
Ok(format!("{:?}", ast))
2017-11-28 03:37:16 -08:00
}
2017-12-01 02:16:28 -08:00
fn read(input: &str) -> Result<Vec<Sexp>, String> {
let mut chars: Peekable<Chars> = 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;
}
2017-11-29 02:08:30 -08:00
}
2017-12-01 02:16:28 -08:00
Ok(sexps)
2017-11-28 03:37:16 -08:00
}
2017-11-27 00:57:26 -08:00
2017-11-30 22:37:49 -08:00
#[derive(Debug)]
enum Token {
LParen,
RParen,
Symbol(String)
}
fn tokenize(input: &mut Peekable<Chars>) -> Vec<Token> {
2017-12-01 02:16:28 -08:00
use self::Token::*;
2017-11-30 22:37:49 -08:00
let mut tokens = Vec::new();
loop {
2017-12-01 02:16:28 -08:00
match input.next() {
2017-11-30 22:37:49 -08:00
None => break,
Some('(') => tokens.push(LParen),
Some(')') => tokens.push(RParen),
2017-12-01 02:16:28 -08:00
Some(c) if c.is_whitespace() => continue,
2017-12-01 02:36:52 -08:00
Some(_) => {
let sym: String = input.peeking_take_while(|next| {
match *next {
'(' | ')' => false,
c if c.is_whitespace() => false,
_ => true
2017-12-01 02:16:28 -08:00
}
2017-12-01 02:36:52 -08:00
}).collect();
2017-12-01 02:16:28 -08:00
tokens.push(Symbol(sym));
2017-11-30 22:37:49 -08:00
}
}
}
2017-12-01 02:16:28 -08:00
tokens
2017-11-30 22:37:49 -08:00
}
2017-12-01 02:16:28 -08:00
fn parse(tokens: &mut Peekable<IntoIter<Token>>) -> Result<Sexp, String> {
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")),
2017-11-29 02:08:30 -08:00
}
}
2017-12-01 02:16:28 -08:00
fn parse_sexp(tokens: &mut Peekable<IntoIter<Token>>) -> Result<Sexp, String> {
use self::Token::*;
let mut vec = Vec::new();
2017-11-29 02:08:30 -08:00
loop {
2017-12-01 02:16:28 -08:00
match tokens.peek() {
None => return Err(format!("Unexpected end of input")),
Some(&RParen) => { tokens.next(); break},
_ => vec.push(parse(tokens)?),
2017-11-29 02:08:30 -08:00
}
}
2017-12-01 02:16:28 -08:00
Ok(Sexp::List(vec))
2017-11-28 03:37:16 -08:00
}
#[derive(Debug)]
enum Sexp {
Atom(AtomT),
List(Vec<Sexp>),
}
#[derive(Debug)]
enum AtomT {
Symbol(String),
2017-11-29 02:08:30 -08:00
//Number(u64),
2017-11-27 00:57:26 -08:00
}
#[derive(Debug)]
2017-12-01 02:16:28 -08:00
struct PointerList<'a> {
next: Option<&'a PointerList<'a>>,
2017-11-28 03:37:16 -08:00
data: usize
2017-11-27 00:57:26 -08:00
}
2017-11-28 03:37:16 -08:00