allow passing some variables into lua
This commit is contained in:
parent
863bc784cc
commit
e4c06e56ee
|
@ -349,7 +349,7 @@ pub struct LuaCode {
|
|||
left_parenthesis: Punctuation,
|
||||
/// The arguments of the lua code.
|
||||
#[get = "pub"]
|
||||
variables: Option<ConnectedList<Identifier, Punctuation>>,
|
||||
inputs: Option<ConnectedList<Identifier, Punctuation>>,
|
||||
/// The right parenthesis of the lua code.
|
||||
#[get = "pub"]
|
||||
right_parenthesis: Punctuation,
|
||||
|
@ -550,10 +550,7 @@ impl<'a> Parser<'a> {
|
|||
Delimiter::Parenthesis,
|
||||
',',
|
||||
|parser| match parser.next_significant_token() {
|
||||
Reading::Atomic(Token::Identifier(identifier)) => {
|
||||
parser.forward();
|
||||
Ok(identifier)
|
||||
}
|
||||
Reading::Atomic(Token::Identifier(identifier)) => Ok(identifier),
|
||||
unexpected => {
|
||||
let err = Error::UnexpectedSyntax(UnexpectedSyntax {
|
||||
expected: syntax::error::SyntaxKind::Identifier,
|
||||
|
@ -597,7 +594,7 @@ impl<'a> Parser<'a> {
|
|||
Ok(Primary::Lua(Box::new(LuaCode {
|
||||
lua_keyword,
|
||||
left_parenthesis: variables.open,
|
||||
variables: variables.list,
|
||||
inputs: variables.list,
|
||||
right_parenthesis: variables.close,
|
||||
left_brace: tree.open,
|
||||
code: tree.tree?,
|
||||
|
|
|
@ -296,7 +296,7 @@ impl Primary {
|
|||
Self::Lua(lua) => {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "lua")] {
|
||||
lua.eval(&VoidHandler).map_or(false, |value| match value {
|
||||
lua.eval(scope, &VoidHandler).map_or(false, |(value, _)| match value {
|
||||
mlua::Value::Boolean(_) => matches!(r#type, ValueType::Boolean),
|
||||
mlua::Value::Integer(_) => matches!(r#type, ValueType::Integer),
|
||||
mlua::Value::String(_) => matches!(r#type, ValueType::String),
|
||||
|
@ -345,7 +345,7 @@ impl Primary {
|
|||
})
|
||||
}
|
||||
Self::Lua(lua) => lua
|
||||
.eval_comptime(&VoidHandler)
|
||||
.eval_comptime(scope, &VoidHandler)
|
||||
.inspect_err(|err| {
|
||||
handler.receive(err.clone());
|
||||
})
|
||||
|
@ -621,7 +621,7 @@ impl Transpiler {
|
|||
Primary::Lua(lua) =>
|
||||
{
|
||||
#[expect(clippy::option_if_let_else)]
|
||||
if let Some(value) = lua.eval_comptime(handler)? {
|
||||
if let Some(value) = lua.eval_comptime(scope, handler)? {
|
||||
self.store_comptime_value(&value, target, lua, handler)
|
||||
} else {
|
||||
let err = TranspileError::MissingValue(MissingValue {
|
||||
|
@ -1033,7 +1033,7 @@ impl Transpiler {
|
|||
Err(err)
|
||||
}
|
||||
},
|
||||
Primary::Lua(lua) => match lua.eval_comptime(handler)? {
|
||||
Primary::Lua(lua) => match lua.eval_comptime(scope, handler)? {
|
||||
Some(ComptimeValue::String(value)) => Ok((
|
||||
Vec::new(),
|
||||
ExtendedCondition::Runtime(Condition::Atom(value.into())),
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
|
||||
#[cfg(feature = "lua")]
|
||||
mod enabled {
|
||||
use std::sync::Arc;
|
||||
|
||||
use mlua::{Lua, Value};
|
||||
|
||||
use crate::{
|
||||
base::{self, source_file::SourceElement, Handler},
|
||||
syntax::syntax_tree::expression::LuaCode,
|
||||
transpile::{
|
||||
error::{LuaRuntimeError, TranspileError, TranspileResult},
|
||||
expression::ComptimeValue,
|
||||
Scope, VariableData,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -19,7 +20,11 @@ mod enabled {
|
|||
/// # Errors
|
||||
/// - If evaluation fails
|
||||
#[tracing::instrument(level = "debug", name = "eval_lua", skip_all, ret)]
|
||||
pub fn eval(&self, handler: &impl Handler<base::Error>) -> TranspileResult<mlua::Value> {
|
||||
pub fn eval(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<(mlua::Value, mlua::Lua)> {
|
||||
tracing::debug!("Evaluating Lua code");
|
||||
|
||||
let lua = Lua::new();
|
||||
|
@ -46,9 +51,17 @@ mod enabled {
|
|||
)
|
||||
};
|
||||
|
||||
self.add_globals(&lua).unwrap();
|
||||
if let Err(err) = self.add_globals(&lua, scope) {
|
||||
let err = TranspileError::LuaRuntimeError(LuaRuntimeError::from_lua_err(
|
||||
&err,
|
||||
self.span(),
|
||||
));
|
||||
handler.receive(crate::Error::from(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
lua.load(self.code())
|
||||
let res = lua
|
||||
.load(self.code())
|
||||
.set_name(name)
|
||||
.eval::<Value>()
|
||||
.map_err(|err| {
|
||||
|
@ -56,6 +69,11 @@ mod enabled {
|
|||
TranspileError::from(LuaRuntimeError::from_lua_err(&err, self.span()));
|
||||
handler.receive(crate::Error::from(err.clone()));
|
||||
err
|
||||
});
|
||||
|
||||
res.map(|v| {
|
||||
tracing::debug!("Lua code evaluated successfully");
|
||||
(v, lua)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -66,17 +84,16 @@ mod enabled {
|
|||
#[tracing::instrument(level = "debug", name = "eval_lua", skip_all, ret)]
|
||||
pub fn eval_comptime(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<ComptimeValue>> {
|
||||
let lua_result = self.eval(handler)?;
|
||||
// required to keep the lua instance alive
|
||||
let (lua_result, _lua) = self.eval(scope, handler)?;
|
||||
|
||||
self.handle_lua_result(lua_result, handler)
|
||||
.inspect_err(|err| {
|
||||
handler.receive(err.clone());
|
||||
})
|
||||
}
|
||||
|
||||
fn add_globals(&self, lua: &Lua) -> mlua::Result<()> {
|
||||
fn add_globals(&self, lua: &Lua, scope: &Arc<Scope>) -> mlua::Result<()> {
|
||||
let globals = lua.globals();
|
||||
|
||||
let location = {
|
||||
|
@ -86,6 +103,32 @@ mod enabled {
|
|||
};
|
||||
globals.set("shu_location", location.to_string_lossy())?;
|
||||
|
||||
if let Some(inputs) = self.inputs() {
|
||||
for x in inputs.elements() {
|
||||
let name = x.span.str();
|
||||
let value = match scope.get_variable(name).as_deref() {
|
||||
Some(VariableData::MacroParameter { macro_name, .. }) => {
|
||||
Value::String(lua.create_string(format!("$({macro_name})"))?)
|
||||
}
|
||||
Some(VariableData::ScoreboardValue { objective, target }) => {
|
||||
let table = lua.create_table()?;
|
||||
table.set("objective", lua.create_string(objective)?)?;
|
||||
table.set("target", lua.create_string(target)?)?;
|
||||
Value::Table(table)
|
||||
}
|
||||
Some(VariableData::BooleanStorage { storage_name, path }) => {
|
||||
let table = lua.create_table()?;
|
||||
table.set("storage", lua.create_string(storage_name)?)?;
|
||||
table.set("path", lua.create_string(path)?)?;
|
||||
Value::Table(table)
|
||||
}
|
||||
Some(_) => todo!("allow other types"),
|
||||
None => todo!("throw correct error"),
|
||||
};
|
||||
globals.set(name, value)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -145,7 +188,11 @@ mod disabled {
|
|||
/// # Errors
|
||||
/// - Always, as the lua feature is disabled
|
||||
#[tracing::instrument(level = "debug", name = "eval_lua", skip_all, ret)]
|
||||
pub fn eval(&self, handler: &impl Handler<base::Error>) -> TranspileResult<()> {
|
||||
pub fn eval(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<()> {
|
||||
handler.receive(TranspileError::LuaDisabled);
|
||||
tracing::error!("Lua code evaluation is disabled");
|
||||
Err(TranspileError::LuaDisabled)
|
||||
|
@ -158,6 +205,7 @@ mod disabled {
|
|||
/// - If Lua code evaluation is disabled.
|
||||
pub fn eval_comptime(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<ComptimeValue>> {
|
||||
handler.receive(TranspileError::LuaDisabled);
|
||||
|
|
|
@ -439,7 +439,7 @@ impl Transpiler {
|
|||
for expression in arguments.iter().flat_map(|x| x.iter()) {
|
||||
let value = match expression {
|
||||
Expression::Primary(Primary::Lua(lua)) => {
|
||||
lua.eval_comptime(handler).and_then(|val| match val {
|
||||
lua.eval_comptime(scope, handler).and_then(|val| match val {
|
||||
Some(ComptimeValue::MacroString(s)) => Ok(Parameter::Static(s)),
|
||||
Some(val) => Ok(Parameter::Static(val.to_string().into())),
|
||||
None => {
|
||||
|
@ -782,7 +782,7 @@ impl Transpiler {
|
|||
Expression::Primary(Primary::MacroStringLiteral(string)) => {
|
||||
Ok(vec![Command::UsesMacro(string.into())])
|
||||
}
|
||||
Expression::Primary(Primary::Lua(code)) => match code.eval_comptime(handler)? {
|
||||
Expression::Primary(Primary::Lua(code)) => match code.eval_comptime(scope, handler)? {
|
||||
Some(ComptimeValue::String(cmd)) => Ok(vec![Command::Raw(cmd)]),
|
||||
Some(ComptimeValue::MacroString(cmd)) => Ok(vec![Command::UsesMacro(cmd)]),
|
||||
Some(ComptimeValue::Boolean(_) | ComptimeValue::Integer(_)) => {
|
||||
|
|
Loading…
Reference in New Issue