Skip to content

Commit

Permalink
bitwise operators (#54)
Browse files Browse the repository at this point in the history
* bitwise operators
* parsing 0xff, 0b100 
* to_hex, to_binary builtin functions
  • Loading branch information
nbittich authored Oct 1, 2023
1 parent 7f5833a commit 8338a8e
Show file tree
Hide file tree
Showing 28 changed files with 692 additions and 272 deletions.
28 changes: 14 additions & 14 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ anyhow = "1.0.75"
bincode = "1.3.3"
dirs = "5.0.1" # todo maybe replace by the home crate
log = "0.4.20"
nom = { version = "7.1.3" }
nom = "7.1.3"
nu-ansi-term = "0.49.0"
rustyline = "12.0.0"
rustyline-derive = "0.9.0"
Expand All @@ -36,8 +36,8 @@ slab_tree = "0.3.2"
strum = { version = "0.25.0", features = ["derive"] }
ctrlc = "3.4.1"

#adana-script-core = { git = "https://github.com/nbittich/adana-script-core.git" }
adana-script-core = "0.14.2"
#adana-script-core = { git = "https://github.com/nbittich/adana-script-core.git", branch = "feature/bitwise-and-new-ints" }
adana-script-core = "0.15.0"

[dependencies.env_logger]
default-features = false
Expand Down
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ ${person.wasup(person.age)}"""

### Operators and constants

There are 16 operators & 3 constants:
There are 22 operators & 3 constants:

| **operator** | **description** |
| ------------ | ---------------- |
Expand All @@ -190,6 +190,12 @@ There are 16 operators & 3 constants:
| `>=` | greater or equal |
| `&&` | and |
| `\|\|` | or |
| `\|` | bitwise or |
| `~` | bitwise not |
| `@` | bitwise and |
| `$` | bitwise xor |
| `<<` | bitwise lshift |
| `>>` | bitwise rshift |
| `==` | equal |
| `()` | parenthesis |
| `π` | PI number |
Expand Down Expand Up @@ -482,7 +488,9 @@ Below, is a list of types and how you declare them. You can also define your str
| -------- | ------------------------------------------------------------------------------------------------ |
| null | `null` |
| bool | `true` / `false` |
| int | `5` |
| int | `5000` |
| u8 | `5` |
| i8 | `-5` |
| double | `12.` / `12.2` |
| string | `"hello"` |
| array | `[1,2,"3", true]` |
Expand Down Expand Up @@ -717,6 +725,8 @@ Here is a list of built-in functions available:
| include | include a script | `include("scripts/test_fn.adana")` |
| require | load a shared object | `require("my_lib.so")` |
| to_int | cast to int | `to_int("2")`<br>`to_int(2.2)` |
| to_hex | format num to hex | `to_hex(2)`<br>`to_hex(2.2)` |
| to_binary | format num to binary | `to_binary(2)` |
| to_double | cast to double | `to_double("2.2")` |
| to_bool | cast to bool | `to_bool("true")` |
| to_string | cast to string | `to_string(true)` |
Expand Down
8 changes: 4 additions & 4 deletions dynamic_lib/example_lib_src/Cargo.lock

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

4 changes: 3 additions & 1 deletion dynamic_lib/example_lib_src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ edition = "2021"
crate-type = ["dylib"]

[dependencies]
adana-script-core = "0.14.1"
adana-script-core = "0.15.0"
#adana-script-core = { git = "https://github.com/nbittich/adana-script-core.git", branch = "feature/bitwise-and-new-ints" }

anyhow = "1.0.75"

[profile.release]
Expand Down
Binary file modified dynamic_lib/libplugin_example.so
Binary file not shown.
112 changes: 87 additions & 25 deletions src/adana_script/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,19 @@ pub fn to_ast(
Value::ImplicitMultiply(v)
if matches!(
v.borrow(),
&Value::Integer(_) | &Value::Decimal(_)
&Value::Integer(_) | &Value::Decimal(_) | &Value::U8(_) | &Value::I8(_)
) =>
{
operations.insert(pos,*v);
operations.insert(pos+1, Value::Operation(Operator::Mult));
}
Value::Operation(Operator::Pow2) => {
operations.insert(pos,Value::Operation(Operator::Pow));
operations.insert(pos+1,Value::Integer(2));
operations.insert(pos+1,Value::U8(2));
}
Value::Operation(Operator::Pow3) => {
operations.insert(pos,Value::Operation(Operator::Pow));
operations.insert(pos+1,Value::Integer(3));
operations.insert(pos+1,Value::U8(3));
}
_ => unreachable!("AST ERROR: unreachable implicit parameter {operation:?}"),
}
Expand All @@ -120,18 +120,24 @@ pub fn to_ast(
let get_next_op_pos = |operations: &Vec<Value>| {
None.or_else(filter_op(Operator::Or, operations))
.or_else(filter_op(Operator::And, operations))
.or_else(filter_op(Operator::BitwiseOr, operations))
.or_else(filter_op(Operator::BitwiseXor, operations))
.or_else(filter_op(Operator::BitwiseAnd, operations))
.or_else(filter_op(Operator::GreaterOrEqual, operations))
.or_else(filter_op(Operator::LessOrEqual, operations))
.or_else(filter_op(Operator::Greater, operations))
.or_else(filter_op(Operator::Less, operations))
.or_else(filter_op(Operator::Equal, operations))
.or_else(filter_op(Operator::NotEqual, operations))
.or_else(filter_op(Operator::BitwiseLShift, operations))
.or_else(filter_op(Operator::BitwiseRShift, operations))
.or_else(filter_op(Operator::Add, operations))
.or_else(filter_op(Operator::Subtr, operations))
.or_else(filter_op(Operator::Mult, operations))
.or_else(filter_op(Operator::Mod, operations))
.or_else(filter_op(Operator::Div, operations))
.or_else(filter_op(Operator::Pow, operations))
.or_else(filter_op(Operator::BitwiseNot, operations))
.or_else(filter_op(Operator::Not, operations))
};

Expand All @@ -145,25 +151,55 @@ pub fn to_ast(

// handle negation
if operation == Value::Operation(Operator::Subtr)
&& matches!(
left.last(),
Some(
Value::Operation(Operator::Subtr)
// || operation == Value::Operation(Operator::BitwiseNot) maybe needed
// but maybe not
&& matches!(
left.last(),
Some(
Value::Operation(Operator::Subtr)
| Value::Operation(Operator::Mult)
| Value::Operation(Operator::Pow)
| Value::Operation(Operator::BitwiseNot)
| Value::Operation(Operator::BitwiseAnd)
| Value::Operation(Operator::BitwiseLShift)
| Value::Operation(Operator::BitwiseRShift)
| Value::Operation(Operator::BitwiseOr)
| Value::Operation(Operator::BitwiseXor)
| Value::Operation(Operator::Add) // FIXME too tired to think about
// it. Is it needed?
| Value::Operation(Operator::Mod)
| Value::Operation(Operator::Div)
)
)
)
{
let right_first = match operations.first() {
Some(Value::Decimal(d)) => Some(Value::Decimal(-d)),
Some(Value::Integer(d)) => Some(Value::Integer(-d)),
Some(Value::Variable(d)) => {
Some(Value::VariableNegate(d.to_string()))
}
let right_first = match (&operation, operations.first()) {
(
Value::Operation(Operator::Subtr),
Some(Value::Decimal(d)),
) => Some(Value::Decimal(-d)),
(
Value::Operation(Operator::Subtr),
Some(Value::Integer(d)),
) => Some(Value::Integer(-d)),
(
Value::Operation(Operator::Subtr),
Some(Value::U8(d)),
) => (*d as i8)
.checked_neg()
.map(Value::I8)
.or_else(|| Some(Value::Integer(-(*d as i128)))),

(
Value::Operation(Operator::Subtr),
Some(Value::I8(d)),
) => d
.checked_neg()
.map(Value::I8)
.or_else(|| Some(Value::Integer(-(*d as i128)))),
(
Value::Operation(Operator::Subtr),
Some(Value::Variable(d)),
) => Some(Value::VariableNegate(d.to_string())),
_ => None,
};
if let Some(first) = right_first {
Expand Down Expand Up @@ -203,7 +239,7 @@ pub fn to_ast(
Ok(curr_node_id)
} else {
Err(anyhow::Error::msg(format!(
"{} invalid expression!",
"{} invalid expression! {op_pos:?}",
nu_ansi_term::Color::Red.paint("AST ERROR:")
)))
}
Expand Down Expand Up @@ -246,6 +282,16 @@ pub fn to_ast(
tree,
curr_node_id,
),
Value::U8(num) => append_to_current_and_return(
TreeNodeValue::Primitive(Primitive::U8(num)),
tree,
curr_node_id,
),
Value::I8(num) => append_to_current_and_return(
TreeNodeValue::Primitive(Primitive::I8(num)),
tree,
curr_node_id,
),
Value::Bool(bool_v) => append_to_current_and_return(
TreeNodeValue::Primitive(Primitive::Bool(bool_v)),
tree,
Expand All @@ -266,16 +312,19 @@ pub fn to_ast(
Value::Variable(name) | Value::VariableRef(name) => {
let primitive =
variable_from_ctx(name.as_str(), false, ctx)?;
if let Primitive::Int(num) = primitive.to_int() {
Ok(num)
} else {
Err(anyhow::format_err!(
match primitive.to_int() {
Primitive::Int(num) => Ok(num),
Primitive::U8(num) => Ok(num as i128),
Primitive::I8(num) => Ok(num as i128),
_ => Err(anyhow::format_err!(
"range error: {primitive:?} is not an integer"
))
)),
}
}

Value::Integer(num) => Ok(num),
Value::U8(num) => Ok(num as i128),
Value::I8(num) => Ok(num as i128),
_ => {
return Err(anyhow::format_err!(
"range error: {start:?} is not an integer"
Expand All @@ -286,14 +335,17 @@ pub fn to_ast(
Value::Variable(name) | Value::VariableRef(name) => {
let primitive =
variable_from_ctx(name.as_str(), false, ctx)?;
if let Primitive::Int(num) = primitive.to_int() {
Ok(num)
} else {
Err(anyhow::format_err!(
match primitive.to_int() {
Primitive::Int(num) => Ok(num),
Primitive::U8(num) => Ok(num as i128),
Primitive::I8(num) => Ok(num as i128),
_ => Err(anyhow::format_err!(
"range error: {primitive:?} is not an integer"
))
)),
}
}
Value::U8(num) => Ok(num as i128),
Value::I8(num) => Ok(num as i128),
Value::Integer(num) => Ok(num),
_ => {
return Err(anyhow::format_err!(
Expand Down Expand Up @@ -465,6 +517,16 @@ pub fn to_ast(
tree,
curr_node_id,
),
(v, index @ Value::U8(_)) => append_to_current_and_return(
TreeNodeValue::ArrayAccess { index, array: v },
tree,
curr_node_id,
),
(v, index @ Value::I8(_)) => append_to_current_and_return(
TreeNodeValue::ArrayAccess { index, array: v },
tree,
curr_node_id,
),
(v, variable @ Value::Variable(_)) => append_to_current_and_return(
TreeNodeValue::ArrayAccess { index: variable, array: v },
tree,
Expand Down
Loading

0 comments on commit 8338a8e

Please sign in to comment.