From e9429ed62af50aca98572d4353758e51c1d076b2 Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 3 Dec 2017 17:11:17 -0800 Subject: [PATCH] Strings partway working --- README.md | 2 ++ src/rukka_lang/mod.rs | 54 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 68e668b..17a48b9 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ TODO: -haskell-ish langauge should be called Robo -typeful scripting language should be called schala rename accordingly! +-idea for Schala - scoped types - be able to define a quick enum type scoped to a function ro something, that only +is meant to be used as a quick bespoke interface between two other things # Schala - a programming language meta-interpreter diff --git a/src/rukka_lang/mod.rs b/src/rukka_lang/mod.rs index fd22e30..3d3ce8b 100644 --- a/src/rukka_lang/mod.rs +++ b/src/rukka_lang/mod.rs @@ -31,7 +31,7 @@ impl ProgrammingLanguageInterface for Rukka { let output_str: String = sexps.into_iter().enumerate().map(|(i, sexp)| { match eval(sexp) { - Ok(result) => format!("{}: {}", i, result), + Ok(result) => format!("{}: {}", i, result.print()), Err(err) => format!("{} Error: {}", i, err), } }).intersperse(format!("\n")).collect(); @@ -40,8 +40,15 @@ impl ProgrammingLanguageInterface for Rukka { } } -fn eval(ast: Sexp) -> Result { - Ok(format!("{:?}", ast)) +fn eval(expr: Sexp) -> Result { + use self::Sexp::*; use self::AtomT::*; + Ok(match expr { + Atom(atom) => match atom { + Symbol(s) => Atom(Symbol(s)), + LangString(s) => Atom(LangString(s)), + }, + List(items) => unimplemented!(), + }) } fn read(input: &str) -> Result, String> { @@ -59,7 +66,8 @@ enum Token { LParen, RParen, Quote, - Word(String) + Word(String), + StringLiteral(String), } #[derive(Debug)] @@ -68,9 +76,23 @@ enum Sexp { List(Vec), } +impl Sexp { + fn print(&self) -> String { + use self::Sexp::*; use self::AtomT::*; + match self { + &Atom(ref atom) => match atom { + &Symbol(ref s) => format!("{}", s), + &LangString(ref s) => format!("\"{}\"", s), + }, + _ => format!("") + } + } +} + #[derive(Debug)] enum AtomT { Symbol(String), + LangString(String), //Number(u64), } @@ -84,6 +106,23 @@ fn tokenize(input: &mut Peekable) -> Vec { Some(')') => tokens.push(RParen), Some('\'') => tokens.push(Quote), Some(c) if c.is_whitespace() => continue, + Some('"') => { + let string: String = input.scan(false, |seen_escape, cur_char| { + let ret = if cur_char == '"' && !*seen_escape { + None + } else { + Some(cur_char) + }; + + if cur_char == '\\' { + *seen_escape = true; + } else { + *seen_escape = false; + } + ret + }).collect(); + tokens.push(StringLiteral(string)); + } Some(c) => { let sym: String = input.peeking_take_while(|next| { match *next { @@ -103,6 +142,7 @@ fn parse(tokens: &mut Peekable>) -> Result { use self::Token::*; match tokens.next() { Some(Word(s)) => Ok(Sexp::Atom(AtomT::Symbol(s))), + Some(StringLiteral(s)) => Ok(Sexp::Atom(AtomT::LangString(s))), Some(LParen) => parse_sexp(tokens), Some(RParen) => Err(format!("Unexpected ')'")), Some(Quote) => { @@ -126,9 +166,3 @@ fn parse_sexp(tokens: &mut Peekable>) -> Result { Ok(Sexp::List(vec)) } -#[derive(Debug)] -struct PointerList<'a> { - next: Option<&'a PointerList<'a>>, - data: usize -} -