switch to storing function name index instead of function index
This commit is contained in:
parent
d856452c76
commit
c77a602545
4 changed files with 48 additions and 31 deletions
|
|
@ -85,9 +85,10 @@ impl Compiler {
|
|||
}
|
||||
Statement::FunctionStmt { function } => {
|
||||
let function_name = function.name.lexeme.clone();
|
||||
let compiled_function = compile_function(function)?;
|
||||
let name_index = self.chunk.add_function(compiled_function);
|
||||
let name_index = self.chunk.add_constant(Value::String(function_name.clone()));
|
||||
self.functions.insert(function_name, name_index);
|
||||
let compiled_function = compile_function(function)?;
|
||||
self.chunk.add_function(compiled_function);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -99,11 +100,11 @@ impl Compiler {
|
|||
name, arguments, ..
|
||||
} => {
|
||||
println!("call {}",name);
|
||||
let function_index = *self.functions.get(name).unwrap();
|
||||
let name_index = *self.functions.get(name).unwrap();
|
||||
for argument in arguments {
|
||||
self.compile_expression(argument)?;
|
||||
}
|
||||
self.emit_bytes(OP_CALL, function_index as u16);
|
||||
self.emit_bytes(OP_CALL, name_index as u16);
|
||||
self.emit_byte(arguments.len() as u16);
|
||||
}
|
||||
Expression::Variable { name, .. } => {
|
||||
|
|
|
|||
25
src/chunk.rs
25
src/chunk.rs
|
|
@ -14,7 +14,7 @@ pub struct Chunk {
|
|||
pub constants: Vec<Value>,
|
||||
lines: Vec<usize>,
|
||||
pub functions: HashMap<String, Chunk>,
|
||||
pub(crate) functions_by_index: Vec<Chunk>,
|
||||
// pub(crate) functions_by_index: Vec<Chunk>,
|
||||
}
|
||||
|
||||
impl Chunk {
|
||||
|
|
@ -25,7 +25,7 @@ impl Chunk {
|
|||
constants: vec![],
|
||||
lines: vec![],
|
||||
functions: HashMap::new(),
|
||||
functions_by_index: Vec::new(),
|
||||
// functions_by_index: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -39,10 +39,9 @@ impl Chunk {
|
|||
self.constants.len() - 1
|
||||
}
|
||||
|
||||
pub fn add_function(&mut self, function: Chunk) -> usize {
|
||||
self.functions_by_index.push(function.clone());
|
||||
pub fn add_function(&mut self, function: Chunk) {
|
||||
// self.functions_by_index.push(function.clone());
|
||||
self.functions.insert(function.name.to_string(), function);
|
||||
self.functions.len() - 1
|
||||
}
|
||||
|
||||
pub fn disassemble(&self) {
|
||||
|
|
@ -103,29 +102,29 @@ impl Chunk {
|
|||
}
|
||||
}
|
||||
|
||||
fn simple_inst(&self, name: &str, offset: usize) -> usize {
|
||||
println!("{}", name);
|
||||
fn simple_inst(&self, op: &str, offset: usize) -> usize {
|
||||
println!("{}", op);
|
||||
offset + 1
|
||||
}
|
||||
|
||||
fn call_inst(&self, name: &str, offset: usize) -> usize {
|
||||
fn call_inst(&self, op: &str, offset: usize) -> usize {
|
||||
let constant = self.code[offset + 1];
|
||||
let num_args = self.code[offset + 2];
|
||||
println!("{} {}({}):", name, constant, num_args);
|
||||
println!("{} {}:{}({}):", op, constant, &self.constants[constant as usize], num_args);
|
||||
offset + 3
|
||||
}
|
||||
|
||||
fn new_inst(&self, name: &str, offset: usize) -> usize {
|
||||
fn new_inst(&self, op: &str, offset: usize) -> usize {
|
||||
let constant = self.code[offset + 1];
|
||||
let len = self.code[offset + 2];
|
||||
print!("{} len: {}:", name, len);
|
||||
print!("{} len: {}:", op, len);
|
||||
self.print_value(&self.constants[constant as usize]);
|
||||
offset + 3
|
||||
}
|
||||
|
||||
fn constant_inst(&self, name: &str, offset: usize) -> usize {
|
||||
fn constant_inst(&self, op: &str, offset: usize) -> usize {
|
||||
let constant = self.code[offset + 1];
|
||||
print!("{} {}:", name, constant);
|
||||
print!("{} {}:", op, constant);
|
||||
self.print_value(&self.constants[constant as usize]);
|
||||
offset + 2
|
||||
}
|
||||
|
|
|
|||
40
src/main.rs
40
src/main.rs
|
|
@ -64,16 +64,32 @@ async fn handle_get(State(state): State<Arc<AppState>>) -> Result<Json<String>,
|
|||
Ok(Json(interpret(&state.code).await.unwrap().to_string()))
|
||||
}
|
||||
|
||||
// let tokens = scan("");
|
||||
//
|
||||
// match ast_compiler::compile(tokens) {
|
||||
// Ok(statements) => {
|
||||
// println!("{:?}", statements);
|
||||
// let chunk = compile(&statements)?;
|
||||
// chunk.disassemble();
|
||||
// println!("{}",interpret(&chunk)?);
|
||||
// }
|
||||
// Err(e) => {
|
||||
// println!("{}", e)
|
||||
// }
|
||||
// }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_compile() -> anyhow::Result<()> {
|
||||
let tokens = scan(
|
||||
r#"
|
||||
fn hello(name: string) -> string:
|
||||
"Hello "+name
|
||||
hello("sander")"#,
|
||||
);
|
||||
|
||||
match ast_compiler::compile(tokens) {
|
||||
Ok(statements) => {
|
||||
println!("{:?}", statements);
|
||||
let chunk = compile(&statements)?;
|
||||
chunk.disassemble();
|
||||
println!("{}", interpret(&chunk).await?);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("{}", e)
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,8 +144,9 @@ impl Vm {
|
|||
debug!("after get {:?}", self.stack);
|
||||
}
|
||||
OP_CALL => {
|
||||
let function_index = self.read(chunk);
|
||||
let function = chunk.functions_by_index.get(function_index).unwrap();
|
||||
let function_name_index = self.read(chunk);
|
||||
let function_name = chunk.constants[function_name_index].to_string();
|
||||
let function = chunk.functions.get(&function_name).unwrap();
|
||||
let mut args = vec![];
|
||||
let num_args = self.read(chunk);
|
||||
for _ in 0..num_args {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue