add repl and support azerty

This commit is contained in:
Matthieu Jolimaitre 2024-10-26 16:43:59 +02:00
parent a2cca0be4e
commit 9ce30d2941
5 changed files with 703 additions and 150 deletions

2
Cargo.lock generated
View file

@ -192,7 +192,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "microlang" name = "microlang"
version = "0.1.0" 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 = [ dependencies = [
"chumsky", "chumsky",
"hashbrown 0.15.0", "hashbrown 0.15.0",

View file

@ -60,7 +60,7 @@ unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
} }
pub const HEAP_START: usize = 0x_4444_4444_0000; 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( pub fn init_heap(
mapper: &mut impl Mapper<Size4KiB>, mapper: &mut impl Mapper<Size4KiB>,

View file

@ -2,7 +2,7 @@ use alloc::boxed::Box;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use spin::{Mutex, MutexGuard}; use spin::{Mutex, MutexGuard};
use crate::println; use crate::{println, util::ArrayQueue};
pub fn keyboard<'r>() -> MutexGuard<'r, Keyboard> { pub fn keyboard<'r>() -> MutexGuard<'r, Keyboard> {
KEYBOARD.lock() KEYBOARD.lock()
@ -14,14 +14,18 @@ lazy_static! {
pub struct Keyboard { pub struct Keyboard {
on_code: Option<Box<dyn FnMut(Code) + Send>>, on_code: Option<Box<dyn FnMut(Code) + Send>>,
last: Option<Code>, keymap: Box<dyn KeyMap + Send>,
} }
impl Keyboard { impl Keyboard {
pub fn init() -> Self { pub fn init() -> Self {
let on_code = None; let on_code = None;
let last = None; let keymap = Box::new(Qwerty::default());
Self { on_code, last } 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) { 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) { pub fn record(&mut self, scan_code: u8) {
let code = self.parse(scan_code); match self.keymap.parse(scan_code) {
match code { KeyMapRes::Ok(c) if let Some(op) = self.on_code.as_mut() => op(c),
Err(err) => println!("Failed to record key : {err:?}"), KeyMapRes::Ok(c) => println!("Ignoring {c:?}"),
Ok(Code::Control) => self.last = Some(Code::Control), KeyMapRes::Partial => (),
Ok(c) if let Some(op) = self.on_code.as_mut() => op(c), KeyMapRes::Unknown => println!("Unknown code : {scan_code:?}"),
Ok(c) => println!("Ignoring {c:?}"),
}; };
} }
pub fn parse(&mut self, scan_code: u8) -> Result<Code, KeyParseErr> {
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)] #[derive(Debug, Clone, Copy)]
pub enum Code { pub enum Code {
Down(Key), Down(Key),
Up(Key), Up(Key),
Control,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Key { pub enum Key {
Char(char), Char(char),
Fun(u8),
BackSpace, BackSpace,
Insert,
Home,
PageUp,
Delete,
End,
Escape,
PageDown,
ArrowUp,
ArrowLeft,
ArrowDown,
ArrowRight,
ShiftLeft,
ShiftRight,
CtrlLeft,
CtrlRight,
AltLeft,
AltRight,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Default)]
pub enum KeyParseErr { pub struct KeyModState {
UnknownCode(u8), 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<u8, 4>,
}
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 KP_1 4F CF
*/ */
#[derive(Debug, Default, Clone)]
pub struct Azerty {
lasts: ArrayQueue<u8, 4>,
}
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,
}
}
}

View file

@ -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 blinkcast::alloc::channel;
use microlang::Context; use microlang::eval::{Context, Scope, Value};
use spin::Mutex;
use crate::{ use crate::{
dev::console::out, dev::console::out,
hard::keyboard::{keyboard, Code, Key}, hard::keyboard::{keyboard, Azerty, Code, Key, KeyModState, Qwerty},
print, println, print, println,
}; };
pub fn main() { pub fn main() {
let (tx, mut rx) = channel(1024); let keymap = Azerty::default();
let buff = Arc::new(Mutex::new(String::new())); let (tx, mut rx) = channel(1024);
keyboard().on_code(move |c| { let mut buff = String::new();
let mut buff = buff.lock(); let mut state = KeyModState::default();
match c { keyboard().keymap(keymap.clone());
Code::Down(Key::Char(c)) => { keyboard().on_code(move |c| match state.translate(&keymap, c) {
print!("{c}"); Code::Down(Key::Char(c)) => {
if c == '\n' { print!("{c}");
let mut new = String::new(); if c == '\n' {
mem::swap(&mut new, &mut buff); let mut new = String::new();
tx.send(new); mem::swap(&mut new, &mut buff);
} else { tx.send(new);
buff.push(c); } 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(); let mut context = Context::empty();
microlang::prelude::prelude(&mut context);
prelude(&mut context);
print!("> "); print!("> ");
loop { 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))
});
}

View file

@ -1,4 +1,44 @@
use core::mem;
#[allow(clippy::empty_loop)] #[allow(clippy::empty_loop)]
pub fn spin() -> ! { pub fn spin() -> ! {
loop {} loop {}
} }
#[derive(Debug, Clone)]
pub struct ArrayQueue<T, const N: usize> {
inner: [Option<T>; N],
}
impl<T, const N: usize> ArrayQueue<T, N> {
pub fn new() -> Self {
let inner = [const { None }; N];
Self { inner }
}
pub fn add(&mut self, item: T) -> Option<T> {
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<T>; N] {
&self.inner
}
pub fn flush(&mut self) -> [Option<T>; N] {
let other = [const { None }; N];
mem::replace(&mut self.inner, other)
}
}
impl<T, const N: usize> Default for ArrayQueue<T, N> {
fn default() -> Self {
Self::new()
}
}