Browse Source

Reformatted with rust-fmt

typed
Weird Constructor 5 months ago
parent
commit
105a59f6a9
  1. 319
      examples/bencharena.rs
  2. 1703
      src/compiler.rs
  3. 576
      src/formatter.rs
  4. 35
      src/io.rs
  5. 1346
      src/lib.rs
  6. 1
      src/main.rs
  7. 312
      src/nvec.rs
  8. 476
      src/ops.rs
  9. 287
      src/packer.rs
  10. 1649
      src/parser.rs
  11. 320
      src/parser/state.rs
  12. 4648
      src/prelude.rs
  13. 60
      src/prog_writer.rs
  14. 166
      src/rpc_helper.rs
  15. 1690
      src/selector.rs
  16. 113
      src/stdlib/csv.rs
  17. 48
      src/stdlib/cursive.rs
  18. 1
      src/stdlib/helpers.rs
  19. 20
      src/stdlib/html2vval.rs
  20. 22
      src/stdlib/http.rs
  21. 7
      src/stdlib/imap.rs
  22. 12
      src/stdlib/mod.rs
  23. 603
      src/stdlib/mqtt.rs
  24. 821
      src/stdlib/net.rs
  25. 18
      src/stdlib/odbc.rs
  26. 274
      src/stdlib/process.rs
  27. 112
      src/stdlib/rcdom.rs
  28. 26
      src/stdlib/util.rs
  29. 689
      src/stdlib/xml.rs
  30. 30
      src/str_int.rs
  31. 681
      src/struct_pattern.rs
  32. 512
      src/threads.rs
  33. 175
      src/util.rs
  34. 1306
      src/vm.rs
  35. 4287
      src/vval.rs
  36. 17
      src/vval_user_obj.rs
  37. 5776
      tests/language.rs
  38. 263
      tests/wlambda_code_blocks.rs
  39. 166
      tests/wlambda_functions.rs

319
examples/bencharena.rs

