Add no-std example.
This commit is contained in:
parent
e6c3f8134d
commit
61a1355c59
@ -3,7 +3,7 @@ Rust Examples
|
|||||||
|
|
||||||
{{#include ../../links.md}}
|
{{#include ../../links.md}}
|
||||||
|
|
||||||
A number of examples can be found in the `examples` folder:
|
A number of examples can be found in the `examples` directory:
|
||||||
|
|
||||||
| Example | Description |
|
| Example | Description |
|
||||||
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
@ -29,3 +29,12 @@ Examples can be run with the following command:
|
|||||||
```bash
|
```bash
|
||||||
cargo run --example {example_name}
|
cargo run --example {example_name}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`no-std` Samples
|
||||||
|
----------------
|
||||||
|
|
||||||
|
To illustrate `no-std` builds, a number of sample applications are available under the `no_std` directory:
|
||||||
|
|
||||||
|
| Example | Environment |
|
||||||
|
| ------------------------------------------------------------------------------------- | :---------: |
|
||||||
|
| [`no_std_win`](https://github.com/jonathandturner/rhai/tree/master/no_std/no_std_win) | Windows API |
|
||||||
|
@ -6,7 +6,7 @@ Example Scripts
|
|||||||
Language Feature Scripts
|
Language Feature Scripts
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
There are also a number of examples scripts that showcase Rhai's features, all in the `scripts` folder:
|
There are also a number of examples scripts that showcase Rhai's features, all in the `scripts` directory:
|
||||||
|
|
||||||
| Script | Description |
|
| Script | Description |
|
||||||
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
||||||
|
24
no_std/no_std_win/Cargo.toml
Normal file
24
no_std/no_std_win/Cargo.toml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[package]
|
||||||
|
name = "no_std_win"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
authors = ["Stephen Chung"]
|
||||||
|
description = "no-std test application for the Windows API"
|
||||||
|
homepage = "https://github.com/jonathandturner/rhai/tree/master/no_std/no_std_win"
|
||||||
|
repository = "https://github.com/jonathandturner/rhai"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rhai = { path = "../../", features = [ "no_std" ], default_features = false }
|
||||||
|
wee_alloc = { version = "0.4.5", default_features = false }
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = "z" # optimize for size
|
||||||
|
debug = false
|
||||||
|
rpath = false
|
||||||
|
lto = "fat"
|
||||||
|
debug-assertions = false
|
||||||
|
codegen-units = 1
|
||||||
|
panic = "abort"
|
18
no_std/no_std_win/README.md
Normal file
18
no_std/no_std_win/README.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
`no-std` Sample for Windows API
|
||||||
|
==============================
|
||||||
|
|
||||||
|
This sample application is a bare-bones `no-std` build for the Windows API.
|
||||||
|
|
||||||
|
[`wee_alloc`](https://crates.io/crates/wee_alloc) is used as the allocator.
|
||||||
|
|
||||||
|
|
||||||
|
To Compile
|
||||||
|
----------
|
||||||
|
|
||||||
|
The nightly compiler is required:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo +nightly build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
The release build is optimized for size. It can be changed to optimize on speed instead.
|
41
no_std/no_std_win/src/main.rs
Normal file
41
no_std/no_std_win/src/main.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//! This is a `no-std` application for the Windows API that evaluates
|
||||||
|
//! a simple expression and uses the result as the return value.
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![feature(alloc_error_handler, start, core_intrinsics, lang_items)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
extern crate wee_alloc;
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
|
||||||
|
use rhai::{Engine, INT};
|
||||||
|
|
||||||
|
#[start]
|
||||||
|
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
|
let engine = Engine::new();
|
||||||
|
|
||||||
|
// Evaluate a simple expression: 40 + 2
|
||||||
|
engine.eval::<INT>("40 + 2").unwrap() as isize
|
||||||
|
}
|
||||||
|
|
||||||
|
#[alloc_error_handler]
|
||||||
|
fn foo(_: core::alloc::Layout) -> ! {
|
||||||
|
core::intrinsics::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
#[lang = "panic_impl"]
|
||||||
|
extern "C" fn rust_begin_panic(_: &core::panic::PanicInfo) -> ! {
|
||||||
|
core::intrinsics::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[lang = "eh_personality"]
|
||||||
|
extern "C" fn eh_personality() {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
extern "C" fn rust_eh_register_frames() {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
extern "C" fn rust_eh_unregister_frames() {}
|
@ -1773,8 +1773,8 @@ impl Engine {
|
|||||||
Expr::CharConstant(x) => Ok(x.0.into()),
|
Expr::CharConstant(x) => Ok(x.0.into()),
|
||||||
Expr::FnPointer(x) => Ok(FnPtr::new_unchecked(x.0.clone()).into()),
|
Expr::FnPointer(x) => Ok(FnPtr::new_unchecked(x.0.clone()).into()),
|
||||||
Expr::Variable(x) if (x.0).0 == KEYWORD_THIS => {
|
Expr::Variable(x) if (x.0).0 == KEYWORD_THIS => {
|
||||||
if let Some(ref val) = this_ptr {
|
if let Some(val) = this_ptr {
|
||||||
Ok((*val).clone())
|
Ok(val.clone())
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(EvalAltResult::ErrorUnboundedThis((x.0).1)))
|
Err(Box::new(EvalAltResult::ErrorUnboundedThis((x.0).1)))
|
||||||
}
|
}
|
||||||
@ -1829,15 +1829,16 @@ impl Engine {
|
|||||||
// Not built in, map to `var = var op rhs`
|
// Not built in, map to `var = var op rhs`
|
||||||
let op = &op[..op.len() - 1]; // extract operator without =
|
let op = &op[..op.len() - 1]; // extract operator without =
|
||||||
let hash = calc_fn_hash(empty(), op, 2, empty());
|
let hash = calc_fn_hash(empty(), op, 2, empty());
|
||||||
|
// Clone the LHS value
|
||||||
let args = &mut [&mut lhs_ptr.clone(), &mut rhs_val];
|
let args = &mut [&mut lhs_ptr.clone(), &mut rhs_val];
|
||||||
|
// Run function
|
||||||
// Set variable value
|
let (value, _) = self
|
||||||
*lhs_ptr = self
|
|
||||||
.exec_fn_call(
|
.exec_fn_call(
|
||||||
state, lib, op, true, hash, args, false, false, None, level,
|
state, lib, op, true, hash, args, false, false, None, level,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
|
||||||
.map_err(|err| err.new_position(*op_pos))?;
|
.map_err(|err| err.new_position(*op_pos))?;
|
||||||
|
// Set value to LHS
|
||||||
|
*lhs_ptr = value;
|
||||||
}
|
}
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
@ -2491,12 +2492,8 @@ impl Engine {
|
|||||||
for ((id, id_pos), rename) in list.iter() {
|
for ((id, id_pos), rename) in list.iter() {
|
||||||
// Mark scope variables as public
|
// Mark scope variables as public
|
||||||
if let Some(index) = scope.get_index(id).map(|(i, _)| i) {
|
if let Some(index) = scope.get_index(id).map(|(i, _)| i) {
|
||||||
let alias = rename
|
let alias = rename.as_ref().map(|(n, _)| n).unwrap_or_else(|| id);
|
||||||
.as_ref()
|
scope.set_entry_alias(index, alias.clone());
|
||||||
.map(|(n, _)| n.clone())
|
|
||||||
.unwrap_or_else(|| id.clone());
|
|
||||||
|
|
||||||
scope.set_entry_alias(index, alias);
|
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(EvalAltResult::ErrorVariableNotFound(
|
return Err(Box::new(EvalAltResult::ErrorVariableNotFound(
|
||||||
id.into(),
|
id.into(),
|
||||||
|
@ -434,7 +434,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
|||||||
(Expr::StringConstant(s), Expr::IntegerConstant(i)) if i.0 >= 0 && (i.0 as usize) < s.0.chars().count() => {
|
(Expr::StringConstant(s), Expr::IntegerConstant(i)) if i.0 >= 0 && (i.0 as usize) < s.0.chars().count() => {
|
||||||
// String literal indexing - get the character
|
// String literal indexing - get the character
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
Expr::CharConstant(Box::new((s.0.chars().nth(i.0 as usize).expect("should get char"), s.1)))
|
Expr::CharConstant(Box::new((s.0.chars().nth(i.0 as usize).unwrap(), s.1)))
|
||||||
}
|
}
|
||||||
// lhs[rhs]
|
// lhs[rhs]
|
||||||
(lhs, rhs) => Expr::Index(Box::new((optimize_expr(lhs, state), optimize_expr(rhs, state), x.2))),
|
(lhs, rhs) => Expr::Index(Box::new((optimize_expr(lhs, state), optimize_expr(rhs, state), x.2))),
|
||||||
@ -614,7 +614,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
|||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
|
|
||||||
// Replace constant with value
|
// Replace constant with value
|
||||||
state.find_constant(&name).expect("should find constant in scope!").clone().set_position(pos)
|
state.find_constant(&name).unwrap().clone().set_position(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom syntax
|
// Custom syntax
|
||||||
@ -655,10 +655,7 @@ fn optimize(
|
|||||||
&& expr.as_ref().map(|v| v.is_constant()).unwrap_or(false)
|
&& expr.as_ref().map(|v| v.is_constant()).unwrap_or(false)
|
||||||
})
|
})
|
||||||
.for_each(|ScopeEntry { name, expr, .. }| {
|
.for_each(|ScopeEntry { name, expr, .. }| {
|
||||||
state.push_constant(
|
state.push_constant(name.as_ref(), expr.as_ref().unwrap().as_ref().clone())
|
||||||
name.as_ref(),
|
|
||||||
(**expr.as_ref().expect("should be Some(expr)")).clone(),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let orig_constants_len = state.constants.len();
|
let orig_constants_len = state.constants.len();
|
||||||
|
Loading…
Reference in New Issue
Block a user