mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: filtering maps, lists, and tuples works.
This commit is contained in:
parent
8d7ca3d6c1
commit
b016b9294b
@ -419,18 +419,6 @@ impl Builtins {
|
|||||||
} else {
|
} else {
|
||||||
return Err(dbg!(Error {}));
|
return Err(dbg!(Error {}));
|
||||||
};
|
};
|
||||||
// TODO(jwall): This can also be tuples or strings.
|
|
||||||
let elems = match list.as_ref() {
|
|
||||||
&C(List(ref elems)) => elems,
|
|
||||||
&C(Tuple(ref _flds)) => {
|
|
||||||
unimplemented!("TODO Tuple functional operations");
|
|
||||||
}
|
|
||||||
&P(Str(ref _s)) => {
|
|
||||||
unimplemented!("TODO String functional operations");
|
|
||||||
}
|
|
||||||
_ => return Err(dbg!(Error {})),
|
|
||||||
};
|
|
||||||
|
|
||||||
// get the func ptr from the stack
|
// get the func ptr from the stack
|
||||||
let fptr = if let Some(ptr) = stack.pop() {
|
let fptr = if let Some(ptr) = stack.pop() {
|
||||||
ptr
|
ptr
|
||||||
@ -444,22 +432,65 @@ impl Builtins {
|
|||||||
return dbg!(Err(Error {}));
|
return dbg!(Err(Error {}));
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result_elems = Vec::new();
|
// TODO(jwall): This can also be tuples or strings.
|
||||||
for e in elems.iter() {
|
let elems = match list.as_ref() {
|
||||||
// push function argument on the stack.
|
&C(List(ref elems)) => {
|
||||||
stack.push(e.clone());
|
let mut result_elems = Vec::new();
|
||||||
// call function and push it's result on the stack.
|
for e in elems.iter() {
|
||||||
let condition = VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
// push function argument on the stack.
|
||||||
// Check for empty or boolean results and only push e back in
|
stack.push(e.clone());
|
||||||
// if they are non empty and true
|
// call function and push it's result on the stack.
|
||||||
match condition.as_ref() {
|
let condition =
|
||||||
&P(Empty) | &P(Bool(false)) => {
|
VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||||
continue;
|
// Check for empty or boolean results and only push e back in
|
||||||
|
// if they are non empty and true
|
||||||
|
match condition.as_ref() {
|
||||||
|
&P(Empty) | &P(Bool(false)) => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => result_elems.push(e.clone()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => result_elems.push(e.clone()),
|
stack.push(Rc::new(C(List(result_elems))));
|
||||||
}
|
}
|
||||||
}
|
&C(Tuple(ref _flds)) => {
|
||||||
stack.push(Rc::new(C(List(result_elems))));
|
let mut new_fields = Vec::new();
|
||||||
|
for (ref name, ref val) in _flds {
|
||||||
|
stack.push(val.clone());
|
||||||
|
stack.push(Rc::new(P(Str(name.clone()))));
|
||||||
|
let condition =
|
||||||
|
VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||||
|
// Check for empty or boolean results and only push e back in
|
||||||
|
// if they are non empty and true
|
||||||
|
match condition.as_ref() {
|
||||||
|
&P(Empty) | &P(Bool(false)) => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => new_fields.push((name.clone(), val.clone())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack.push(Rc::new(C(Tuple(dbg!(new_fields)))));
|
||||||
|
}
|
||||||
|
&P(Str(ref s)) => {
|
||||||
|
let mut buf = String::new();
|
||||||
|
for c in s.chars() {
|
||||||
|
stack.push(Rc::new(P(Str(c.to_string()))));
|
||||||
|
// call function and push it's result on the stack.
|
||||||
|
let condition =
|
||||||
|
VM::fcall_impl(path.as_ref().to_owned(), f, stack, env.clone())?;
|
||||||
|
// Check for empty or boolean results and only push c back in
|
||||||
|
// if they are non empty and true
|
||||||
|
match condition.as_ref() {
|
||||||
|
&P(Empty) | &P(Bool(false)) => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => buf.push(c),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack.push(Rc::new(P(Str(buf))));
|
||||||
|
}
|
||||||
|
_ => return Err(dbg!(Error {})),
|
||||||
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,3 +798,32 @@ fn simple_maps() {
|
|||||||
])),
|
])),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple_filters() {
|
||||||
|
assert_parse_cases![
|
||||||
|
"filter(func(el) => true, [1,2,3]);" => C(List(vec![
|
||||||
|
Rc::new(P(Int(1))),
|
||||||
|
Rc::new(P(Int(2))),
|
||||||
|
Rc::new(P(Int(3))),
|
||||||
|
])),
|
||||||
|
"filter(func(el) => false, [1,2,3]);" => C(List(vec![
|
||||||
|
])),
|
||||||
|
"filter(func(el) => el != 1, [1,2,3]);" => C(List(vec![
|
||||||
|
Rc::new(P(Int(2))),
|
||||||
|
Rc::new(P(Int(3))),
|
||||||
|
])),
|
||||||
|
"filter(func(el) => true, \"foo\");" => P(Str("foo".to_owned())),
|
||||||
|
"filter(func(el) => false, \"foo\");" => P(Str("".to_owned())),
|
||||||
|
"filter(func(el) => el != \"f\", \"foo\");" => P(Str("oo".to_owned())),
|
||||||
|
"filter(func(k, v) => true, {foo = 1});" => C(Tuple(vec![
|
||||||
|
("foo".to_owned(), Rc::new(P(Int(1)))),
|
||||||
|
])),
|
||||||
|
"filter(func(k, v) => false, {foo = 1});" => C(Tuple(vec![
|
||||||
|
])),
|
||||||
|
"filter(func(k, v) => k != \"foo\", {foo = 1});" => C(Tuple(vec![
|
||||||
|
])),
|
||||||
|
"filter(func(k, v) => v != 1, {foo = 1});" => C(Tuple(vec![
|
||||||
|
])),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user