@ -1,161 +1,158 @@
use std::rc::Rc;
use std::cell::RefCell;
use std::time::Instant;
thread_local! {
static ARENA_INTERN: RefCell<Arena1> = RefCell::new(Arena1::new());
}
#[allow(dead_code)]
struct XXX {
u: f64,
a: f64,
b: f64,
c: f64,
d: f64,
}
enum Val {
None,
N(AR1),
X(XXX),
}
#[allow(dead_code)]
enum Val2 {
None,
N(Rc<(Val2, Val2)>),
X(XXX),
}
impl Val {
pub fn n(a: Val, b: Val) -> Self { Val::N(AR1::new(a, b)) }
pub fn x(a: f64) -> Self {
let mut x = XXX::new();
x.a = a;
Val::X(x)
}
}
impl Val2 {
pub fn n(a: Val2, b: Val2) -> Self { Val2::N(Rc::new((a, b))) }
pub fn x(a: f64) -> Self {
let mut x = XXX::new();
x.a = a;
Val2::X(x)
}
}
impl XXX {
pub fn new() -> Self {
Self {
u: 0.0,
a: 0.0,
b: 0.0,
c: 0.0,
d: 0.0,
}
}
}
struct Arena1 {
free: Vec<Rc<(Val, Val)>>,
}
impl Arena1 {
pub fn new() -> Self {
let mut free = vec![];
free.resize_with(10, || Rc::new((Val::None, Val::None)));
Self { free }
}
#[inline]
pub fn alloc(&mut self) -> Rc<(Val, Val)> {
if let Some(a) = self.free.pop() {
a
} else {
Rc::new((Val::None, Val::None))
}
}
#[inline]
pub fn free(&mut self, rc: &mut Rc<(Val, Val)>) {
*Rc::get_mut(rc).unwrap() = (Val::None, Val::None);
self.free.push(rc.clone());
}
}
#[derive(Clone)]
struct AR1 {
cont: Rc<(Val, Val)>,
}
impl AR1 {
pub fn new(a: Val, b: Val) -> Self {
ARENA_INTERN.with(|x| {
let mut rc = x.borrow_mut().alloc();
*Rc::get_mut(&mut rc).unwrap() = (a, b);
Self { cont: rc }
})
}
}
impl Drop for AR1 {
fn drop(&mut self) {
if Rc::strong_count(&self.cont) == 1 {
ARENA_INTERN.with(|x| {
x.borrow_mut().free(&mut self.cont);
})
}
}
}
fn t1(n: usize) {
let mut v = vec![];
let now = Instant::now();
for _ in 0..10000 {
for _ in 0..n {
v.push(Val::n(Val::x(21.32), Val::x(22.1)));
}
v.clear();
for _ in 0..n {
v.push(Val::n(Val::x(21.32), Val::x(22.1)));
}
v.clear();
}
println!("arena [{:5}]: {}", n, now.elapsed().as_millis());
}
fn t2(n: usize) {
let mut v = vec![];
let now = Instant::now();
for _ in 0..10000 {
for _ in 0..n {
v.push(Val2::n(Val2::x(21.32), Val2::x(22.1)));
}
v.clear();
for _ in 0..n {
v.push(Val2::n(Val2::x(21.32), Val2::x(22.1)));
}
v.clear();
}
println!("alloc [{:5}]: {}", n, now.elapsed().as_millis());
}
fn main() {
for t in 0..4 {
println!("*** {}", t);
t1(3000);
t2(3000);
t1(10);
t2(10);
t1(100);
t2(100);
t1(500);
t2(500);
t1(1000);
t2(1000);
}
}
use std::cell::RefCell;
use std::rc::Rc;
use std::time::Instant;
thread_local! {
static ARENA_INTERN: RefCell<Arena1> = RefCell::new(Arena1::new());
}
#[allow(dead_code)]
struct XXX {
u: f64,
a: f64,
b: f64,
c: f64,
d: f64,
}
enum Val {
None,
N(AR1),
X(XXX),
}
#[allow(dead_code)]
enum Val2 {
None,
N(Rc<(Val2, Val2)>),
X(XXX),
}
impl Val {
pub fn n(a: Val, b: Val) -> Self {
Val::N(AR1::new(a, b))
}
pub fn x(a: f64) -> Self {
let mut x = XXX::new();
x.a = a;
Val::X(x)
}
}
impl Val2 {
pub fn n(a: Val2, b: Val2) -> Self {
Val2::N(Rc::new((a, b)))
}
pub fn x(a: f64) -> Self {
let mut x = XXX::new();
x.a = a;
Val2::X(x)
}
}
impl XXX {
pub fn new() -> Self {
Self { u: 0.0, a: 0.0, b: 0.0, c: 0.0, d: 0.0 }
}
}
struct Arena1 {
free: Vec<Rc<(Val, Val)>>,
}
impl Arena1 {
pub fn new() -> Self {
let mut free = vec![];
free.resize_with(10, || Rc::new((Val::None, Val::None)));
Self { free }
}
#[inline]
pub fn alloc(&mut self) -> Rc<(Val, Val)> {
if let Some(a) = self.free.pop() {
a
} else {
Rc::new((Val::None, Val::None))
}
}
#[inline]
pub fn free(&mut self, rc: &mut Rc<(Val, Val)>) {
*Rc::get_mut(rc).unwrap() = (Val::None, Val::None);
self.free.push(rc.clone());
}
}
#[derive(Clone)]
struct AR1 {
cont: Rc<(Val, Val)>,
}
impl AR1 {
pub fn new(a: Val, b: Val) -> Self {
ARENA_INTERN.with(|x| {
let mut rc = x.borrow_mut().alloc();
*Rc::get_mut(&mut rc).unwrap() = (a, b);
Self { cont: rc }
})
}
}
impl Drop for AR1 {
fn drop(&mut self) {
if Rc::strong_count(&self.cont) == 1 {
ARENA_INTERN.with(|x| {
x.borrow_mut().free(&mut self.cont);
})
}
}
}
fn t1(n: usize) {
let mut v = vec![];
let now = Instant::now();
for _ in 0..10000 {
for _ in 0..n {
v.push(Val::n(Val::x(21.32), Val::x(22.1)));
}
v.clear();
for _ in 0..n {
v.push(Val::n(Val::x(21.32), Val::x(22.1)));
}
v.clear();
}
println!("arena [{:5}]: {}", n, now.elapsed().as_millis());
}
fn t2(n: usize) {
let mut v = vec![];
let now = Instant::now();
for _ in 0..10000 {
for _ in 0..n {
v.push(Val2::n(Val2::x(21.32), Val2::x(22.1)));
}
v.clear();
for _ in 0..n {
v.push(Val2::n(Val2::x(21.32), Val2::x(22.1)));
}
v.clear();
}
println!("alloc [{:5}]: {}", n, now.elapsed().as_millis());
}
fn main() {
for t in 0..4 {
println!("*** {}", t);
t1(3000);
t2(3000);
t1(10);
t2(10);
t1(100);
t2(100);
t1(500);
t2(500);
t1(1000);
t2(1000);
}
}

1703
src/compiler.rs

File diff suppressed because it is too large Load Diff

