boolean values and refactored binary ops
This commit is contained in:
parent
57b64bbd24
commit
aa24a006ce
5 changed files with 112 additions and 93 deletions
|
|
@ -1,9 +1,6 @@
|
||||||
use crate::chunk::Chunk;
|
use crate::chunk::Chunk;
|
||||||
use crate::opcode::{
|
use crate::opcode::{OP_ADD, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY, OP_NEGATE, OP_RETURN, OP_SUBTRACT, OP_TRUE};
|
||||||
OP_ADD, OP_CONSTANT, OP_DIVIDE, OP_MULTIPLY, OP_NEGATE, OP_RETURN, OP_SUBTRACT,
|
|
||||||
};
|
|
||||||
use crate::scanner::scan;
|
use crate::scanner::scan;
|
||||||
use crate::tokens::TokenType::Print;
|
|
||||||
use crate::tokens::{Token, TokenType};
|
use crate::tokens::{Token, TokenType};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
@ -136,6 +133,15 @@ fn number(s: &mut Compiler) -> anyhow::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn literal(s: &mut Compiler) -> anyhow::Result<()>{
|
||||||
|
match s.previous_token.tokentype {
|
||||||
|
TokenType::False => s.emit_byte(OP_FALSE),
|
||||||
|
TokenType::True => s.emit_byte(OP_TRUE),
|
||||||
|
_ =>{}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn grouping(s: &mut Compiler) -> anyhow::Result<()> {
|
fn grouping(s: &mut Compiler) -> anyhow::Result<()> {
|
||||||
s.expression()?;
|
s.expression()?;
|
||||||
s.consume(TokenType::RightParen, "Expect ')' after expression.")
|
s.consume(TokenType::RightParen, "Expect ')' after expression.")
|
||||||
|
|
@ -222,6 +228,8 @@ static RULES: LazyLock<HashMap<TokenType, Rule>> = LazyLock::new(|| {
|
||||||
rules.insert(TokenType::I64Type, Rule::new(None, None, PREC_NONE));
|
rules.insert(TokenType::I64Type, Rule::new(None, None, PREC_NONE));
|
||||||
rules.insert(TokenType::DateType, Rule::new(None, None, PREC_NONE));
|
rules.insert(TokenType::DateType, Rule::new(None, None, PREC_NONE));
|
||||||
rules.insert(TokenType::StringType, Rule::new(None, None, PREC_NONE));
|
rules.insert(TokenType::StringType, Rule::new(None, None, PREC_NONE));
|
||||||
|
rules.insert(TokenType::False, Rule::new(Some(literal), None, PREC_NONE));
|
||||||
|
rules.insert(TokenType::True, Rule::new(Some(literal), None, PREC_NONE));
|
||||||
|
|
||||||
rules
|
rules
|
||||||
});
|
});
|
||||||
|
|
|
||||||
68
src/lib.rs
68
src/lib.rs
|
|
@ -1,14 +1,17 @@
|
||||||
use crate::chunk::Chunk;
|
use crate::chunk::Chunk;
|
||||||
use crate::opcode::{OP_ADD,OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_CONSTANT, OP_NEGATE, OP_RETURN};
|
use crate::opcode::{
|
||||||
|
OP_ADD, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY, OP_NEGATE, OP_RETURN, OP_SUBTRACT,
|
||||||
|
OP_TRUE,
|
||||||
|
};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
|
pub mod compiler;
|
||||||
mod keywords;
|
mod keywords;
|
||||||
pub mod opcode;
|
pub mod opcode;
|
||||||
pub mod scanner;
|
pub mod scanner;
|
||||||
mod tokens;
|
mod tokens;
|
||||||
mod value;
|
mod value;
|
||||||
pub mod compiler;
|
|
||||||
|
|
||||||
pub fn interpret(chunk: Chunk) -> Result {
|
pub fn interpret(chunk: Chunk) -> Result {
|
||||||
let mut vm = Vm {
|
let mut vm = Vm {
|
||||||
|
|
@ -41,34 +44,20 @@ impl Vm {
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
self.push(value.clone());
|
self.push(value.clone());
|
||||||
}
|
}
|
||||||
OP_ADD => {
|
OP_FALSE => self.push(Value::Bool(false)),
|
||||||
let a = self.pop();
|
OP_TRUE => self.push(Value::Bool(true)),
|
||||||
let b = self.pop();
|
OP_ADD => binary_op(self, add),
|
||||||
self.push(binary_op(a, b, |a, b| a + b))
|
OP_SUBTRACT => binary_op(self, sub),
|
||||||
}
|
OP_MULTIPLY => binary_op(self, mul),
|
||||||
OP_SUBTRACT => {
|
OP_DIVIDE => binary_op(self, div),
|
||||||
let a = self.pop();
|
|
||||||
let b = self.pop();
|
|
||||||
self.push(binary_op(a, b, |a, b| a - b))
|
|
||||||
}
|
|
||||||
OP_MULTIPLY => {
|
|
||||||
let a = self.pop();
|
|
||||||
let b = self.pop();
|
|
||||||
self.push(binary_op(a, b, |a, b| a * b))
|
|
||||||
}
|
|
||||||
OP_DIVIDE => {
|
|
||||||
let a = self.pop();
|
|
||||||
let b = self.pop();
|
|
||||||
self.push(binary_op(a, b, |a, b| a / b))
|
|
||||||
}
|
|
||||||
OP_NEGATE => {
|
OP_NEGATE => {
|
||||||
let value = self.pop();
|
let value = &self.pop();
|
||||||
self.push(-value);
|
let result = -value;
|
||||||
|
match result {
|
||||||
|
Ok(result) => self.push(result),
|
||||||
|
Err(e) => panic!("Error: {:?} {:?}", e, value),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// OP_RETURN => {
|
|
||||||
// println!("{:?}", self.pop());
|
|
||||||
// return Result::Ok;
|
|
||||||
// }
|
|
||||||
OP_RETURN => {
|
OP_RETURN => {
|
||||||
println!("return {:?}", self.pop());
|
println!("return {:?}", self.pop());
|
||||||
return Result::Ok;
|
return Result::Ok;
|
||||||
|
|
@ -91,8 +80,27 @@ impl Vm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary_op(a: Value, b: Value, op: impl Fn(Value, Value) -> Value) -> Value {
|
fn binary_op(stack: &mut Vm, op: impl Fn(&Value, &Value) -> anyhow::Result<Value> + Copy) {
|
||||||
op(a, b)
|
let a = stack.pop();
|
||||||
|
let b = stack.pop();
|
||||||
|
let result = op(&a, &b);
|
||||||
|
match result {
|
||||||
|
Ok(result) => stack.push(result),
|
||||||
|
Err(e) => panic!("Error: {:?} {:?} and {:?}", e, a, b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(a: &Value, b: &Value) -> anyhow::Result<Value> {
|
||||||
|
a + b
|
||||||
|
}
|
||||||
|
fn sub(a: &Value, b: &Value) -> anyhow::Result<Value> {
|
||||||
|
a - b
|
||||||
|
}
|
||||||
|
fn mul(a: &Value, b: &Value) -> anyhow::Result<Value> {
|
||||||
|
a * b
|
||||||
|
}
|
||||||
|
fn div(a: &Value, b: &Value) -> anyhow::Result<Value> {
|
||||||
|
a / b
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
// chunk.add(crudlang::opcode::OP_ADD, 123);
|
// chunk.add(crudlang::opcode::OP_ADD, 123);
|
||||||
//
|
//
|
||||||
// chunk.add(crudlang::opcode::OP_RETURN, 123);
|
// chunk.add(crudlang::opcode::OP_RETURN, 123);
|
||||||
let chunk = compile("1 + 2")?;
|
let chunk = compile("-true")?;
|
||||||
chunk.disassemble();
|
chunk.disassemble();
|
||||||
|
|
||||||
let result = interpret(chunk);
|
let result = interpret(chunk);
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,5 @@ pub const OP_DIVIDE: u16 = 5;
|
||||||
pub const OP_NEGATE: u16 = 6;
|
pub const OP_NEGATE: u16 = 6;
|
||||||
pub const OP_PRINT: u16 = 7;
|
pub const OP_PRINT: u16 = 7;
|
||||||
pub const OP_RETURN: u16 = 8;
|
pub const OP_RETURN: u16 = 8;
|
||||||
|
pub const OP_TRUE: u16 = 9;
|
||||||
|
pub const OP_FALSE: u16 = 10;
|
||||||
|
|
|
||||||
117
src/value.rs
117
src/value.rs
|
|
@ -1,3 +1,4 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
|
@ -91,95 +92,95 @@ impl Into<Value> for HashMap<Value, Value> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Neg for Value {
|
impl Neg for &Value {
|
||||||
type Output = Value;
|
type Output = anyhow::Result<Value>;
|
||||||
|
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
Value::I32(i) => Value::I32(-i),
|
Value::I32(i) => Ok(Value::I32(-i)),
|
||||||
Value::I64(i) => Value::I64(-i),
|
Value::I64(i) => Ok(Value::I64(-i)),
|
||||||
Value::F32(i) => Value::F32(-i),
|
Value::F32(i) => Ok(Value::F32(-i)),
|
||||||
Value::F64(i) => Value::F64(-i),
|
Value::F64(i) => Ok(Value::F64(-i)),
|
||||||
_ => panic!("Cannot negate {:?}", self),
|
_ => Err(anyhow!("Cannot negate")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<Value> for Value {
|
impl Add<&Value> for &Value {
|
||||||
type Output = Value;
|
type Output = anyhow::Result<Value>;
|
||||||
|
|
||||||
fn add(self, rhs: Value) -> Self::Output {
|
fn add(self, rhs: &Value) -> Self::Output {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::I32(a), Value::I32(b)) => Value::I32(a + b),
|
(Value::I32(a), Value::I32(b)) => Ok(Value::I32(a + b)),
|
||||||
(Value::I64(a), Value::I64(b)) => Value::I64(a + b),
|
(Value::I64(a), Value::I64(b)) => Ok(Value::I64(a + b)),
|
||||||
(Value::U32(a), Value::U32(b)) => Value::U32(a + b),
|
(Value::U32(a), Value::U32(b)) => Ok(Value::U32(a + b)),
|
||||||
(Value::U64(a), Value::U64(b)) => Value::U64(a + b),
|
(Value::U64(a), Value::U64(b)) => Ok(Value::U64(a + b)),
|
||||||
(Value::F32(a), Value::F32(b)) => Value::F32(a + b),
|
(Value::F32(a), Value::F32(b)) => Ok(Value::F32(a + b)),
|
||||||
(Value::F64(a), Value::F64(b)) => Value::F64(a + b),
|
(Value::F64(a), Value::F64(b)) => Ok(Value::F64(a + b)),
|
||||||
(Value::String(s), Value::I32(i)) => Value::String(format!("{}{}", s, i)),
|
(Value::String(s), Value::I32(i)) => Ok(Value::String(format!("{}{}", s, i))),
|
||||||
(Value::String(s), Value::I64(i)) => Value::String(format!("{}{}", s, i)),
|
(Value::String(s), Value::I64(i)) => Ok(Value::String(format!("{}{}", s, i))),
|
||||||
(Value::String(s), Value::U32(u)) => Value::String(format!("{}{}", s, u)),
|
(Value::String(s), Value::U32(u)) => Ok(Value::String(format!("{}{}", s, u))),
|
||||||
(Value::String(s), Value::U64(u)) => Value::String(format!("{}{}", s, u)),
|
(Value::String(s), Value::U64(u)) => Ok(Value::String(format!("{}{}", s, u))),
|
||||||
(Value::String(s), Value::F32(f)) => Value::String(format!("{}{}", s, f)),
|
(Value::String(s), Value::F32(f)) => Ok(Value::String(format!("{}{}", s, f))),
|
||||||
(Value::String(s), Value::F64(f)) => Value::String(format!("{}{}", s, f)),
|
(Value::String(s), Value::F64(f)) => Ok(Value::String(format!("{}{}", s, f))),
|
||||||
(Value::String(s), Value::Bool(b)) => Value::String(format!("{}{}", s, b)),
|
(Value::String(s), Value::Bool(b)) => Ok(Value::String(format!("{}{}", s, b))),
|
||||||
(Value::String(s), Value::Char(c)) => Value::String(format!("{}{}", s, c)),
|
(Value::String(s), Value::Char(c)) => Ok(Value::String(format!("{}{}", s, c))),
|
||||||
(Value::String(s1), Value::String(s2)) => Value::String(format!("{}{}", s1, s2)),
|
(Value::String(s1), Value::String(s2)) => Ok(Value::String(format!("{}{}", s1, s2))),
|
||||||
(Value::String(s1), Value::List(l)) => Value::String(format!("{}{:?}", s1, l)),
|
(Value::String(s1), Value::List(l)) => Ok(Value::String(format!("{}{:?}", s1, l))),
|
||||||
(Value::String(s1), Value::Map(m)) => Value::String(format!("{}{:?}", s1, m)),
|
(Value::String(s1), Value::Map(m)) => Ok(Value::String(format!("{}{:?}", s1, m))),
|
||||||
//enum?
|
//enum?
|
||||||
_ => panic!("Cannot add"),
|
_ => Err(anyhow!("Cannot add")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub<Value> for Value {
|
impl Sub<&Value> for &Value {
|
||||||
type Output = Value;
|
type Output = anyhow::Result<Value>;
|
||||||
|
|
||||||
fn sub(self, rhs: Value) -> Self::Output {
|
fn sub(self, rhs: &Value) -> Self::Output {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::I32(a), Value::I32(b)) => Value::I32(a - b),
|
(Value::I32(a), Value::I32(b)) => Ok(Value::I32(a - b)),
|
||||||
(Value::I64(a), Value::I64(b)) => Value::I64(a - b),
|
(Value::I64(a), Value::I64(b)) => Ok(Value::I64(a - b)),
|
||||||
(Value::U32(a), Value::U32(b)) => Value::U32(a - b),
|
(Value::U32(a), Value::U32(b)) => Ok(Value::U32(a - b)),
|
||||||
(Value::U64(a), Value::U64(b)) => Value::U64(a - b),
|
(Value::U64(a), Value::U64(b)) => Ok(Value::U64(a - b)),
|
||||||
(Value::F32(a), Value::F32(b)) => Value::F32(a - b),
|
(Value::F32(a), Value::F32(b)) => Ok(Value::F32(a - b)),
|
||||||
(Value::F64(a), Value::F64(b)) => Value::F64(a - b),
|
(Value::F64(a), Value::F64(b)) => Ok(Value::F64(a - b)),
|
||||||
//enum?
|
//enum?
|
||||||
_ => panic!("Cannot subtract"),
|
_ => Err(anyhow!("Cannot subtract")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<Value> for Value {
|
impl Mul<&Value> for &Value {
|
||||||
type Output = Value;
|
type Output = anyhow::Result<Value>;
|
||||||
|
|
||||||
fn mul(self, rhs: Value) -> Self::Output {
|
fn mul(self, rhs: &Value) -> Self::Output {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::I32(a), Value::I32(b)) => Value::I32(a * b),
|
(Value::I32(a), Value::I32(b)) => Ok(Value::I32(a * b)),
|
||||||
(Value::I64(a), Value::I64(b)) => Value::I64(a * b),
|
(Value::I64(a), Value::I64(b)) => Ok(Value::I64(a * b)),
|
||||||
(Value::U32(a), Value::U32(b)) => Value::U32(a * b),
|
(Value::U32(a), Value::U32(b)) => Ok(Value::U32(a * b)),
|
||||||
(Value::U64(a), Value::U64(b)) => Value::U64(a * b),
|
(Value::U64(a), Value::U64(b)) => Ok(Value::U64(a * b)),
|
||||||
(Value::F32(a), Value::F32(b)) => Value::F32(a * b),
|
(Value::F32(a), Value::F32(b)) => Ok(Value::F32(a * b)),
|
||||||
(Value::F64(a), Value::F64(b)) => Value::F64(a * b),
|
(Value::F64(a), Value::F64(b)) => Ok(Value::F64(a * b)),
|
||||||
//enum?
|
//enum?
|
||||||
_ => panic!("Cannot multiply"),
|
_ => Err(anyhow!("Cannot multiply")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<Value> for Value {
|
impl Div<&Value> for &Value {
|
||||||
type Output = Value;
|
type Output = anyhow::Result<Value>;
|
||||||
|
|
||||||
fn div(self, rhs: Value) -> Self::Output {
|
fn div(self, rhs: &Value) -> Self::Output {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::I32(a), Value::I32(b)) => Value::I32(a / b),
|
(Value::I32(a), Value::I32(b)) => Ok(Value::I32(a / b)),
|
||||||
(Value::I64(a), Value::I64(b)) => Value::I64(a / b),
|
(Value::I64(a), Value::I64(b)) => Ok(Value::I64(a / b)),
|
||||||
(Value::U32(a), Value::U32(b)) => Value::U32(a / b),
|
(Value::U32(a), Value::U32(b)) => Ok(Value::U32(a / b)),
|
||||||
(Value::U64(a), Value::U64(b)) => Value::U64(a / b),
|
(Value::U64(a), Value::U64(b)) => Ok(Value::U64(a / b)),
|
||||||
(Value::F32(a), Value::F32(b)) => Value::F32(a / b),
|
(Value::F32(a), Value::F32(b)) => Ok(Value::F32(a / b)),
|
||||||
(Value::F64(a), Value::F64(b)) => Value::F64(a / b),
|
(Value::F64(a), Value::F64(b)) => Ok(Value::F64(a / b)),
|
||||||
//enum?
|
//enum?
|
||||||
_ => panic!("Cannot divide"),
|
_ => Err(anyhow!("Cannot divide")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue