Skip to content

Commit

Permalink
seperate int and float.
Browse files Browse the repository at this point in the history
  • Loading branch information
nulluser committed Jun 1, 2024
1 parent b8f1027 commit 72a473a
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 25 deletions.
94 changes: 82 additions & 12 deletions src/backend/eval/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use std::collections::HashMap;
use crate::{
backend::{
environment::Environment,
values::{NumberVal, ObjectVal, Val},
values::{FloatVal, IntegerVal, ObjectVal, ToFloat, Val},
},
frontend::ast::{BinaryOp, Expr, Literal, Property},
mk_number,
mk_float, mk_integer,
};

pub fn evaluate_expr(expr: Expr, env: &mut Environment) -> Val {
Expand Down Expand Up @@ -36,7 +36,8 @@ pub fn evaluate_identifier(identifier: String, env: &mut Environment) -> Val {

pub fn evaluate_literal(literal: Literal, env: &mut Environment) -> Val {
match literal {
Literal::Integer(value) => mk_number!(value as f64) as Val,
Literal::Integer(value) => mk_integer!(value) as Val,
Literal::Float(value) => mk_float!(value) as Val,
Literal::String(_) => unimplemented!(),
Literal::Object(object) => evaluate_object_expr(object, env),
}
Expand All @@ -59,16 +60,85 @@ pub fn evaluate_binary_op(op: BinaryOp, left: Expr, right: Expr, env: &mut Envir
let right_val = evaluate_expr(right, env);

match (left_val, right_val) {
(Val::Number(l), Val::Number(r)) => {
let result = match op {
BinaryOp::Add => l.value + r.value,
BinaryOp::Subtract => l.value - r.value,
BinaryOp::Multiply => l.value * r.value,
BinaryOp::Divide => l.value / r.value,
BinaryOp::Modulus => l.value % r.value,
(Val::Integer(l), Val::Integer(r)) => {
match op {
BinaryOp::Add => Val::Integer(IntegerVal {
value: l.value + r.value,
}),
BinaryOp::Subtract => Val::Integer(IntegerVal {
value: l.value - r.value,
}),
BinaryOp::Multiply => Val::Integer(IntegerVal {
value: l.value * r.value,
}),
BinaryOp::Divide => Val::Integer(IntegerVal {
value: l.value / r.value,
}), // Note: integer division
BinaryOp::Modulus => Val::Integer(IntegerVal {
value: l.value % r.value,
}),
_ => panic!("Unsupported binary operation"),
};
mk_number!(result) as Val
}
}
(Val::Float(l), Val::Float(r)) => {
match op {
BinaryOp::Add => Val::Float(FloatVal {
value: l.value + r.value,
}),
BinaryOp::Subtract => Val::Float(FloatVal {
value: l.value - r.value,
}),
BinaryOp::Multiply => Val::Float(FloatVal {
value: l.value * r.value,
}),
BinaryOp::Divide => Val::Float(FloatVal {
value: l.value / r.value,
}),
BinaryOp::Modulus => Val::Float(FloatVal {
value: l.value % r.value,
}), // Note: % operator for floats
_ => panic!("Unsupported binary operation"),
}
}
(Val::Integer(l), Val::Float(r)) => {
match op {
BinaryOp::Add => Val::Float(FloatVal {
value: l.to_float() + r.value,
}),
BinaryOp::Subtract => Val::Float(FloatVal {
value: l.to_float() - r.value,
}),
BinaryOp::Multiply => Val::Float(FloatVal {
value: l.to_float() * r.value,
}),
BinaryOp::Divide => Val::Float(FloatVal {
value: l.to_float() / r.value,
}),
BinaryOp::Modulus => Val::Float(FloatVal {
value: l.to_float() % r.value,
}), // Convert to float and then mod
_ => panic!("Unsupported binary operation"),
}
}
(Val::Float(l), Val::Integer(r)) => {
match op {
BinaryOp::Add => Val::Float(FloatVal {
value: l.value + r.to_float(),
}),
BinaryOp::Subtract => Val::Float(FloatVal {
value: l.value - r.to_float(),
}),
BinaryOp::Multiply => Val::Float(FloatVal {
value: l.value * r.to_float(),
}),
BinaryOp::Divide => Val::Float(FloatVal {
value: l.value / r.to_float(),
}),
BinaryOp::Modulus => Val::Float(FloatVal {
value: l.value % r.to_float(),
}), // Convert to float and then mod
_ => panic!("Unsupported binary operation"),
}
}
_ => panic!("Binary operations are only supported for numbers"),
}
Expand Down
52 changes: 43 additions & 9 deletions src/backend/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::collections::HashMap;
#[derive(Debug, PartialEq)]
pub enum ValueType {
Null,
Number,
Float,
Integer,
Bool,
Object,
}
Expand All @@ -22,13 +23,34 @@ impl RuntimeVal for NullVal {
}

#[derive(Debug, PartialEq, Clone)]
pub struct NumberVal {
pub struct FloatVal {
pub value: f64,
}

impl RuntimeVal for NumberVal {
impl RuntimeVal for FloatVal {
fn get_type(&self) -> ValueType {
ValueType::Number
ValueType::Float
}
}

#[derive(Debug, PartialEq, Clone)]
pub struct IntegerVal {
pub value: i64,
}

impl RuntimeVal for IntegerVal {
fn get_type(&self) -> ValueType {
ValueType::Integer
}
}

pub trait ToFloat {
fn to_float(&self) -> f64;
}

impl ToFloat for IntegerVal {
fn to_float(&self) -> f64 {
self.value as f64
}
}

Expand Down Expand Up @@ -58,7 +80,8 @@ impl RuntimeVal for ObjectVal {
#[derive(Debug, PartialEq, Clone)]
pub enum Val {
Null(NullVal),
Number(NumberVal),
Float(FloatVal),
Integer(IntegerVal),
Bool(BoolVal),
Object(ObjectVal),
}
Expand All @@ -67,7 +90,8 @@ impl RuntimeVal for Val {
fn get_type(&self) -> ValueType {
match self {
Val::Null(_) => ValueType::Null,
Val::Number(_) => ValueType::Number,
Val::Float(_) => ValueType::Float,
Val::Integer(_) => ValueType::Integer,
Val::Bool(_) => ValueType::Bool,
Val::Object(_) => ValueType::Object,
}
Expand All @@ -93,11 +117,21 @@ macro_rules! mk_bool {
}

#[macro_export]
macro_rules! mk_number {
macro_rules! mk_float {
($n:expr) => {
Val::Float(FloatVal { value: $n })
};
() => {
mk_float!(0.0)
};
}

#[macro_export]
macro_rules! mk_integer {
($n:expr) => {
Val::Number(NumberVal { value: $n })
Val::Integer(IntegerVal { value: $n })
};
() => {
mk_number!(0.0)
mk_integer!(0)
};
}
1 change: 1 addition & 0 deletions src/frontend/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub enum Stmt {
#[derive(Debug)]
pub enum Literal {
Integer(i64),
Float(f64),
String(String),
Object(Vec<Property>),
// Other literal types...
Expand Down
29 changes: 25 additions & 4 deletions src/frontend/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub enum Token {

// Literals
IntegerLiteral(i64),
FloatLiteral(f64),
StringLiteral(String),

// Operators
Expand All @@ -30,6 +31,7 @@ impl std::fmt::Display for Token {
Token::Keyword(keyword) => write!(f, "{:?}", keyword),
Token::Identifier(name) => write!(f, "{}", name),
Token::IntegerLiteral(value) => write!(f, "{}", value),
Token::FloatLiteral(value) => write!(f, "{}", value),
Token::StringLiteral(value) => write!(f, "{}", value),
Token::Operator(operator) => write!(f, "{:?}", operator),
Token::Symbol(symbol) => write!(f, "{:?}", symbol),
Expand Down Expand Up @@ -245,21 +247,40 @@ pub fn tokenize(source_code: String) -> Vec<Token> {
// Numeric literal
if character.is_ascii_digit() {
let mut num: i64 = 0;
let mut decimal_num: f64 = 0.0;
let mut decimal_place: f64 = 1.0;
let mut is_decimal = false;

while !src.is_empty() {
if let Some(&number) = src.first() {
if number.is_ascii_digit() {
// Convert the char digit to its numeric value
let digit_value = number.to_digit(10).unwrap() as i64;
num = num * 10 + digit_value;
if is_decimal {
decimal_place *= 0.1;
decimal_num += digit_value as f64 * decimal_place;
} else {
num = num * 10 + digit_value;
}
src.drain(0..1); // Remove the processed character
} else if number == '.' && !is_decimal {
// Handle the decimal point
is_decimal = true;
src.drain(0..1); // Remove the decimal point
} else {
break; // Break the loop if the character is not a numeric digit
break; // Break the loop if the character is not a numeric digit or a single decimal point
}
}
}

drain_char = false;
tokens.push(Token::IntegerLiteral(num))
// Identifier, or keyword

if is_decimal {
let final_num = num as f64 + decimal_num;
tokens.push(Token::FloatLiteral(final_num));
} else {
tokens.push(Token::IntegerLiteral(num));
}
} else if character.is_ascii_alphabetic() || character == '_' {
let mut word = String::new();
while !src.is_empty() {
Expand Down
1 change: 1 addition & 0 deletions src/frontend/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ impl Parser {
// Token::Keyword(_) => todo!(),
Token::Identifier(name) => Expr::Identifier(name.to_string()) as Expr,
Token::IntegerLiteral(integer) => Expr::Literal(Literal::Integer(integer)) as Expr,
Token::FloatLiteral(float) => Expr::Literal(Literal::Float(float)) as Expr,
// Token::StringLiteral(_) => todo!(),
// Token::Operator(_) => todo!(),
Token::Symbol(Symbol::LeftParen) => {
Expand Down

0 comments on commit 72a473a

Please sign in to comment.