576
src/formatter.rs

@ -8,7 +8,7 @@ It provides the [create_formatter_fun]. It's syntax supports most of the
Rust string formatting functionality.
*/
use crate::vval::{VVal, Env, VValFun};
use crate::vval::{Env, VVal, VValFun};
use crate::parser::state::State;
use crate::parser::state::{ParseError, ParseErrorKind};
@ -18,15 +18,18 @@ use std::fmt::Write;
fn parse_argument(ps: &mut State) -> Result<VVal, ParseError> {
let mut is_integer = true;
let mut identifier = String::new();
let mut index = String::new();
let mut index = String::new();
while !ps.lookahead_one_of(":$.}") {
match ps.expect_some(ps.peek())? {
c if c.is_digit(10) => {
ps.consume();
if is_integer { index.push(c); }
else { identifier.push(c); }
},
if is_integer {
index.push(c);
} else {
identifier.push(c);
}
}
c => {
if !index.is_empty() {
identifier = index.clone();
@ -43,7 +46,7 @@ fn parse_argument(ps: &mut State) -> Result<VVal, ParseError> {
if is_integer {
Ok(VVal::vec2(VVal::new_sym("index"), VVal::new_str_mv(index)))
} else {
Ok(VVal::vec2(VVal::new_sym("key"), VVal::new_str_mv(identifier)))
Ok(VVal::vec2(VVal::new_sym("key"), VVal::new_str_mv(identifier)))
}
}
@ -55,18 +58,16 @@ fn parse_count(ps: &mut State) -> Result<VVal, ParseError> {
if let Ok(idx) = integer.to_string().parse::<u32>() {
Ok(VVal::vec2(VVal::new_sym("count"), VVal::Int(idx as i64)))
} else {
Err(ps.err(
ParseErrorKind::BadFormat(
"expected proper integer".to_string())))
Err(ps.err(ParseErrorKind::BadFormat("expected proper integer".to_string())))
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub(crate) enum CastType {
Str = 0,
Int = 1,
Flt = 2,
Str = 0,
Int = 1,
Flt = 2,
Written = 4,
}
@ -84,9 +85,9 @@ impl CastType {
#[derive(Debug, Copy, Clone, PartialEq)]
pub(crate) enum FormatType {
Unknown = 0,
Hex = 1,
Oct = 2,
Bin = 3,
Hex = 1,
Oct = 2,
Bin = 3,
}
impl FormatType {
@ -101,93 +102,92 @@ impl FormatType {
}
fn parse_format_spec(ps: &mut State, arg: &VVal) -> Result<VVal, ParseError> {
let mut fill : Option<char> = None;
let mut align_char : Option<char> = None;
let mut fill: Option<char> = None;
let mut align_char: Option<char> = None;
let align = ps.peek2();
if let Some(align) = align {
match align.at(1) {
c @ '<'
| c @ '^'
| c @ '>' => {
fill = Some(align.at(0));
c @ '<' | c @ '^' | c @ '>' => {
fill = Some(align.at(0));
align_char = Some(c);
ps.consume();
ps.consume();
},
_ => { },
}
_ => {}
}
}
if align_char .is_none() {
if align_char.is_none() {
match ps.expect_some(ps.peek())? {
c @ '<'
| c @ '^'
| c @ '>' => {
c @ '<' | c @ '^' | c @ '>' => {
align_char = Some(c);
ps.consume();
},
_ => { },
}
_ => {}
}
}
let mut sign : Option<char> = None;
let mut sign: Option<char> = None;
match ps.expect_some(ps.peek())? {
c @ '-'
| c @ '+' => {
c @ '-' | c @ '+' => {
sign = Some(c);
ps.consume();
},
_ => { },
}
_ => {}
}
let alternate = ps.consume_if_eq('#');
let pad0 = ps.consume_if_eq('0');
let pad0 = ps.consume_if_eq('0');
let width =
if ps.find_char_not_of('$', ".").is_some()
|| ( ps.peek().is_some()
&& ps.lookahead_one_of("0123456789")) {
parse_count(ps)?
} else {
VVal::None
};
let width = if ps.find_char_not_of('$', ".").is_some()
|| (ps.peek().is_some() && ps.lookahead_one_of("0123456789"))
{
parse_count(ps)?
} else {
VVal::None
};
let precision =
if ps.consume_if_eq('.') {
if ps.consume_if_eq('*') {
if arg.at(0).unwrap().with_s_ref(|s| s == "index") {
let idx = arg.at(1).unwrap();
arg.set(1, VVal::Int(idx.i() + 1));
let precision = if ps.consume_if_eq('.') {
if ps.consume_if_eq('*') {
if arg.at(0).unwrap().with_s_ref(|s| s == "index") {
let idx = arg.at(1).unwrap();
arg.set(1, VVal::Int(idx.i() + 1));
VVal::vec2(VVal::new_sym("index"), idx)
} else {
return Err(ps.err(
ParseErrorKind::BadFormat(
"can't use * in combination with named arg".to_string())));
}
VVal::vec2(VVal::new_sym("index"), idx)
} else {
parse_count(ps)?
return Err(ps.err(ParseErrorKind::BadFormat(
"can't use * in combination with named arg".to_string(),
)));
}
} else {
VVal::None
};
let mut cast_type =
if ps.consume_if_eq('!') {
match ps.expect_some(ps.peek())? {
'i' => { ps.consume(); Some(CastType::Int) },
'f' => { ps.consume(); Some(CastType::Flt) },
'w' => { ps.consume(); Some(CastType::Written) },
c => {
return Err(ps.err(
ParseErrorKind::BadFormat(
format!("Unknown cast type: {}", c))));
}
parse_count(ps)?
}
} else {
VVal::None
};
let mut cast_type = if ps.consume_if_eq('!') {
match ps.expect_some(ps.peek())? {
'i' => {
ps.consume();
Some(CastType::Int)
}
} else {
None
};
'f' => {
ps.consume();
Some(CastType::Flt)
}
'w' => {
ps.consume();
Some(CastType::Written)
}
c => {
return Err(ps.err(ParseErrorKind::BadFormat(format!("Unknown cast type: {}", c))));
}
}
} else {
None
};
let m = VVal::map();
@ -195,15 +195,15 @@ fn parse_format_spec(ps: &mut State, arg: &VVal) -> Result<VVal, ParseError> {
'x' => {
ps.consume();
m.set_key_str("type", VVal::Int(FormatType::Hex as i64)).unwrap();
},
}
'o' => {
ps.consume();
m.set_key_str("type", VVal::Int(FormatType::Oct as i64)).unwrap();
},
}
'b' => {
ps.consume();
m.set_key_str("type", VVal::Int(FormatType::Bin as i64)).unwrap();
},
}
_ => {
m.set_key_str("type", VVal::Int(FormatType::Unknown as i64)).unwrap();
}
@ -215,18 +215,28 @@ fn parse_format_spec(ps: &mut State, arg: &VVal) -> Result<VVal, ParseError> {
m.set_key_str("fill", VVal::new_str(" ")).unwrap();
}
match align_char {
Some('<') => { m.set_key_str("align", VVal::Int(-1)).unwrap(); },
Some('>') => { m.set_key_str("align", VVal::Int( 1)).unwrap(); },
Some('^') => { m.set_key_str("align", VVal::Int( 2)).unwrap(); },
_ => (),
Some('<') => {
m.set_key_str("align", VVal::Int(-1)).unwrap();
}
Some('>') => {
m.set_key_str("align", VVal::Int(1)).unwrap();
}
Some('^') => {
m.set_key_str("align", VVal::Int(2)).unwrap();
}
_ => (),
}
match sign {
Some('-') => { m.set_key_str("sign", VVal::Int(-1)).unwrap(); },
Some('+') => { m.set_key_str("sign", VVal::Int( 1)).unwrap(); },
_ => (),
Some('-') => {
m.set_key_str("sign", VVal::Int(-1)).unwrap();
}
Some('+') => {
m.set_key_str("sign", VVal::Int(1)).unwrap();
}
_ => (),
}
m.set_key_str("alternate", VVal::Bol(alternate)).unwrap();
m.set_key_str("pad0", VVal::Bol(pad0)).unwrap();
m.set_key_str("alternate", VVal::Bol(alternate)).unwrap();
m.set_key_str("pad0", VVal::Bol(pad0)).unwrap();
if width.is_some() {
m.set_key_str("width", width).unwrap();
}
@ -250,17 +260,14 @@ fn parse_format(ps: &mut State, implicit_index: &mut usize) -> Result<VVal, Pars
let mut was_implicit_idx = false;
let c = ps.expect_some(ps.peek())?;
let arg =
if c != ':' && c != '}' {
parse_argument(ps)?
} else {
let arg = VVal::vec2(VVal::new_sym("index"),
VVal::Int(*implicit_index as i64));
*implicit_index += 1;
was_implicit_idx = true;
arg
};
let arg = if c != ':' && c != '}' {
parse_argument(ps)?
} else {
let arg = VVal::vec2(VVal::new_sym("index"), VVal::Int(*implicit_index as i64));
*implicit_index += 1;
was_implicit_idx = true;
arg
};
let c = ps.expect_some(ps.peek())?;
if c == ':' {
@ -278,8 +285,7 @@ fn parse_format(ps: &mut State, implicit_index: &mut usize) -> Result<VVal, Pars
}
if !ps.consume_if_eq('}') {
return Err(ps.err(
ParseErrorKind::ExpectedToken('}', "format end")));
return Err(ps.err(ParseErrorKind::ExpectedToken('}', "format end")));
}
Ok(VVal::vec3(VVal::new_sym("format"), arg, fmt))
@ -303,23 +309,24 @@ fn parse_formatter(s: &str) -> Result<VVal, ParseError> {
ps.consume();
if !cur_text.is_empty() {
fmt.push(VVal::vec2(VVal::new_sym("text"),
VVal::new_str(&cur_text)));
fmt.push(VVal::vec2(VVal::new_sym("text"), VVal::new_str(&cur_text)));
cur_text = String::new();
}
fmt.push(parse_format(&mut ps, &mut impl_idx)?);
}
},
}
'}' => {
if ps.consume_lookahead("}}") {
cur_text.push('}');
} else {
return Err(ps.err(
ParseErrorKind::UnexpectedToken('}', "format end")));
return Err(ps.err(ParseErrorKind::UnexpectedToken('}', "format end")));
}
},
c => { ps.consume(); cur_text.push(c); },
}
c => {
ps.consume();
cur_text.push(c);
}
}
}
@ -332,7 +339,7 @@ fn parse_formatter(s: &str) -> Result<VVal, ParseError> {
#[derive(Debug, Clone)]
pub(crate) struct FormatState {
str_data: Option<String>,
str_data: Option<String>,
byte_data: Option<Vec<u8>>,
}
@ -346,7 +353,7 @@ impl core::fmt::Write for FormatState {
if let Some(sd) = &mut self.str_data.as_mut() {
sd.push_str(s);
} else if let Some(bd) = &mut self.byte_data.as_mut() {
let r : &[u8] = s.as_ref();
let r: &[u8] = s.as_ref();
for b in r.iter() {
bd.push(*b);
}
@ -356,16 +363,16 @@ impl core::fmt::Write for FormatState {
}
impl FormatState {
// fn add_char(&mut self, c: char) {
// if let Some(sd) = &mut self.str_data.as_mut() {
// sd.push(c);
// } else if let Some(bd) = &mut self.byte_data.as_mut() {
// let mut b = [0; 4];
// for cb in c.encode_utf8(&mut b).as_bytes().iter() {
// bd.push(*cb);
// }
// }
// }
// fn add_char(&mut self, c: char) {
// if let Some(sd) = &mut self.str_data.as_mut() {
// sd.push(c);
// } else if let Some(bd) = &mut self.byte_data.as_mut() {
// let mut b = [0; 4];
// for cb in c.encode_utf8(&mut b).as_bytes().iter() {
// bd.push(*cb);
// }
// }
// }
fn cur_len(&self) -> usize {
if let Some(sd) = &self.str_data.as_ref() {
@ -400,14 +407,12 @@ impl FormatState {
}
pub(crate) type FormatNode = Box<dyn Fn(&mut FormatState, &[VVal]) -> std::fmt::Result>;
pub(crate) type CountNode = Box<dyn Fn(&mut FormatState, &[VVal]) -> usize>;
pub(crate) type CountNode = Box<dyn Fn(&mut FormatState, &[VVal]) -> usize>;
pub(crate) fn compile_count(count: &VVal) -> CountNode {
if count.v_with_s_ref(0, |s| s == "count") {
let count = count.v_i(1);
Box::new(move |_fs: &mut FormatState, _args: &[VVal]| -> usize {
count as usize
})
Box::new(move |_fs: &mut FormatState, _args: &[VVal]| -> usize { count as usize })
} else {
let count = count.clone();
Box::new(move |_fs: &mut FormatState, _args: &[VVal]| -> usize {
@ -417,8 +422,14 @@ pub(crate) fn compile_count(count: &VVal) -> CountNode {
}
#[allow(clippy::many_single_char_names)]
pub(crate) fn write_vval<F>(arg: &VVal, fs: &mut FormatState, ct: CastType, mut f: F) -> std::fmt::Result
where F: FnMut(&mut FormatState, &VVal) -> std::fmt::Result
pub(crate) fn write_vval<F>(
arg: &VVal,
fs: &mut FormatState,
ct: CastType,
mut f: F,
) -> std::fmt::Result
where
F: FnMut(&mut FormatState, &VVal) -> std::fmt::Result,
{
use crate::nvec::NVec;
@ -434,14 +445,14 @@ pub(crate) fn write_vval<F>(arg: &VVal, fs: &mut FormatState, ct: CastType, mut
f(fs, &VVal::Int(*a))?;
write!(fs, ",")?;
f(fs, &VVal::Int(*b))?;
},
}
NVec::Vec3(a, b, c) => {
f(fs, &VVal::Int(*a))?;
write!(fs, ",")?;
f(fs, &VVal::Int(*b))?;
write!(fs, ",")?;
f(fs, &VVal::Int(*c))?;
},
}
NVec::Vec4(a, b, c, d) => {
f(fs, &VVal::Int(*a))?;
write!(fs, ",")?;
@ -450,10 +461,10 @@ pub(crate) fn write_vval<F>(arg: &VVal, fs: &mut FormatState, ct: CastType, mut
f(fs, &VVal::Int(*c))?;
write!(fs, ",")?;
f(fs, &VVal::Int(*d))?;
},
}
}
write!(fs, ")")?;
},
}
VVal::FVec(v) => {
write!(fs, "(")?;
match v.as_ref() {
@ -461,14 +472,14 @@ pub(crate) fn write_vval<F>(arg: &VVal, fs: &mut FormatState, ct: CastType, mut
f(fs, &VVal::Flt(*a))?;
write!(fs, ",")?;
f(fs, &VVal::Flt(*b))?;
},
}
NVec::Vec3(a, b, c) => {
f(fs, &VVal::Flt(*a))?;
write!(fs, ",")?;
f(fs, &VVal::Flt(*b))?;
write!(fs, ",")?;
f(fs, &VVal::Flt(*c))?;
},
}
NVec::Vec4(a, b, c, d) => {
f(fs, &VVal::Flt(*a))?;
write!(fs, ",")?;
@ -477,10 +488,10 @@ pub(crate) fn write_vval<F>(arg: &VVal, fs: &mut FormatState, ct: CastType, mut
f(fs, &VVal::Flt(*c))?;
write!(fs, ",")?;
f(fs, &VVal::Flt(*d))?;
},
}
}
write!(fs, ")")?;
},
}
VVal::Pair(ab) => {
let (a, b) = ab.as_ref();
write!(fs, "(")?;
@ -488,29 +499,35 @@ pub(crate) fn write_vval<F>(arg: &VVal, fs: &mut FormatState, ct: CastType, mut
write!(fs, ",")?;
f(fs, b)?;
write!(fs, ")")?;
},
}
VVal::Lst(_) => {
write!(fs, "[")?;
let mut first = true;
for (a, _) in arg.iter() {
if first { first = false; }
else { write!(fs, ",")?; }
if first {
first = false;
} else {
write!(fs, ",")?;
}
f(fs, &a)?;
}
write!(fs, "]")?;
},
}
VVal::Map(m) => {
use crate::str_int::*;
write!(fs, "{{")?;
let hm = m.borrow();
let mut keys : Vec<&Symbol> = hm.keys().collect();
let mut keys: Vec<&Symbol> = hm.keys().collect();
keys.sort();
let mut first = true;
for k in keys {
if first { first = false; }
else { write!(fs, ", ")?; }
if first {
first = false;
} else {
write!(fs, ", ")?;
}
let v = hm.get(k).unwrap();
write!(fs, "{}:", k.as_ref())?;
@ -518,60 +535,78 @@ pub(crate) fn write_vval<F>(arg: &VVal, fs: &mut FormatState, ct: CastType, mut
}
write!(fs, "}}")?;
},
}
v => f(fs, v)?,
}
Ok(())
}
pub(crate) fn with_format_arg_write<F>(arg: &FormatArg, args: &[VVal], fs: &mut FormatState, ct: CastType, f: F) -> std::fmt::Result
where F: FnMut(&mut FormatState, &VVal) -> std::fmt::Result
pub(crate) fn with_format_arg_write<F>(
arg: &FormatArg,
args: &[VVal],
fs: &mut FormatState,
ct: CastType,
f: F,
) -> std::fmt::Result
where
F: FnMut(&mut FormatState, &VVal) -> std::fmt::Result,
{
match arg {
FormatArg::Index(i) => { write_vval(&args[*i], fs, ct, f) },
FormatArg::Index(i) => write_vval(&args[*i], fs, ct, f),
FormatArg::Key(k) => {
let val =
k.with_s_ref(|ks|
args[0].get_key(ks).unwrap_or(VVal::None));
let val = k.with_s_ref(|ks| args[0].get_key(ks).unwrap_or(VVal::None));
write_vval(&val, fs, ct, f)
},
}
}
}
macro_rules! ft_align_write {
($ftype: ident, $align: ident, $fs: ident, $prefix: literal, $postfix: expr, $arg0: expr, $arg1: expr) => {
match $ftype {
FormatType::Bin =>
align_write!($align, $fs, $prefix, concat!($postfix, "b"), $arg0, $arg1),
FormatType::Oct =>
align_write!($align, $fs, $prefix, concat!($postfix, "o"), $arg0, $arg1),
FormatType::Hex =>
align_write!($align, $fs, $prefix, concat!($postfix, "x"), $arg0, $arg1),
FormatType::Unknown =>
align_write!($align, $fs, $prefix, $postfix, $arg0, $arg1),
FormatType::Bin => {
align_write!($align, $fs, $prefix, concat!($postfix, "b"), $arg0, $arg1)
}
FormatType::Oct => {
align_write!($align, $fs, $prefix, concat!($postfix, "o"), $arg0, $arg1)
}
FormatType::Hex => {
align_write!($align, $fs, $prefix, concat!($postfix, "x"), $arg0, $arg1)
}
FormatType::Unknown => align_write!($align, $fs, $prefix, $postfix, $arg0, $arg1),
}
};
}
macro_rules! align_write {
($align: ident, $fs: ident, $prefix: literal, $postfix: expr, $arg0: expr, $arg1: expr) => {
match $align {
1 => { write!($fs, concat!("{", $prefix, ">", $postfix, "}"), $arg0, $arg1) },
2 => { write!($fs, concat!("{", $prefix, "^", $postfix, "}"), $arg0, $arg1) },
_ => { write!($fs, concat!("{", $prefix, "<", $postfix, "}"), $arg0, $arg1) },
1 => {
write!($fs, concat!("{", $prefix, ">", $postfix, "}"), $arg0, $arg1)
}
2 => {
write!($fs, concat!("{", $prefix, "^", $postfix, "}"), $arg0, $arg1)
}
_ => {
write!($fs, concat!("{", $prefix, "<", $postfix, "}"), $arg0, $arg1)
}
}
};
($align: ident, $fs: ident, $prefix: literal, $postfix: expr, $arg0: expr, $arg1: expr, $arg2: expr) => {
match $align {
1 => { write!($fs, concat!("{", $prefix, ">", $postfix, "}"), $arg0, $arg1, $arg2) },
2 => { write!($fs, concat!("{", $prefix, "^", $postfix, "}"), $arg0, $arg1, $arg2) },
_ => { write!($fs, concat!("{", $prefix, "<", $postfix, "}"), $arg0, $arg1, $arg2) },
1 => {
write!($fs, concat!("{", $prefix, ">", $postfix, "}"), $arg0, $arg1, $arg2)
}
2 => {
write!($fs, concat!("{", $prefix, "^", $postfix, "}"), $arg0, $arg1, $arg2)
}
_ => {
write!($fs, concat!("{", $prefix, "<", $postfix, "}"), $arg0, $arg1, $arg2)
}
}
};
}
pub(crate) type AlignNode = Box<dyn Fn(&mut FormatState, &[VVal], usize) -> std::fmt::Result>;
pub(crate) type AlignNode = Box<dyn Fn(&mut FormatState, &[VVal], usize) -> std::fmt::Result>;
pub(crate) fn compile_align_fun(fill: String, width: Option<CountNode>, align: i64) -> AlignNode {
if let Some(width) = width {
@ -583,30 +618,26 @@ pub(crate) fn compile_align_fun(fill: String, width: Option<CountNode>, align: i
let pad_len = width - len;
match align {
1 => {
1 => {
let idx = fs.cur_len() - len;
let pad = fill.repeat(pad_len);
fs.insert_at(idx, &pad);
},
2 => {
let first_half_pad = pad_len / 2;
}
2 => {
let first_half_pad = pad_len / 2;
let second_half_pad =
if first_half_pad <= pad_len {
pad_len - first_half_pad
} else {
0
};
if first_half_pad <= pad_len { pad_len - first_half_pad } else { 0 };
let idx = fs.cur_len() - len;
let pad_l = fill.repeat(first_half_pad);
let pad_r = fill.repeat(second_half_pad);
fs.insert_at(idx, &pad_l);
fs.insert_at(fs.cur_len(), &pad_r);
},
}
-1 => {
let pad = fill.repeat(pad_len);
fs.insert_at(fs.cur_len(), &pad);
},
_ => (),
}
_ => (),
}
}
@ -623,23 +654,15 @@ pub(crate) fn compile_align_fun(fill: String, width: Option<CountNode>, align: i
#[allow(clippy::collapsible_else_if)]
pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
let width = fmt.get_key("width");
let width : Option<CountNode> =
if let Some(width) = width {
Some(compile_count(&width))
} else {
None
};
let width: Option<CountNode> =
if let Some(width) = width { Some(compile_count(&width)) } else { None };
let prec = fmt.get_key("precision");
let prec : Option<CountNode> =
if let Some(prec) = prec {
Some(compile_count(&prec))
} else {
None
};
let prec: Option<CountNode> =
if let Some(prec) = prec { Some(compile_count(&prec)) } else { None };
let align = fmt.v_ik("align");
let mut fill = fmt.v_s_rawk("fill");
let mut fill = fmt.v_s_rawk("fill");
if fill.is_empty() {
fill = String::from(" ");
}
@ -651,8 +674,7 @@ pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
match cast_type {
CastType::Int => {
if let Some(width) = width {
let align =
if align == 0 { 1 } else { align };
let align = if align == 0 { 1 } else { align };
if fmt.v_ik("pad0") > 0 {
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
@ -662,7 +684,6 @@ pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
ft_align_write!(ftype, align, fs, "0:", "01$", v.i(), width)
})
})
} else {
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
let width = (*width)(fs, args);
@ -672,56 +693,49 @@ pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
})
})
}
} else {
match ftype {
FormatType::Bin =>
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{:b}"), v.i())
})
}),
FormatType::Oct =>
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{:o}"), v.i())
})
}),
FormatType::Hex =>
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{:x}"), v.i())
})
}),
FormatType::Unknown =>
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{}"), v.i())
})
FormatType::Bin => Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{:b}"), v.i())
})
}),
FormatType::Oct => Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{:o}"), v.i())
})
}),
FormatType::Hex => Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{:x}"), v.i())
})
}),
FormatType::Unknown => Box::new(move |fs: &mut FormatState, args: &[VVal]| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
write!(fs, concat!("{}"), v.i())
})
}),
}
}
},
}
CastType::Flt => {
if let Some(width) = width {
let align =
if align == 0 { 1 } else { align };
let align = if align == 0 { 1 } else { align };
if let Some(prec) = prec {
if fmt.v_ik("pad0") > 0 {
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
let width = (*width)(fs, args);
let prec = (*prec)(fs, args);
let prec = (*prec)(fs, args);
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
align_write!(align, fs, "0:", "01$.2$", v.f(), width, prec)
})
})
} else {
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
let width = (*width)(fs, args);
let prec = (*prec)(fs, args);
let prec = (*prec)(fs, args);
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
align_write!(align, fs, "0:", "1$.2$", v.f(), width, prec)
@ -737,7 +751,6 @@ pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
align_write!(align, fs, "0:", "01$", v.f(), width)
})
})
} else {
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
let width = (*width)(fs, args);
@ -748,7 +761,6 @@ pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
})
}
}
} else if let Some(prec) = prec {
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
let prec = (*prec)(fs, args);
@ -786,7 +798,7 @@ pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
Box::new(move |fs: &mut FormatState, args: &[VVal]| {
let mut len = 0;
with_format_arg_write(&arg, args, fs, cast_type,|fs, v| {
with_format_arg_write(&arg, args, fs, cast_type, |fs, v| {
if v.is_bytes() {
v.with_bv_ref(|bv| {
len = bv.len();
@ -812,7 +824,7 @@ pub(crate) fn compile_format(arg: FormatArg, fmt: &VVal) -> FormatNode {
}
pub(crate) fn compile_formatter(fmt: &VVal) -> (FormatNode, usize) {
let mut fmts : Vec<FormatNode> = vec![];
let mut fmts: Vec<FormatNode> = vec![];
let mut max_argc = 0;
for (item, _) in fmt.iter() {
@ -823,44 +835,41 @@ pub(crate) fn compile_formatter(fmt: &VVal) -> (FormatNode, usize) {
fmts.push(Box::new(move |fs: &mut FormatState, _args: &[VVal]| {
arg.with_s_ref(|s| fs.write_str(s))
}));
},
}
_ => {
let arg =
arg.at(0).unwrap().with_s_ref(|arg_syn| {
match arg_syn {
"index" => {
if max_argc < arg.v_i(1) + 1 {
max_argc = arg.v_i(1) + 1;
}
FormatArg::Index(arg.v_i(1) as usize)
},
_ => {
if max_argc < 1 {
max_argc = 1;