keywords and interned strings use &'static str instead of indexes into vecs
This commit is contained in:
parent
681176282c
commit
86992078e9
125
src/compiler.rs
125
src/compiler.rs
|
@ -219,7 +219,7 @@ impl Chunk {
|
||||||
}
|
}
|
||||||
Constant | MatchConstant => {
|
Constant | MatchConstant => {
|
||||||
let next = self.bytecode[*i + 1];
|
let next = self.bytecode[*i + 1];
|
||||||
let value = &self.constants[next as usize].show(self);
|
let value = &self.constants[next as usize].show();
|
||||||
println!("{i:04}: {:16} {next:04}: {value}", op.to_string());
|
println!("{i:04}: {:16} {next:04}: {value}", op.to_string());
|
||||||
*i += 1;
|
*i += 1;
|
||||||
}
|
}
|
||||||
|
@ -242,9 +242,9 @@ impl Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kw_from(&self, kw: &str) -> Option<Value> {
|
// pub fn kw_from(&self, kw: &str) -> Option<Value> {
|
||||||
self.kw_index_from(kw).map(Value::Keyword)
|
// self.kw_index_from(kw).map(Value::Keyword)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn kw_index_from(&self, kw: &str) -> Option<usize> {
|
pub fn kw_index_from(&self, kw: &str) -> Option<usize> {
|
||||||
self.keywords.iter().position(|s| *s == kw)
|
self.keywords.iter().position(|s| *s == kw)
|
||||||
|
@ -334,13 +334,13 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kw_from(&self, kw: &str) -> Option<Value> {
|
// pub fn kw_from(&self, kw: &str) -> Option<Value> {
|
||||||
self.kw_index_from(kw).map(Value::Keyword)
|
// self.kw_index_from(kw).map(Value::Keyword)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn kw_index_from(&self, kw: &str) -> Option<usize> {
|
// pub fn kw_index_from(&self, kw: &str) -> Option<usize> {
|
||||||
self.chunk.keywords.iter().position(|s| *s == kw)
|
// self.chunk.keywords.iter().position(|s| *s == kw)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn visit(&mut self, node: &'static Spanned<Ast>) {
|
pub fn visit(&mut self, node: &'static Spanned<Ast>) {
|
||||||
let root_node = self.ast;
|
let root_node = self.ast;
|
||||||
|
@ -353,31 +353,36 @@ impl Compiler {
|
||||||
self.span = root_span;
|
self.span = root_span;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_keyword(&mut self, s: &'static str) {
|
// fn emit_keyword(&mut self, s: &'static str) {
|
||||||
let existing_kw = self.chunk.keywords.iter().position(|kw| *kw == s);
|
// // let existing_kw = self.chunk.keywords.iter().position(|kw| *kw == s);
|
||||||
let kw_index = match existing_kw {
|
// // let kw_index = match existing_kw {
|
||||||
Some(index) => index,
|
// // Some(index) => index,
|
||||||
None => self.chunk.keywords.len(),
|
// // None => self.chunk.keywords.len(),
|
||||||
};
|
// // };
|
||||||
if kw_index == self.chunk.keywords.len() {
|
// // if kw_index == self.chunk.keywords.len() {
|
||||||
self.chunk.keywords.push(s);
|
// // self.chunk.keywords.push(s);
|
||||||
}
|
// // }
|
||||||
self.emit_constant(Value::Keyword(kw_index));
|
// self.emit_constant(Value::Keyword(s));
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn emit_constant(&mut self, val: Value) {
|
fn emit_constant(&mut self, val: Value) {
|
||||||
let constant_index = self.chunk.constants.len();
|
let const_idx = if let Some(idx) = self.chunk.constants.iter().position(|v| *v == val) {
|
||||||
if constant_index > u8::MAX as usize {
|
idx
|
||||||
|
} else {
|
||||||
|
self.chunk.constants.push(val);
|
||||||
|
self.chunk.constants.len() - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if const_idx > u8::MAX as usize {
|
||||||
panic!(
|
panic!(
|
||||||
"internal Ludus compiler error: too many constants in chunk:{}:: {}",
|
"internal Ludus compiler error: too many constants in chunk:{}:: {}",
|
||||||
self.span, self.ast
|
self.span, self.ast
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
self.chunk.constants.push(val);
|
|
||||||
self.emit_op(Op::Constant);
|
self.emit_op(Op::Constant);
|
||||||
// self.chunk.bytecode.push(Op::Constant as u8);
|
// self.chunk.bytecode.push(Op::Constant as u8);
|
||||||
// self.spans.push(self.span);
|
// self.spans.push(self.span);
|
||||||
self.emit_byte(constant_index);
|
self.emit_byte(const_idx);
|
||||||
// self.chunk.bytecode.push(constant_index as u8);
|
// self.chunk.bytecode.push(constant_index as u8);
|
||||||
// self.spans.push(self.span);
|
// self.spans.push(self.span);
|
||||||
self.stack_depth += 1;
|
self.stack_depth += 1;
|
||||||
|
@ -386,7 +391,10 @@ impl Compiler {
|
||||||
fn match_constant(&mut self, val: Value) {
|
fn match_constant(&mut self, val: Value) {
|
||||||
let constant_index = match self.chunk.constants.iter().position(|v| *v == val) {
|
let constant_index = match self.chunk.constants.iter().position(|v| *v == val) {
|
||||||
Some(idx) => idx,
|
Some(idx) => idx,
|
||||||
None => self.chunk.constants.len(),
|
None => {
|
||||||
|
self.chunk.constants.push(val);
|
||||||
|
self.chunk.constants.len() - 1
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if constant_index > u8::MAX as usize {
|
if constant_index > u8::MAX as usize {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -394,15 +402,8 @@ impl Compiler {
|
||||||
self.span, self.ast
|
self.span, self.ast
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if constant_index == self.chunk.constants.len() {
|
|
||||||
self.chunk.constants.push(val);
|
|
||||||
}
|
|
||||||
self.emit_op(Op::MatchConstant);
|
self.emit_op(Op::MatchConstant);
|
||||||
self.emit_byte(constant_index);
|
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) {
|
fn emit_op(&mut self, op: Op) {
|
||||||
|
@ -476,15 +477,15 @@ impl Compiler {
|
||||||
self.stack_depth += 1;
|
self.stack_depth += 1;
|
||||||
}
|
}
|
||||||
String(s) => {
|
String(s) => {
|
||||||
let existing_str = self.chunk.strings.iter().position(|e| e == s);
|
// let existing_str = self.chunk.strings.iter().position(|e| e == s);
|
||||||
let str_index = match existing_str {
|
// let str_index = match existing_str {
|
||||||
Some(idx) => idx,
|
// Some(idx) => idx,
|
||||||
None => self.chunk.strings.len(),
|
// None => self.chunk.strings.len(),
|
||||||
};
|
// };
|
||||||
self.chunk.strings.push(s);
|
// self.chunk.strings.push(s);
|
||||||
self.emit_constant(Value::Interned(str_index));
|
self.emit_constant(Value::Interned(s));
|
||||||
}
|
}
|
||||||
Keyword(s) => self.emit_keyword(s),
|
Keyword(s) => self.emit_constant(Value::Keyword(s)),
|
||||||
Block(lines) => {
|
Block(lines) => {
|
||||||
self.scope_depth += 1;
|
self.scope_depth += 1;
|
||||||
let stack_depth = self.stack_depth;
|
let stack_depth = self.stack_depth;
|
||||||
|
@ -589,24 +590,24 @@ impl Compiler {
|
||||||
if kw_index == self.chunk.keywords.len() {
|
if kw_index == self.chunk.keywords.len() {
|
||||||
self.chunk.keywords.push(s);
|
self.chunk.keywords.push(s);
|
||||||
}
|
}
|
||||||
self.match_constant(Value::Keyword(kw_index));
|
self.match_constant(Value::Keyword(s));
|
||||||
}
|
}
|
||||||
AsPattern(word, typ) => {
|
AsPattern(word, typ) => {
|
||||||
self.emit_constant(self.chunk.kw_from(typ).unwrap());
|
self.emit_constant(Value::Keyword(typ));
|
||||||
self.emit_op(Op::MatchType);
|
self.emit_op(Op::MatchType);
|
||||||
self.stack_depth -= 1;
|
self.stack_depth -= 1;
|
||||||
self.bind(word);
|
self.bind(word);
|
||||||
}
|
}
|
||||||
StringPattern(s) => {
|
StringPattern(s) => {
|
||||||
let existing_str = self.chunk.strings.iter().position(|e| e == s);
|
// let existing_str = self.chunk.strings.iter().position(|e| e == s);
|
||||||
let str_index = match existing_str {
|
// let str_index = match existing_str {
|
||||||
Some(idx) => idx,
|
// Some(idx) => idx,
|
||||||
None => self.chunk.strings.len(),
|
// None => self.chunk.strings.len(),
|
||||||
};
|
// };
|
||||||
if str_index == self.chunk.strings.len() {
|
// if str_index == self.chunk.strings.len() {
|
||||||
self.chunk.strings.push(s)
|
// self.chunk.strings.push(s)
|
||||||
}
|
// }
|
||||||
self.match_constant(Value::Interned(str_index));
|
self.match_constant(Value::Interned(s));
|
||||||
}
|
}
|
||||||
TuplePattern(members) => {
|
TuplePattern(members) => {
|
||||||
self.emit_op(Op::MatchTuple);
|
self.emit_op(Op::MatchTuple);
|
||||||
|
@ -696,7 +697,7 @@ impl Compiler {
|
||||||
};
|
};
|
||||||
// algo:
|
// algo:
|
||||||
// push the keyword onto the stack
|
// push the keyword onto the stack
|
||||||
self.emit_keyword(key);
|
self.emit_constant(Value::Keyword(key));
|
||||||
// pull the value out of the dict
|
// pull the value out of the dict
|
||||||
self.emit_op(Op::LoadDictValue);
|
self.emit_op(Op::LoadDictValue);
|
||||||
self.emit_byte(dict_stack_pos);
|
self.emit_byte(dict_stack_pos);
|
||||||
|
@ -759,15 +760,15 @@ impl Compiler {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Pair(key, value) => {
|
Pair(key, value) => {
|
||||||
let existing_kw = self.chunk.keywords.iter().position(|kw| kw == key);
|
// let existing_kw = self.chunk.keywords.iter().position(|kw| kw == key);
|
||||||
let kw_index = match existing_kw {
|
// let kw_index = match existing_kw {
|
||||||
Some(index) => index,
|
// Some(index) => index,
|
||||||
None => self.chunk.keywords.len(),
|
// None => self.chunk.keywords.len(),
|
||||||
};
|
// };
|
||||||
if kw_index == self.chunk.keywords.len() {
|
// if kw_index == self.chunk.keywords.len() {
|
||||||
self.chunk.keywords.push(key);
|
// self.chunk.keywords.push(key);
|
||||||
}
|
// }
|
||||||
self.emit_constant(Value::Keyword(kw_index));
|
self.emit_constant(Value::Keyword(key));
|
||||||
self.visit(value);
|
self.visit(value);
|
||||||
}
|
}
|
||||||
Synthetic(first, second, rest) => {
|
Synthetic(first, second, rest) => {
|
||||||
|
|
|
@ -61,14 +61,12 @@ pub fn run(src: &'static str) {
|
||||||
println!("=== vm run: test ===");
|
println!("=== vm run: test ===");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: investigate lifeteims and remove this clone
|
|
||||||
let show_chunk = compiler.chunk.clone();
|
|
||||||
let vm_chunk = compiler.chunk;
|
let vm_chunk = compiler.chunk;
|
||||||
|
|
||||||
let mut vm = Vm::new(vm_chunk);
|
let mut vm = Vm::new(vm_chunk);
|
||||||
let result = vm.run();
|
let result = vm.run();
|
||||||
let output = match result {
|
let output = match result {
|
||||||
Ok(val) => val.show(&show_chunk),
|
Ok(val) => val.show(),
|
||||||
Err(panic) => format!("Ludus panicked! {panic}"),
|
Err(panic) => format!("Ludus panicked! {panic}"),
|
||||||
};
|
};
|
||||||
vm.print_stack();
|
vm.print_stack();
|
||||||
|
@ -78,9 +76,9 @@ pub fn run(src: &'static str) {
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
env::set_var("RUST_BACKTRACE", "1");
|
env::set_var("RUST_BACKTRACE", "1");
|
||||||
let src = "
|
let src = "
|
||||||
fn foo (_) -> [1, 2, 3]
|
fn foo (_) -> :foo
|
||||||
|
|
||||||
foo (1)
|
foo (nil)
|
||||||
";
|
";
|
||||||
run(src);
|
run(src);
|
||||||
}
|
}
|
||||||
|
|
57
src/value.rs
57
src/value.rs
|
@ -29,14 +29,13 @@ pub enum Value {
|
||||||
Nil,
|
Nil,
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
Keyword(usize),
|
Keyword(&'static str),
|
||||||
Interned(usize),
|
Interned(&'static str),
|
||||||
FnDecl(usize),
|
|
||||||
String(Rc<String>),
|
String(Rc<String>),
|
||||||
Number(f64),
|
Number(f64),
|
||||||
Tuple(Rc<Vec<Value>>),
|
Tuple(Rc<Vec<Value>>),
|
||||||
List(Box<Vector<Value>>),
|
List(Box<Vector<Value>>),
|
||||||
Dict(Box<HashMap<usize, Value>>),
|
Dict(Box<HashMap<&'static str, Value>>),
|
||||||
Box(Rc<RefCell<Value>>),
|
Box(Rc<RefCell<Value>>),
|
||||||
Fn(Rc<OnceCell<LFn>>),
|
Fn(Rc<OnceCell<LFn>>),
|
||||||
}
|
}
|
||||||
|
@ -49,8 +48,8 @@ impl std::fmt::Display for Value {
|
||||||
Nil => write!(f, "nil"),
|
Nil => write!(f, "nil"),
|
||||||
True => write!(f, "true"),
|
True => write!(f, "true"),
|
||||||
False => write!(f, "false"),
|
False => write!(f, "false"),
|
||||||
Keyword(idx) => write!(f, ":{idx}"),
|
Keyword(str) => write!(f, ":{str}"),
|
||||||
Interned(idx) => write!(f, "\"@{idx}\""),
|
Interned(str) => write!(f, "\"{str}\""),
|
||||||
String(str) => write!(f, "\"{str}\""),
|
String(str) => write!(f, "\"{str}\""),
|
||||||
Number(n) => write!(f, "{n}"),
|
Number(n) => write!(f, "{n}"),
|
||||||
Tuple(members) => write!(
|
Tuple(members) => write!(
|
||||||
|
@ -82,76 +81,63 @@ impl std::fmt::Display for Value {
|
||||||
),
|
),
|
||||||
Box(value) => write!(f, "box {}", value.as_ref().borrow()),
|
Box(value) => write!(f, "box {}", value.as_ref().borrow()),
|
||||||
Fn(lfn) => write!(f, "fn {}", lfn.get().unwrap().name),
|
Fn(lfn) => write!(f, "fn {}", lfn.get().unwrap().name),
|
||||||
_ => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn show(&self, ctx: &Chunk) -> String {
|
pub fn show(&self) -> String {
|
||||||
use Value::*;
|
use Value::*;
|
||||||
match &self {
|
match &self {
|
||||||
Nil => "nil".to_string(),
|
Nil => "nil".to_string(),
|
||||||
True => "true".to_string(),
|
True => "true".to_string(),
|
||||||
False => "false".to_string(),
|
False => "false".to_string(),
|
||||||
Number(n) => format!("{n}"),
|
Number(n) => format!("{n}"),
|
||||||
Interned(i) => {
|
Interned(str) => format!("\"{str}\""),
|
||||||
let str_str = ctx.strings[*i];
|
|
||||||
format!("\"{str_str}\"")
|
|
||||||
}
|
|
||||||
String(str) => {
|
String(str) => {
|
||||||
let str_str = str.to_string();
|
let str_str = str.to_string();
|
||||||
format!("\"{str_str}\"")
|
format!("\"{str_str}\"")
|
||||||
}
|
}
|
||||||
Keyword(i) => {
|
Keyword(str) => format!(":{str}"),
|
||||||
let kw_str = ctx.keywords[*i];
|
|
||||||
format!(":{kw_str}")
|
|
||||||
}
|
|
||||||
Tuple(t) => {
|
Tuple(t) => {
|
||||||
let members = t.iter().map(|e| e.show(ctx)).collect::<Vec<_>>().join(", ");
|
let members = t.iter().map(|e| e.show()).collect::<Vec<_>>().join(", ");
|
||||||
format!("({members})")
|
format!("({members})")
|
||||||
}
|
}
|
||||||
List(l) => {
|
List(l) => {
|
||||||
let members = l.iter().map(|e| e.show(ctx)).collect::<Vec<_>>().join(", ");
|
let members = l.iter().map(|e| e.show()).collect::<Vec<_>>().join(", ");
|
||||||
format!("[{members}]")
|
format!("[{members}]")
|
||||||
}
|
}
|
||||||
Dict(d) => {
|
Dict(d) => {
|
||||||
let members = d
|
let members = d
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
let key_show = Value::Keyword(*k).show(ctx);
|
let key_show = Value::Keyword(k).show();
|
||||||
let value_show = v.show(ctx);
|
let value_show = v.show();
|
||||||
format!("{key_show} {value_show}")
|
format!("{key_show} {value_show}")
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
format!("#{{{members}}}")
|
format!("#{{{members}}}")
|
||||||
}
|
}
|
||||||
Box(x) => format!("box {{ {} }}", x.as_ref().borrow().show(ctx)),
|
Box(x) => format!("box {{ {} }}", x.as_ref().borrow().show()),
|
||||||
Fn(lfn) => format!("fn {}", lfn.get().unwrap().name),
|
Fn(lfn) => format!("fn {}", lfn.get().unwrap().name),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stringify(&self, ctx: &Chunk) -> String {
|
pub fn stringify(&self) -> String {
|
||||||
use Value::*;
|
use Value::*;
|
||||||
match &self {
|
match &self {
|
||||||
Nil => "nil".to_string(),
|
Nil => "nil".to_string(),
|
||||||
True => "true".to_string(),
|
True => "true".to_string(),
|
||||||
False => "false".to_string(),
|
False => "false".to_string(),
|
||||||
Number(n) => format!("{n}"),
|
Number(n) => format!("{n}"),
|
||||||
Interned(i) => {
|
Interned(str) => str.to_string(),
|
||||||
let str_str = ctx.strings[*i];
|
Keyword(str) => str.to_string(),
|
||||||
str_str.to_string()
|
|
||||||
}
|
|
||||||
Keyword(i) => {
|
|
||||||
let kw_str = ctx.keywords[*i];
|
|
||||||
format!(":{kw_str}")
|
|
||||||
}
|
|
||||||
Tuple(t) => {
|
Tuple(t) => {
|
||||||
let members = t
|
let members = t
|
||||||
.iter()
|
.iter()
|
||||||
.map(|e| e.stringify(ctx))
|
.map(|e| e.stringify())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
members.to_string()
|
members.to_string()
|
||||||
|
@ -159,7 +145,7 @@ impl Value {
|
||||||
List(l) => {
|
List(l) => {
|
||||||
let members = l
|
let members = l
|
||||||
.iter()
|
.iter()
|
||||||
.map(|e| e.stringify(ctx))
|
.map(|e| e.stringify())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
members.to_string()
|
members.to_string()
|
||||||
|
@ -168,8 +154,8 @@ impl Value {
|
||||||
let members = d
|
let members = d
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
let key_show = Value::Keyword(*k).show(ctx);
|
let key_show = Value::Keyword(k).stringify();
|
||||||
let value_show = v.show(ctx);
|
let value_show = v.stringify();
|
||||||
format!("{key_show} {value_show}")
|
format!("{key_show} {value_show}")
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
@ -177,7 +163,7 @@ impl Value {
|
||||||
members.to_string()
|
members.to_string()
|
||||||
}
|
}
|
||||||
String(s) => s.as_ref().clone(),
|
String(s) => s.as_ref().clone(),
|
||||||
Box(x) => x.as_ref().borrow().stringify(ctx),
|
Box(x) => x.as_ref().borrow().stringify(),
|
||||||
Fn(lfn) => lfn.get().unwrap().name.to_string(),
|
Fn(lfn) => lfn.get().unwrap().name.to_string(),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -192,7 +178,6 @@ impl Value {
|
||||||
False => "bool",
|
False => "bool",
|
||||||
Keyword(..) => "keyword",
|
Keyword(..) => "keyword",
|
||||||
Interned(..) => "string",
|
Interned(..) => "string",
|
||||||
FnDecl(..) => "fn",
|
|
||||||
String(..) => "string",
|
String(..) => "string",
|
||||||
Number(..) => "number",
|
Number(..) => "number",
|
||||||
Tuple(..) => "tuple",
|
Tuple(..) => "tuple",
|
||||||
|
|
23
src/vm.rs
23
src/vm.rs
|
@ -300,9 +300,11 @@ impl Vm {
|
||||||
}
|
}
|
||||||
MatchType => {
|
MatchType => {
|
||||||
let as_type = self.pop();
|
let as_type = self.pop();
|
||||||
|
let Value::Keyword(as_type) = as_type else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
let idx = self.stack.len() - self.match_depth as usize - 1;
|
let idx = self.stack.len() - self.match_depth as usize - 1;
|
||||||
let val_type = self.stack[idx].type_of();
|
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.matches = val_type == as_type;
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
}
|
}
|
||||||
|
@ -473,7 +475,7 @@ impl Vm {
|
||||||
}
|
}
|
||||||
TypeOf => {
|
TypeOf => {
|
||||||
let val = self.pop();
|
let val = self.pop();
|
||||||
let type_of = self.chunk().kw_from(val.type_of()).unwrap();
|
let type_of = Value::Keyword(val.type_of());
|
||||||
self.push(type_of);
|
self.push(type_of);
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
}
|
}
|
||||||
|
@ -626,7 +628,7 @@ impl Vm {
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
}
|
}
|
||||||
Panic => {
|
Panic => {
|
||||||
let msg = self.pop().show(self.chunk());
|
let msg = self.pop().show();
|
||||||
return self.panic_with(msg);
|
return self.panic_with(msg);
|
||||||
}
|
}
|
||||||
EmptyString => {
|
EmptyString => {
|
||||||
|
@ -650,7 +652,7 @@ impl Vm {
|
||||||
}
|
}
|
||||||
Stringify => {
|
Stringify => {
|
||||||
let to_stringify = self.pop();
|
let to_stringify = self.pop();
|
||||||
let the_string = to_stringify.stringify(self.chunk());
|
let the_string = to_stringify.stringify();
|
||||||
let stringified = Value::String(Rc::new(the_string));
|
let stringified = Value::String(Rc::new(the_string));
|
||||||
self.push(stringified);
|
self.push(stringified);
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
|
@ -661,8 +663,7 @@ impl Vm {
|
||||||
|
|
||||||
let val = self.pop();
|
let val = self.pop();
|
||||||
let Value::Fn(_) = val else {
|
let Value::Fn(_) = val else {
|
||||||
return self
|
return self.panic_with(format!("{} is not a function", val.show()));
|
||||||
.panic_with(format!("{} is not a function", val.show(self.chunk())));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut frame = CallFrame {
|
let mut frame = CallFrame {
|
||||||
|
@ -679,18 +680,12 @@ impl Vm {
|
||||||
self.ip = 0;
|
self.ip = 0;
|
||||||
|
|
||||||
if crate::DEBUG_RUN {
|
if crate::DEBUG_RUN {
|
||||||
println!(
|
println!("== calling into {} ==", self.frame.function.show());
|
||||||
"== calling into {} ==",
|
|
||||||
self.frame.function.show(self.chunk())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Return => {
|
Return => {
|
||||||
if crate::DEBUG_RUN {
|
if crate::DEBUG_RUN {
|
||||||
println!(
|
println!("== returning from {} ==", self.frame.function.show())
|
||||||
"== returning from {} ==",
|
|
||||||
self.frame.function.show(self.chunk())
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
self.frame = self.call_stack.pop().unwrap();
|
self.frame = self.call_stack.pop().unwrap();
|
||||||
self.ip = self.frame.ip;
|
self.ip = self.frame.ip;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user