use crate::{
compilation::{
Lexer, Parser,
error::CompilationError,
token::{Token, TokenKind},
},
execution::{Chunk, op_code::OpCode},
};
use super::PrefixParselet;
#[derive(Clone)]
pub struct LiteralParselet;
impl PrefixParselet for LiteralParselet {
fn parse(
&self,
_lexer: &mut Lexer,
parser: &mut Parser,
chunk: &mut Chunk,
_token: Token,
) -> Result<(), CompilationError> {
let kind = parser.current().kind;
match kind {
TokenKind::False => {
parser.emit_byte(OpCode::False as u8, chunk);
Ok(())
}
TokenKind::Nil => {
parser.emit_byte(OpCode::Nil as u8, chunk);
Ok(())
}
TokenKind::True => {
parser.emit_byte(OpCode::True as u8, chunk);
Ok(())
}
_ => Err(CompilationError::Unreachable {
file: file!().into(),
line: line!(),
}),
}
}
}
#[cfg(test)]
mod tests {
use alloc::{collections::btree_map::BTreeMap, string::String};
use super::*;
const fn is_normal<T: Sized + Send + Sync>() {}
#[test]
const fn normal_types() {
is_normal::<&LiteralParselet>();
is_normal::<LiteralParselet>();
}
#[test]
fn parse_rejects_non_literal_current_token() {
let enums = BTreeMap::<String, i8>::new();
let mut lexer = Lexer::new(&enums, "");
let mut parser = Parser::new();
let mut chunk = Chunk::default();
let token = parser.current();
let result = LiteralParselet.parse(&mut lexer, &mut parser, &mut chunk, token);
assert!(matches!(result, Err(CompilationError::Unreachable { .. })));
}
}