From ad6fcccc79a8efd05f4e98265c3e7f7aa1239cc5 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Thu, 5 Dec 2024 11:51:42 -0500 Subject: [PATCH] add concat --- src/base.rs | 34 +++++++++++++++++++++++++++++----- src/main.rs | 3 ++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/base.rs b/src/base.rs index 44dcdd3..440af48 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,7 +1,6 @@ use crate::value::*; -use crate::vm::*; +use imbl::*; use std::rc::Rc; -// use imbl::*; // use std::fmt; #[derive(Clone, Debug)] @@ -81,7 +80,7 @@ pub fn chars<'src>(x: &Value<'src>) -> Value<'src> { Value::InternedString(s) => { let chars = s.chars(); - let mut charlist = imbl::vector![]; + let mut charlist = vector![]; for char in chars { if char.is_ascii() { charlist.push_back(Value::AllocatedString(Rc::new(char.to_string()))) @@ -99,7 +98,7 @@ pub fn chars<'src>(x: &Value<'src>) -> Value<'src> { Value::AllocatedString(s) => { let chars = s.chars(); - let mut charlist = imbl::vector![]; + let mut charlist = vector![]; for char in chars { if char.is_ascii() { charlist.push_back(Value::AllocatedString(Rc::new(char.to_string()))) @@ -118,6 +117,30 @@ pub fn chars<'src>(x: &Value<'src>) -> Value<'src> { } } +// TODO: figure out how to get to opportunistic mutation here +pub fn concat<'src>(x: &Value<'src>, y: &Value<'src>) -> Value<'src> { + match (x, y) { + (Value::InternedString(x), Value::InternedString(y)) => { + Value::AllocatedString(Rc::new(format!("{x}{y}"))) + } + (Value::AllocatedString(x), Value::AllocatedString(y)) => { + Value::AllocatedString(Rc::new(format!("{x}{y}"))) + } + (Value::AllocatedString(x), Value::InternedString(y)) => { + Value::AllocatedString(Rc::new(format!("{x}{y}"))) + } + (Value::InternedString(x), Value::AllocatedString(y)) => { + Value::AllocatedString(Rc::new(format!("{x}{y}"))) + } + (Value::List(x), Value::List(y)) => { + let mut newlist = x.clone(); + newlist.append(y.clone()); + Value::List(newlist) + } + _ => unreachable!("internal Ludus error"), + } +} + pub fn base<'src>() -> Vec<(&'src str, Value<'src>)> { vec![ ("eq?", Value::Base(Base::Binary(eq))), @@ -130,6 +153,7 @@ pub fn base<'src>() -> Vec<(&'src str, Value<'src>)> { ("assoc", Value::Base(Base::Ternary(assoc))), ("bool", Value::Base(Base::Unary(r#bool))), ("chars", Value::Base(Base::Unary(chars))), + ("concat", Value::Base(Base::Binary(concat))), ] } @@ -138,7 +162,7 @@ pub fn base<'src>() -> Vec<(&'src str, Value<'src>)> { // * [ ] atan_2 (x) -> number // * [x] bool (x) -> bool // * [ ] ceil (x) -> number -// * [ ] chars (x) -> list +// * [x] chars (x) -> list // * [ ] concat (x, y) -> value // * [ ] conj (x, y) -> list // * [ ] cos (x) -> number diff --git a/src/main.rs b/src/main.rs index 527ce17..570dc4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,7 +58,8 @@ use crate::base::*; pub fn main() { let src = " -chars (\"féo\") +let foo = [1, 2, 3] +concat(foo, [4, 5, 6]) "; let (tokens, lex_errs) = lexer().parse(src).into_output_errors(); if !lex_errs.is_empty() {