Compare commits

..

2 Commits

Author SHA1 Message Date
19cba2a7b3 Split Number into Int & Float 2024-05-06 10:13:21 -05:00
7218898ce0 Naive typechecking of binary operators 2024-05-06 09:53:18 -05:00
12 changed files with 100 additions and 70 deletions

View File

@ -26,11 +26,11 @@
## v0.0.12 ## v0.0.12
- [x] Infer datatype of an identifier - [x] Infer datatype of an identifier
- [ ] Infer datatype of a binary operatior - [x] Infer datatype of a binary operatior
- [ ] Infer datatype of unary operator - [ ] Infer datatype of unary operator
- [ ] Infer datatype of a function call expression - [ ] Infer datatype of a function call expression
- [ ] Infer datatype of binary operators - [ ] Infer datatype of binary operators
- [ ] Infer Int & Float as different types - [x] Infer Int & Float as different types
- [ ] Execute semantic analysis on the function's block - [ ] Execute semantic analysis on the function's block
- [ ] Write tests - [ ] Write tests
- [ ] Abstract the parsing of datatypes, such that in the future generics can be implemented in a single place - [ ] Abstract the parsing of datatypes, such that in the future generics can be implemented in a single place

View File

@ -30,7 +30,7 @@ mod tests {
let binding = Binding { let binding = Binding {
datatype: None, datatype: None,
identifier: &id_token, identifier: &id_token,
expression: Expression::Number(&value), expression: Expression::Int(&value),
is_mutable: false, is_mutable: false,
}; };

View File

@ -11,7 +11,8 @@ impl Transpilable for Expression<'_> {
/// - Identifier /// - Identifier
fn transpile(&self) -> String { fn transpile(&self) -> String {
match self { match self {
Expression::Number(value) => format!("{}", value), Expression::Int(value) => format!("{}", value),
Expression::Float(value) => format!("{}", value),
Expression::String(value) => { Expression::String(value) => {
format!("{}", *value) format!("{}", *value)
} }
@ -41,7 +42,7 @@ mod tests {
#[test] #[test]
fn should_transpile_number() { fn should_transpile_number() {
let str = String::from("42"); let str = String::from("42");
let exp = Expression::Number(&str); let exp = Expression::Int(&str);
let result = exp.transpile(); let result = exp.transpile();
assert_eq!("42", result); assert_eq!("42", result);

View File

@ -35,7 +35,7 @@ mod tests {
let binding = Binding { let binding = Binding {
datatype: None, datatype: None,
identifier: &id_token, identifier: &id_token,
expression: Expression::Number(&value), expression: Expression::Int(&value),
is_mutable: false, is_mutable: false,
}; };

View File

@ -256,15 +256,15 @@ mod tests {
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
let t1 = tokens.get(0).unwrap(); let t1 = tokens.get(0).unwrap();
assert_eq!(TokenType::Number, t1.token_type); assert_eq!(TokenType::Int, t1.token_type);
assert_eq!("126", t1.value); assert_eq!("126", t1.value);
let t2 = tokens.get(1).unwrap(); let t2 = tokens.get(1).unwrap();
assert_eq!(TokenType::Number, t2.token_type); assert_eq!(TokenType::Float, t2.token_type);
assert_eq!("278.98", t2.value); assert_eq!("278.98", t2.value);
let t3 = tokens.get(2).unwrap(); let t3 = tokens.get(2).unwrap();
assert_eq!(TokenType::Number, t3.token_type); assert_eq!(TokenType::Float, t3.token_type);
assert_eq!("0.282398", t3.value); assert_eq!("0.282398", t3.value);
assert_eq!("1789e+1", tokens.get(3).unwrap().value); assert_eq!("1789e+1", tokens.get(3).unwrap().value);
@ -324,7 +324,7 @@ mod tests {
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::Number, tokens[2].token_type); assert_eq!(TokenType::Int, tokens[2].token_type);
} }
#[test] #[test]
@ -333,7 +333,7 @@ mod tests {
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::Number, tokens[2].token_type); assert_eq!(TokenType::Int, tokens[2].token_type);
} }
#[test] #[test]
@ -341,10 +341,10 @@ mod tests {
let input = String::from("3\n \n 22"); let input = String::from("3\n \n 22");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
} }
#[test] #[test]
@ -352,13 +352,13 @@ mod tests {
let input = String::from("3\n \n 22\n 111"); let input = String::from("3\n \n 22\n 111");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
assert_eq!(TokenType::NewLine, tokens[4].token_type); assert_eq!(TokenType::NewLine, tokens[4].token_type);
assert_eq!(TokenType::INDENT, tokens[5].token_type); assert_eq!(TokenType::INDENT, tokens[5].token_type);
assert_eq!(TokenType::Number, tokens[6].token_type); assert_eq!(TokenType::Int, tokens[6].token_type);
} }
#[test] #[test]
@ -366,12 +366,12 @@ mod tests {
let input = String::from("3\n \n 22\n 111"); let input = String::from("3\n \n 22\n 111");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
assert_eq!(TokenType::NewLine, tokens[4].token_type); assert_eq!(TokenType::NewLine, tokens[4].token_type);
assert_eq!(TokenType::Number, tokens[5].token_type); assert_eq!(TokenType::Int, tokens[5].token_type);
} }
#[test] #[test]
@ -379,13 +379,13 @@ mod tests {
let input = String::from("3\n \n 22\n111"); let input = String::from("3\n \n 22\n111");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
assert_eq!(TokenType::NewLine, tokens[4].token_type); assert_eq!(TokenType::NewLine, tokens[4].token_type);
assert_eq!(TokenType::DEDENT, tokens[5].token_type); assert_eq!(TokenType::DEDENT, tokens[5].token_type);
assert_eq!(TokenType::Number, tokens[6].token_type); assert_eq!(TokenType::Int, tokens[6].token_type);
} }
#[test] #[test]
@ -393,16 +393,16 @@ mod tests {
let input = String::from("1\n 2\n 3\n 4\n5"); let input = String::from("1\n 2\n 3\n 4\n5");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
assert_eq!(TokenType::NewLine, tokens[4].token_type); assert_eq!(TokenType::NewLine, tokens[4].token_type);
assert_eq!(TokenType::INDENT, tokens[5].token_type); assert_eq!(TokenType::INDENT, tokens[5].token_type);
assert_eq!(TokenType::Number, tokens[6].token_type); assert_eq!(TokenType::Int, tokens[6].token_type);
assert_eq!(TokenType::NewLine, tokens[7].token_type); assert_eq!(TokenType::NewLine, tokens[7].token_type);
assert_eq!(TokenType::DEDENT, tokens[8].token_type); assert_eq!(TokenType::DEDENT, tokens[8].token_type);
assert_eq!(TokenType::Number, tokens[9].token_type); assert_eq!(TokenType::Int, tokens[9].token_type);
assert_eq!(TokenType::NewLine, tokens[10].token_type); assert_eq!(TokenType::NewLine, tokens[10].token_type);
assert_eq!(TokenType::DEDENT, tokens[11].token_type); assert_eq!(TokenType::DEDENT, tokens[11].token_type);
} }
@ -412,13 +412,13 @@ mod tests {
let input = String::from("1\n 2\n 3\n4"); let input = String::from("1\n 2\n 3\n4");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
assert_eq!(TokenType::NewLine, tokens[4].token_type); assert_eq!(TokenType::NewLine, tokens[4].token_type);
assert_eq!(TokenType::INDENT, tokens[5].token_type); assert_eq!(TokenType::INDENT, tokens[5].token_type);
assert_eq!(TokenType::Number, tokens[6].token_type); assert_eq!(TokenType::Int, tokens[6].token_type);
assert_eq!(TokenType::NewLine, tokens[7].token_type); assert_eq!(TokenType::NewLine, tokens[7].token_type);
assert_eq!(TokenType::DEDENT, tokens[8].token_type); assert_eq!(TokenType::DEDENT, tokens[8].token_type);
assert_eq!(TokenType::DEDENT, tokens[9].token_type); assert_eq!(TokenType::DEDENT, tokens[9].token_type);
@ -435,10 +435,10 @@ mod indentation_tests {
let input = String::from("1\n 2"); let input = String::from("1\n 2");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
assert_eq!(TokenType::DEDENT, tokens[4].token_type); assert_eq!(TokenType::DEDENT, tokens[4].token_type);
assert_eq!(TokenType::EOF, tokens[5].token_type); assert_eq!(TokenType::EOF, tokens[5].token_type);
} }
@ -448,13 +448,13 @@ mod indentation_tests {
let input = String::from("1\n 2\n 3"); let input = String::from("1\n 2\n 3");
let tokens = get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
assert_eq!(TokenType::Number, tokens[0].token_type); assert_eq!(TokenType::Int, tokens[0].token_type);
assert_eq!(TokenType::NewLine, tokens[1].token_type); assert_eq!(TokenType::NewLine, tokens[1].token_type);
assert_eq!(TokenType::INDENT, tokens[2].token_type); assert_eq!(TokenType::INDENT, tokens[2].token_type);
assert_eq!(TokenType::Number, tokens[3].token_type); assert_eq!(TokenType::Int, tokens[3].token_type);
assert_eq!(TokenType::NewLine, tokens[4].token_type); assert_eq!(TokenType::NewLine, tokens[4].token_type);
assert_eq!(TokenType::INDENT, tokens[5].token_type); assert_eq!(TokenType::INDENT, tokens[5].token_type);
assert_eq!(TokenType::Number, tokens[6].token_type); assert_eq!(TokenType::Int, tokens[6].token_type);
assert_eq!(TokenType::DEDENT, tokens[7].token_type); assert_eq!(TokenType::DEDENT, tokens[7].token_type);
assert_eq!(TokenType::DEDENT, tokens[8].token_type); assert_eq!(TokenType::DEDENT, tokens[8].token_type);
assert_eq!(TokenType::EOF, tokens[9].token_type); assert_eq!(TokenType::EOF, tokens[9].token_type);

View File

@ -1,7 +1,7 @@
use crate::error_handling::LexError; use crate::error_handling::LexError;
use crate::lexic::{token::Token, utils, LexResult}; use crate::lexic::{token::Token, utils, LexResult};
/// Function to scan a number /// Function to scan an int/float
/// ///
/// This function assumes that the character at `start_pos` is a number [0-9], /// This function assumes that the character at `start_pos` is a number [0-9],
/// if not it will panic /// if not it will panic
@ -36,7 +36,7 @@ fn scan_decimal(chars: &Vec<char>, start_pos: usize, current: String) -> LexResu
let current_len = current.len(); let current_len = current.len();
LexResult::Some( LexResult::Some(
Token::new_number(current, start_pos - current_len), Token::new_int(current, start_pos - current_len),
start_pos, start_pos,
) )
} }
@ -98,7 +98,7 @@ fn scan_double_impl(chars: &Vec<char>, start_pos: usize, current: String) -> Lex
let current_len = current.len(); let current_len = current.len();
LexResult::Some( LexResult::Some(
Token::new_number(current, start_pos - current_len), Token::new_float(current, start_pos - current_len),
start_pos, start_pos,
) )
} }
@ -144,7 +144,7 @@ fn scan_digits(chars: &Vec<char>, start_pos: usize, current: String) -> (Token,
let current_len = current.len(); let current_len = current.len();
( (
Token::new_number(current, start_pos - current_len), Token::new_float(current, start_pos - current_len),
start_pos, start_pos,
) )
} }
@ -163,7 +163,7 @@ fn scan_hex_digits(chars: &Vec<char>, start_pos: usize, current: String) -> (Tok
let current_len = current.len(); let current_len = current.len();
( (
Token::new_number(current, start_pos - current_len), Token::new_int(current, start_pos - current_len),
start_pos, start_pos,
) )
} }
@ -187,7 +187,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(3, next); assert_eq!(3, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("123", token.value); assert_eq!("123", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -199,7 +199,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(4, next); assert_eq!(4, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("0123", token.value); assert_eq!("0123", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -211,7 +211,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(8, next); assert_eq!(8, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("123456", token.value); assert_eq!("123456", token.value);
assert_eq!(2, token.position); assert_eq!(2, token.position);
} else { } else {
@ -227,7 +227,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(3, next); assert_eq!(3, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("123", token.value); assert_eq!("123", token.value);
} else { } else {
panic!() panic!()
@ -241,7 +241,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(4, next); assert_eq!(4, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("0x20", token.value); assert_eq!("0x20", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -253,7 +253,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(12, next); assert_eq!(12, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("0xff23DA", token.value); assert_eq!("0xff23DA", token.value);
assert_eq!(4, token.position); assert_eq!(4, token.position);
} else { } else {
@ -277,7 +277,7 @@ mod tests {
let input = str_to_vec("0 x20 "); let input = str_to_vec("0 x20 ");
let start_pos = 0; let start_pos = 0;
if let LexResult::Some(token, _) = scan(&input, start_pos) { if let LexResult::Some(token, _) = scan(&input, start_pos) {
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("0", token.value); assert_eq!("0", token.value);
} else { } else {
panic!() panic!()
@ -290,7 +290,7 @@ mod tests {
let input = str_to_vec("1x20"); let input = str_to_vec("1x20");
let start_pos = 0; let start_pos = 0;
if let LexResult::Some(token, _) = scan(&input, start_pos) { if let LexResult::Some(token, _) = scan(&input, start_pos) {
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("1", token.value); assert_eq!("1", token.value);
} else { } else {
panic!() panic!()
@ -304,7 +304,7 @@ mod tests {
let start_pos = 0; let start_pos = 0;
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(4, next); assert_eq!(4, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!("3.22", token.value); assert_eq!("3.22", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -315,7 +315,7 @@ mod tests {
let start_pos = 0; let start_pos = 0;
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(11, next); assert_eq!(11, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!("123456.7890", token.value); assert_eq!("123456.7890", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -356,7 +356,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!("1e+0", token.value); assert_eq!("1e+0", token.value);
assert_eq!(4, next); assert_eq!(4, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
panic!() panic!()
@ -366,7 +366,7 @@ mod tests {
let start_pos = 0; let start_pos = 0;
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(4, next); assert_eq!(4, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!("1e-0", token.value); assert_eq!("1e-0", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -377,7 +377,7 @@ mod tests {
let start_pos = 0; let start_pos = 0;
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(4, next); assert_eq!(4, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!("0e+0", token.value); assert_eq!("0e+0", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -388,7 +388,7 @@ mod tests {
let start_pos = 0; let start_pos = 0;
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(19, next); assert_eq!(19, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!("123498790e+12349870", token.value); assert_eq!("123498790e+12349870", token.value);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
@ -404,7 +404,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!("1.24e+1", token.value); assert_eq!("1.24e+1", token.value);
assert_eq!(7, next); assert_eq!(7, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
panic!() panic!()
@ -415,7 +415,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!("0.00000000000001e+1", token.value); assert_eq!("0.00000000000001e+1", token.value);
assert_eq!(19, next); assert_eq!(19, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Float, token.token_type);
assert_eq!(0, token.position); assert_eq!(0, token.position);
} else { } else {
panic!() panic!()
@ -429,7 +429,7 @@ mod tests {
if let LexResult::Some(token, next) = scan(&input, start_pos) { if let LexResult::Some(token, next) = scan(&input, start_pos) {
assert_eq!(5, next); assert_eq!(5, next);
assert_eq!(TokenType::Number, token.token_type); assert_eq!(TokenType::Int, token.token_type);
assert_eq!("123", token.value); assert_eq!("123", token.value);
assert_eq!(2, token.position); assert_eq!(2, token.position);
} else { } else {

View File

@ -2,7 +2,8 @@
pub enum TokenType { pub enum TokenType {
Identifier, Identifier,
Datatype, Datatype,
Number, Int,
Float,
String, String,
Operator, Operator,
LeftParen, LeftParen,
@ -47,9 +48,17 @@ impl Token {
} }
} }
pub fn new_number(value: String, position: usize) -> Token { pub fn new_int(value: String, position: usize) -> Token {
Token { Token {
token_type: TokenType::Number, token_type: TokenType::Int,
value,
position,
}
}
pub fn new_float(value: String, position: usize) -> Token {
Token {
token_type: TokenType::Float,
value, value,
position, position,
} }

View File

@ -10,8 +10,8 @@ impl Typed for Expression<'_> {
/// Attempts to get the datatype for an expression. /// Attempts to get the datatype for an expression.
fn get_type(&self, scope: &SymbolTable) -> Result<String, MistiError> { fn get_type(&self, scope: &SymbolTable) -> Result<String, MistiError> {
match self { match self {
// TODO: Distinguish between Int & Float Expression::Int(_) => Ok("Int".into()),
Expression::Number(_) => Ok("Int".into()), Expression::Float(_) => Ok("Float".into()),
Expression::String(_) => Ok("String".into()), Expression::String(_) => Ok("String".into()),
Expression::Boolean(_) => Ok("Bool".into()), Expression::Boolean(_) => Ok("Bool".into()),
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
@ -26,12 +26,30 @@ impl Typed for Expression<'_> {
})) }))
} }
}; };
Ok(datatype) Ok(datatype)
} }
Expression::FunctionCall(_) => todo!(), Expression::FunctionCall(_) => todo!(),
Expression::UnaryOperator(_, _) => todo!(), Expression::UnaryOperator(_, _) => todo!(),
Expression::BinaryOperator(_, _, _) => todo!(), Expression::BinaryOperator(exp1, exp2, operator) => {
let t1 = exp1.get_type(scope)?;
let t2 = exp2.get_type(scope)?;
// TODO: There's definitely a better way to do this
if *operator == "+" && t1 == "Int" && t2 == "Int" {
return Ok("Int".into());
} else if *operator == "-" && t1 == "Int" && t2 == "Int" {
return Ok("Int".into());
}
return Err(MistiError::Semantic(SemanticError {
error_start: 0,
error_end: 1,
reason: format!(
"Unsupported binary operator or invalid arguments to the operator."
),
}));
}
} }
} }
} }

View File

@ -43,7 +43,8 @@ pub struct Parameter<'a> {
#[derive(Debug)] #[derive(Debug)]
pub enum Expression<'a> { pub enum Expression<'a> {
Number(&'a String), Int(&'a String),
Float(&'a String),
String(&'a String), String(&'a String),
Boolean(bool), Boolean(bool),
Identifier(&'a String), Identifier(&'a String),

View File

@ -12,7 +12,8 @@ use crate::{
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> { pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
match tokens.get_significant(pos) { match tokens.get_significant(pos) {
Some((token, token_pos)) => match token.token_type { Some((token, token_pos)) => match token.token_type {
TokenType::Number => Ok((Expression::Number(&token.value), token_pos + 1)), TokenType::Int => Ok((Expression::Int(&token.value), token_pos + 1)),
TokenType::Float => Ok((Expression::Float(&token.value), token_pos + 1)),
TokenType::String => Ok((Expression::String(&token.value), token_pos + 1)), TokenType::String => Ok((Expression::String(&token.value), token_pos + 1)),
TokenType::Identifier if token.value == "true" || token.value == "false" => { TokenType::Identifier if token.value == "true" || token.value == "false" => {
Ok((Expression::Boolean(token.value == "true"), token_pos + 1)) Ok((Expression::Boolean(token.value == "true"), token_pos + 1))
@ -50,7 +51,7 @@ mod tests {
let expression = try_parse(&tokens, 0); let expression = try_parse(&tokens, 0);
match expression { match expression {
Ok((Expression::Number(value), _)) => { Ok((Expression::Int(value), _)) => {
assert_eq!("40", format!("{}", value)) assert_eq!("40", format!("{}", value))
} }
_ => panic!(), _ => panic!(),

View File

@ -52,7 +52,7 @@ mod tests {
match expression { match expression {
Ok((Expression::UnaryOperator(operator, expression), _)) => { Ok((Expression::UnaryOperator(operator, expression), _)) => {
match (operator, *expression) { match (operator, *expression) {
(op, Expression::Number(value)) => { (op, Expression::Int(value)) => {
assert_eq!(*op, "-"); assert_eq!(*op, "-");
assert_eq!(*value, "10"); assert_eq!(*value, "10");
} }

View File

@ -135,7 +135,7 @@ mod tests {
let first_argument = arguments_list.arguments.get(0).unwrap(); let first_argument = arguments_list.arguments.get(0).unwrap();
let Expression::Number(_) = first_argument else { let Expression::Int(_) = first_argument else {
panic!("Expected a number") panic!("Expected a number")
}; };
} }
@ -153,7 +153,7 @@ mod tests {
assert_eq!(arguments_list.arguments.len(), 1); assert_eq!(arguments_list.arguments.len(), 1);
let first_argument = arguments_list.arguments.get(0).unwrap(); let first_argument = arguments_list.arguments.get(0).unwrap();
let Expression::Number(_) = first_argument else { let Expression::Int(_) = first_argument else {
panic!("Expected a number") panic!("Expected a number")
}; };
} }
@ -175,7 +175,7 @@ mod tests {
}; };
let second_argument = arguments_list.arguments.get(1).unwrap(); let second_argument = arguments_list.arguments.get(1).unwrap();
let Expression::Number(_) = second_argument else { let Expression::Int(_) = second_argument else {
panic!("Expected a number") panic!("Expected a number")
}; };
} }