From 9ce30d29410b392e7bd5489fb5d2d144bd618720 Mon Sep 17 00:00:00 2001 From: Matthieu Jolimaitre Date: Sat, 26 Oct 2024 16:43:59 +0200 Subject: [PATCH] add repl and support azerty --- Cargo.lock | 2 +- src/dev/memory.rs | 2 +- src/hard/keyboard.rs | 716 +++++++++++++++++++++++++++++++++++-------- src/program/shell.rs | 93 ++++-- src/util.rs | 40 +++ 5 files changed, 703 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f5201c..a9545b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,7 +192,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "microlang" version = "0.1.0" -source = "git+https://git.barnulf.net/mb/microlang.git#3868298f006b58dd1df2c4d615e044d5698846f7" +source = "git+https://git.barnulf.net/mb/microlang.git#08962bfba6da1c08d901d843a537c564069541a2" dependencies = [ "chumsky", "hashbrown 0.15.0", diff --git a/src/dev/memory.rs b/src/dev/memory.rs index 47f9768..81f15fa 100644 --- a/src/dev/memory.rs +++ b/src/dev/memory.rs @@ -60,7 +60,7 @@ unsafe impl FrameAllocator for BootInfoFrameAllocator { } pub const HEAP_START: usize = 0x_4444_4444_0000; -pub const HEAP_SIZE: usize = 500 * 1024; // 500 KiB +pub const HEAP_SIZE: usize = 1_000 * 1024; // 1 MiB pub fn init_heap( mapper: &mut impl Mapper, diff --git a/src/hard/keyboard.rs b/src/hard/keyboard.rs index fd8038f..856aada 100644 --- a/src/hard/keyboard.rs +++ b/src/hard/keyboard.rs @@ -2,7 +2,7 @@ use alloc::boxed::Box; use lazy_static::lazy_static; use spin::{Mutex, MutexGuard}; -use crate::println; +use crate::{println, util::ArrayQueue}; pub fn keyboard<'r>() -> MutexGuard<'r, Keyboard> { KEYBOARD.lock() @@ -14,14 +14,18 @@ lazy_static! { pub struct Keyboard { on_code: Option>, - last: Option, + keymap: Box, } impl Keyboard { pub fn init() -> Self { let on_code = None; - let last = None; - Self { on_code, last } + let keymap = Box::new(Qwerty::default()); + Self { on_code, keymap } + } + + pub fn keymap(&mut self, keymap: impl KeyMap + Send + 'static) { + self.keymap = Box::new(keymap) as _; } pub fn on_code(&mut self, op: impl FnMut(Code) + Send + 'static) { @@ -29,142 +33,333 @@ impl Keyboard { } pub fn record(&mut self, scan_code: u8) { - let code = self.parse(scan_code); - match code { - Err(err) => println!("Failed to record key : {err:?}"), - Ok(Code::Control) => self.last = Some(Code::Control), - Ok(c) if let Some(op) = self.on_code.as_mut() => op(c), - Ok(c) => println!("Ignoring {c:?}"), + match self.keymap.parse(scan_code) { + KeyMapRes::Ok(c) if let Some(op) = self.on_code.as_mut() => op(c), + KeyMapRes::Ok(c) => println!("Ignoring {c:?}"), + KeyMapRes::Partial => (), + KeyMapRes::Unknown => println!("Unknown code : {scan_code:?}"), }; } - - pub fn parse(&mut self, scan_code: u8) -> Result { - let code = match (self.last, scan_code) { - (None, 0xE0) => Code::Control, - (None, 0x1E) => Code::Down(Key::Char('a')), - (None, 0x30) => Code::Down(Key::Char('b')), - (None, 0x2E) => Code::Down(Key::Char('c')), - (None, 0x20) => Code::Down(Key::Char('d')), - (None, 0x12) => Code::Down(Key::Char('e')), - (None, 0x21) => Code::Down(Key::Char('f')), - (None, 0x22) => Code::Down(Key::Char('g')), - (None, 0x23) => Code::Down(Key::Char('h')), - (None, 0x17) => Code::Down(Key::Char('i')), - (None, 0x24) => Code::Down(Key::Char('j')), - (None, 0x25) => Code::Down(Key::Char('k')), - (None, 0x26) => Code::Down(Key::Char('l')), - (None, 0x32) => Code::Down(Key::Char('m')), - (None, 0x31) => Code::Down(Key::Char('n')), - (None, 0x18) => Code::Down(Key::Char('o')), - (None, 0x19) => Code::Down(Key::Char('p')), - (None, 0x10) => Code::Down(Key::Char('q')), - (None, 0x13) => Code::Down(Key::Char('r')), - (None, 0x1F) => Code::Down(Key::Char('s')), - (None, 0x14) => Code::Down(Key::Char('t')), - (None, 0x16) => Code::Down(Key::Char('u')), - (None, 0x2F) => Code::Down(Key::Char('v')), - (None, 0x11) => Code::Down(Key::Char('w')), - (None, 0x2D) => Code::Down(Key::Char('x')), - (None, 0x15) => Code::Down(Key::Char('y')), - (None, 0x2C) => Code::Down(Key::Char('z')), - (None, 0x0B) => Code::Down(Key::Char('0')), - (None, 0x02) => Code::Down(Key::Char('1')), - (None, 0x03) => Code::Down(Key::Char('2')), - (None, 0x04) => Code::Down(Key::Char('3')), - (None, 0x05) => Code::Down(Key::Char('4')), - (None, 0x06) => Code::Down(Key::Char('5')), - (None, 0x07) => Code::Down(Key::Char('6')), - (None, 0x08) => Code::Down(Key::Char('7')), - (None, 0x09) => Code::Down(Key::Char('8')), - (None, 0x0A) => Code::Down(Key::Char('9')), - (None, 0x29) => Code::Down(Key::Char('`')), - (None, 0x0C) => Code::Down(Key::Char('-')), - (None, 0x0D) => Code::Down(Key::Char('=')), - (None, 0x2B) => Code::Down(Key::Char('\\')), - (None, 0x1A) => Code::Down(Key::Char('[')), - (None, 0x34) => Code::Down(Key::Char('.')), - (None, 0x35) => Code::Down(Key::Char('/')), - (None, 0x1B) => Code::Down(Key::Char(']')), - (None, 0x27) => Code::Down(Key::Char(';')), - (None, 0x28) => Code::Down(Key::Char('\'')), - (None, 0x33) => Code::Down(Key::Char(',')), - (None, 0x1C) => Code::Down(Key::Char('\n')), - (None, 0x39) => Code::Down(Key::Char(' ')), - (None, 0x0F) => Code::Down(Key::Char('\t')), - (None, 0x0E) => Code::Down(Key::BackSpace), - (None, 0x9E) => Code::Up(Key::Char('a')), - (None, 0xB0) => Code::Up(Key::Char('b')), - (None, 0xAE) => Code::Up(Key::Char('c')), - (None, 0xA0) => Code::Up(Key::Char('d')), - (None, 0x92) => Code::Up(Key::Char('e')), - (None, 0xA1) => Code::Up(Key::Char('f')), - (None, 0xA2) => Code::Up(Key::Char('g')), - (None, 0xA3) => Code::Up(Key::Char('h')), - (None, 0x97) => Code::Up(Key::Char('i')), - (None, 0xA4) => Code::Up(Key::Char('j')), - (None, 0xA5) => Code::Up(Key::Char('k')), - (None, 0xA6) => Code::Up(Key::Char('l')), - (None, 0xB2) => Code::Up(Key::Char('m')), - (None, 0xB1) => Code::Up(Key::Char('n')), - (None, 0x98) => Code::Up(Key::Char('o')), - (None, 0x99) => Code::Up(Key::Char('p')), - (None, 0x90) => Code::Up(Key::Char('q')), - (None, 0x93) => Code::Up(Key::Char('r')), - (None, 0x9F) => Code::Up(Key::Char('s')), - (None, 0x94) => Code::Up(Key::Char('t')), - (None, 0x96) => Code::Up(Key::Char('u')), - (None, 0xAF) => Code::Up(Key::Char('v')), - (None, 0x91) => Code::Up(Key::Char('w')), - (None, 0xAD) => Code::Up(Key::Char('x')), - (None, 0x95) => Code::Up(Key::Char('y')), - (None, 0xAC) => Code::Up(Key::Char('z')), - (None, 0x8B) => Code::Up(Key::Char('0')), - (None, 0x82) => Code::Up(Key::Char('1')), - (None, 0x83) => Code::Up(Key::Char('2')), - (None, 0x84) => Code::Up(Key::Char('3')), - (None, 0x85) => Code::Up(Key::Char('4')), - (None, 0x86) => Code::Up(Key::Char('5')), - (None, 0x87) => Code::Up(Key::Char('6')), - (None, 0x88) => Code::Up(Key::Char('7')), - (None, 0x89) => Code::Up(Key::Char('8')), - (None, 0x8A) => Code::Up(Key::Char('9')), - (None, 0xA9) => Code::Up(Key::Char('`')), - (None, 0x8C) => Code::Up(Key::Char('-')), - (None, 0x8D) => Code::Up(Key::Char('=')), - (None, 0xAB) => Code::Up(Key::Char('\\')), - (None, 0x9A) => Code::Up(Key::Char('[')), - (None, 0xB4) => Code::Up(Key::Char('.')), - (None, 0xB5) => Code::Up(Key::Char('/')), - (None, 0x9B) => Code::Up(Key::Char(']')), - (None, 0xA7) => Code::Up(Key::Char(';')), - (None, 0xA8) => Code::Up(Key::Char('\'')), - (None, 0xB3) => Code::Up(Key::Char(',')), - (None, 0x9C) => Code::Up(Key::Char('\n')), - (None, 0xB9) => Code::Up(Key::Char(' ')), - (None, 0x8F) => Code::Up(Key::Char('\t')), - (None, 0x8E) => Code::Up(Key::BackSpace), - _ => Err(KeyParseErr::UnknownCode(scan_code))?, - }; - Ok(code) - } } #[derive(Debug, Clone, Copy)] pub enum Code { Down(Key), Up(Key), - Control, } #[derive(Debug, Clone, Copy)] pub enum Key { Char(char), + Fun(u8), BackSpace, + Insert, + Home, + PageUp, + Delete, + End, + Escape, + PageDown, + ArrowUp, + ArrowLeft, + ArrowDown, + ArrowRight, + ShiftLeft, + ShiftRight, + CtrlLeft, + CtrlRight, + AltLeft, + AltRight, } -#[derive(Debug, Clone, Copy)] -pub enum KeyParseErr { - UnknownCode(u8), +#[derive(Debug, Default)] +pub struct KeyModState { + ctrl: bool, + shift: bool, + alt: bool, +} + +impl KeyModState { + pub fn translate(&mut self, keymap: &impl KeyMap, key: Code) -> Code { + self.update(key); + match key { + Code::Down(Key::Char(c)) => Code::Down(Key::Char(keymap.apply_mod(c, &self))), + Code::Up(Key::Char(c)) => Code::Up(Key::Char(keymap.apply_mod(c, &self))), + _ => key, + } + } + + fn update(&mut self, key: Code) { + match key { + Code::Down(Key::AltLeft) => self.alt = true, + Code::Down(Key::AltRight) => self.alt = true, + Code::Down(Key::CtrlLeft) => self.ctrl = true, + Code::Down(Key::CtrlRight) => self.ctrl = true, + Code::Down(Key::ShiftLeft) => self.shift = true, + Code::Down(Key::ShiftRight) => self.shift = true, + Code::Up(Key::AltLeft) => self.alt = false, + Code::Up(Key::AltRight) => self.alt = false, + Code::Up(Key::CtrlLeft) => self.ctrl = false, + Code::Up(Key::CtrlRight) => self.ctrl = false, + Code::Up(Key::ShiftLeft) => self.shift = false, + Code::Up(Key::ShiftRight) => self.shift = false, + _ => (), + } + } +} + +pub enum KeyMapRes { + Ok(Code), + Partial, + Unknown, +} + +pub trait KeyMap { + fn parse(&mut self, scan_code: u8) -> KeyMapRes; + fn apply_mod(&self, key: char, _state: &KeyModState) -> char { + key + } +} + +#[derive(Debug, Default, Clone)] +pub struct Qwerty { + lasts: ArrayQueue, +} + +impl KeyMap for Qwerty { + fn parse(&mut self, scan_code: u8) -> KeyMapRes { + use Code::*; + use KeyMapRes::*; + self.lasts.add(scan_code); + let res = match *self.lasts.content() { + [Some(0x1E), None, _, _] => Ok(Down(Key::Char('a'))), + [Some(0x30), None, _, _] => Ok(Down(Key::Char('b'))), + [Some(0x2E), None, _, _] => Ok(Down(Key::Char('c'))), + [Some(0x20), None, _, _] => Ok(Down(Key::Char('d'))), + [Some(0x12), None, _, _] => Ok(Down(Key::Char('e'))), + [Some(0x21), None, _, _] => Ok(Down(Key::Char('f'))), + [Some(0x22), None, _, _] => Ok(Down(Key::Char('g'))), + [Some(0x23), None, _, _] => Ok(Down(Key::Char('h'))), + [Some(0x17), None, _, _] => Ok(Down(Key::Char('i'))), + [Some(0x24), None, _, _] => Ok(Down(Key::Char('j'))), + [Some(0x25), None, _, _] => Ok(Down(Key::Char('k'))), + [Some(0x26), None, _, _] => Ok(Down(Key::Char('l'))), + [Some(0x32), None, _, _] => Ok(Down(Key::Char('m'))), + [Some(0x31), None, _, _] => Ok(Down(Key::Char('n'))), + [Some(0x18), None, _, _] => Ok(Down(Key::Char('o'))), + [Some(0x19), None, _, _] => Ok(Down(Key::Char('p'))), + [Some(0x10), None, _, _] => Ok(Down(Key::Char('q'))), + [Some(0x13), None, _, _] => Ok(Down(Key::Char('r'))), + [Some(0x1F), None, _, _] => Ok(Down(Key::Char('s'))), + [Some(0x14), None, _, _] => Ok(Down(Key::Char('t'))), + [Some(0x16), None, _, _] => Ok(Down(Key::Char('u'))), + [Some(0x2F), None, _, _] => Ok(Down(Key::Char('v'))), + [Some(0x11), None, _, _] => Ok(Down(Key::Char('w'))), + [Some(0x2D), None, _, _] => Ok(Down(Key::Char('x'))), + [Some(0x15), None, _, _] => Ok(Down(Key::Char('y'))), + [Some(0x2C), None, _, _] => Ok(Down(Key::Char('z'))), + [Some(0x0B), None, _, _] => Ok(Down(Key::Char('0'))), + [Some(0x02), None, _, _] => Ok(Down(Key::Char('1'))), + [Some(0x03), None, _, _] => Ok(Down(Key::Char('2'))), + [Some(0x04), None, _, _] => Ok(Down(Key::Char('3'))), + [Some(0x05), None, _, _] => Ok(Down(Key::Char('4'))), + [Some(0x06), None, _, _] => Ok(Down(Key::Char('5'))), + [Some(0x07), None, _, _] => Ok(Down(Key::Char('6'))), + [Some(0x08), None, _, _] => Ok(Down(Key::Char('7'))), + [Some(0x09), None, _, _] => Ok(Down(Key::Char('8'))), + [Some(0x0A), None, _, _] => Ok(Down(Key::Char('9'))), + [Some(0x29), None, _, _] => Ok(Down(Key::Char('`'))), + [Some(0x0C), None, _, _] => Ok(Down(Key::Char('-'))), + [Some(0x0D), None, _, _] => Ok(Down(Key::Char('='))), + [Some(0x2B), None, _, _] => Ok(Down(Key::Char('\\'))), + [Some(0x1A), None, _, _] => Ok(Down(Key::Char('['))), + [Some(0x34), None, _, _] => Ok(Down(Key::Char('.'))), + [Some(0x35), None, _, _] => Ok(Down(Key::Char('/'))), + [Some(0x1B), None, _, _] => Ok(Down(Key::Char(']'))), + [Some(0x27), None, _, _] => Ok(Down(Key::Char(';'))), + [Some(0x28), None, _, _] => Ok(Down(Key::Char('\''))), + [Some(0x33), None, _, _] => Ok(Down(Key::Char(','))), + [Some(0x1C), None, _, _] => Ok(Down(Key::Char('\n'))), + [Some(0x39), None, _, _] => Ok(Down(Key::Char(' '))), + [Some(0x0F), None, _, _] => Ok(Down(Key::Char('\t'))), + [Some(0x0E), None, _, _] => Ok(Down(Key::BackSpace)), + [Some(0x01), None, _, _] => Ok(Down(Key::Escape)), + [Some(0x2A), None, _, _] => Ok(Down(Key::ShiftLeft)), + [Some(0x1D), None, _, _] => Ok(Down(Key::CtrlLeft)), + [Some(0x38), None, _, _] => Ok(Down(Key::AltLeft)), + [Some(0x36), None, _, _] => Ok(Down(Key::ShiftRight)), + [Some(0x50), None, _, _] => Ok(Down(Key::Char('2'))), // KeyPad variant + [Some(0x51), None, _, _] => Ok(Down(Key::Char('3'))), // KeyPad variant + [Some(0x4B), None, _, _] => Ok(Down(Key::Char('4'))), // KeyPad variant + [Some(0x4C), None, _, _] => Ok(Down(Key::Char('5'))), // KeyPad variant + [Some(0x4D), None, _, _] => Ok(Down(Key::Char('6'))), // KeyPad variant + [Some(0x47), None, _, _] => Ok(Down(Key::Char('7'))), // KeyPad variant + [Some(0x48), None, _, _] => Ok(Down(Key::Char('8'))), // KeyPad variant + [Some(0x49), None, _, _] => Ok(Down(Key::Char('9'))), // KeyPad variant + [Some(0x37), None, _, _] => Ok(Down(Key::Char('*'))), // KeyPad variant + [Some(0x4A), None, _, _] => Ok(Down(Key::Char('-'))), // KeyPad variant + [Some(0x4E), None, _, _] => Ok(Down(Key::Char('+'))), // KeyPad variant + [Some(0x53), None, _, _] => Ok(Down(Key::Char('.'))), // KeyPad variant + [Some(0x52), None, _, _] => Ok(Down(Key::Char('0'))), // KeyPad variant + [Some(0x4F), None, _, _] => Ok(Down(Key::Char('1'))), // KeyPad variant + [Some(0x3B), None, _, _] => Ok(Down(Key::Fun(1))), + [Some(0x3C), None, _, _] => Ok(Down(Key::Fun(2))), + [Some(0x3D), None, _, _] => Ok(Down(Key::Fun(3))), + [Some(0x3E), None, _, _] => Ok(Down(Key::Fun(4))), + [Some(0x3F), None, _, _] => Ok(Down(Key::Fun(5))), + [Some(0x40), None, _, _] => Ok(Down(Key::Fun(6))), + [Some(0x41), None, _, _] => Ok(Down(Key::Fun(7))), + [Some(0x42), None, _, _] => Ok(Down(Key::Fun(8))), + [Some(0x43), None, _, _] => Ok(Down(Key::Fun(9))), + [Some(0x44), None, _, _] => Ok(Down(Key::Fun(10))), + [Some(0x57), None, _, _] => Ok(Down(Key::Fun(11))), + [Some(0x58), None, _, _] => Ok(Down(Key::Fun(12))), + [Some(0x9E), None, _, _] => Ok(Up(Key::Char('a'))), + [Some(0xB0), None, _, _] => Ok(Up(Key::Char('b'))), + [Some(0xAE), None, _, _] => Ok(Up(Key::Char('c'))), + [Some(0xA0), None, _, _] => Ok(Up(Key::Char('d'))), + [Some(0x92), None, _, _] => Ok(Up(Key::Char('e'))), + [Some(0xA1), None, _, _] => Ok(Up(Key::Char('f'))), + [Some(0xA2), None, _, _] => Ok(Up(Key::Char('g'))), + [Some(0xA3), None, _, _] => Ok(Up(Key::Char('h'))), + [Some(0x97), None, _, _] => Ok(Up(Key::Char('i'))), + [Some(0xA4), None, _, _] => Ok(Up(Key::Char('j'))), + [Some(0xA5), None, _, _] => Ok(Up(Key::Char('k'))), + [Some(0xA6), None, _, _] => Ok(Up(Key::Char('l'))), + [Some(0xB2), None, _, _] => Ok(Up(Key::Char('m'))), + [Some(0xB1), None, _, _] => Ok(Up(Key::Char('n'))), + [Some(0x98), None, _, _] => Ok(Up(Key::Char('o'))), + [Some(0x99), None, _, _] => Ok(Up(Key::Char('p'))), + [Some(0x90), None, _, _] => Ok(Up(Key::Char('q'))), + [Some(0x93), None, _, _] => Ok(Up(Key::Char('r'))), + [Some(0x9F), None, _, _] => Ok(Up(Key::Char('s'))), + [Some(0x94), None, _, _] => Ok(Up(Key::Char('t'))), + [Some(0x96), None, _, _] => Ok(Up(Key::Char('u'))), + [Some(0xAF), None, _, _] => Ok(Up(Key::Char('v'))), + [Some(0x91), None, _, _] => Ok(Up(Key::Char('w'))), + [Some(0xAD), None, _, _] => Ok(Up(Key::Char('x'))), + [Some(0x95), None, _, _] => Ok(Up(Key::Char('y'))), + [Some(0xAC), None, _, _] => Ok(Up(Key::Char('z'))), + [Some(0x8B), None, _, _] => Ok(Up(Key::Char('0'))), + [Some(0x82), None, _, _] => Ok(Up(Key::Char('1'))), + [Some(0x83), None, _, _] => Ok(Up(Key::Char('2'))), + [Some(0x84), None, _, _] => Ok(Up(Key::Char('3'))), + [Some(0x85), None, _, _] => Ok(Up(Key::Char('4'))), + [Some(0x86), None, _, _] => Ok(Up(Key::Char('5'))), + [Some(0x87), None, _, _] => Ok(Up(Key::Char('6'))), + [Some(0x88), None, _, _] => Ok(Up(Key::Char('7'))), + [Some(0x89), None, _, _] => Ok(Up(Key::Char('8'))), + [Some(0x8A), None, _, _] => Ok(Up(Key::Char('9'))), + [Some(0xA9), None, _, _] => Ok(Up(Key::Char('`'))), + [Some(0x8C), None, _, _] => Ok(Up(Key::Char('-'))), + [Some(0x8D), None, _, _] => Ok(Up(Key::Char('='))), + [Some(0xAB), None, _, _] => Ok(Up(Key::Char('\\'))), + [Some(0x9A), None, _, _] => Ok(Up(Key::Char('['))), + [Some(0xB4), None, _, _] => Ok(Up(Key::Char('.'))), + [Some(0xB5), None, _, _] => Ok(Up(Key::Char('/'))), + [Some(0x9B), None, _, _] => Ok(Up(Key::Char(']'))), + [Some(0xA7), None, _, _] => Ok(Up(Key::Char(';'))), + [Some(0xA8), None, _, _] => Ok(Up(Key::Char('\''))), + [Some(0xB3), None, _, _] => Ok(Up(Key::Char(','))), + [Some(0x9C), None, _, _] => Ok(Up(Key::Char('\n'))), + [Some(0xB9), None, _, _] => Ok(Up(Key::Char(' '))), + [Some(0x8F), None, _, _] => Ok(Up(Key::Char('\t'))), + [Some(0x8E), None, _, _] => Ok(Up(Key::BackSpace)), + [Some(0x81), None, _, _] => Ok(Up(Key::Escape)), + [Some(0xAA), None, _, _] => Ok(Up(Key::ShiftLeft)), + [Some(0x9D), None, _, _] => Ok(Up(Key::CtrlLeft)), + [Some(0xB8), None, _, _] => Ok(Up(Key::AltLeft)), + [Some(0xB6), None, _, _] => Ok(Up(Key::ShiftRight)), + [Some(0xD0), None, _, _] => Ok(Up(Key::Char('2'))), // KeyPad variant + [Some(0xD1), None, _, _] => Ok(Up(Key::Char('3'))), // KeyPad variant + [Some(0xCB), None, _, _] => Ok(Up(Key::Char('4'))), // KeyPad variant + [Some(0xCC), None, _, _] => Ok(Up(Key::Char('5'))), // KeyPad variant + [Some(0xCD), None, _, _] => Ok(Up(Key::Char('6'))), // KeyPad variant + [Some(0xC7), None, _, _] => Ok(Up(Key::Char('7'))), // KeyPad variant + [Some(0xC8), None, _, _] => Ok(Up(Key::Char('8'))), // KeyPad variant + [Some(0xC9), None, _, _] => Ok(Up(Key::Char('9'))), // KeyPad variant + [Some(0xB7), None, _, _] => Ok(Up(Key::Char('*'))), // KeyPad variant + [Some(0xCA), None, _, _] => Ok(Up(Key::Char('-'))), // KeyPad variant + [Some(0xCE), None, _, _] => Ok(Up(Key::Char('+'))), // KeyPad variant + [Some(0xD3), None, _, _] => Ok(Up(Key::Char('.'))), // KeyPad variant + [Some(0xD2), None, _, _] => Ok(Up(Key::Char('0'))), // KeyPad variant + [Some(0xCF), None, _, _] => Ok(Up(Key::Char('1'))), // KeyPad variant + [Some(0xBB), None, _, _] => Ok(Up(Key::Fun(1))), + [Some(0xBC), None, _, _] => Ok(Up(Key::Fun(2))), + [Some(0xBD), None, _, _] => Ok(Up(Key::Fun(3))), + [Some(0xBE), None, _, _] => Ok(Up(Key::Fun(4))), + [Some(0xBF), None, _, _] => Ok(Up(Key::Fun(5))), + [Some(0xC0), None, _, _] => Ok(Up(Key::Fun(6))), + [Some(0xC1), None, _, _] => Ok(Up(Key::Fun(7))), + [Some(0xC2), None, _, _] => Ok(Up(Key::Fun(8))), + [Some(0xC3), None, _, _] => Ok(Up(Key::Fun(9))), + [Some(0xC4), None, _, _] => Ok(Up(Key::Fun(10))), + [Some(0xD7), None, _, _] => Ok(Up(Key::Fun(11))), + [Some(0xD8), None, _, _] => Ok(Up(Key::Fun(12))), + [Some(0xE0), None, _, _] => KeyMapRes::Partial, + [Some(0x35), Some(0xE0), None, _] => Ok(Down(Key::Char('/'))), // KeyPad variant + [Some(0x52), Some(0xE0), None, _] => Ok(Down(Key::Insert)), + [Some(0x47), Some(0xE0), None, _] => Ok(Down(Key::Home)), + [Some(0x49), Some(0xE0), None, _] => Ok(Down(Key::PageUp)), + [Some(0x53), Some(0xE0), None, _] => Ok(Down(Key::Delete)), + [Some(0x4F), Some(0xE0), None, _] => Ok(Down(Key::End)), + [Some(0x51), Some(0xE0), None, _] => Ok(Down(Key::PageDown)), + [Some(0x48), Some(0xE0), None, _] => Ok(Down(Key::ArrowUp)), + [Some(0x4B), Some(0xE0), None, _] => Ok(Down(Key::ArrowLeft)), + [Some(0x50), Some(0xE0), None, _] => Ok(Down(Key::ArrowDown)), + [Some(0x4D), Some(0xE0), None, _] => Ok(Down(Key::ArrowRight)), + [Some(0x1D), Some(0xE0), None, _] => Ok(Down(Key::CtrlRight)), + [Some(0x38), Some(0xE0), None, _] => Ok(Down(Key::AltRight)), + [Some(0xB5), Some(0xE0), None, _] => Ok(Up(Key::Char('/'))), // KeyPad variant + [Some(0xD2), Some(0xE0), None, _] => Ok(Up(Key::Insert)), + [Some(0x97), Some(0xE0), None, _] => Ok(Up(Key::Home)), + [Some(0xC9), Some(0xE0), None, _] => Ok(Up(Key::PageUp)), + [Some(0xD3), Some(0xE0), None, _] => Ok(Up(Key::Delete)), + [Some(0xCF), Some(0xE0), None, _] => Ok(Up(Key::End)), + [Some(0xD1), Some(0xE0), None, _] => Ok(Up(Key::PageDown)), + [Some(0xC8), Some(0xE0), None, _] => Ok(Up(Key::ArrowUp)), + [Some(0xCB), Some(0xE0), None, _] => Ok(Up(Key::ArrowLeft)), + [Some(0xD0), Some(0xE0), None, _] => Ok(Up(Key::ArrowDown)), + [Some(0xCD), Some(0xE0), None, _] => Ok(Up(Key::ArrowRight)), + [Some(0x9D), Some(0xE0), None, _] => Ok(Up(Key::CtrlRight)), + [Some(0xB8), Some(0xE0), None, _] => Ok(Up(Key::AltRight)), + _ => KeyMapRes::Unknown, + }; + + if let KeyMapRes::Ok(_) | KeyMapRes::Unknown = res { + self.lasts.flush(); + } + + res + } + + fn apply_mod(&self, key: char, state: &KeyModState) -> char { + match key { + '0' if state.shift => ')', + '1' if state.shift => '!', + '2' if state.shift => '@', + '3' if state.shift => '#', + '4' if state.shift => '$', + '5' if state.shift => '%', + '6' if state.shift => '^', + '7' if state.shift => '&', + '8' if state.shift => '*', + '9' if state.shift => '(', + '`' if state.shift => '~', + '-' if state.shift => '_', + '=' if state.shift => '+', + '[' if state.shift => '{', + ']' if state.shift => '}', + '\\' if state.shift => '|', + ';' if state.shift => ':', + '\'' if state.shift => '"', + ',' if state.shift => '<', + '.' if state.shift => '>', + '/' if state.shift => '?', + c if state.shift && c.is_alphabetic() => c.to_uppercase().next().unwrap(), + _ => key, + } + } } /* @@ -276,3 +471,276 @@ KP_0 52 D2 KP_1 4F CF */ + +#[derive(Debug, Default, Clone)] +pub struct Azerty { + lasts: ArrayQueue, +} + +impl KeyMap for Azerty { + fn parse(&mut self, scan_code: u8) -> KeyMapRes { + use Code::*; + use KeyMapRes::*; + self.lasts.add(scan_code); + let res = match *self.lasts.content() { + [Some(0x0B), None, _, _] => Ok(Down(Key::Char('à'))), + [Some(0x02), None, _, _] => Ok(Down(Key::Char('&'))), + [Some(0x03), None, _, _] => Ok(Down(Key::Char('é'))), + [Some(0x04), None, _, _] => Ok(Down(Key::Char('"'))), + [Some(0x05), None, _, _] => Ok(Down(Key::Char('\''))), + [Some(0x06), None, _, _] => Ok(Down(Key::Char('('))), + [Some(0x07), None, _, _] => Ok(Down(Key::Char('-'))), + [Some(0x08), None, _, _] => Ok(Down(Key::Char('è'))), + [Some(0x09), None, _, _] => Ok(Down(Key::Char('_'))), + [Some(0x0A), None, _, _] => Ok(Down(Key::Char('ç'))), + + [Some(0x8B), None, _, _] => Ok(Up(Key::Char('à'))), + [Some(0x82), None, _, _] => Ok(Up(Key::Char('&'))), + [Some(0x83), None, _, _] => Ok(Up(Key::Char('é'))), + [Some(0x84), None, _, _] => Ok(Up(Key::Char('"'))), + [Some(0x85), None, _, _] => Ok(Up(Key::Char('\''))), + [Some(0x86), None, _, _] => Ok(Up(Key::Char('('))), + [Some(0x87), None, _, _] => Ok(Up(Key::Char('-'))), + [Some(0x88), None, _, _] => Ok(Up(Key::Char('è'))), + [Some(0x89), None, _, _] => Ok(Up(Key::Char('_'))), + [Some(0x8A), None, _, _] => Ok(Up(Key::Char('ç'))), + + [Some(1), None, _, _] => Ok(Down(Key::Escape)), + [Some(129), None, _, _] => Ok(Up(Key::Escape)), + [Some(14), None, _, _] => Ok(Down(Key::BackSpace)), + [Some(142), None, _, _] => Ok(Up(Key::BackSpace)), + // [Some(111), None, _, _] => Ok(Down(Key::BackSpace)), + // [Some(239), None, _, _] => Ok(Up(Key::BackSpace)), + [Some(12), None, _, _] => Ok(Down(Key::Char(')'))), + [Some(140), None, _, _] => Ok(Up(Key::Char(')'))), + [Some(13), None, _, _] => Ok(Down(Key::Char('='))), + [Some(141), None, _, _] => Ok(Up(Key::Char('='))), + [Some(15), None, _, _] => Ok(Down(Key::Char('\t'))), + [Some(143), None, _, _] => Ok(Up(Key::Char('\t'))), + [Some(16), None, _, _] => Ok(Down(Key::Char('a'))), + [Some(144), None, _, _] => Ok(Up(Key::Char('a'))), + [Some(17), None, _, _] => Ok(Down(Key::Char('z'))), + [Some(145), None, _, _] => Ok(Up(Key::Char('z'))), + [Some(18), None, _, _] => Ok(Down(Key::Char('e'))), + [Some(146), None, _, _] => Ok(Up(Key::Char('e'))), + [Some(19), None, _, _] => Ok(Down(Key::Char('r'))), + [Some(147), None, _, _] => Ok(Up(Key::Char('r'))), + [Some(20), None, _, _] => Ok(Down(Key::Char('t'))), + [Some(148), None, _, _] => Ok(Up(Key::Char('t'))), + [Some(21), None, _, _] => Ok(Down(Key::Char('y'))), + [Some(149), None, _, _] => Ok(Up(Key::Char('y'))), + [Some(22), None, _, _] => Ok(Down(Key::Char('u'))), + [Some(150), None, _, _] => Ok(Up(Key::Char('u'))), + [Some(23), None, _, _] => Ok(Down(Key::Char('i'))), + [Some(151), None, _, _] => Ok(Up(Key::Char('i'))), + [Some(24), None, _, _] => Ok(Down(Key::Char('o'))), + [Some(152), None, _, _] => Ok(Up(Key::Char('o'))), + [Some(25), None, _, _] => Ok(Down(Key::Char('p'))), + [Some(153), None, _, _] => Ok(Up(Key::Char('p'))), + [Some(27), None, _, _] => Ok(Down(Key::Char('$'))), + [Some(155), None, _, _] => Ok(Up(Key::Char('$'))), + [Some(28), None, _, _] => Ok(Down(Key::Char('\n'))), + [Some(156), None, _, _] => Ok(Up(Key::Char('\n'))), + [Some(29), None, _, _] => Ok(Down(Key::CtrlLeft)), + [Some(157), None, _, _] => Ok(Up(Key::CtrlLeft)), + [Some(30), None, _, _] => Ok(Down(Key::Char('q'))), + [Some(158), None, _, _] => Ok(Up(Key::Char('q'))), + [Some(31), None, _, _] => Ok(Down(Key::Char('s'))), + [Some(159), None, _, _] => Ok(Up(Key::Char('s'))), + [Some(32), None, _, _] => Ok(Down(Key::Char('d'))), + [Some(160), None, _, _] => Ok(Up(Key::Char('d'))), + [Some(33), None, _, _] => Ok(Down(Key::Char('f'))), + [Some(161), None, _, _] => Ok(Up(Key::Char('f'))), + [Some(34), None, _, _] => Ok(Down(Key::Char('g'))), + [Some(162), None, _, _] => Ok(Up(Key::Char('g'))), + [Some(35), None, _, _] => Ok(Down(Key::Char('h'))), + [Some(163), None, _, _] => Ok(Up(Key::Char('h'))), + [Some(36), None, _, _] => Ok(Down(Key::Char('j'))), + [Some(164), None, _, _] => Ok(Up(Key::Char('j'))), + [Some(37), None, _, _] => Ok(Down(Key::Char('k'))), + [Some(165), None, _, _] => Ok(Up(Key::Char('k'))), + [Some(38), None, _, _] => Ok(Down(Key::Char('l'))), + [Some(166), None, _, _] => Ok(Up(Key::Char('l'))), + [Some(39), None, _, _] => Ok(Down(Key::Char('m'))), + [Some(167), None, _, _] => Ok(Up(Key::Char('m'))), + [Some(41), None, _, _] => Ok(Down(Key::Char('*'))), + [Some(169), None, _, _] => Ok(Up(Key::Char('*'))), + [Some(42), None, _, _] => Ok(Down(Key::ShiftLeft)), + [Some(170), None, _, _] => Ok(Up(Key::ShiftLeft)), + [Some(43), None, _, _] => Ok(Down(Key::Char('*'))), + [Some(171), None, _, _] => Ok(Up(Key::Char('*'))), + [Some(44), None, _, _] => Ok(Down(Key::Char('w'))), + [Some(172), None, _, _] => Ok(Up(Key::Char('w'))), + [Some(45), None, _, _] => Ok(Down(Key::Char('x'))), + [Some(173), None, _, _] => Ok(Up(Key::Char('x'))), + [Some(46), None, _, _] => Ok(Down(Key::Char('c'))), + [Some(174), None, _, _] => Ok(Up(Key::Char('c'))), + [Some(47), None, _, _] => Ok(Down(Key::Char('v'))), + [Some(175), None, _, _] => Ok(Up(Key::Char('v'))), + [Some(48), None, _, _] => Ok(Down(Key::Char('b'))), + [Some(176), None, _, _] => Ok(Up(Key::Char('b'))), + [Some(49), None, _, _] => Ok(Down(Key::Char('n'))), + [Some(177), None, _, _] => Ok(Up(Key::Char('n'))), + [Some(50), None, _, _] => Ok(Down(Key::Char(','))), + [Some(178), None, _, _] => Ok(Up(Key::Char(','))), + [Some(51), None, _, _] => Ok(Down(Key::Char(';'))), + [Some(179), None, _, _] => Ok(Up(Key::Char(';'))), + [Some(52), None, _, _] => Ok(Down(Key::Char(':'))), + [Some(180), None, _, _] => Ok(Up(Key::Char(':'))), + [Some(53), None, _, _] => Ok(Down(Key::Char('!'))), + [Some(181), None, _, _] => Ok(Up(Key::Char('!'))), + [Some(54), None, _, _] => Ok(Down(Key::ShiftRight)), + [Some(182), None, _, _] => Ok(Up(Key::ShiftRight)), + [Some(55), None, _, _] => Ok(Down(Key::Char('*'))), // Keypad Variant + [Some(183), None, _, _] => Ok(Up(Key::Char('*'))), // Keypad Variant + [Some(56), None, _, _] => Ok(Down(Key::AltLeft)), + [Some(184), None, _, _] => Ok(Up(Key::AltLeft)), + [Some(57), None, _, _] => Ok(Down(Key::Char(' '))), + [Some(185), None, _, _] => Ok(Up(Key::Char(' '))), + [Some(59), None, _, _] => Ok(Down(Key::Fun(1))), + [Some(187), None, _, _] => Ok(Up(Key::Fun(1))), + [Some(60), None, _, _] => Ok(Down(Key::Fun(2))), + [Some(188), None, _, _] => Ok(Up(Key::Fun(2))), + [Some(61), None, _, _] => Ok(Down(Key::Fun(3))), + [Some(189), None, _, _] => Ok(Up(Key::Fun(3))), + [Some(62), None, _, _] => Ok(Down(Key::Fun(4))), + [Some(190), None, _, _] => Ok(Up(Key::Fun(4))), + [Some(63), None, _, _] => Ok(Down(Key::Fun(5))), + [Some(191), None, _, _] => Ok(Up(Key::Fun(5))), + [Some(64), None, _, _] => Ok(Down(Key::Fun(6))), + [Some(192), None, _, _] => Ok(Up(Key::Fun(6))), + [Some(65), None, _, _] => Ok(Down(Key::Fun(7))), + [Some(193), None, _, _] => Ok(Up(Key::Fun(7))), + [Some(66), None, _, _] => Ok(Down(Key::Fun(8))), + [Some(194), None, _, _] => Ok(Up(Key::Fun(8))), + [Some(67), None, _, _] => Ok(Down(Key::Fun(9))), + [Some(195), None, _, _] => Ok(Up(Key::Fun(9))), + [Some(68), None, _, _] => Ok(Down(Key::Fun(10))), + [Some(196), None, _, _] => Ok(Up(Key::Fun(10))), + [Some(71), None, _, _] => Ok(Down(Key::Char('7'))), // Keypad Variant + [Some(199), None, _, _] => Ok(Up(Key::Char('7'))), // Keypad Variant + [Some(72), None, _, _] => Ok(Down(Key::Char('8'))), // Keypad Variant + [Some(200), None, _, _] => Ok(Up(Key::Char('8'))), // Keypad Variant + [Some(73), None, _, _] => Ok(Down(Key::Char('9'))), // Keypad Variant + [Some(201), None, _, _] => Ok(Up(Key::Char('9'))), // Keypad Variant + [Some(75), None, _, _] => Ok(Down(Key::Char('4'))), // Keypad Variant + [Some(203), None, _, _] => Ok(Up(Key::Char('4'))), // Keypad Variant + [Some(76), None, _, _] => Ok(Down(Key::Char('5'))), // Keypad Variant + [Some(204), None, _, _] => Ok(Up(Key::Char('5'))), // Keypad Variant + [Some(77), None, _, _] => Ok(Down(Key::Char('6'))), // Keypad Variant + [Some(205), None, _, _] => Ok(Up(Key::Char('6'))), // Keypad Variant + [Some(80), None, _, _] => Ok(Down(Key::Char('2'))), // Keypad Variant + [Some(208), None, _, _] => Ok(Up(Key::Char('2'))), // Keypad Variant + [Some(81), None, _, _] => Ok(Down(Key::Char('3'))), // Keypad Variant + [Some(209), None, _, _] => Ok(Up(Key::Char('3'))), // Keypad Variant + [Some(82), None, _, _] => Ok(Down(Key::Char('0'))), // Keypad Variant + [Some(210), None, _, _] => Ok(Up(Key::Char('0'))), // Keypad Variant + [Some(79), None, _, _] => Ok(Down(Key::Char('1'))), // Keypad Variant + [Some(207), None, _, _] => Ok(Up(Key::Char('1'))), // Keypad Variant + [Some(83), None, _, _] => Ok(Down(Key::Char('.'))), // Keypad Variant + [Some(211), None, _, _] => Ok(Up(Key::Char('.'))), // Keypad Variant + [Some(78), None, _, _] => Ok(Down(Key::Char('+'))), // Keypad Variant + [Some(206), None, _, _] => Ok(Up(Key::Char('+'))), // Keypad Variant + [Some(74), None, _, _] => Ok(Down(Key::Char('-'))), // Keypad Variant + [Some(202), None, _, _] => Ok(Up(Key::Char('-'))), // Keypad Variant + [Some(86), None, _, _] => Ok(Down(Key::Char('<'))), // Keypad Variant + [Some(214), None, _, _] => Ok(Up(Key::Char('<'))), // Keypad Variant + [Some(87), None, _, _] => Ok(Down(Key::Fun(11))), + [Some(215), None, _, _] => Ok(Up(Key::Fun(11))), + [Some(88), None, _, _] => Ok(Down(Key::Fun(12))), + [Some(216), None, _, _] => Ok(Up(Key::Fun(12))), + [Some(96), None, _, _] => Ok(Down(Key::Char('\n'))), + [Some(224), None, _, _] => Ok(Up(Key::Char('\n'))), + [Some(98), None, _, _] => Ok(Down(Key::Char('/'))), // Keypad Variant + [Some(226), None, _, _] => Ok(Up(Key::Char('/'))), // Keypad Variant + // [Some(101), None, _, _] => Ok(Down(Key::Char('Break'))), + // [Some(101), None, _, _] => Ok(Down(Key::Char('Break'))), + // [Some(119), None, _, _] => Ok(Down(Key::Char('Pause'))), + // [Some(26), None, _, _] => Ok(Down(Key::Char('asciicircum'))), + // [Some(40), None, _, _] => Ok(Down(Key::Char('bar'))), + // [Some(58), None, _, _] => Ok(Down(Key::Char('Caps_Lock'))), + // [Some(69), None, _, _] => Ok(Down(Key::Char('Num_Lock'))), + // [Some(70), None, _, _] => Ok(Down(Key::Char('Scroll_Lock'))), + // [Some(84), None, _, _] => Ok(Down(Key::Char('Last_Console'))), + // [Some(84), None, _, _] => Ok(Down(Key::Char('Last_Console'))), + // [Some(99), None, _, _] => Ok(Down(Key::Char('Compose'))), + [Some(0x35), Some(0xE0), None, _] => Ok(Down(Key::Char('/'))), // KeyPad variant + [Some(0x52), Some(0xE0), None, _] => Ok(Down(Key::Insert)), + [Some(0x47), Some(0xE0), None, _] => Ok(Down(Key::Home)), + [Some(0x49), Some(0xE0), None, _] => Ok(Down(Key::PageUp)), + [Some(0x53), Some(0xE0), None, _] => Ok(Down(Key::Delete)), + [Some(0x4F), Some(0xE0), None, _] => Ok(Down(Key::End)), + [Some(0x51), Some(0xE0), None, _] => Ok(Down(Key::PageDown)), + [Some(0x48), Some(0xE0), None, _] => Ok(Down(Key::ArrowUp)), + [Some(0x4B), Some(0xE0), None, _] => Ok(Down(Key::ArrowLeft)), + [Some(0x50), Some(0xE0), None, _] => Ok(Down(Key::ArrowDown)), + [Some(0x4D), Some(0xE0), None, _] => Ok(Down(Key::ArrowRight)), + [Some(0x1D), Some(0xE0), None, _] => Ok(Down(Key::CtrlRight)), + [Some(0x38), Some(0xE0), None, _] => Ok(Down(Key::AltRight)), + [Some(0xB5), Some(0xE0), None, _] => Ok(Up(Key::Char('/'))), // KeyPad variant + [Some(0xD2), Some(0xE0), None, _] => Ok(Up(Key::Insert)), + [Some(0x97), Some(0xE0), None, _] => Ok(Up(Key::Home)), + [Some(0xC9), Some(0xE0), None, _] => Ok(Up(Key::PageUp)), + [Some(0xD3), Some(0xE0), None, _] => Ok(Up(Key::Delete)), + [Some(0xCF), Some(0xE0), None, _] => Ok(Up(Key::End)), + [Some(0xD1), Some(0xE0), None, _] => Ok(Up(Key::PageDown)), + [Some(0xC8), Some(0xE0), None, _] => Ok(Up(Key::ArrowUp)), + [Some(0xCB), Some(0xE0), None, _] => Ok(Up(Key::ArrowLeft)), + [Some(0xD0), Some(0xE0), None, _] => Ok(Up(Key::ArrowDown)), + [Some(0xCD), Some(0xE0), None, _] => Ok(Up(Key::ArrowRight)), + [Some(0x9D), Some(0xE0), None, _] => Ok(Up(Key::CtrlRight)), + [Some(0xB8), Some(0xE0), None, _] => Ok(Up(Key::AltRight)), + + _ => KeyMapRes::Unknown, + }; + + if let KeyMapRes::Ok(_) | KeyMapRes::Unknown = res { + self.lasts.flush(); + } + + res + } + + fn apply_mod(&self, key: char, state: &KeyModState) -> char { + match key { + 'à' if state.shift => '0', + '&' if state.shift => '1', + 'é' if state.shift => '2', + '"' if state.shift => '3', + '\'' if state.shift => '4', + '(' if state.shift => '5', + '-' if state.shift => '6', + 'è' if state.shift => '7', + '_' if state.shift => '8', + 'ç' if state.shift => '9', + '^' if state.shift => '¨', + '$' if state.shift => '£', + 'ù' if state.shift => '%', + '*' if state.shift => 'µ', + ')' if state.shift => '°', + '=' if state.shift => '+', + '<' if state.shift => '>', + ',' if state.shift => '?', + ';' if state.shift => '.', + ':' if state.shift => '/', + '!' if state.shift => '§', + '&' if state.alt => '¹', + 'é' if state.alt => '~', + '"' if state.alt => '#', + '\'' if state.alt => '{', + '(' if state.alt => '[', + '-' if state.alt => '|', + 'è' if state.alt => '`', + '_' if state.alt => '\\', + 'ç' if state.alt => '^', + 'à' if state.alt => '@', + ')' if state.alt => ']', + '=' if state.alt => '}', + '$' if state.alt => '¤', + + // '' if state.alt => '', + c if state.shift && c.is_alphabetic() => c.to_uppercase().next().unwrap(), + _ => key, + } + } +} diff --git a/src/program/shell.rs b/src/program/shell.rs index f610c61..1393b8c 100644 --- a/src/program/shell.rs +++ b/src/program/shell.rs @@ -1,42 +1,47 @@ -use core::mem; +use core::{cell::RefCell, mem}; -use alloc::{string::String, sync::Arc}; +use alloc::{ + rc::Rc, + string::{String, ToString}, + vec::Vec, +}; use blinkcast::alloc::channel; -use microlang::Context; -use spin::Mutex; +use microlang::eval::{Context, Scope, Value}; use crate::{ dev::console::out, - hard::keyboard::{keyboard, Code, Key}, + hard::keyboard::{keyboard, Azerty, Code, Key, KeyModState, Qwerty}, print, println, }; pub fn main() { - let (tx, mut rx) = channel(1024); + let keymap = Azerty::default(); - let buff = Arc::new(Mutex::new(String::new())); - keyboard().on_code(move |c| { - let mut buff = buff.lock(); - match c { - Code::Down(Key::Char(c)) => { - print!("{c}"); - if c == '\n' { - let mut new = String::new(); - mem::swap(&mut new, &mut buff); - tx.send(new); - } else { - buff.push(c); - } + let (tx, mut rx) = channel(1024); + let mut buff = String::new(); + let mut state = KeyModState::default(); + keyboard().keymap(keymap.clone()); + keyboard().on_code(move |c| match state.translate(&keymap, c) { + Code::Down(Key::Char(c)) => { + print!("{c}"); + if c == '\n' { + let mut new = String::new(); + mem::swap(&mut new, &mut buff); + tx.send(new); + } else { + buff.push(c); } - Code::Down(Key::BackSpace) => { - out().correct(); - buff.pop(); - } - _ => (), } + Code::Down(Key::BackSpace) => { + out().correct(); + buff.pop(); + } + _ => (), }); let mut context = Context::empty(); + microlang::prelude::prelude(&mut context); + prelude(&mut context); print!("> "); loop { @@ -49,3 +54,43 @@ pub fn main() { } } } + +fn prelude(context: &mut Context) { + context.define_built("out", |args, _ctx| { + let mut first = true; + for arg in args { + let str = arg.serialize(); + if first { + print!("{str}"); + first = false; + } else { + print!(" {str}"); + } + } + println!(); + Ok(Value::None) + }); + + context.define_built("env", |_args, ctx| { + fn rec(scope: &Scope) -> Vec<(String, String)> { + scope + .defs + .iter() + .map(|(key, value)| (key.to_string(), value.serialize())) + .chain( + scope + .parent + .clone() + .map(|p| rec(&p.borrow()).into_iter()) + .into_iter() + .flatten(), + ) + .collect() + } + let values = rec(&ctx.frame.borrow()) + .into_iter() + .map(|(n, v)| Value::array([Value::str(n), Value::str(v)].to_vec())) + .collect(); + Ok(Value::array(values)) + }); +} diff --git a/src/util.rs b/src/util.rs index 87c30af..af657bc 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,44 @@ +use core::mem; + #[allow(clippy::empty_loop)] pub fn spin() -> ! { loop {} } + +#[derive(Debug, Clone)] +pub struct ArrayQueue { + inner: [Option; N], +} + +impl ArrayQueue { + pub fn new() -> Self { + let inner = [const { None }; N]; + Self { inner } + } + + pub fn add(&mut self, item: T) -> Option { + let mut current = Some(item); + for i in 0..N { + mem::swap(&mut current, &mut self.inner[i]); + if current.is_none() { + break; + } + } + current + } + + pub fn content(&self) -> &[Option; N] { + &self.inner + } + + pub fn flush(&mut self) -> [Option; N] { + let other = [const { None }; N]; + mem::replace(&mut self.inner, other) + } +} + +impl Default for ArrayQueue { + fn default() -> Self { + Self::new() + } +}