better implementation for if/else
This commit is contained in:
parent
0d8786ebff
commit
d8079f34f6
3 changed files with 49 additions and 44 deletions
|
|
@ -211,3 +211,10 @@ fn add(a: string, b: string) -> string:
|
||||||
a + " " + b
|
a + " " + b
|
||||||
```
|
```
|
||||||
* get() is the entry point for http GET method calls, likewise for POST, PUT, DELETE, etc.
|
* get() is the entry point for http GET method calls, likewise for POST, PUT, DELETE, etc.
|
||||||
|
|
||||||
|
ISSUES
|
||||||
|
* Make everything an expression. If is a statement and so it can not be type checked
|
||||||
|
* improve indenting
|
||||||
|
* add an extra pass that creates a more IR-like representation (enum instead of bytes)
|
||||||
|
* easier debugging
|
||||||
|
* chunk debug to stdout can be removed
|
||||||
|
|
@ -8,12 +8,7 @@ use crate::symbol_builder::{Symbol, calculate_type, infer_type};
|
||||||
use crate::tokens::TokenType;
|
use crate::tokens::TokenType;
|
||||||
use crate::tokens::TokenType::Unknown;
|
use crate::tokens::TokenType::Unknown;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::vm::{
|
use crate::vm::{OP_ADD, OP_AND, OP_ASSIGN, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CALL, OP_CALL_BUILTIN, OP_CONSTANT, OP_DEF_LIST, OP_DEF_MAP, OP_DIVIDE, OP_DUP, OP_EQUAL, OP_GET, OP_GOTO, OP_GOTO_IF, OP_GOTO_NIF, OP_GREATER, OP_GREATER_EQUAL, OP_LESS, OP_LESS_EQUAL, OP_LIST_GET, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_OR, OP_POP, OP_PRINT, OP_RETURN, OP_SHL, OP_SHR, OP_SUBTRACT};
|
||||||
OP_ADD, OP_AND, OP_ASSIGN, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CALL, OP_CALL_BUILTIN,
|
|
||||||
OP_CONSTANT, OP_DEF_LIST, OP_DEF_MAP, OP_DIVIDE, OP_EQUAL, OP_GET, OP_GOTO_IF, OP_GREATER,
|
|
||||||
OP_GREATER_EQUAL, OP_IF, OP_IF_ELSE, OP_LESS, OP_LESS_EQUAL, OP_LIST_GET, OP_MULTIPLY,
|
|
||||||
OP_NEGATE, OP_NOT, OP_OR, OP_POP, OP_PRINT, OP_RETURN, OP_SHL, OP_SHR, OP_SUBTRACT,
|
|
||||||
};
|
|
||||||
use crate::{Registry, SymbolTable};
|
use crate::{Registry, SymbolTable};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
@ -165,22 +160,28 @@ impl Compiler {
|
||||||
else_branch,
|
else_branch,
|
||||||
} => {
|
} => {
|
||||||
self.compile_expression(namespace, condition, symbols, registry)?;
|
self.compile_expression(namespace, condition, symbols, registry)?;
|
||||||
compile(
|
|
||||||
Some(&format!("{}.?",namespace)),
|
self.emit_byte(OP_DUP);
|
||||||
then_branch,
|
self.emit_bytes(OP_GOTO_NIF, 0);
|
||||||
symbols,
|
let goto_addr1 = self.chunk.code.len()-1;
|
||||||
registry,
|
self.emit_byte(OP_POP);
|
||||||
)?;
|
self.compile_statements(then_branch, symbols, registry, namespace)?;
|
||||||
if else_branch.is_none() {
|
self.emit_bytes(OP_GOTO, 0);
|
||||||
self.emit_byte(OP_IF);
|
let goto_addr2 = self.chunk.code.len()-1;
|
||||||
} else {
|
if else_branch.is_some() {
|
||||||
self.emit_byte(OP_IF_ELSE);
|
self.chunk.code[goto_addr1] = self.chunk.code.len() as u16;
|
||||||
compile(
|
self.emit_bytes(OP_GOTO_IF, 0);
|
||||||
Some(format!("{}.:", namespace).as_str()),
|
let goto_addr3 = self.chunk.code.len() - 1;
|
||||||
|
|
||||||
|
self.compile_statements(
|
||||||
else_branch.as_ref().unwrap(),
|
else_branch.as_ref().unwrap(),
|
||||||
symbols,
|
symbols,
|
||||||
registry,
|
registry,
|
||||||
|
namespace,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
self.chunk.code[goto_addr2] = self.chunk.code.len() as u16; // fill in the placeholder
|
||||||
|
self.chunk.code[goto_addr3] = self.chunk.code.len() as u16; // fill in the placeholder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Statement::ForStatement {
|
Statement::ForStatement {
|
||||||
|
|
@ -303,7 +304,11 @@ impl Compiler {
|
||||||
return Err(self.raise(UndeclaredVariable(name.to_string())));
|
return Err(self.raise(UndeclaredVariable(name.to_string())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::Assignment { variable_name, value, .. } => {
|
Expression::Assignment {
|
||||||
|
variable_name,
|
||||||
|
value,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
self.compile_expression(namespace, value, symbols, registry)?;
|
self.compile_expression(namespace, value, symbols, registry)?;
|
||||||
let name_index = self.vars.get(variable_name);
|
let name_index = self.vars.get(variable_name);
|
||||||
if let Some(name_index) = name_index {
|
if let Some(name_index) = name_index {
|
||||||
|
|
|
||||||
43
src/vm.rs
43
src/vm.rs
|
|
@ -250,31 +250,13 @@ impl Vm {
|
||||||
self.push(result);
|
self.push(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OP_IF => {
|
OP_GOTO_NIF => {
|
||||||
let condition = self.pop();
|
let b = self.pop();
|
||||||
if condition == Value::Bool(true) {
|
let goto_addr = self.read(chunk);
|
||||||
if let Some(then) = self.registry.get(&format!("{}.?", chunk.name)) {
|
if b == Value::Bool(false) {
|
||||||
let result = interpret_function(then, vec![])?;
|
self.ip = goto_addr;
|
||||||
self.push(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
OP_IF_ELSE => {
|
|
||||||
let condition = self.pop();
|
|
||||||
self.push(if condition == Value::Bool(true) {
|
|
||||||
if let Some(then) = self.registry.get(&format!("{}.?", chunk.name)) {
|
|
||||||
interpret_function(then, vec![])?
|
|
||||||
} else {
|
|
||||||
return Err(Something);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Some(then) = self.registry.get(&format!("{}.:", chunk.name)) {
|
|
||||||
interpret_function(then, vec![])?
|
|
||||||
} else {
|
|
||||||
return Err(Something);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
OP_GOTO_IF => {
|
OP_GOTO_IF => {
|
||||||
let b = self.pop();
|
let b = self.pop();
|
||||||
let goto_addr = self.read(chunk);
|
let goto_addr = self.read(chunk);
|
||||||
|
|
@ -282,6 +264,15 @@ impl Vm {
|
||||||
self.ip = goto_addr;
|
self.ip = goto_addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
OP_GOTO => {
|
||||||
|
let goto_addr = self.read(chunk);
|
||||||
|
self.ip = goto_addr;
|
||||||
|
}
|
||||||
|
OP_DUP =>{
|
||||||
|
let value = self.pop();
|
||||||
|
self.push(value.clone());
|
||||||
|
self.push(value);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -393,6 +384,8 @@ pub const OP_DEF_F64: u16 = 40;
|
||||||
pub const OP_ASSIGN: u16 = 41;
|
pub const OP_ASSIGN: u16 = 41;
|
||||||
pub const OP_LIST_GET: u16 = 42;
|
pub const OP_LIST_GET: u16 = 42;
|
||||||
pub const OP_CALL_BUILTIN: u16 = 43;
|
pub const OP_CALL_BUILTIN: u16 = 43;
|
||||||
pub const OP_IF: u16 = 44;
|
pub const OP_DUP: u16 = 44;
|
||||||
pub const OP_IF_ELSE: u16 = 45;
|
// pub const OP_IF_ELSE: u16 = 45;
|
||||||
pub const OP_GOTO_IF: u16 = 46;
|
pub const OP_GOTO_IF: u16 = 46;
|
||||||
|
pub const OP_GOTO_NIF: u16 = 48;
|
||||||
|
pub const OP_GOTO: u16 = 47;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue