Compare commits

..

No commits in common. "6f4be5a929904c5d4c275c23fbd286d152471b16" and "a26a1c0d4ac09908f25048dc6f196dce5321ef18" have entirely different histories.

3 changed files with 2 additions and 175 deletions

View File

@ -124,7 +124,7 @@ impl InterpreterState {
} }
pub fn stack_top(&self) -> Option<&StackValue> { pub fn stack_top(&self) -> Option<&StackValue> {
self.stack.get(self.stack.len() - 1) self.stack.get(0)
} }
} }

View File

@ -153,15 +153,6 @@ pub struct LexError {
pub type LexResult<T> = Result<T, LexError>; pub type LexResult<T> = Result<T, LexError>;
#[derive(Debug, Clone, Copy)]
enum NumericLiteralType {
Binary,
Octal,
Decimal,
Hexadecimal,
Float,
}
impl LexerInfo { impl LexerInfo {
fn make_error(&self, message: impl Into<String>, start_line: usize, start_col: usize) -> LexError { fn make_error(&self, message: impl Into<String>, start_line: usize, start_col: usize) -> LexError {
LexError { LexError {
@ -325,10 +316,6 @@ impl LexerInfo {
c = self.advance(); c = self.advance();
} }
if c == ':' {
return self.parse_numeric_type(start, start_line, start_col, NumericLiteralType::Binary);
}
let value = self.create_binary_integer(start); let value = self.create_binary_integer(start);
Ok(Token::I64(value as i64)) Ok(Token::I64(value as i64))
} }
@ -339,10 +326,6 @@ impl LexerInfo {
c = self.advance(); c = self.advance();
} }
if c == ':' {
return self.parse_numeric_type(start, start_line, start_col, NumericLiteralType::Octal);
}
let value = self.create_octal_integer(start); let value = self.create_octal_integer(start);
Ok(Token::I64(value as i64)) Ok(Token::I64(value as i64))
} }
@ -358,10 +341,6 @@ impl LexerInfo {
return self.parse_float(start, start_line, start_col); return self.parse_float(start, start_line, start_col);
} }
if c == ':' {
return self.parse_numeric_type(start, start_line, start_col, NumericLiteralType::Decimal);
}
let value = self.create_decimal_integer(start); let value = self.create_decimal_integer(start);
Ok(Token::I64(value as i64)) Ok(Token::I64(value as i64))
} }
@ -372,10 +351,6 @@ impl LexerInfo {
c = self.advance(); c = self.advance();
} }
if c == ':' {
return self.parse_numeric_type(start, start_line, start_col, NumericLiteralType::Hexadecimal);
}
let value = self.create_hexadecimal_integer(start); let value = self.create_hexadecimal_integer(start);
Ok(Token::I64(value as i64)) Ok(Token::I64(value as i64))
} }
@ -386,157 +361,10 @@ impl LexerInfo {
c = self.advance(); c = self.advance();
} }
if c == ':' {
return self.parse_numeric_type(start, start_line, start_col, NumericLiteralType::Float);
}
let value = self.create_float(start); let value = self.create_float(start);
Ok(Token::Double(value)) Ok(Token::Double(value))
} }
fn parse_numeric_type(&mut self, start: usize, start_line: usize, start_col: usize, literal_type: NumericLiteralType) -> LexResult<Token> {
let mut c = self.advance(); // skip ':'
let mut is_float = false;
let mut is_unsigned = false;
let mut bit_size = 64; // default
if c == 'f' {
is_float = true;
if !matches!(literal_type, NumericLiteralType::Decimal | NumericLiteralType::Float) {
return Err(self.make_error("Invalid numeric literal: float type not allowed.", start_line, start_col));
}
c = self.advance();
if c == '6' && self.far_peek(1) == '4' {
bit_size = 64;
self.advance();
self.advance();
} else if c == '3' && self.far_peek(1) == '2' {
bit_size = 32;
self.advance();
self.advance();
} else {
return Err(self.make_error("Invalid float type: must be of type 'f64' or 'f32'.", start_line, start_col));
}
} else if c == 'i' || c == 'u' {
if matches!(literal_type, NumericLiteralType::Float) {
return Err(self.make_error("Invalid float type: must be of type 'f64' or 'f32'.", start_line, start_col));
}
is_unsigned = c == 'u';
c = self.advance();
if c == '6' && self.far_peek(1) == '4' {
bit_size = 64;
self.advance();
self.advance();
} else if c == '3' && self.far_peek(1) == '2' {
bit_size = 32;
self.advance();
self.advance();
} else if c == '1' && self.far_peek(1) == '6' {
bit_size = 16;
self.advance();
self.advance();
} else if c == '8' {
bit_size = 8;
self.advance();
} else {
let type_name = if is_unsigned { "unsigned" } else { "signed" };
return Err(self.make_error(
format!("Invalid {} integer type: must be of type '{}64', '{}32', '{}16', or '{}8'.",
type_name, if is_unsigned { "u" } else { "i" },
if is_unsigned { "u" } else { "i" },
if is_unsigned { "u" } else { "i" },
if is_unsigned { "u" } else { "i" }),
start_line, start_col));
}
} else {
return Err(self.make_error("Invalid numeric type: type must start with 'f', 'i', or 'u'.", start_line, start_col));
}
// Create the token based on the parsed type
if is_float {
let value = self.create_float(start);
match bit_size {
32 => Ok(Token::Float(value as f32)),
64 => Ok(Token::Double(value)),
_ => unreachable!()
}
} else {
let value = match literal_type {
NumericLiteralType::Binary => self.create_binary_integer(start),
NumericLiteralType::Octal => self.create_octal_integer(start),
NumericLiteralType::Decimal => self.create_decimal_integer(start),
NumericLiteralType::Hexadecimal => self.create_hexadecimal_integer(start),
NumericLiteralType::Float => return Err(self.make_error("Internal error: float literal in integer path", start_line, start_col)),
};
self.create_integer_token(value, is_unsigned, bit_size, start, start_line, start_col)
}
}
fn create_integer_token(&self, value: u64, is_unsigned: bool, bit_size: u32, start: usize, start_line: usize, start_col: usize) -> LexResult<Token> {
let is_negative = self.source[start..].starts_with('-');
match (is_unsigned, bit_size) {
(false, 64) => Ok(Token::I64(value as i64)),
(false, 32) => {
let signed = value as i64;
if signed < i32::MIN as i64 || signed > i32::MAX as i64 {
return Err(self.make_error("Integer overflow: value exceeds range for i32.", start_line, start_col));
}
Ok(Token::I32(value as i32))
}
(false, 16) => {
let signed = value as i64;
if signed < i16::MIN as i64 || signed > i16::MAX as i64 {
return Err(self.make_error("Integer overflow: value exceeds range for i16.", start_line, start_col));
}
Ok(Token::I16(value as i16))
}
(false, 8) => {
let signed = value as i64;
if signed < i8::MIN as i64 || signed > i8::MAX as i64 {
return Err(self.make_error("Integer overflow: value exceeds range for i8.", start_line, start_col));
}
Ok(Token::I8(value as i8))
}
(true, 64) => {
if is_negative {
return Err(self.make_error("Integer overflow: value exceeds range for u64.", start_line, start_col));
}
Ok(Token::U64(value))
}
(true, 32) => {
if is_negative {
return Err(self.make_error("Integer overflow: value exceeds range for u32.", start_line, start_col));
}
if value > u32::MAX as u64 {
return Err(self.make_error("Integer overflow: value exceeds range for u32.", start_line, start_col));
}
Ok(Token::U32(value as u32))
}
(true, 16) => {
if is_negative {
return Err(self.make_error("Integer overflow: value exceeds range for u16.", start_line, start_col));
}
if value > u16::MAX as u64 {
return Err(self.make_error("Integer overflow: value exceeds range for u16.", start_line, start_col));
}
Ok(Token::U16(value as u16))
}
(true, 8) => {
if is_negative {
return Err(self.make_error("Integer overflow: value exceeds range for u8.", start_line, start_col));
}
if value > u8::MAX as u64 {
return Err(self.make_error("Integer overflow: value exceeds range for u8.", start_line, start_col));
}
Ok(Token::U8(value as u8))
}
_ => Err(self.make_error("Invalid bit size for integer type.", start_line, start_col))
}
}
fn create_binary_integer(&self, start: usize) -> u64 { fn create_binary_integer(&self, start: usize) -> u64 {
let token = &self.source[start..self.pos]; let token = &self.source[start..self.pos];
let mut value = 0u64; let mut value = 0u64;

View File

@ -67,8 +67,7 @@ pub fn repl() -> i32 {
LexResult::Ok(tokens) => { LexResult::Ok(tokens) => {
for token in tokens { for token in tokens {
if !interpreter.execute(token) { if !interpreter.execute(token) {
println!("A runtime error occured!"); return 1;
break;
} }
} }