Make #alias work.
This commit is contained in:
parent
ff840c04c2
commit
a215133ea6
@ -3,9 +3,10 @@ use anyhow::Error;
|
||||
use piccolo::{
|
||||
async_callback::{AsyncSequence, Locals},
|
||||
meta_ops::{self, MetaResult},
|
||||
stash::Fetchable,
|
||||
Callback, Closure, Context, Executor, ExternError, FromValue, Function, IntoValue, Lua,
|
||||
MetaMethod, Stack, StashedError, StashedExecutor, StashedFunction, StashedTable, StashedValue,
|
||||
Table, Value, Variadic,
|
||||
MetaMethod, Stack, StashedError, StashedExecutor, StashedFunction, StashedValue, Table, Value,
|
||||
Variadic,
|
||||
};
|
||||
use yew::UseStateSetter;
|
||||
|
||||
@ -147,11 +148,21 @@ pub fn install_lua_globals(
|
||||
.map_err(|_| Error::msg("Can't add command"))?;
|
||||
};
|
||||
}
|
||||
|
||||
register_command!(alias);
|
||||
macro_rules! register_stateless_command {
|
||||
($sym: ident) => {
|
||||
cmd_table
|
||||
.set(
|
||||
ctx,
|
||||
ctx.intern_static(stringify!($sym).as_bytes()),
|
||||
$sym(ctx),
|
||||
)
|
||||
.map_err(|_| Error::msg("Can't add command"))?;
|
||||
};
|
||||
}
|
||||
register_stateless_command!(alias);
|
||||
register_command!(close_mud);
|
||||
register_command!(connect_mud);
|
||||
register_command!(create_match_table);
|
||||
register_stateless_command!(create_match_table);
|
||||
register_command!(delete_mud);
|
||||
register_command!(echo);
|
||||
register_command!(echo_frame);
|
||||
@ -210,6 +221,22 @@ pub fn install_lua_globals(
|
||||
.map_err(|_| Error::msg("Can't add handler"))?;
|
||||
};
|
||||
}
|
||||
macro_rules! register_stateless_class_function {
|
||||
($class_table: ident, $sym: ident) => {
|
||||
$class_table
|
||||
.set(
|
||||
ctx,
|
||||
ctx.intern_static(stringify!($sym).as_bytes()),
|
||||
$sym(ctx),
|
||||
)
|
||||
.map_err(|_| Error::msg("Can't add handler"))?;
|
||||
};
|
||||
($class_table: ident, $name: literal, $sym: ident) => {
|
||||
$class_table
|
||||
.set(ctx, ctx.intern_static($name.as_bytes()), $sym(ctx))
|
||||
.map_err(|_| Error::msg("Can't add handler"))?;
|
||||
};
|
||||
}
|
||||
|
||||
register_class_function!(mud_class_table, mudoutput_line);
|
||||
register_class_function!(mud_class_table, mudoutput_prompt);
|
||||
@ -254,9 +281,17 @@ pub fn install_lua_globals(
|
||||
let match_table_class_table = Table::new(&ctx);
|
||||
classes_table.set(ctx, "match_table", match_table_class_table)?;
|
||||
match_table_class_table.set(ctx, MetaMethod::Index, match_table_class_table)?;
|
||||
register_class_function!(match_table_class_table, "add", match_table_add);
|
||||
register_class_function!(match_table_class_table, "remove", match_table_remove);
|
||||
register_class_function!(match_table_class_table, "lua_table", match_table_lua_table);
|
||||
register_stateless_class_function!(match_table_class_table, "add", match_table_add);
|
||||
register_stateless_class_function!(
|
||||
match_table_class_table,
|
||||
"remove",
|
||||
match_table_remove
|
||||
);
|
||||
register_stateless_class_function!(
|
||||
match_table_class_table,
|
||||
"lua_table",
|
||||
match_table_lua_table
|
||||
);
|
||||
register_class_function!(
|
||||
match_table_class_table,
|
||||
"try_run_sub",
|
||||
@ -312,12 +347,15 @@ pub fn prep_metaop_call<'gc, const N: usize>(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn call_checking_metatable<'gc, 'a>(
|
||||
pub async fn call_checking_metatable<'gc, T: Fetchable>(
|
||||
seq: &mut AsyncSequence,
|
||||
obj: StashedTable,
|
||||
obj: T,
|
||||
func_name: &'static str,
|
||||
arguments: &[StashedValue],
|
||||
) -> Result<(), StashedError> {
|
||||
) -> Result<(), StashedError>
|
||||
where
|
||||
for<'gcb> <T as Fetchable>::Fetched<'gcb>: IntoValue<'gcb>,
|
||||
{
|
||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let obj = locals.fetch(&obj);
|
||||
stack.consume(ctx)?;
|
||||
|
@ -1,23 +1,20 @@
|
||||
use crate::{
|
||||
echo_to_term_frame, id_intern::intern_id, GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell,
|
||||
TermFrame,
|
||||
echo_to_term_frame,
|
||||
id_intern::intern_id,
|
||||
match_table::{create_match_table, match_table_add},
|
||||
GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell, TermFrame,
|
||||
};
|
||||
use gc_arena::{Gc, Rootable};
|
||||
use piccolo::{
|
||||
self, async_sequence, Callback, CallbackReturn, Context, FromValue, Function, IntoValue,
|
||||
SequenceReturn, Table, UserData, Value, Variadic,
|
||||
SequenceReturn, StashedTable, StashedUserData, StashedValue, Table, UserData, Value, Variadic,
|
||||
};
|
||||
use regex::Regex;
|
||||
use std::{rc::Rc, str};
|
||||
use yew::UseStateSetter;
|
||||
|
||||
use super::call_checking_metatable;
|
||||
|
||||
pub fn alias<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
_global_memo: &'a GlobalMemoCell,
|
||||
_global_layout: &'a UseStateSetter<GlobalLayoutCell>,
|
||||
) -> Callback<'gc> {
|
||||
pub fn alias<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let info: Table = ctx.get_global("info")?;
|
||||
let cur_frame: TermFrame =
|
||||
@ -43,11 +40,20 @@ pub fn alias<'gc, 'a>(
|
||||
))?;
|
||||
}
|
||||
|
||||
let aliases: Table = cur_frame.get(ctx, "aliases")?;
|
||||
let aliases: UserData = cur_frame.get(ctx, "aliases")?;
|
||||
|
||||
aliases.set(ctx, alias_match, sub_to)?;
|
||||
stack.push_back(aliases.into_value(ctx));
|
||||
stack.push_back(alias_match.into_value(ctx));
|
||||
stack.push_back(sub_to.into_value(ctx));
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let add_func = locals.stash(&ctx, Function::Callback(match_table_add(ctx)));
|
||||
async move {
|
||||
seq.call(&add_func, 0).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
Ok(piccolo::CallbackReturn::Sequence(seq))
|
||||
})
|
||||
}
|
||||
|
||||
@ -229,7 +235,8 @@ pub fn ensure_frame_instance<'gc>(ctx: Context<'gc>, frame: &TermFrame) -> Callb
|
||||
let frame_tab = locals.stash(&ctx, frame_tab);
|
||||
let frame = locals.stash(&ctx, frame);
|
||||
async move {
|
||||
call_checking_metatable(&mut seq, frame_tab, "new", &[frame]).await?;
|
||||
call_checking_metatable::<StashedTable>(&mut seq, frame_tab, "new", &[frame])
|
||||
.await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
@ -251,10 +258,21 @@ pub(super) fn new_frame<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
||||
|
||||
frame_tab.set(ctx, ctx.intern_static(b"frame"), frame)?;
|
||||
|
||||
let aliases_tab: Table = Table::new(&ctx);
|
||||
frame_tab.set(ctx, ctx.intern_static(b"aliases"), aliases_tab)?;
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let frame_tab = locals.stash(&ctx, frame_tab);
|
||||
let create_match_tab = locals.stash(&ctx, Function::Callback(create_match_table(ctx)));
|
||||
async move {
|
||||
seq.call(&create_match_tab, 0).await?;
|
||||
seq.try_enter(|ctx, locals, _exec, mut stack| {
|
||||
let frame_tab = locals.fetch(&frame_tab);
|
||||
frame_tab.set(ctx, "aliases", stack.consume::<Value>(ctx)?)?;
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(piccolo::SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
Ok(piccolo::CallbackReturn::Sequence(seq))
|
||||
})
|
||||
}
|
||||
|
||||
@ -268,7 +286,7 @@ pub(super) fn send_command_to_frame<'gc>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
let frame = locals.stash(&ctx, frame);
|
||||
let line = locals.stash(&ctx, line.into_value(ctx));
|
||||
async move {
|
||||
call_checking_metatable(&mut seq, frame, "input", &[line]).await?;
|
||||
call_checking_metatable::<StashedTable>(&mut seq, frame, "input", &[line]).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
@ -278,47 +296,64 @@ pub(super) fn send_command_to_frame<'gc>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
|
||||
pub(super) fn frame_input<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let callback_return = {
|
||||
let frame_tab: Table = Table::from_value(
|
||||
ctx,
|
||||
stack
|
||||
.pop_front()
|
||||
.ok_or_else(|| anyhow::Error::msg("classes.frame:new missing object!"))?,
|
||||
.ok_or_else(|| anyhow::Error::msg("classes.frame:input missing object!"))?,
|
||||
)?;
|
||||
let line: Value = stack
|
||||
.pop_front()
|
||||
.ok_or_else(|| anyhow::Error::msg("classes.frame:new missing line!"))?;
|
||||
.ok_or_else(|| anyhow::Error::msg("classes.frame:input missing line!"))?;
|
||||
stack.consume(ctx)?;
|
||||
|
||||
// Check for an alias match...
|
||||
for (alias_match, alias_sub) in frame_tab.get::<&str, Table>(ctx, "aliases")?.iter() {
|
||||
if let Some(alias_match) = piccolo::String::from_value(ctx, alias_match)
|
||||
.ok()
|
||||
.and_then(|am| am.to_str().ok())
|
||||
.and_then(|v| Regex::new(v).ok())
|
||||
{
|
||||
if let Some(alias_sub) = piccolo::String::from_value(ctx, alias_sub)
|
||||
.ok()
|
||||
.and_then(|am| am.to_str().ok())
|
||||
{}
|
||||
}
|
||||
}
|
||||
let aliases: UserData = frame_tab.get(ctx, "aliases")?;
|
||||
let frame: Value = frame_tab.get(ctx, "frame")?;
|
||||
|
||||
let linked_mud = frame_tab.get_value(ctx, ctx.intern_static(b"linked_mud"));
|
||||
if linked_mud.is_nil() {
|
||||
return Ok(piccolo::CallbackReturn::Return);
|
||||
}
|
||||
let linked_mud: Table = Table::from_value(ctx, linked_mud)?;
|
||||
|
||||
// linked_mud:mudinput_line(line)
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let linked_mud = locals.stash(&ctx, linked_mud);
|
||||
let aliases = locals.stash(&ctx, aliases);
|
||||
let line = locals.stash(&ctx, line);
|
||||
let frame_tab = locals.stash(&ctx, frame_tab);
|
||||
let frame = locals.stash(&ctx, frame);
|
||||
async move {
|
||||
call_checking_metatable(&mut seq, linked_mud, "mudinput_line", &[line]).await?;
|
||||
call_checking_metatable::<StashedUserData>(
|
||||
&mut seq,
|
||||
aliases.clone(),
|
||||
"try_run_sub",
|
||||
&[line.clone(), frame],
|
||||
)
|
||||
.await?;
|
||||
let (alias_hit, linked_mud, linked_mud_nil) =
|
||||
seq.try_enter(|ctx, locals, _ex, mut stack| {
|
||||
let linked_mud = locals
|
||||
.fetch(&frame_tab)
|
||||
.get_value(ctx, ctx.intern_static(b"linked_mud"));
|
||||
Ok((
|
||||
stack.consume::<bool>(ctx)?,
|
||||
locals.stash(&ctx, linked_mud),
|
||||
linked_mud.is_nil(),
|
||||
))
|
||||
})?;
|
||||
|
||||
if alias_hit || linked_mud_nil {
|
||||
return Ok(SequenceReturn::Return);
|
||||
}
|
||||
|
||||
call_checking_metatable::<StashedValue>(
|
||||
&mut seq,
|
||||
linked_mud,
|
||||
"mudinput_line",
|
||||
&[line],
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
|
||||
Ok(piccolo::CallbackReturn::Sequence(seq))
|
||||
};
|
||||
callback_return
|
||||
})
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ pub(super) fn connect_mud<'gc>(
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let conntab = locals.stash(&ctx, conntab);
|
||||
async move {
|
||||
call_checking_metatable(&mut seq, conntab, "new", &[]).await?;
|
||||
call_checking_metatable::<StashedTable>(&mut seq, conntab, "new", &[]).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
@ -319,7 +319,7 @@ pub(super) fn mudoutput<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
||||
.collect();
|
||||
async move {
|
||||
for (func_name, params) in fns {
|
||||
call_checking_metatable(
|
||||
call_checking_metatable::<StashedTable>(
|
||||
&mut seq,
|
||||
conntab.clone(),
|
||||
func_name,
|
||||
@ -401,7 +401,13 @@ pub(super) fn mudoutput_line<'gc>(
|
||||
let line = locals.stash(&ctx, line.into_value(ctx));
|
||||
async move {
|
||||
for frameroute in frameroutes {
|
||||
call_checking_metatable(&mut seq, frameroute, "route", &[line.clone()]).await?;
|
||||
call_checking_metatable::<StashedTable>(
|
||||
&mut seq,
|
||||
frameroute,
|
||||
"route",
|
||||
&[line.clone()],
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
@ -494,7 +500,8 @@ pub(super) fn new_mud<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) ->
|
||||
let curr_frame = locals.stash(&ctx, curr_frame);
|
||||
|
||||
async move {
|
||||
call_checking_metatable(&mut seq, frameroute, "new", &[curr_frame]).await?;
|
||||
call_checking_metatable::<StashedTable>(&mut seq, frameroute, "new", &[curr_frame])
|
||||
.await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
|
@ -8,12 +8,11 @@ use gc_arena::{Collect, GcRefLock, Rootable};
|
||||
use itertools::Itertools;
|
||||
use piccolo::{Callback, Context, IntoValue, Table, UserData, Value};
|
||||
use regex::Regex;
|
||||
use yew::UseStateSetter;
|
||||
|
||||
use crate::{
|
||||
lua_engine::frames::try_unwrap_frame,
|
||||
parsing::{parse_commands, quote_string, ArgumentGuard, ParsedArgument, ParsedCommand},
|
||||
GlobalLayoutCell, GlobalMemoCell,
|
||||
GlobalMemoCell,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Collect)]
|
||||
@ -251,6 +250,87 @@ pub enum SubTextPart {
|
||||
Variable(String),
|
||||
}
|
||||
|
||||
pub fn create_match_table<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let _: () = stack.consume(ctx)?;
|
||||
let user_data = UserData::<'gc>::new::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>(
|
||||
&ctx,
|
||||
GcRefLock::new(&ctx, <MatchSubTable as Default>::default().into()),
|
||||
);
|
||||
let match_table_class: Table = ctx
|
||||
.get_global::<Table>("classes")?
|
||||
.get(ctx, "match_table")?;
|
||||
user_data.set_metatable(&ctx, Some(match_table_class));
|
||||
|
||||
stack.push_back(user_data.into_value(ctx));
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_add<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let (match_table, match_text, sub_text): (UserData, piccolo::String, piccolo::String) =
|
||||
stack.consume(ctx)?;
|
||||
match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow_mut(&ctx)
|
||||
.add_record(match_text.to_str()?, sub_text.to_str()?)?;
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_remove<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let (match_table, match_text): (UserData, piccolo::String) = stack.consume(ctx)?;
|
||||
match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow_mut(&ctx)
|
||||
.remove_record(match_text.to_str()?)?;
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_lua_table<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let match_table: UserData = stack.consume(ctx)?;
|
||||
stack.push_back(
|
||||
match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow_mut(&ctx)
|
||||
.to_value(ctx)?,
|
||||
);
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_try_run_sub<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
global_memo: &'a GlobalMemoCell,
|
||||
) -> Callback<'gc> {
|
||||
let global_memo = global_memo.clone();
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let (match_table, sub, frame): (UserData, piccolo::String, Value) = stack.consume(ctx)?;
|
||||
let frame = try_unwrap_frame(ctx, &frame)?;
|
||||
|
||||
let cmds = match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow()
|
||||
.try_sub(sub.to_str()?);
|
||||
|
||||
match cmds {
|
||||
None => stack.push_back(false.into_value(ctx)),
|
||||
Some(cmds) => {
|
||||
let mut cq = global_memo.command_queue.borrow_mut();
|
||||
for cmd in cmds.into_iter().rev() {
|
||||
cq.push_front((frame.clone(), cmd));
|
||||
}
|
||||
stack.push_back(Value::Boolean(true))
|
||||
}
|
||||
}
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -452,97 +532,3 @@ mod tests {
|
||||
.is_err())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_match_table<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
_global_memo: &'a GlobalMemoCell,
|
||||
_global_layout: &'a UseStateSetter<GlobalLayoutCell>,
|
||||
) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let _: () = stack.consume(ctx)?;
|
||||
let user_data = UserData::<'gc>::new::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>(
|
||||
&ctx,
|
||||
GcRefLock::new(&ctx, <MatchSubTable as Default>::default().into()),
|
||||
);
|
||||
let match_table_class: Table = ctx
|
||||
.get_global::<Table>("classes")?
|
||||
.get(ctx, "match_table")?;
|
||||
user_data.set_metatable(&ctx, Some(match_table_class));
|
||||
|
||||
stack.push_back(user_data.into_value(ctx));
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_add<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
_global_memo: &'a GlobalMemoCell,
|
||||
) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let (match_table, match_text, sub_text): (UserData, piccolo::String, piccolo::String) =
|
||||
stack.consume(ctx)?;
|
||||
match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow_mut(&ctx)
|
||||
.add_record(match_text.to_str()?, sub_text.to_str()?)?;
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_remove<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
_global_memo: &'a GlobalMemoCell,
|
||||
) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let (match_table, match_text): (UserData, piccolo::String) = stack.consume(ctx)?;
|
||||
match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow_mut(&ctx)
|
||||
.remove_record(match_text.to_str()?)?;
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_lua_table<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
_global_memo: &'a GlobalMemoCell,
|
||||
) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let match_table: UserData = stack.consume(ctx)?;
|
||||
stack.push_back(
|
||||
match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow_mut(&ctx)
|
||||
.to_value(ctx)?,
|
||||
);
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_table_try_run_sub<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
global_memo: &'a GlobalMemoCell,
|
||||
) -> Callback<'gc> {
|
||||
let global_memo = global_memo.clone();
|
||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||
let (match_table, sub, frame): (UserData, piccolo::String, Value) = stack.consume(ctx)?;
|
||||
let frame = try_unwrap_frame(ctx, &frame)?;
|
||||
|
||||
let cmds = match_table
|
||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||
.borrow()
|
||||
.try_sub(sub.to_str()?);
|
||||
|
||||
match cmds {
|
||||
None => stack.push_back(false.into_value(ctx)),
|
||||
Some(cmds) => {
|
||||
let mut cq = global_memo.command_queue.borrow_mut();
|
||||
for cmd in cmds.into_iter().rev() {
|
||||
cq.push_front((frame.clone(), cmd));
|
||||
}
|
||||
stack.push_back(Value::Boolean(true))
|
||||
}
|
||||
}
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user