From b5e731646b7659161d85e1ba95b9f038b8f2ed96 Mon Sep 17 00:00:00 2001 From: Nordine Bittich <3816305+nbittich@users.noreply.github.com> Date: Sun, 4 Feb 2024 19:43:35 +0100 Subject: [PATCH] Feature/optional parenthesises (#55) --- .github/workflows/pull_request.yml | 3 +- Cargo.lock | 36 ++++------------ Cargo.toml | 4 +- README.md | 24 ++++++++--- dynamic_lib/example_lib_src/Cargo.lock | 20 ++++----- dynamic_lib/example_lib_src/Cargo.toml | 2 +- file_tests/sort.adana | 4 +- file_tests/string.adana | 8 ++-- file_tests/test2.adana | 2 +- file_tests/test_array.adana | 6 +-- file_tests/test_fizzbuzz.adana | 8 ++-- file_tests/test_fizzbuzz_else.adana | 10 ++--- file_tests/test_if_else.adana | 4 +- file_tests/test_nested.adana | 8 ++-- file_tests/test_recursion.adana | 6 +-- file_tests/test_string_arr.adana | 6 +-- file_tests/testfib.adana | 4 +- src/adana_script/ast.rs | 6 +-- src/adana_script/mod.rs | 4 +- src/adana_script/parser.rs | 55 ++++++++++++++++-------- src/adana_script/require_dynamic_lib.rs | 2 +- src/adana_script/tests/misc.rs | 51 ++++++++++++++++++++++ src/adana_script/tests/test_parser.rs | 56 +++++++++++++++++++++++++ src/args.rs | 18 ++++++++ src/db/database.rs | 6 --- src/db/file_db.rs | 4 ++ src/db/file_lock.rs | 3 ++ src/main.rs | 35 ++++++++++++---- 28 files changed, 275 insertions(+), 120 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e7867e8..d01ad2f 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -15,7 +15,8 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: toolchain: stable - # targets: x86_64-unknown-linux-musl + targets: x86_64-unknown-linux-gnu + - run: rustup component add clippy - run: cargo test --verbose -- --nocapture - run: cargo clippy --all-targets --all-features -- -D warnings - run: cargo publish --dry-run diff --git a/Cargo.lock b/Cargo.lock index 8a42d90..eadfdf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,20 +23,20 @@ dependencies = [ "serde_json", "serial_test", "slab_tree", - "strum 0.26.1", + "strum", ] [[package]] name = "adana-script-core" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36d89c0a6f07bddba7a690a2e6c37045dc879d40cdc35cff0a9d38f32a8af0ca" +checksum = "aa8a7bb732df5f039dcadd732decc5d1f77c4ab72cc595a1b7d359ea9bfe98ba" dependencies = [ "anyhow", "libloading", "serde", "serde_derive", - "strum 0.25.0", + "strum", ] [[package]] @@ -919,9 +919,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -995,35 +995,13 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros 0.25.3", -] - [[package]] name = "strum" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" dependencies = [ - "strum_macros 0.26.1", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", + "strum_macros", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index dc413a0..68c0852 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,13 +32,13 @@ nu-ansi-term = "0.50.0" rustyline = "13.0.0" rustyline-derive = "0.10.0" serde = { version = "1.0.196", features = ['serde_derive', 'rc'] } -serde_json = "1.0.111" +serde_json = "1.0.113" slab_tree = "0.3.2" strum = { version = "0.26.1", features = ["derive"] } ctrlc = "3.4.2" #adana-script-core = { git = "https://github.com/nbittich/adana-script-core.git", branch = "feature/bitwise-and-new-ints" } -adana-script-core = "0.16.0" +adana-script-core = "0.16.1" arboard = "3.3.0" [dependencies.env_logger] diff --git a/README.md b/README.md index 90ddee9..94ca0b9 100644 --- a/README.md +++ b/README.md @@ -356,7 +356,7 @@ If it is not installed yet, you will see instructions on how to install it, e.g: std lib doesn't exist: "/home/nbittich/.local/share/.libs_adana/adana-std/fs.so". Try to install it like so: - - wget -P /tmp https://github.com/nbittich/adana-std/releases/download/0.16.0/adana-std.tar.gz + - wget -P /tmp https://github.com/nbittich/adana-std/releases/download/0.16.1/adana-std.tar.gz - mkdir /home/nbittich/.local/share/.libs_adana/adana-std && tar xvzf /tmp/adana-std.tar.gz \ -C /home/nbittich/.local/share/.libs_adana/adana-std ``` @@ -367,7 +367,7 @@ There are two loops, the while loop and the for-each loop. The while loop looks like the one in C, while the for-each loop is a little bit more modern. -For-each loop doesn't require parenthesizes. +For-each loop & while loop don't require parenthesizes. You can only iterate over structs, strings and arrays. ```C @@ -379,6 +379,14 @@ while(count < 10) { } ``` +``` +# also valid +while count < 10 { + println(count) + count = count + 1 +} +``` + ```javascript for n in [1,2,3] { println(n) @@ -430,7 +438,7 @@ for (index,a in arr) { You can break if you match a certain condition within a while: ```C -while(count < 10) { +while count < 10 { println(count) count = count + 1 if(count % 3 ==0) { @@ -461,12 +469,12 @@ for i in 1..=10 { ### Conditions -Same as C: +Same as C but parenthesizes are optional: ```C -if(age > 12) { +if age > 12 { println("age > 12") -} else if(age <9) { +} else if age < 9 { println("age < 9") } else { println("dunno") @@ -813,7 +821,11 @@ RUST_LOG=adana=debug adana #### Run a script without entering in the repl ``` +# using file adana -sp /path/to/script.adana + +# using code +adana -e 1+1 ``` ``` diff --git a/dynamic_lib/example_lib_src/Cargo.lock b/dynamic_lib/example_lib_src/Cargo.lock index 57cbaaa..26ad186 100644 --- a/dynamic_lib/example_lib_src/Cargo.lock +++ b/dynamic_lib/example_lib_src/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "adana-script-core" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36d89c0a6f07bddba7a690a2e6c37045dc879d40cdc35cff0a9d38f32a8af0ca" +checksum = "aa8a7bb732df5f039dcadd732decc5d1f77c4ab72cc595a1b7d359ea9bfe98ba" dependencies = [ "anyhow", "libloading", @@ -77,18 +77,18 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -97,18 +97,18 @@ dependencies = [ [[package]] name = "strum" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" dependencies = [ "heck", "proc-macro2", diff --git a/dynamic_lib/example_lib_src/Cargo.toml b/dynamic_lib/example_lib_src/Cargo.toml index 6fb1542..beca582 100644 --- a/dynamic_lib/example_lib_src/Cargo.toml +++ b/dynamic_lib/example_lib_src/Cargo.toml @@ -11,7 +11,7 @@ edition = "2021" crate-type = ["dylib"] [dependencies] -adana-script-core = "0.16.0" +adana-script-core = "0.16.1" #adana-script-core = { git = "https://github.com/nbittich/adana-script-core.git", branch = "feature/bitwise-and-new-ints" } anyhow = "1.0.79" diff --git a/file_tests/sort.adana b/file_tests/sort.adana index d52c009..e035e5c 100644 --- a/file_tests/sort.adana +++ b/file_tests/sort.adana @@ -1,10 +1,10 @@ sort = (array) => { is_sorted = false - while (!is_sorted) { + while !is_sorted { is_sorted = true bound = length(array) - 1 for i in 0..bound { - if (array[i] > array[i+1]) { + if array[i] > array[i+1] { is_sorted = false temp = array[i+1] array[i+1] = array[i] diff --git a/file_tests/string.adana b/file_tests/string.adana index ee274f5..b557996 100644 --- a/file_tests/string.adana +++ b/file_tests/string.adana @@ -3,13 +3,13 @@ # c: the character to search # return: array of strings split = (s, c) => { - if(s == null || length(s) == 0 || c == null || length(c) == 0) { + if s == null || length(s) == 0 || c == null || length(c) == 0 { return null } res = [] buf = "" count = 0 - while(count < length(s)) { + while count < length(s) { curr = s[count] if(buf == "aka") { return [buf] @@ -22,10 +22,10 @@ split = (s, c) => { } count = count + 1 } - if(length(buf) != 0) { + if length(buf) != 0 { res = res + [buf] } - if(s!= null && length(res) == 0) { + if s!= null && length(res) == 0 { res = [s] } res diff --git a/file_tests/test2.adana b/file_tests/test2.adana index 5d741f8..e239233 100644 --- a/file_tests/test2.adana +++ b/file_tests/test2.adana @@ -3,7 +3,7 @@ b = null x = null z = null r = null -if(a > 20) { +if a > 20 { b = 12 x = 15 z = 18 diff --git a/file_tests/test_array.adana b/file_tests/test_array.adana index a86da16..c46e9e3 100644 --- a/file_tests/test_array.adana +++ b/file_tests/test_array.adana @@ -13,7 +13,7 @@ copy = [] count = 0 # copy the array one by one -while (count < arrlen) { +while count < arrlen { copy = copy + [arr[count]] count = count + 1 } @@ -28,7 +28,7 @@ arr[9] = "Yolo" i = 9 list = [] -while(i !=0) { +while i !=0 { list = [i, list] i = i -1 } @@ -37,4 +37,4 @@ while(i !=0) { println(list) # should print 2 -println(length(list)) \ No newline at end of file +println(length(list)) diff --git a/file_tests/test_fizzbuzz.adana b/file_tests/test_fizzbuzz.adana index 884df4c..aec20fb 100644 --- a/file_tests/test_fizzbuzz.adana +++ b/file_tests/test_fizzbuzz.adana @@ -3,7 +3,7 @@ text = "" while (count <= 100) { toprint = false - if(count % 3 == 0) { + if count % 3 == 0 { #fizz toprint = true text = multiline { @@ -13,7 +13,7 @@ while (count <= 100) { } } - if(count % 5 == 0) { + if count % 5 == 0 { # buzz toprint = true text = multiline { @@ -22,7 +22,7 @@ while (count <= 100) { } } - if(count % 3 == 0 && count % 5 == 0) { + if count % 3 == 0 && count % 5 == 0 { # Fizz Buzz toprint = true text = count + " = FizzBuzz" @@ -30,7 +30,7 @@ while (count <= 100) { count = count + 1 - if(toprint) { + if toprint { println(text) } diff --git a/file_tests/test_fizzbuzz_else.adana b/file_tests/test_fizzbuzz_else.adana index 164e450..446da1b 100644 --- a/file_tests/test_fizzbuzz_else.adana +++ b/file_tests/test_fizzbuzz_else.adana @@ -1,21 +1,21 @@ count = -1 text = "" -while (count <= 100) { +while count <= 100 { count = count + 1 - if(count % 3 == 0 && count % 5 == 0) { + if count % 3 == 0 && count % 5 == 0 { # Fizz Buzz text = count + " = FizzBuzz" println(text) - } else if(count % 5 == 0) { + } else if count % 5 == 0 { # buzz text = multiline { count + " = Buzz" # oops } println(text) - } else if(count % 3 == 0) { + } else if count % 3 == 0 { #fizz text = multiline { count @@ -24,7 +24,7 @@ while (count <= 100) { } println(text) - }else { + } else { println(count + " neither fizz nor buzz") } } diff --git a/file_tests/test_if_else.adana b/file_tests/test_if_else.adana index 0f0d2a5..a9ace4d 100644 --- a/file_tests/test_if_else.adana +++ b/file_tests/test_if_else.adana @@ -1,7 +1,7 @@ -if(count == 102) { +if count == 102 { count = count -1 println("101") } else { count = count -50 println("oops") -} \ No newline at end of file +} diff --git a/file_tests/test_nested.adana b/file_tests/test_nested.adana index 79dfee8..33651eb 100644 --- a/file_tests/test_nested.adana +++ b/file_tests/test_nested.adana @@ -3,19 +3,19 @@ b = 12 x = 99 s = "" z = "" -while (a != 0) { +while a != 0 { - if(a % 3 == 0) { + if a % 3 == 0 { s = "mod 3" a = a -2 } - if (a % 3 != 0 || a % 2 != 0) { + if a % 3 != 0 || a % 2 != 0 { z = "mod " + a a = a-1 } - while(x > 50) { + while x > 50 { x = x-1 } diff --git a/file_tests/test_recursion.adana b/file_tests/test_recursion.adana index 9a1bf82..150ee72 100644 --- a/file_tests/test_recursion.adana +++ b/file_tests/test_recursion.adana @@ -1,7 +1,7 @@ fact = (n) => { - if(n>=1) { + if n>=1 { n * fact(n-1) - }else { + } else { 1 } -} \ No newline at end of file +} diff --git a/file_tests/test_string_arr.adana b/file_tests/test_string_arr.adana index 5027c79..55fc44b 100644 --- a/file_tests/test_string_arr.adana +++ b/file_tests/test_string_arr.adana @@ -1,7 +1,7 @@ v = "eodrnin" count = 0 # we can iterate over a string -while(count < length(v)) { +while count < length(v) { println(v[count]) count = count + 1 } @@ -19,9 +19,9 @@ i = 0 s = "" -while(i < length("kekeke")) { +while i < length("kekeke") { s = s + "kekeke"[i] i = i +1 } -v \ No newline at end of file +v diff --git a/file_tests/testfib.adana b/file_tests/testfib.adana index 559da58..d59aee7 100644 --- a/file_tests/testfib.adana +++ b/file_tests/testfib.adana @@ -3,7 +3,7 @@ a = 0 b = 1 c = n x = null -while (n > 1) +while n > 1 { n = n -1 c = a + b @@ -11,7 +11,7 @@ while (n > 1) b = c } -if(c < 55) { +if c < 55 { # extra comment x = "this is a complex program: " + c # hello } diff --git a/src/adana_script/ast.rs b/src/adana_script/ast.rs index 18a6340..e4e5f86 100644 --- a/src/adana_script/ast.rs +++ b/src/adana_script/ast.rs @@ -216,9 +216,9 @@ pub fn to_ast( } if cfg!(test) { - println!("Left => {left:?}"); - println!("Op => {operation:?}"); - println!("Right => {operations:?}"); + println!("Left => {left:#?}"); + println!("Op => {operation:#?}"); + println!("Right => {operations:#?}"); println!(); } diff --git a/src/adana_script/mod.rs b/src/adana_script/mod.rs index 937ec03..2b1bd80 100644 --- a/src/adana_script/mod.rs +++ b/src/adana_script/mod.rs @@ -25,7 +25,7 @@ pub fn print_ast(script: &str) -> anyhow::Result<()> { anyhow::ensure!( rest.trim().is_empty(), format!( - "{} rest is not empty! {instructions:?} => {rest}", + "{} rest is not empty! {instructions:#?} => {rest}", Color::Red.paint("PRINT AST ERROR:") ) ); @@ -35,7 +35,7 @@ pub fn print_ast(script: &str) -> anyhow::Result<()> { let mut tree: Tree = Tree::new(); println!("==================INSTRUCTION================"); - println!("{instruction:?}"); + println!("{instruction:#?}"); to_ast(&mut dummy_ctx, instruction, &mut tree, &None)?; let mut tree_fmt = String::new(); diff --git a/src/adana_script/parser.rs b/src/adana_script/parser.rs index 9b4be78..ed15daf 100644 --- a/src/adana_script/parser.rs +++ b/src/adana_script/parser.rs @@ -29,6 +29,13 @@ pub(super) fn comments(s: &str) -> Res> { fn tag_no_space<'a>(t: &'a str) -> impl Fn(&'a str) -> Res<&'a str> { move |s: &str| delimited(multispace0, tag(t), multispace0)(s) } + +fn tag_no_space_opt<'a>( + t: &'a str, +) -> impl Fn(&'a str) -> Res> { + move |s: &str| opt(tag_no_space(t))(s) +} + fn recognize_hexadecimal(input: &str) -> Res<&str> { // <'a, E: ParseError<&'a str>> preceded( @@ -227,18 +234,32 @@ fn parse_constant(s: &str) -> Res { fn parse_block_paren(s: &str) -> Res { let parser = |p| many1(parse_value)(p); - parse_paren(parser)(s) + parse_paren(parser, false)(s) +} +fn parse_block_paren_opt(s: &str) -> Res { + let parser = |p| many1(parse_value)(p); + parse_paren(parser, true)(s) } -fn parse_paren<'a, F>(parser: F) -> impl Fn(&'a str) -> Res +fn parse_paren<'a, F>( + parser: F, + paren_opt: bool, +) -> impl Fn(&'a str) -> Res where F: Fn(&'a str) -> Res>, { move |s| { - preceded( - tag_no_space("("), - terminated(map(&parser, Value::BlockParen), tag_no_space(")")), - )(s) + let parser = map(&parser, Value::BlockParen); + if paren_opt { + preceded( + tag_no_space_opt("("), + terminated(parser, tag_no_space_opt(")")), + )(s) + } else { + preceded(tag_no_space("("), terminated(parser, tag_no_space(")")))( + s, + ) + } } } @@ -267,7 +288,7 @@ fn parse_fn(s: &str) -> Res { }; map( separated_pair( - map_parser(take_until("=>"), parse_paren(parser)), + map_parser(take_until("=>"), parse_paren(parser, false)), tag("=>"), alt(( parse_expr, @@ -377,7 +398,7 @@ fn parse_drop(s: &str) -> Res { )(p) }; - map(preceded(tag_no_space(DROP), parse_paren(parser)), |variables| { + map(preceded(tag_no_space(DROP), parse_paren(parser, false)), |variables| { Value::Drop(Box::new(variables)) })(s) } @@ -733,13 +754,13 @@ fn parse_simple_instruction(s: &str) -> Res { }, ), alt(( - parse_fn_call, - parse_fn, - parse_struct_access, - parse_array_access, - parse_struct, - parse_fstring, - parse_array, + all_consuming(parse_fn_call), + all_consuming(parse_fn), + all_consuming(parse_struct_access), + all_consuming(parse_array_access), + all_consuming(parse_struct), + all_consuming(parse_fstring), + all_consuming(parse_array), parse_expression, )), ))(s) @@ -750,7 +771,7 @@ fn parse_if_statement(s: &str) -> Res { preceded( tag_no_space(IF), tuple(( - parse_block_paren, + parse_block_paren_opt, parse_block(parse_instructions), opt(preceded( tag_no_space(ELSE), @@ -789,7 +810,7 @@ fn parse_while_statement(s: &str) -> Res { map( preceded( tag_no_space(WHILE), - pair(parse_block_paren, parse_block(parse_instructions)), + pair(parse_block_paren_opt, parse_block(parse_instructions)), ), |(cond, exprs)| Value::WhileExpr { cond: Box::new(cond), exprs }, )(s) diff --git a/src/adana_script/require_dynamic_lib.rs b/src/adana_script/require_dynamic_lib.rs index 106c60e..5f6ca30 100644 --- a/src/adana_script/require_dynamic_lib.rs +++ b/src/adana_script/require_dynamic_lib.rs @@ -1,5 +1,5 @@ const STD_DOWNLOAD_URI: &str = - "https://github.com/nbittich/adana-std/releases/download/0.16.0/adana-std.tar.gz"; + "https://github.com/nbittich/adana-std/releases/download/0.16.1/adana-std.tar.gz"; use std::{ path::Path, diff --git a/src/adana_script/tests/misc.rs b/src/adana_script/tests/misc.rs index f47476e..83e6ec9 100644 --- a/src/adana_script/tests/misc.rs +++ b/src/adana_script/tests/misc.rs @@ -746,3 +746,54 @@ fn recur_early_return() { compute(script, &mut ctx, "N/A").unwrap() ); } + +#[test] +fn test_if_no_parenthesis() { + let mut ctx = BTreeMap::from([ + ("age".into(), Primitive::Int(35).ref_prim()), + ("gender".into(), Primitive::String("MALE".to_string()).ref_prim()), + ]); + + let script = r#" + if age < 40 && gender == "MALE" { + "yes" + } else { + "no" + } + "#; + assert_eq!( + Primitive::String("yes".into()), + compute(script, &mut ctx, "N/A").unwrap() + ); +} + +#[test] +fn test_while_no_parenthesis() { + let mut ctx = BTreeMap::from([ + ("age".into(), Primitive::Int(35).ref_prim()), + ("gender".into(), Primitive::String("MALE".to_string()).ref_prim()), + ]); + + let script = r#" + while age != 0 { + age = age -1 + } + age + "#; + assert_eq!(Primitive::Int(0), compute(script, &mut ctx, "N/A").unwrap()); +} + +#[test] +fn test_buggy_fn_call() { + let mut ctx = BTreeMap::new(); + + let script = r#" + f= (x) => {x*2} + a = 39 + b= 42 + f(a) + f(b) + + + "#; + assert_eq!(Primitive::Int(162), compute(script, &mut ctx, "N/A").unwrap()); +} diff --git a/src/adana_script/tests/test_parser.rs b/src/adana_script/tests/test_parser.rs index a3a0e74..b41b8ab 100644 --- a/src/adana_script/tests/test_parser.rs +++ b/src/adana_script/tests/test_parser.rs @@ -639,6 +639,62 @@ fn test_parser_array_directly_access() { ) } +#[test] +fn test_parser_buggy_fn_call_op() { + use Value::*; + let expr = r#" + f= (x) => {x*2} + a = 39 + b= 42 + f(a) + f(b) + + "#; + let (r, v) = parse_instructions(expr).unwrap(); + assert_eq!("", r); + println!("{v:#?}"); + assert_eq!( + v, + vec![ + VariableExpr { + name: Box::new(Variable("f".to_string())), + expr: Box::new(Function { + parameters: Box::new(BlockParen(vec![Variable( + "x".to_string() + )])), + exprs: vec![BlockParen(vec![ + Variable("x".to_string()), + Operation(Operator::Mult), + U8(2) + ])] + }) + }, + VariableExpr { + name: Box::new(Variable("a".to_string())), + expr: Box::new(U8(39)) + }, + VariableExpr { + name: Box::new(Variable("b".to_string())), + expr: Box::new(U8(42)) + }, + Expression(vec![ + FunctionCall { + parameters: Box::new(BlockParen(vec![Variable( + "a".to_string() + )])), + function: Box::new(Variable("f".to_string())) + }, + Operation(Operator::Add), + FunctionCall { + parameters: Box::new(BlockParen(vec![Variable( + "b".to_string() + )])), + function: Box::new(Variable("f".to_string())) + } + ]) + ] + ) +} + #[test] fn test_parse_string_escaped() { let expr = r#""u\nno""#; diff --git a/src/args.rs b/src/args.rs index 2fbeb06..096af1e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -2,6 +2,7 @@ use anyhow::Context; pub enum Argument { InMemory, + Execute(String), ScriptPath(String), DbPath(String), NoFallbackInMemory, @@ -26,6 +27,23 @@ pub fn parse_args( let path = args.next().context("script path missing!!")?; arguments.push(Argument::ScriptPath(path)); } + "--execute" | "-e" => { + anyhow::ensure!( + !arguments + .iter() + .any(|a| matches!(a, Argument::Execute(_))), + "execute should be specified only once!" + ); + let mut rest = String::new(); + + for a in &mut args { + rest.push(' '); + println!("{a}"); + rest.push_str(&a); + } + arguments.push(Argument::Execute(rest)); + break; + } "--inmemory" | "-im" => { anyhow::ensure!( !arguments.iter().any(|a| matches!(a, Argument::InMemory)), diff --git a/src/db/database.rs b/src/db/database.rs index 18c16e0..cc2f0cc 100644 --- a/src/db/database.rs +++ b/src/db/database.rs @@ -18,8 +18,6 @@ fn get_default_db_path() -> Option> { } db_dir.push("adana.db"); - println!("Db Path: {}", db_dir.to_string_lossy()); - Some(db_dir.into_boxed_path()) } @@ -43,10 +41,6 @@ impl Config { path: path .map(|p| { let path: Box = p.as_ref().into(); - println!( - "Db Path: {}", - path.as_ref().to_string_lossy() - ); path }) .or_else(get_default_db_path), diff --git a/src/db/file_db.rs b/src/db/file_db.rs index 96f4749..cd2405b 100644 --- a/src/db/file_db.rs +++ b/src/db/file_db.rs @@ -197,6 +197,10 @@ where K: 'static + Key + DeserializeOwned + std::fmt::Debug, V: 'static + Value + DeserializeOwned + std::fmt::Debug, { + pub fn get_path(&self) -> &PathBuf { + self.__file_lock.get_path() + } + fn __flush( inner_db: Arc>>, file_lock: &FileLock, diff --git a/src/db/file_lock.rs b/src/db/file_lock.rs index 369aa01..cc9300a 100644 --- a/src/db/file_lock.rs +++ b/src/db/file_lock.rs @@ -46,6 +46,9 @@ pub fn read_file(p: &PathBuf) -> anyhow::Result> { } impl FileLock { + pub fn get_path(&self) -> &PathBuf { + &self.inner_p + } pub fn open>(path: P) -> Result { let _lock_p = path.as_ref().with_extension("lock"); let inner_p = path.as_ref().to_path_buf(); diff --git a/src/main.rs b/src/main.rs index bf45769..7cdeb38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,10 @@ use args::*; use db::DbOp; use log::debug; use rustyline::error::ReadlineError; -use std::path::{Path, PathBuf}; +use std::{ + borrow::Cow, + path::{Path, PathBuf}, +}; use prelude::{colors::LightBlue, colors::Style, BTreeMap}; @@ -30,14 +33,8 @@ const PKG_NAME: &str = env!("CARGO_PKG_NAME"); fn main() -> anyhow::Result<()> { env_logger::init(); - ctrlc::set_handler(|| { - debug!("catch CTRL-C! DO NOT REMOVE this. receive ctrl+c signal 2") - })?; let args = parse_args(std::env::args())?; - clear_terminal(); - println!("{PKG_NAME} v{VERSION} (rust version: {RUST_VERSION})"); - let config = if args.is_empty() { Config::default() } else { @@ -99,7 +96,16 @@ fn main() -> anyhow::Result<()> { None } }); - if let Some(script_path) = script_path { + + let mut direct_execution_script = args.iter().find_map(|a| { + if let Argument::Execute(script) = a { + Some(Cow::Borrowed(script)) + } else { + None + } + }); + + let script = if let Some(script_path) = script_path { let pb = PathBuf::from(&script_path); if !pb.exists() { return Err(anyhow::anyhow!( @@ -122,8 +128,13 @@ fn main() -> anyhow::Result<()> { .parent() .context("no parent directory found for {script_path}")?; std::env::set_current_dir(parent)?; - let mut script_context = BTreeMap::new(); let script = std::fs::read_to_string(canon)?; + Some(Cow::Owned(script)) + } else { + direct_execution_script.take() + }; + if let Some(script) = script { + let mut script_context = BTreeMap::new(); let script_res = { match compute(&script, &mut script_context, &path_to_shared_lib) { @@ -140,6 +151,11 @@ fn main() -> anyhow::Result<()> { return Ok(()); } + ctrlc::set_handler(|| { + debug!("catch CTRL-C! DO NOT REMOVE this. receive ctrl+c signal 2") + })?; + clear_terminal(); + println!("{PKG_NAME} v{VERSION} (rust version: {RUST_VERSION})"); println!("shared lib path: {path_to_shared_lib:?}"); println!(); @@ -148,6 +164,7 @@ fn main() -> anyhow::Result<()> { start_app(&mut db, history_path, &path_to_shared_lib, default_cache) } Ok(Db::FileBased(mut db)) => { + println!("Db Path: {}", db.get_path().display()); start_app(&mut db, history_path, &path_to_shared_lib, default_cache) } Err(e) => Err(e),