add as patterns
This commit is contained in:
parent
cda217f6ef
commit
34ab24c4c9
|
@ -33,6 +33,7 @@ pub enum Op {
|
|||
MatchWord,
|
||||
PanicIfNoMatch,
|
||||
MatchConstant,
|
||||
MatchType,
|
||||
MatchTuple,
|
||||
PushTuple,
|
||||
LoadTuple,
|
||||
|
@ -140,6 +141,7 @@ impl std::fmt::Display for Op {
|
|||
ResetMatch => "reset_match",
|
||||
PanicIfNoMatch => "panic_if_no_match",
|
||||
MatchConstant => "match_constant",
|
||||
MatchType => "match_type",
|
||||
MatchTuple => "match_tuple",
|
||||
PushTuple => "push_tuple",
|
||||
LoadTuple => "load_tuple",
|
||||
|
@ -210,7 +212,7 @@ impl Chunk {
|
|||
| PanicIfNoMatch | MatchWord | 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 => {
|
||||
| EmptyString | ConcatStrings | Stringify | MatchType => {
|
||||
println!("{i:04}: {op}")
|
||||
}
|
||||
Constant | MatchConstant => {
|
||||
|
@ -359,10 +361,12 @@ impl Compiler {
|
|||
)
|
||||
}
|
||||
self.chunk.constants.push(val);
|
||||
self.chunk.bytecode.push(Op::Constant as u8);
|
||||
self.spans.push(self.span);
|
||||
self.chunk.bytecode.push(constant_index as u8);
|
||||
self.spans.push(self.span);
|
||||
self.emit_op(Op::Constant);
|
||||
// self.chunk.bytecode.push(Op::Constant as u8);
|
||||
// self.spans.push(self.span);
|
||||
self.emit_byte(constant_index);
|
||||
// self.chunk.bytecode.push(constant_index as u8);
|
||||
// self.spans.push(self.span);
|
||||
self.stack_depth += 1;
|
||||
}
|
||||
|
||||
|
@ -380,10 +384,12 @@ impl Compiler {
|
|||
if constant_index == self.chunk.constants.len() {
|
||||
self.chunk.constants.push(val);
|
||||
}
|
||||
self.chunk.bytecode.push(Op::MatchConstant as u8);
|
||||
self.spans.push(self.span);
|
||||
self.chunk.bytecode.push(constant_index as u8);
|
||||
self.spans.push(self.span);
|
||||
self.emit_op(Op::MatchConstant);
|
||||
self.emit_byte(constant_index);
|
||||
// self.chunk.bytecode.push(Op::MatchConstant as u8);
|
||||
// self.spans.push(self.span);
|
||||
// self.chunk.bytecode.push(constant_index as u8);
|
||||
// self.spans.push(self.span);
|
||||
}
|
||||
|
||||
fn emit_op(&mut self, op: Op) {
|
||||
|
@ -572,6 +578,12 @@ impl Compiler {
|
|||
}
|
||||
self.match_constant(Value::Keyword(kw_index));
|
||||
}
|
||||
AsPattern(word, typ) => {
|
||||
self.emit_constant(self.chunk.kw_from(typ).unwrap());
|
||||
self.emit_op(Op::MatchType);
|
||||
self.stack_depth -= 1;
|
||||
self.bind(word);
|
||||
}
|
||||
StringPattern(s) => {
|
||||
let existing_str = self.chunk.strings.iter().position(|e| e == s);
|
||||
let str_index = match existing_str {
|
||||
|
@ -1142,7 +1154,6 @@ impl Compiler {
|
|||
| Do(..)
|
||||
| Splat(..)
|
||||
| InterpolatedPattern(..)
|
||||
| AsPattern(..)
|
||||
| Splattern(..) => todo!(),
|
||||
And | Or => unreachable!(),
|
||||
}
|
||||
|
@ -1160,7 +1171,7 @@ impl Compiler {
|
|||
| MatchFalse | MatchWord | ResetMatch | PanicIfNoMatch | GetKey | PanicNoWhen
|
||||
| PanicNoMatch | TypeOf | Duplicate | Truncate | Decrement | LoadTuple
|
||||
| LoadList | Eq | Add | Sub | Mult | Div | Unbox | BoxStore | Assert | Get | At
|
||||
| Not | Panic | EmptyString | ConcatStrings | Stringify => {
|
||||
| Not | Panic | EmptyString | ConcatStrings | Stringify | MatchType => {
|
||||
println!("{i:04}: {op}")
|
||||
}
|
||||
Constant | MatchConstant => {
|
||||
|
|
|
@ -74,10 +74,8 @@ pub fn run(src: &'static str) {
|
|||
pub fn main() {
|
||||
env::set_var("RUST_BACKTRACE", "1");
|
||||
let src = "
|
||||
let x = 42
|
||||
let y = :foo
|
||||
let z = \"thing\"
|
||||
\"{x} {y} {z}\"
|
||||
let (x as :keyword, y as :number) = (:ok, 42)
|
||||
[x, y]
|
||||
";
|
||||
run(src);
|
||||
}
|
||||
|
|
16
src/vm.rs
16
src/vm.rs
|
@ -249,6 +249,15 @@ impl<'a> Vm<'a> {
|
|||
self.matches = true;
|
||||
self.ip += 1;
|
||||
}
|
||||
MatchType => {
|
||||
let as_type = self.pop();
|
||||
let idx = self.stack.len() - self.match_depth as usize - 1;
|
||||
let val_type = self.stack[idx].type_of();
|
||||
let val_type = self.chunk.kw_from(val_type).unwrap();
|
||||
self.matches = val_type == as_type;
|
||||
self.ip += 1;
|
||||
self.interpret()
|
||||
}
|
||||
MatchNil => {
|
||||
let idx = self.stack.len() - self.match_depth as usize - 1;
|
||||
if self.stack[idx] == Value::Nil {
|
||||
|
@ -579,14 +588,15 @@ impl<'a> Vm<'a> {
|
|||
self.push(Value::String(Rc::new("".to_string())));
|
||||
self.ip += 1;
|
||||
}
|
||||
//TODO: don't use the schlemiel's algo here
|
||||
ConcatStrings => {
|
||||
let second = self.pop();
|
||||
let first = self.pop();
|
||||
let combined = match (first, second) {
|
||||
(Value::String(first), Value::String(second)) => {
|
||||
let mut newstr = first.as_ref().clone();
|
||||
newstr.push_str(second.as_str());
|
||||
Value::String(Rc::new(newstr))
|
||||
let mut new = first.as_ref().clone();
|
||||
new.push_str(second.as_str());
|
||||
Value::String(Rc::new(new))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user