Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moving Value::Int from i64 to BigInt #55

Merged
merged 3 commits into from
May 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

Current main branch.

- General
- Moved `macros` into separate repository [tokay-macros](https://github.com/tokay-lang/tokay-macros)
- Compiler
- Include `prelude.tok` with default parselets
- Values
- Turned Value::Int to crate [num-bigint](https://crates.io/crates/num-bigint), replaced Value::Addr by the same type.

## [v0.5]

Expand Down
78 changes: 78 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ glob = "0.3"
charclass = "0.1"
clap = { version = "2", features = ["yaml"] }
indexmap = "1.8"
num = "0.4"
num-bigint = "0.4"
rustyline = "8.2"
tokay-macros = "0.1"
6 changes: 1 addition & 5 deletions src/_builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ DON'T CHANGE THIS FILE MANUALLY, IT WILL GO AWAY!!!
*/
use crate::builtin::Builtin;

pub static BUILTINS: [Builtin; 40] = [
pub static BUILTINS: [Builtin; 39] = [
Builtin {
name: "Float",
func: crate::value::token::tokay_token_float,
Expand All @@ -22,10 +22,6 @@ pub static BUILTINS: [Builtin; 40] = [
name: "Word",
func: crate::value::token::tokay_token_word,
},
Builtin {
name: "addr",
func: crate::value::value::Value::tokay_method_addr,
},
Builtin {
name: "ast",
func: crate::compiler::ast::tokay_function_ast,
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ fn traverse_node_value(compiler: &mut Compiler, node: &Dict) -> ImlValue {
match emit {
// Literals
"value_string" => ImlValue::from(node["value"].clone()),
"value_integer" => RefValue::from(node["value"].to_i64()).into(),
"value_float" => RefValue::from(node["value"].to_f64()).into(),
"value_integer" => node["value"].clone().into(),
"value_float" => node["value"].clone().into(),
"value_true" => value!(true).into(),
"value_false" => value!(false).into(),
"value_null" => value!(null).into(),
Expand Down
8 changes: 6 additions & 2 deletions src/compiler/iml/result.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::compiler::*;
use crate::reader::Offset;
use crate::value::{Object, RefValue, Value};
use num::ToPrimitive;

/** Intermediate traversal result.

Expand Down Expand Up @@ -41,8 +42,11 @@ impl ImlResult {
Value::Null => Some(Op::PushNull),
Value::True => Some(Op::PushTrue),
Value::False => Some(Op::PushFalse),
Value::Int(0) => Some(Op::Push0),
Value::Int(1) => Some(Op::Push1),
Value::Int(i) => match i.to_i64() {
Some(0) => Some(Op::Push0),
Some(1) => Some(Op::Push1),
_ => None,
},
_ => None,
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/value/object.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::Dict;
use crate::vm::{Accept, Context, Reject};
use num_bigint::BigInt;
use std::any::Any;

// BoxedObject
Expand Down Expand Up @@ -182,6 +183,11 @@ pub trait Object:
self.repr()
}

/// Object as BigInt
fn to_bigint(&self) -> BigInt {
BigInt::from(self.id())
}

/// Check whether the object is callable.
fn is_callable(&self, _without_arguments: bool) -> bool {
false
Expand Down
116 changes: 32 additions & 84 deletions src/value/refvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use super::{BoxedObject, Dict, Method, Object, Value};
use crate::builtin::Builtin;
use crate::value;
use crate::vm::{Accept, Context, Reject};
use num::{ToPrimitive, Zero};
use num_bigint::BigInt;
use std::cell::RefCell;
use std::rc::Rc;

Expand Down Expand Up @@ -43,23 +45,6 @@ impl RefValue {

match this {
Value::Object(this) => this.name(),
Value::Addr(addr) => {
// addr fast lane iinc, idec
match op {
"not" => return Ok(value!(*addr == 0)),
"iinc" => {
*addr += 1;
return Ok(self.clone());
}
"idec" => {
if *addr > 0 {
*addr -= 1;
}
return Ok(self.clone());
}
_ => "addr",
}
}
Value::Float(float) => {
// float fast lane neg, iinc, idec
match op {
Expand All @@ -79,8 +64,8 @@ impl RefValue {
Value::Int(int) => {
// int fast lane neg, iinc, idec
match op {
"neg" => return Ok(value!(-*int)),
"not" => return Ok(value!(*int == 0)),
"neg" => return Ok(value!(-int.clone())),
"not" => return Ok(value!(int.is_zero())),
"iinc" => {
*int += 1;
return Ok(self.clone());
Expand Down Expand Up @@ -129,19 +114,6 @@ impl RefValue {
}
}

// Addr inline fast-lane
(Value::Addr(addr), _) => match op {
"iadd" => {
*addr += that.to_usize();
return Ok(self.clone());
}
"imul" => {
*addr *= that.to_usize();
return Ok(self.clone());
}
_ => None,
},

// Float inline fast-lane
(Value::Float(float), _) => match op {
"iadd" => {
Expand Down Expand Up @@ -207,41 +179,6 @@ impl RefValue {
}
}

// Addr
(Value::Addr(_), _) | (_, Value::Addr(_)) => match op {
"add" => return Ok(value!(this.to_usize() + that.to_usize())),
"mul" => return Ok(value!(this.to_usize() * that.to_usize())),
"sub" => {
let minuend = this.to_usize();
let subtrahend = that.to_usize();

if subtrahend > minuend {
return Err(String::from(
"Attempt to substract with overflow (addr-value)",
));
}

return Ok(value!(minuend - subtrahend));
}
"div" => {
let dividend = this.to_usize();
let divisor = that.to_usize();

if divisor == 0 {
return Err(String::from("Division by zero"));
}

// If there's no remainder, perform an integer division
if dividend % divisor == 0 {
return Ok(value!(dividend / divisor));
}
// Otherwise do a floating point division
else {
return Ok(value!(dividend as f64 / divisor as f64));
}
}
_ => None,
},
(Value::Float(_), _) | (_, Value::Float(_)) => match op {
"add" => return Ok(value!(this.to_f64() + that.to_f64())),
"mul" => return Ok(value!(this.to_f64() * that.to_f64())),
Expand All @@ -258,25 +195,41 @@ impl RefValue {
}
_ => None,
},

(_, _) => match op {
"add" => return Ok(value!(this.to_i64() + that.to_i64())),
"mul" => return Ok(value!(this.to_i64() * that.to_i64())),
"sub" => return Ok(value!(this.to_i64() - that.to_i64())),
"add" => return Ok(value!(this.to_bigint() + that.to_bigint())),
"mul" => return Ok(value!(this.to_bigint() * that.to_bigint())),
"sub" => return Ok(value!(this.to_bigint() - that.to_bigint())),
"div" => {
let dividend = this.to_i64();
let divisor = that.to_i64();
let dividend = this.to_bigint();
let divisor = that.to_bigint();

if divisor == 0 {
if divisor.is_zero() {
return Err(String::from("Division by zero"));
}

// If there's no remainder, perform an integer division
if dividend % divisor == 0 {
if (&dividend % &divisor).is_zero() {
return Ok(value!(dividend / divisor));
}
// Otherwise do a floating point division
else {
return Ok(value!(dividend as f64 / divisor as f64));
let f_dividend = dividend.to_f64();
let f_divisor = divisor.to_f64();

if f_dividend.is_none() || f_divisor.is_none() {
// just do an integer division
return Ok(value!(dividend / divisor));
}

let f_dividend = f_dividend.unwrap();
let f_divisor = f_divisor.unwrap();

if f_divisor == 0.0 {
return Err(String::from("Division by zero"));
}

return Ok(value!(f_dividend / f_divisor));
}
}
_ => None,
Expand Down Expand Up @@ -344,6 +297,10 @@ impl Object for RefValue {
self.borrow().to_string()
}

fn to_bigint(&self) -> BigInt {
self.borrow().to_bigint()
}

fn is_callable(&self, without_arguments: bool) -> bool {
self.borrow().is_callable(without_arguments)
}
Expand Down Expand Up @@ -554,15 +511,6 @@ fn binary_op() {
);
}

// ADDR
{
// Substraction overflow
assert_eq!(
crate::run("a = addr(10) a - 20", ""),
Err("Line 1, column 14: Attempt to substract with overflow (addr-value)".to_string())
);
}

// STR
{
// Binary add
Expand Down
Loading