diff --git a/src/compiler.rs b/src/compiler.rs index 5bdb704..dfc5f0d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1,9 +1,6 @@ use crate::chunk::Chunk; -use crate::opcode::{ - OP_ADD, OP_CONSTANT, OP_DIVIDE, OP_MULTIPLY, OP_NEGATE, OP_RETURN, OP_SUBTRACT, -}; +use crate::opcode::{OP_ADD, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY, OP_NEGATE, OP_RETURN, OP_SUBTRACT, OP_TRUE}; use crate::scanner::scan; -use crate::tokens::TokenType::Print; use crate::tokens::{Token, TokenType}; use crate::value::Value; use anyhow::anyhow; @@ -136,6 +133,15 @@ fn number(s: &mut Compiler) -> anyhow::Result<()> { 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<()> { s.expression()?; s.consume(TokenType::RightParen, "Expect ')' after expression.") @@ -222,6 +228,8 @@ static RULES: LazyLock> = LazyLock::new(|| { rules.insert(TokenType::I64Type, 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::False, Rule::new(Some(literal), None, PREC_NONE)); + rules.insert(TokenType::True, Rule::new(Some(literal), None, PREC_NONE)); rules }); diff --git a/src/lib.rs b/src/lib.rs index b93fa8d..7136e54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,17 @@ 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; pub mod chunk; +pub mod compiler; mod keywords; pub mod opcode; pub mod scanner; mod tokens; mod value; -pub mod compiler; pub fn interpret(chunk: Chunk) -> Result { let mut vm = Vm { @@ -41,34 +44,20 @@ impl Vm { self.ip += 1; self.push(value.clone()); } - OP_ADD => { - let a = self.pop(); - let b = self.pop(); - self.push(binary_op(a, b, |a, b| a + b)) - } - OP_SUBTRACT => { - 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_FALSE => self.push(Value::Bool(false)), + OP_TRUE => self.push(Value::Bool(true)), + OP_ADD => binary_op(self, add), + OP_SUBTRACT => binary_op(self, sub), + OP_MULTIPLY => binary_op(self, mul), + OP_DIVIDE => binary_op(self, div), OP_NEGATE => { - let value = self.pop(); - self.push(-value); + let value = &self.pop(); + 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 => { println!("return {:?}", self.pop()); return Result::Ok; @@ -91,8 +80,27 @@ impl Vm { } } -fn binary_op(a: Value, b: Value, op: impl Fn(Value, Value) -> Value) -> Value { - op(a, b) +fn binary_op(stack: &mut Vm, op: impl Fn(&Value, &Value) -> anyhow::Result + Copy) { + 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 { + a + b +} +fn sub(a: &Value, b: &Value) -> anyhow::Result { + a - b +} +fn mul(a: &Value, b: &Value) -> anyhow::Result { + a * b +} +fn div(a: &Value, b: &Value) -> anyhow::Result { + a / b } #[derive(Debug, PartialEq)] diff --git a/src/main.rs b/src/main.rs index c885497..ce087e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ fn main() -> anyhow::Result<()> { // chunk.add(crudlang::opcode::OP_ADD, 123); // // chunk.add(crudlang::opcode::OP_RETURN, 123); - let chunk = compile("1 + 2")?; + let chunk = compile("-true")?; chunk.disassemble(); let result = interpret(chunk); diff --git a/src/opcode.rs b/src/opcode.rs index 7662cf0..afaead5 100644 --- a/src/opcode.rs +++ b/src/opcode.rs @@ -6,3 +6,5 @@ pub const OP_DIVIDE: u16 = 5; pub const OP_NEGATE: u16 = 6; pub const OP_PRINT: u16 = 7; pub const OP_RETURN: u16 = 8; +pub const OP_TRUE: u16 = 9; +pub const OP_FALSE: u16 = 10; diff --git a/src/value.rs b/src/value.rs index ae248f4..4f770fd 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,3 +1,4 @@ +use anyhow::anyhow; use chrono::Utc; use std::collections::HashMap; use std::ops::{Add, Div, Mul, Neg, Sub}; @@ -91,95 +92,95 @@ impl Into for HashMap { } } -impl Neg for Value { - type Output = Value; +impl Neg for &Value { + type Output = anyhow::Result; fn neg(self) -> Self::Output { match self { - Value::I32(i) => Value::I32(-i), - Value::I64(i) => Value::I64(-i), - Value::F32(i) => Value::F32(-i), - Value::F64(i) => Value::F64(-i), - _ => panic!("Cannot negate {:?}", self), + Value::I32(i) => Ok(Value::I32(-i)), + Value::I64(i) => Ok(Value::I64(-i)), + Value::F32(i) => Ok(Value::F32(-i)), + Value::F64(i) => Ok(Value::F64(-i)), + _ => Err(anyhow!("Cannot negate")), } } } -impl Add for Value { - type Output = Value; +impl Add<&Value> for &Value { + type Output = anyhow::Result; - fn add(self, rhs: Value) -> Self::Output { + fn add(self, rhs: &Value) -> Self::Output { match (self, rhs) { - (Value::I32(a), Value::I32(b)) => Value::I32(a + b), - (Value::I64(a), Value::I64(b)) => Value::I64(a + b), - (Value::U32(a), Value::U32(b)) => Value::U32(a + b), - (Value::U64(a), Value::U64(b)) => Value::U64(a + b), - (Value::F32(a), Value::F32(b)) => Value::F32(a + b), - (Value::F64(a), Value::F64(b)) => Value::F64(a + b), - (Value::String(s), Value::I32(i)) => Value::String(format!("{}{}", s, i)), - (Value::String(s), Value::I64(i)) => Value::String(format!("{}{}", s, i)), - (Value::String(s), Value::U32(u)) => Value::String(format!("{}{}", s, u)), - (Value::String(s), Value::U64(u)) => Value::String(format!("{}{}", s, u)), - (Value::String(s), Value::F32(f)) => Value::String(format!("{}{}", s, f)), - (Value::String(s), Value::F64(f)) => Value::String(format!("{}{}", s, f)), - (Value::String(s), Value::Bool(b)) => Value::String(format!("{}{}", s, b)), - (Value::String(s), Value::Char(c)) => Value::String(format!("{}{}", s, c)), - (Value::String(s1), Value::String(s2)) => Value::String(format!("{}{}", s1, s2)), - (Value::String(s1), Value::List(l)) => Value::String(format!("{}{:?}", s1, l)), - (Value::String(s1), Value::Map(m)) => Value::String(format!("{}{:?}", s1, m)), + (Value::I32(a), Value::I32(b)) => Ok(Value::I32(a + b)), + (Value::I64(a), Value::I64(b)) => Ok(Value::I64(a + b)), + (Value::U32(a), Value::U32(b)) => Ok(Value::U32(a + b)), + (Value::U64(a), Value::U64(b)) => Ok(Value::U64(a + b)), + (Value::F32(a), Value::F32(b)) => Ok(Value::F32(a + b)), + (Value::F64(a), Value::F64(b)) => Ok(Value::F64(a + b)), + (Value::String(s), Value::I32(i)) => Ok(Value::String(format!("{}{}", s, i))), + (Value::String(s), Value::I64(i)) => Ok(Value::String(format!("{}{}", s, i))), + (Value::String(s), Value::U32(u)) => Ok(Value::String(format!("{}{}", s, u))), + (Value::String(s), Value::U64(u)) => Ok(Value::String(format!("{}{}", s, u))), + (Value::String(s), Value::F32(f)) => Ok(Value::String(format!("{}{}", s, f))), + (Value::String(s), Value::F64(f)) => Ok(Value::String(format!("{}{}", s, f))), + (Value::String(s), Value::Bool(b)) => Ok(Value::String(format!("{}{}", s, b))), + (Value::String(s), Value::Char(c)) => Ok(Value::String(format!("{}{}", s, c))), + (Value::String(s1), Value::String(s2)) => Ok(Value::String(format!("{}{}", s1, s2))), + (Value::String(s1), Value::List(l)) => Ok(Value::String(format!("{}{:?}", s1, l))), + (Value::String(s1), Value::Map(m)) => Ok(Value::String(format!("{}{:?}", s1, m))), //enum? - _ => panic!("Cannot add"), + _ => Err(anyhow!("Cannot add")), } } } -impl Sub for Value { - type Output = Value; +impl Sub<&Value> for &Value { + type Output = anyhow::Result; - fn sub(self, rhs: Value) -> Self::Output { + fn sub(self, rhs: &Value) -> Self::Output { match (self, rhs) { - (Value::I32(a), Value::I32(b)) => Value::I32(a - b), - (Value::I64(a), Value::I64(b)) => Value::I64(a - b), - (Value::U32(a), Value::U32(b)) => Value::U32(a - b), - (Value::U64(a), Value::U64(b)) => Value::U64(a - b), - (Value::F32(a), Value::F32(b)) => Value::F32(a - b), - (Value::F64(a), Value::F64(b)) => Value::F64(a - b), + (Value::I32(a), Value::I32(b)) => Ok(Value::I32(a - b)), + (Value::I64(a), Value::I64(b)) => Ok(Value::I64(a - b)), + (Value::U32(a), Value::U32(b)) => Ok(Value::U32(a - b)), + (Value::U64(a), Value::U64(b)) => Ok(Value::U64(a - b)), + (Value::F32(a), Value::F32(b)) => Ok(Value::F32(a - b)), + (Value::F64(a), Value::F64(b)) => Ok(Value::F64(a - b)), //enum? - _ => panic!("Cannot subtract"), + _ => Err(anyhow!("Cannot subtract")), } } } -impl Mul for Value { - type Output = Value; +impl Mul<&Value> for &Value { + type Output = anyhow::Result; - fn mul(self, rhs: Value) -> Self::Output { + fn mul(self, rhs: &Value) -> Self::Output { match (self, rhs) { - (Value::I32(a), Value::I32(b)) => Value::I32(a * b), - (Value::I64(a), Value::I64(b)) => Value::I64(a * b), - (Value::U32(a), Value::U32(b)) => Value::U32(a * b), - (Value::U64(a), Value::U64(b)) => Value::U64(a * b), - (Value::F32(a), Value::F32(b)) => Value::F32(a * b), - (Value::F64(a), Value::F64(b)) => Value::F64(a * b), + (Value::I32(a), Value::I32(b)) => Ok(Value::I32(a * b)), + (Value::I64(a), Value::I64(b)) => Ok(Value::I64(a * b)), + (Value::U32(a), Value::U32(b)) => Ok(Value::U32(a * b)), + (Value::U64(a), Value::U64(b)) => Ok(Value::U64(a * b)), + (Value::F32(a), Value::F32(b)) => Ok(Value::F32(a * b)), + (Value::F64(a), Value::F64(b)) => Ok(Value::F64(a * b)), //enum? - _ => panic!("Cannot multiply"), + _ => Err(anyhow!("Cannot multiply")), } } } -impl Div for Value { - type Output = Value; +impl Div<&Value> for &Value { + type Output = anyhow::Result; - fn div(self, rhs: Value) -> Self::Output { + fn div(self, rhs: &Value) -> Self::Output { match (self, rhs) { - (Value::I32(a), Value::I32(b)) => Value::I32(a / b), - (Value::I64(a), Value::I64(b)) => Value::I64(a / b), - (Value::U32(a), Value::U32(b)) => Value::U32(a / b), - (Value::U64(a), Value::U64(b)) => Value::U64(a / b), - (Value::F32(a), Value::F32(b)) => Value::F32(a / b), - (Value::F64(a), Value::F64(b)) => Value::F64(a / b), + (Value::I32(a), Value::I32(b)) => Ok(Value::I32(a / b)), + (Value::I64(a), Value::I64(b)) => Ok(Value::I64(a / b)), + (Value::U32(a), Value::U32(b)) => Ok(Value::U32(a / b)), + (Value::U64(a), Value::U64(b)) => Ok(Value::U64(a / b)), + (Value::F32(a), Value::F32(b)) => Ok(Value::F32(a / b)), + (Value::F64(a), Value::F64(b)) => Ok(Value::F64(a / b)), //enum? - _ => panic!("Cannot divide"), + _ => Err(anyhow!("Cannot divide")), } } }