2021-08-31 02:10:10 +02:00
|
|
|
use {
|
2023-02-13 18:39:45 +01:00
|
|
|
r3vi::{
|
|
|
|
view::{
|
|
|
|
OuterViewPort,
|
|
|
|
singleton::*,
|
|
|
|
},
|
|
|
|
buffer::{
|
|
|
|
singleton::*,
|
|
|
|
vec::*,
|
|
|
|
index_hashmap::*
|
|
|
|
}
|
|
|
|
},
|
2021-08-31 02:10:10 +02:00
|
|
|
crate::{
|
2023-02-13 18:39:45 +01:00
|
|
|
type_system::{Context, TypeTerm, ReprTree},
|
2023-08-21 16:31:44 +02:00
|
|
|
editors::list::{ListCmd, PTYListController, PTYListStyle},
|
2021-11-19 12:19:52 +01:00
|
|
|
terminal::{
|
2023-08-21 16:31:44 +02:00
|
|
|
TerminalAtom, TerminalStyle, make_label
|
2021-11-19 12:19:52 +01:00
|
|
|
},
|
2023-02-13 18:39:45 +01:00
|
|
|
diagnostics::{Message},
|
2023-08-17 22:45:34 +02:00
|
|
|
tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
|
2023-02-24 19:26:46 +01:00
|
|
|
commander::ObjCommander
|
2021-11-19 12:19:52 +01:00
|
|
|
},
|
|
|
|
std::sync::Arc,
|
|
|
|
std::sync::RwLock,
|
2023-08-14 01:49:14 +02:00
|
|
|
std::iter::FromIterator,
|
2023-02-13 18:39:45 +01:00
|
|
|
cgmath::{Point2}
|
2021-08-31 02:10:10 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
|
|
|
|
pub struct DigitEditor {
|
2022-12-19 11:26:07 +01:00
|
|
|
ctx: Arc<RwLock<Context>>,
|
2021-08-31 02:10:10 +02:00
|
|
|
radix: u32,
|
2022-10-23 19:29:50 +02:00
|
|
|
data: SingletonBuffer<Option<char>>,
|
|
|
|
msg: VecBuffer<Message>,
|
2021-08-31 02:10:10 +02:00
|
|
|
}
|
|
|
|
|
2023-02-24 19:26:46 +01:00
|
|
|
impl ObjCommander for DigitEditor {
|
|
|
|
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
|
|
|
let cmd_obj = cmd_obj.read().unwrap();
|
|
|
|
let cmd_type = cmd_obj.get_type().clone();
|
2021-08-31 02:10:10 +02:00
|
|
|
|
2023-08-14 01:49:14 +02:00
|
|
|
if cmd_type == (&self.ctx, "( Char )").into() {
|
2023-02-24 19:26:46 +01:00
|
|
|
if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
|
|
|
|
let c = cmd_view.get();
|
2022-10-23 19:29:50 +02:00
|
|
|
|
|
|
|
self.msg.clear();
|
2023-05-19 11:26:05 +02:00
|
|
|
|
|
|
|
if self.ctx.read().unwrap().meta_chars.contains(&c) {
|
2023-08-21 14:00:03 +02:00
|
|
|
eprintln!("digitedit: meta char");
|
2023-05-19 11:26:05 +02:00
|
|
|
return TreeNavResult::Exit;
|
2023-08-14 01:49:14 +02:00
|
|
|
|
|
|
|
} else if c.to_digit(self.radix).is_none() {
|
|
|
|
/* in case the character c is not in the range of digit-chars,
|
|
|
|
add a message to the diagnostics view
|
|
|
|
*/
|
|
|
|
|
2023-08-21 16:31:44 +02:00
|
|
|
let message = IndexBuffer::from_iter(vec![
|
2022-10-23 19:29:50 +02:00
|
|
|
(Point2::new(1, 0), make_label("invalid digit '")),
|
2023-02-24 19:26:46 +01:00
|
|
|
(Point2::new(2, 0), make_label(&format!("{}", c))
|
2022-12-18 01:39:01 +01:00
|
|
|
.map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))),
|
2022-10-23 19:29:50 +02:00
|
|
|
(Point2::new(3, 0), make_label("'"))
|
|
|
|
]);
|
2023-08-14 01:49:14 +02:00
|
|
|
|
|
|
|
self.msg.push(crate::diagnostics::make_error(message.get_port().flatten()));
|
2023-08-18 03:07:40 +02:00
|
|
|
self.data.set(Some(c));
|
2023-08-14 01:49:14 +02:00
|
|
|
} else {
|
|
|
|
self.data.set(Some(c));
|
2022-10-23 19:29:50 +02:00
|
|
|
}
|
2021-08-31 02:10:10 +02:00
|
|
|
}
|
|
|
|
}
|
2023-02-24 19:26:46 +01:00
|
|
|
|
|
|
|
TreeNavResult::Continue
|
2021-08-31 02:10:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
impl DigitEditor {
|
|
|
|
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
|
|
|
|
DigitEditor {
|
|
|
|
ctx,
|
|
|
|
radix,
|
|
|
|
data: SingletonBuffer::new(None),
|
|
|
|
msg: VecBuffer::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-18 04:15:47 +01:00
|
|
|
pub fn into_node(self, depth: usize) -> NestedNode {
|
2023-02-13 18:39:45 +01:00
|
|
|
let data = self.get_data();
|
2022-12-19 11:26:07 +01:00
|
|
|
let editor = Arc::new(RwLock::new(self));
|
2023-02-20 03:40:37 +01:00
|
|
|
let ed = editor.write().unwrap();
|
2022-12-19 11:26:07 +01:00
|
|
|
let r = ed.radix;
|
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
NestedNode::new(ed.ctx.clone(), data, depth)
|
2022-12-19 11:26:07 +01:00
|
|
|
.set_cmd(editor.clone())
|
|
|
|
.set_view(
|
|
|
|
ed.data
|
|
|
|
.get_port()
|
|
|
|
.map(move |c| {
|
|
|
|
TerminalAtom::new(
|
|
|
|
c.unwrap_or('?'),
|
|
|
|
if c.unwrap_or('?').to_digit(r).is_some() {
|
|
|
|
TerminalStyle::fg_color((100, 140, 100))
|
|
|
|
} else {
|
|
|
|
//TerminalStyle::bg_color((90, 10, 10))
|
|
|
|
TerminalStyle::fg_color((200, 40, 40))
|
|
|
|
},
|
|
|
|
)
|
|
|
|
})
|
|
|
|
.to_grid()
|
|
|
|
)
|
|
|
|
.set_diag(
|
|
|
|
ed.msg.get_port().to_sequence()
|
|
|
|
)
|
|
|
|
}
|
2022-05-08 23:30:49 +02:00
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
|
|
|
|
let radix = self.radix;
|
|
|
|
self.data.get_port().map(move |c| c?.to_digit(radix))
|
2022-10-23 19:29:50 +02:00
|
|
|
}
|
2023-02-13 18:39:45 +01:00
|
|
|
|
|
|
|
pub fn get_type(&self) -> TypeTerm {
|
2023-08-12 19:03:14 +02:00
|
|
|
TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap())
|
2023-02-13 18:39:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
|
|
|
|
ReprTree::ascend(
|
|
|
|
&ReprTree::new_leaf(
|
2023-08-15 23:18:51 +02:00
|
|
|
self.ctx.read().unwrap().type_term_from_str("( Seq u32 )").unwrap(),
|
|
|
|
self.get_data_port().into()
|
2023-02-13 18:39:45 +01:00
|
|
|
),
|
|
|
|
self.get_type()
|
|
|
|
)
|
|
|
|
}
|
2022-10-23 19:29:50 +02:00
|
|
|
}
|
|
|
|
|
2023-08-17 22:45:34 +02:00
|
|
|
|
2021-08-31 02:10:10 +02:00
|
|
|
pub struct PosIntEditor {
|
|
|
|
radix: u32,
|
2023-08-17 22:45:34 +02:00
|
|
|
digits: NestedNode,
|
|
|
|
|
|
|
|
// todo: endianness
|
2021-08-31 02:10:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl PosIntEditor {
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
|
2023-08-15 23:18:51 +02:00
|
|
|
let mut node = Context::make_node(
|
|
|
|
&ctx,
|
|
|
|
(&ctx, format!("( List ( Digit {} ) )", radix).as_str()).into(),
|
|
|
|
0
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
// Set Type
|
|
|
|
node.data = ReprTree::ascend(
|
|
|
|
&node.data.clone(),
|
|
|
|
TypeTerm::App(vec![
|
|
|
|
TypeTerm::TypeID(ctx.read().unwrap().get_typeid("PosInt").unwrap()),
|
|
|
|
TypeTerm::Num(radix as i64).into(),
|
|
|
|
TypeTerm::TypeID(ctx.read().unwrap().get_typeid("BigEndian").unwrap())
|
2023-08-17 22:45:34 +02:00
|
|
|
]
|
2023-08-15 23:18:51 +02:00
|
|
|
));
|
2023-02-18 04:15:47 +01:00
|
|
|
|
2023-03-25 08:56:38 +01:00
|
|
|
PTYListController::for_node( &mut node, Some(' '), None );
|
|
|
|
PTYListStyle::for_node( &mut node,
|
|
|
|
(
|
2023-02-18 04:15:47 +01:00
|
|
|
match radix {
|
2023-08-21 14:00:03 +02:00
|
|
|
2 => "0b".into(),
|
|
|
|
8 => "0o".into(),
|
|
|
|
10 => "0d".into(),
|
2023-02-18 04:15:47 +01:00
|
|
|
16 => "0x".into(),
|
|
|
|
_ => "".into()
|
|
|
|
},
|
|
|
|
"".into(),
|
2023-03-25 08:56:38 +01:00
|
|
|
"".into()
|
|
|
|
)
|
|
|
|
);
|
2023-02-13 18:39:45 +01:00
|
|
|
|
2021-08-31 02:10:10 +02:00
|
|
|
PosIntEditor {
|
|
|
|
radix,
|
2023-02-13 18:39:45 +01:00
|
|
|
digits: node
|
2021-08-31 02:10:10 +02:00
|
|
|
}
|
|
|
|
}
|
2021-08-31 03:03:51 +02:00
|
|
|
|
2023-08-17 22:45:34 +02:00
|
|
|
pub fn from_u64(ctx: Arc<RwLock<Context>>, radix: u32, value: u64) -> Self {
|
|
|
|
let mut edit = PosIntEditor::new(ctx, radix);
|
|
|
|
edit.set_value_u64( value );
|
|
|
|
edit
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_value_u64(&mut self, mut value: u64) {
|
|
|
|
self.digits.send_cmd_obj(ListCmd::Clear.into_repr_tree(&self.digits.ctx));
|
|
|
|
|
|
|
|
while value > 0 {
|
|
|
|
let digit_val = (value % self.radix as u64) as u32;
|
|
|
|
value /= self.radix as u64;
|
|
|
|
|
|
|
|
// if BigEndian
|
|
|
|
self.digits.goto(TreeCursor::home());
|
|
|
|
|
|
|
|
self.digits.send_cmd_obj(ReprTree::from_char(&self.digits.ctx, char::from_digit(digit_val, self.radix).expect("invalid digit")));
|
|
|
|
}
|
|
|
|
self.digits.goto(TreeCursor::none());
|
|
|
|
}
|
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn into_node(self) -> NestedNode {
|
|
|
|
self.digits
|
|
|
|
}
|
2023-08-17 22:45:34 +02:00
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
/*
|
2021-08-31 03:03:51 +02:00
|
|
|
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
|
|
|
|
let radix = self.radix;
|
2022-12-19 11:26:07 +01:00
|
|
|
self.digits
|
2021-11-19 12:19:52 +01:00
|
|
|
.get_data_port()
|
|
|
|
.filter_map(move |digit_editor| {
|
|
|
|
digit_editor.read().unwrap().data.get()?.to_digit(radix)
|
|
|
|
})
|
2021-08-31 03:03:51 +02:00
|
|
|
}
|
2021-09-06 00:08:36 +02:00
|
|
|
|
|
|
|
pub fn get_value(&self) -> u32 {
|
|
|
|
let mut value = 0;
|
|
|
|
let mut weight = 1;
|
2021-11-19 12:19:52 +01:00
|
|
|
for digit_value in self
|
|
|
|
.get_data_port()
|
|
|
|
.get_view()
|
|
|
|
.unwrap()
|
|
|
|
.iter()
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.into_iter()
|
|
|
|
.rev()
|
|
|
|
{
|
2021-09-06 00:08:36 +02:00
|
|
|
value += digit_value * weight;
|
|
|
|
weight *= self.radix;
|
|
|
|
}
|
|
|
|
|
|
|
|
value
|
2021-08-31 02:10:10 +02:00
|
|
|
}
|
2022-12-19 11:26:07 +01:00
|
|
|
*/
|
2021-08-31 02:10:10 +02:00
|
|
|
}
|
2022-05-08 23:30:49 +02:00
|
|
|
|