Strings partway working
This commit is contained in:
parent
6e188976f9
commit
e9429ed62a
@ -4,6 +4,8 @@ TODO:
|
|||||||
-haskell-ish langauge should be called Robo
|
-haskell-ish langauge should be called Robo
|
||||||
-typeful scripting language should be called schala
|
-typeful scripting language should be called schala
|
||||||
rename accordingly!
|
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
|
# Schala - a programming language meta-interpreter
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ impl ProgrammingLanguageInterface for Rukka {
|
|||||||
|
|
||||||
let output_str: String = sexps.into_iter().enumerate().map(|(i, sexp)| {
|
let output_str: String = sexps.into_iter().enumerate().map(|(i, sexp)| {
|
||||||
match eval(sexp) {
|
match eval(sexp) {
|
||||||
Ok(result) => format!("{}: {}", i, result),
|
Ok(result) => format!("{}: {}", i, result.print()),
|
||||||
Err(err) => format!("{} Error: {}", i, err),
|
Err(err) => format!("{} Error: {}", i, err),
|
||||||
}
|
}
|
||||||
}).intersperse(format!("\n")).collect();
|
}).intersperse(format!("\n")).collect();
|
||||||
@ -40,8 +40,15 @@ impl ProgrammingLanguageInterface for Rukka {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(ast: Sexp) -> Result<String, String> {
|
fn eval(expr: Sexp) -> Result<Sexp, String> {
|
||||||
Ok(format!("{:?}", ast))
|
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<Vec<Sexp>, String> {
|
fn read(input: &str) -> Result<Vec<Sexp>, String> {
|
||||||
@ -59,7 +66,8 @@ enum Token {
|
|||||||
LParen,
|
LParen,
|
||||||
RParen,
|
RParen,
|
||||||
Quote,
|
Quote,
|
||||||
Word(String)
|
Word(String),
|
||||||
|
StringLiteral(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -68,9 +76,23 @@ enum Sexp {
|
|||||||
List(Vec<Sexp>),
|
List(Vec<Sexp>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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!("<unprintable>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum AtomT {
|
enum AtomT {
|
||||||
Symbol(String),
|
Symbol(String),
|
||||||
|
LangString(String),
|
||||||
//Number(u64),
|
//Number(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +106,23 @@ fn tokenize(input: &mut Peekable<Chars>) -> Vec<Token> {
|
|||||||
Some(')') => tokens.push(RParen),
|
Some(')') => tokens.push(RParen),
|
||||||
Some('\'') => tokens.push(Quote),
|
Some('\'') => tokens.push(Quote),
|
||||||
Some(c) if c.is_whitespace() => continue,
|
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) => {
|
Some(c) => {
|
||||||
let sym: String = input.peeking_take_while(|next| {
|
let sym: String = input.peeking_take_while(|next| {
|
||||||
match *next {
|
match *next {
|
||||||
@ -103,6 +142,7 @@ fn parse(tokens: &mut Peekable<IntoIter<Token>>) -> Result<Sexp, String> {
|
|||||||
use self::Token::*;
|
use self::Token::*;
|
||||||
match tokens.next() {
|
match tokens.next() {
|
||||||
Some(Word(s)) => Ok(Sexp::Atom(AtomT::Symbol(s))),
|
Some(Word(s)) => Ok(Sexp::Atom(AtomT::Symbol(s))),
|
||||||
|
Some(StringLiteral(s)) => Ok(Sexp::Atom(AtomT::LangString(s))),
|
||||||
Some(LParen) => parse_sexp(tokens),
|
Some(LParen) => parse_sexp(tokens),
|
||||||
Some(RParen) => Err(format!("Unexpected ')'")),
|
Some(RParen) => Err(format!("Unexpected ')'")),
|
||||||
Some(Quote) => {
|
Some(Quote) => {
|
||||||
@ -126,9 +166,3 @@ fn parse_sexp(tokens: &mut Peekable<IntoIter<Token>>) -> Result<Sexp, String> {
|
|||||||
Ok(Sexp::List(vec))
|
Ok(Sexp::List(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct PointerList<'a> {
|
|
||||||
next: Option<&'a PointerList<'a>>,
|
|
||||||
data: usize
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user