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 } => {
|
Statement::FunctionStmt { function } => {
|
||||||
let function_name = function.name.lexeme.clone();
|
let function_name = function.name.lexeme.clone();
|
||||||
let compiled_function = compile_function(function)?;
|
let name_index = self.chunk.add_constant(Value::String(function_name.clone()));
|
||||||
let name_index = self.chunk.add_function(compiled_function);
|
|
||||||
self.functions.insert(function_name, name_index);
|
self.functions.insert(function_name, name_index);
|
||||||
|
let compiled_function = compile_function(function)?;
|
||||||
|
self.chunk.add_function(compiled_function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -99,11 +100,11 @@ impl Compiler {
|
||||||
name, arguments, ..
|
name, arguments, ..
|
||||||
} => {
|
} => {
|
||||||
println!("call {}",name);
|
println!("call {}",name);
|
||||||
let function_index = *self.functions.get(name).unwrap();
|
let name_index = *self.functions.get(name).unwrap();
|
||||||
for argument in arguments {
|
for argument in arguments {
|
||||||
self.compile_expression(argument)?;
|
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);
|
self.emit_byte(arguments.len() as u16);
|
||||||
}
|
}
|
||||||
Expression::Variable { name, .. } => {
|
Expression::Variable { name, .. } => {
|
||||||
|
|
|
||||||
25
src/chunk.rs
25
src/chunk.rs
|
|
@ -14,7 +14,7 @@ pub struct Chunk {
|
||||||
pub constants: Vec<Value>,
|
pub constants: Vec<Value>,
|
||||||
lines: Vec<usize>,
|
lines: Vec<usize>,
|
||||||
pub functions: HashMap<String, Chunk>,
|
pub functions: HashMap<String, Chunk>,
|
||||||
pub(crate) functions_by_index: Vec<Chunk>,
|
// pub(crate) functions_by_index: Vec<Chunk>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chunk {
|
impl Chunk {
|
||||||
|
|
@ -25,7 +25,7 @@ impl Chunk {
|
||||||
constants: vec![],
|
constants: vec![],
|
||||||
lines: vec![],
|
lines: vec![],
|
||||||
functions: HashMap::new(),
|
functions: HashMap::new(),
|
||||||
functions_by_index: Vec::new(),
|
// functions_by_index: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,10 +39,9 @@ impl Chunk {
|
||||||
self.constants.len() - 1
|
self.constants.len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_function(&mut self, function: Chunk) -> usize {
|
pub fn add_function(&mut self, function: Chunk) {
|
||||||
self.functions_by_index.push(function.clone());
|
// self.functions_by_index.push(function.clone());
|
||||||
self.functions.insert(function.name.to_string(), function);
|
self.functions.insert(function.name.to_string(), function);
|
||||||
self.functions.len() - 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disassemble(&self) {
|
pub fn disassemble(&self) {
|
||||||
|
|
@ -103,29 +102,29 @@ impl Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn simple_inst(&self, name: &str, offset: usize) -> usize {
|
fn simple_inst(&self, op: &str, offset: usize) -> usize {
|
||||||
println!("{}", name);
|
println!("{}", op);
|
||||||
offset + 1
|
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 constant = self.code[offset + 1];
|
||||||
let num_args = self.code[offset + 2];
|
let num_args = self.code[offset + 2];
|
||||||
println!("{} {}({}):", name, constant, num_args);
|
println!("{} {}:{}({}):", op, constant, &self.constants[constant as usize], num_args);
|
||||||
offset + 3
|
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 constant = self.code[offset + 1];
|
||||||
let len = self.code[offset + 2];
|
let len = self.code[offset + 2];
|
||||||
print!("{} len: {}:", name, len);
|
print!("{} len: {}:", op, len);
|
||||||
self.print_value(&self.constants[constant as usize]);
|
self.print_value(&self.constants[constant as usize]);
|
||||||
offset + 3
|
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];
|
let constant = self.code[offset + 1];
|
||||||
print!("{} {}:", name, constant);
|
print!("{} {}:", op, constant);
|
||||||
self.print_value(&self.constants[constant as usize]);
|
self.print_value(&self.constants[constant as usize]);
|
||||||
offset + 2
|
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()))
|
Ok(Json(interpret(&state.code).await.unwrap().to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// let tokens = scan("");
|
|
||||||
//
|
//
|
||||||
// match ast_compiler::compile(tokens) {
|
|
||||||
// Ok(statements) => {
|
#[cfg(test)]
|
||||||
// println!("{:?}", statements);
|
mod tests {
|
||||||
// let chunk = compile(&statements)?;
|
use super::*;
|
||||||
// chunk.disassemble();
|
|
||||||
// println!("{}",interpret(&chunk)?);
|
#[tokio::test]
|
||||||
// }
|
async fn test_compile() -> anyhow::Result<()> {
|
||||||
// Err(e) => {
|
let tokens = scan(
|
||||||
// println!("{}", e)
|
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);
|
debug!("after get {:?}", self.stack);
|
||||||
}
|
}
|
||||||
OP_CALL => {
|
OP_CALL => {
|
||||||
let function_index = self.read(chunk);
|
let function_name_index = self.read(chunk);
|
||||||
let function = chunk.functions_by_index.get(function_index).unwrap();
|
let function_name = chunk.constants[function_name_index].to_string();
|
||||||
|
let function = chunk.functions.get(&function_name).unwrap();
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
let num_args = self.read(chunk);
|
let num_args = self.read(chunk);
|
||||||
for _ in 0..num_args {
|
for _ in 0..num_args {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue