add list splats
This commit is contained in:
parent
b8b720b877
commit
b557c487cc
|
@ -41,6 +41,8 @@ pub enum Op {
|
|||
MatchList,
|
||||
LoadList,
|
||||
PushList,
|
||||
AppendList,
|
||||
ConcatList,
|
||||
PushDict,
|
||||
LoadDictValue,
|
||||
MatchDict,
|
||||
|
@ -153,6 +155,8 @@ impl std::fmt::Display for Op {
|
|||
MatchList => "match_list",
|
||||
LoadList => "load_list",
|
||||
PushList => "push_list",
|
||||
AppendList => "append_list",
|
||||
ConcatList => "concat_list",
|
||||
PushDict => "push_dict",
|
||||
LoadDictValue => "load_dict_value",
|
||||
MatchDict => "match_dict",
|
||||
|
@ -228,7 +232,8 @@ impl Chunk {
|
|||
| PanicIfNoMatch | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch | TypeOf
|
||||
| Duplicate | Decrement | Truncate | Noop | LoadTuple | LoadList | Eq | Add | Sub
|
||||
| Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | EmptyString
|
||||
| ConcatStrings | Stringify | MatchType | Return | Match | Print => {
|
||||
| ConcatStrings | Stringify | MatchType | Return | Match | Print | AppendList
|
||||
| ConcatList | PushList => {
|
||||
println!("{i:04}: {op}")
|
||||
}
|
||||
Constant | MatchConstant => {
|
||||
|
@ -238,7 +243,7 @@ impl Chunk {
|
|||
*i += 1;
|
||||
}
|
||||
PushBinding | MatchTuple | MatchList | MatchDict | LoadDictValue | PushTuple
|
||||
| PushDict | PushList | PushBox | Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch
|
||||
| PushDict | PushBox | Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch
|
||||
| JumpIfMatch | JumpBack | JumpIfZero | MatchDepth | PopN | StoreAt | Call
|
||||
| SetUpvalue | GetUpvalue => {
|
||||
let next = self.bytecode[*i + 1];
|
||||
|
@ -590,7 +595,7 @@ impl<'a> Compiler<'a> {
|
|||
self.emit_op(Op::Match);
|
||||
self.bind(name);
|
||||
}
|
||||
Word(name) => match self.resolve_local(name) {
|
||||
Word(name) | Splat(name) => match self.resolve_local(name) {
|
||||
Some(position) => {
|
||||
self.emit_op(Op::PushBinding);
|
||||
self.emit_byte(position);
|
||||
|
@ -757,12 +762,17 @@ impl<'a> Compiler<'a> {
|
|||
self.stack_depth = self.stack_depth + 1 - members.len();
|
||||
}
|
||||
List(members) => {
|
||||
self.emit_op(Op::PushList);
|
||||
self.stack_depth += 1;
|
||||
for member in members {
|
||||
self.visit(member);
|
||||
if matches!(member, (Splat(..), _)) {
|
||||
self.emit_op(Op::ConcatList);
|
||||
} else {
|
||||
self.emit_op(Op::AppendList);
|
||||
}
|
||||
self.stack_depth -= 1;
|
||||
}
|
||||
self.emit_op(Op::PushList);
|
||||
self.emit_byte(members.len());
|
||||
self.stack_depth = self.stack_depth + 1 - members.len();
|
||||
}
|
||||
LBox(name, expr) => {
|
||||
self.visit(expr);
|
||||
|
@ -1273,7 +1283,7 @@ impl<'a> Compiler<'a> {
|
|||
self.stack_depth -= 1;
|
||||
}
|
||||
}
|
||||
Arguments(..) | Placeholder | Splat(..) | InterpolatedPattern(..) | Splattern(..) => {
|
||||
Arguments(..) | Placeholder | InterpolatedPattern(..) | Splattern(..) => {
|
||||
todo!()
|
||||
}
|
||||
And | Or => unreachable!(),
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -76,14 +76,11 @@ pub fn run(src: &'static str) {
|
|||
pub fn main() {
|
||||
env::set_var("RUST_BACKTRACE", "1");
|
||||
let src = "
|
||||
fn increase (x) -> add (x, 1)
|
||||
|
||||
fn double (x) -> mult (x, 2)
|
||||
|
||||
fn halve (x) -> div (x, 2)
|
||||
|
||||
do 1 > increase > double > increase > halve
|
||||
let x = []
|
||||
let y = [1, 2, 3]
|
||||
let z = [...y, 4, ...x]
|
||||
|
||||
z
|
||||
|
||||
";
|
||||
run(src);
|
||||
|
|
37
src/vm.rs
37
src/vm.rs
|
@ -368,12 +368,39 @@ impl Vm {
|
|||
};
|
||||
self.ip += 1;
|
||||
}
|
||||
// PushList => {
|
||||
// let list_len = self.chunk().bytecode[self.ip + 1];
|
||||
// let list_members = self.stack.split_off(self.stack.len() - list_len as usize);
|
||||
// let list = Value::List(Box::new(Vector::from(list_members)));
|
||||
// self.push(list);
|
||||
// self.ip += 2;
|
||||
// }
|
||||
PushList => {
|
||||
let list_len = self.chunk().bytecode[self.ip + 1];
|
||||
let list_members = self.stack.split_off(self.stack.len() - list_len as usize);
|
||||
let list = Value::List(Box::new(Vector::from(list_members)));
|
||||
self.push(list);
|
||||
self.ip += 2;
|
||||
self.push(Value::List(Box::new(Vector::new())));
|
||||
self.ip += 1;
|
||||
}
|
||||
AppendList => {
|
||||
let value = self.pop();
|
||||
let list = self.pop();
|
||||
let Value::List(mut list) = list else {
|
||||
return self.panic("only lists may be splatted into lists");
|
||||
};
|
||||
list.push_back(value);
|
||||
self.push(Value::List(list));
|
||||
self.ip += 1;
|
||||
}
|
||||
ConcatList => {
|
||||
let splatted = self.pop();
|
||||
let target = self.pop();
|
||||
let Value::List(mut target) = target else {
|
||||
unreachable!()
|
||||
};
|
||||
let Value::List(splatted) = splatted else {
|
||||
return self.panic("only lists may be splatted into lists");
|
||||
};
|
||||
target.append(*splatted);
|
||||
self.push(Value::List(target));
|
||||
self.ip += 1;
|
||||
}
|
||||
MatchList => {
|
||||
let idx = self.stack.len() - self.match_depth as usize - 1;
|
||||
|
|
Loading…
Reference in New Issue
Block a user