Add support for characters and bytes

This commit is contained in:
Jeff 2024-09-09 23:45:06 -04:00
parent fcfcb4a429
commit 1b92c57df8
4 changed files with 57 additions and 2 deletions

View File

@ -424,6 +424,22 @@ impl<'src> Lexer<'src> {
} }
} }
if c == 'x' {
self.next_char();
while let Some(c) = self.peek_char() {
if c.is_ascii_hexdigit() {
self.next_char();
} else {
break;
}
}
let text = &self.source[start_pos..self.position];
return Ok((Token::Byte(text), Span(start_pos, self.position)));
}
if c.is_ascii_digit() { if c.is_ascii_digit() {
self.next_char(); self.next_char();
} else { } else {

View File

@ -1,5 +1,5 @@
use std::{ use std::{
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter, LowerHex},
mem, mem,
num::ParseIntError, num::ParseIntError,
}; };
@ -115,6 +115,27 @@ impl<'src> Parser<'src> {
Ok(()) Ok(())
} }
fn parse_byte(&mut self, _allow_assignment: bool) -> Result<(), ParseError> {
if let Token::Byte(text) = self.previous_token {
let byte = u8::from_str_radix(&text[2..], 16)?;
let value = Value::byte(byte);
self.emit_constant(value)?;
}
Ok(())
}
fn parse_character(&mut self, _allow_assignment: bool) -> Result<(), ParseError> {
if let Token::Character(character) = self.previous_token {
let value = Value::character(character);
self.emit_constant(value)?;
}
Ok(())
}
fn parse_float(&mut self, _allow_assignment: bool) -> Result<(), ParseError> { fn parse_float(&mut self, _allow_assignment: bool) -> Result<(), ParseError> {
if let Token::Float(text) = self.previous_token { if let Token::Float(text) = self.previous_token {
let float = text.parse::<f64>().unwrap(); let float = text.parse::<f64>().unwrap();
@ -418,7 +439,16 @@ impl From<&TokenKind> for ParseRule<'_> {
infix: None, infix: None,
precedence: Precedence::None, precedence: Precedence::None,
}, },
TokenKind::Character => todo!(), TokenKind::Byte => ParseRule {
prefix: Some(Parser::parse_byte),
infix: None,
precedence: Precedence::None,
},
TokenKind::Character => ParseRule {
prefix: Some(Parser::parse_character),
infix: None,
precedence: Precedence::None,
},
TokenKind::Float => ParseRule { TokenKind::Float => ParseRule {
prefix: Some(Parser::parse_float), prefix: Some(Parser::parse_float),
infix: None, infix: None,

View File

@ -11,6 +11,7 @@ pub enum Token<'src> {
// Hard-coded values // Hard-coded values
Boolean(&'src str), Boolean(&'src str),
Byte(&'src str),
Character(char), Character(char),
Float(&'src str), Float(&'src str),
Identifier(&'src str), Identifier(&'src str),
@ -70,6 +71,7 @@ impl<'src> Token<'src> {
match self { match self {
Token::Eof => 0, Token::Eof => 0,
Token::Boolean(text) => text.len(), Token::Boolean(text) => text.len(),
Token::Byte(_) => 3,
Token::Character(_) => 3, Token::Character(_) => 3,
Token::Float(text) => text.len(), Token::Float(text) => text.len(),
Token::Identifier(text) => text.len(), Token::Identifier(text) => text.len(),
@ -128,6 +130,7 @@ impl<'src> Token<'src> {
Token::Bool => TokenOwned::Bool, Token::Bool => TokenOwned::Bool,
Token::Boolean(boolean) => TokenOwned::Boolean(boolean.to_string()), Token::Boolean(boolean) => TokenOwned::Boolean(boolean.to_string()),
Token::Break => TokenOwned::Break, Token::Break => TokenOwned::Break,
Token::Byte(byte) => TokenOwned::Byte(byte.to_string()),
Token::Character(character) => TokenOwned::Character(*character), Token::Character(character) => TokenOwned::Character(*character),
Token::Colon => TokenOwned::Colon, Token::Colon => TokenOwned::Colon,
Token::Comma => TokenOwned::Comma, Token::Comma => TokenOwned::Comma,
@ -182,6 +185,7 @@ impl<'src> Token<'src> {
Token::Bool => TokenKind::Bool, Token::Bool => TokenKind::Bool,
Token::Boolean(_) => TokenKind::Boolean, Token::Boolean(_) => TokenKind::Boolean,
Token::Break => TokenKind::Break, Token::Break => TokenKind::Break,
Token::Byte(_) => TokenKind::Byte,
Token::Character(_) => TokenKind::Character, Token::Character(_) => TokenKind::Character,
Token::Colon => TokenKind::Colon, Token::Colon => TokenKind::Colon,
Token::Comma => TokenKind::Comma, Token::Comma => TokenKind::Comma,
@ -238,6 +242,7 @@ impl<'src> Display for Token<'src> {
Token::Bool => write!(f, "bool"), Token::Bool => write!(f, "bool"),
Token::Boolean(value) => write!(f, "{}", value), Token::Boolean(value) => write!(f, "{}", value),
Token::Break => write!(f, "break"), Token::Break => write!(f, "break"),
Token::Byte(value) => write!(f, "{}", value),
Token::Character(value) => write!(f, "'{}'", value), Token::Character(value) => write!(f, "'{}'", value),
Token::Colon => write!(f, ":"), Token::Colon => write!(f, ":"),
Token::Comma => write!(f, ","), Token::Comma => write!(f, ","),
@ -296,6 +301,7 @@ pub enum TokenOwned {
// Hard-coded values // Hard-coded values
Boolean(String), Boolean(String),
Byte(String),
Character(char), Character(char),
Float(String), Float(String),
Integer(String), Integer(String),
@ -357,6 +363,7 @@ impl Display for TokenOwned {
TokenOwned::Bool => Token::Bool.fmt(f), TokenOwned::Bool => Token::Bool.fmt(f),
TokenOwned::Boolean(boolean) => Token::Boolean(boolean).fmt(f), TokenOwned::Boolean(boolean) => Token::Boolean(boolean).fmt(f),
TokenOwned::Break => Token::Break.fmt(f), TokenOwned::Break => Token::Break.fmt(f),
TokenOwned::Byte(byte) => Token::Byte(byte).fmt(f),
TokenOwned::Character(character) => Token::Character(*character).fmt(f), TokenOwned::Character(character) => Token::Character(*character).fmt(f),
TokenOwned::Colon => Token::Colon.fmt(f), TokenOwned::Colon => Token::Colon.fmt(f),
TokenOwned::Comma => Token::Comma.fmt(f), TokenOwned::Comma => Token::Comma.fmt(f),
@ -413,6 +420,7 @@ pub enum TokenKind {
// Hard-coded values // Hard-coded values
Boolean, Boolean,
Byte,
Character, Character,
Float, Float,
Integer, Integer,
@ -474,6 +482,7 @@ impl Display for TokenKind {
TokenKind::Bool => Token::Bool.fmt(f), TokenKind::Bool => Token::Bool.fmt(f),
TokenKind::Boolean => write!(f, "boolean value"), TokenKind::Boolean => write!(f, "boolean value"),
TokenKind::Break => Token::Break.fmt(f), TokenKind::Break => Token::Break.fmt(f),
TokenKind::Byte => write!(f, "byte value"),
TokenKind::Character => write!(f, "character value"), TokenKind::Character => write!(f, "character value"),
TokenKind::Colon => Token::Colon.fmt(f), TokenKind::Colon => Token::Colon.fmt(f),
TokenKind::Comma => Token::Comma.fmt(f), TokenKind::Comma => Token::Comma.fmt(f),