Skip to content

Commit

Permalink
one line require
Browse files Browse the repository at this point in the history
  • Loading branch information
nbittich committed Sep 24, 2023
1 parent 93a34fd commit d4ec70a
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 25 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,11 @@ was used to build adana.

The rust version is specified when running the repl.

To load a dynamic library, you can either specify a relative path, or an
To load a library dynamically, you can either specify a relative path, or an
absolute path. In case of a relative path, it should be relative to the
shared lib path (by default: `$HOME/.local/share/.libs_adana`).

You can override this by providing a path when starting the repl (e.g: `adana --slp /tmp`).
You can override this by providing a path when starting the repl (e.g: `adana -slp /tmp`).

If the path is a directory, it will try to build it using `cargo`, so you
need to have rust installed on your machine.
Expand All @@ -322,6 +322,12 @@ For example:
text = lib.hello("Nordine", "la", "forme?")
```

Or in one line:

```python
text = require("libplugin_example.so").hello("Nordine", "la", "forme?")
```

<hr>

### Loops
Expand Down
69 changes: 46 additions & 23 deletions src/adana_script/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,31 @@ use adana_script_core::{
Primitive, RefPrimitive, Rem, Sin, Sqrt, Sub, Tan, ToBool, ToNumber,
TypeOf,
},
Operator, TreeNodeValue, Value,
BuiltInFunctionType, Operator, TreeNodeValue, Value,
};

/// copy existing functions in a new ctx
fn scoped_ctx(
ctx: &mut BTreeMap<String, RefPrimitive>,
) -> anyhow::Result<BTreeMap<String, RefPrimitive>> {
let mut scope_ctx = BTreeMap::new();

// copy also the function definition to the scoped ctx
for (k, p) in ctx.iter() {
let maybe_fn = p
.read()
.map_err(|e| anyhow::format_err!("could not acquire lock {e}"))?;
if matches!(
*maybe_fn,
Primitive::Function { parameters: _, exprs: _ }
| Primitive::NativeLibrary(_)
) {
scope_ctx.insert(k.to_string(), p.clone());
}
}

Ok(scope_ctx)
}
fn compute_recur(
node: Option<NodeRef<TreeNodeValue>>,
ctx: &mut BTreeMap<String, RefPrimitive>,
Expand Down Expand Up @@ -503,6 +525,24 @@ fn compute_recur(
Ok(struc.index_at(key))
}
}
(
v @ Value::BuiltInFunction {
fn_type: BuiltInFunctionType::Require,
..
},
key @ Primitive::String(k),
) => {
let native_lib = compute_lazy(v.clone(), ctx, shared_lib)?;
if let Primitive::NativeLibrary(lib) =
native_lib.as_ref_ok()?
{
Ok(Primitive::NativeFunction(k.clone(), lib.clone()))
} else {
Err(anyhow::format_err!(
"could not parse built in fn {key} => {native_lib:?}"
))
}
}
(s @ Value::Struct(_), key @ Primitive::String(_))
| (
s @ Value::StructAccess { struc: _, key: _ },
Expand Down Expand Up @@ -579,24 +619,7 @@ fn compute_recur(
exprs,
} = function
{
let mut scope_ctx = BTreeMap::new();

// copy also the function definition to the scoped ctx
for (k, p) in ctx.iter() {
let maybe_fn = p.read().map_err(|e| {
anyhow::format_err!(
"could not acquire lock {e}"
)
})?;
if matches!(
*maybe_fn,
Primitive::Function { parameters: _, exprs: _ }
| Primitive::NativeLibrary(_)
) {
scope_ctx.insert(k.to_string(), p.clone());
}
}

let mut scope_ctx = scoped_ctx(ctx)?;
for (i, param) in function_parameters.iter().enumerate()
{
if let Some(value) = param_values.get(i) {
Expand All @@ -619,7 +642,6 @@ fn compute_recur(
)));
}
}

// TODO remove this and replace Arc<Mutex<T>> by Arc<T>
// call function in a specific os thread with its own stack
// This was relative to a small stack allocated by musl
Expand Down Expand Up @@ -675,11 +697,12 @@ fn compute_recur(
dbg!(&parameters);
}

let mut cloned_ctx = ctx.clone();
let mut scope_ctx = scoped_ctx(ctx)?;

let slb = shared_lib.as_ref().to_path_buf();
let fun = move |v, extra_ctx| {
cloned_ctx.extend(extra_ctx);
compute_lazy(v, &mut cloned_ctx, &slb)
scope_ctx.extend(extra_ctx);
compute_lazy(v, &mut scope_ctx, &slb)
};
unsafe {
lib.call_function(
Expand Down
1 change: 1 addition & 0 deletions src/adana_script/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ fn parse_struct_access(s: &str) -> Res<Value> {
pair(alt((parse_struct, parse_variable)), parse_key_dots),
pair(parse_array_access, parse_key_brackets),
pair(parse_array_access, parse_key_dots),
pair(parse_builtin_fn, parse_key_dots),
)),
|(s, key)| Value::StructAccess {
struc: Box::new(s),
Expand Down
18 changes: 18 additions & 0 deletions src/adana_script/tests/dynload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,21 @@ fn build_from_adana_dynamic_lib_test() {
dbg!(ctx);
println!("{res:?}");
}
#[test]
#[serial]
fn require_direct_call_test() {
let mut ctx = BTreeMap::new();

let q = r#"
text = require("example_lib_src").hello("Nordine", "la", "forme?")
"#;
let res = compute(q, &mut ctx, "dynamic_lib").unwrap();

assert_eq!(
Primitive::String("Hello Nordine la forme?".to_string()),
ctx["text"].read().unwrap().clone()
);

dbg!(ctx);
println!("{res:?}");
}

0 comments on commit d4ec70a

Please sign in to comment.