Compare commits

...

2 Commits

Author SHA1 Message Date
9df1593de9 Fix decimal parsing, add u128-support for integer parsing 2025-07-22 23:20:38 +03:00
8954d1a6d0 Add binop_hint 2025-07-22 23:14:38 +03:00
7 changed files with 33 additions and 12 deletions

View File

@ -40,7 +40,7 @@ pub enum TypeKind {
#[derive(Debug, Clone)]
pub enum Literal {
Integer(u64),
Integer(u128),
Decimal(f64),
Bool(bool),
String(String),

View File

@ -23,7 +23,10 @@ impl Parse for Type {
return Err(stream.expected_err("array length (number)")?);
};
stream.expect(Token::BracketClose)?;
TypeKind::Array(Box::new(inner.0), length)
TypeKind::Array(
Box::new(inner.0),
length.parse().expect("Array length not parseable as u64!"),
)
} else if let Some(Token::Et) = stream.peek() {
stream.expect(Token::Et)?;
let mutable = if let Some(Token::MutKeyword) = stream.peek() {
@ -157,15 +160,19 @@ impl Parse for PrimaryExpression {
let Some(Token::DecimalValue(fractional)) = stream.next() else {
return Err(stream.expected_err("fractional part")?);
};
let log = (fractional as f64).log10().ceil() as u32;
let value = (*v as f64) + (fractional as f64) / (10u64.pow(log) as f64);
Expression(
Kind::Literal(Literal::Decimal(value)),
Kind::Literal(Literal::Decimal(
format!("{}.{}", v, fractional)
.parse()
.expect("Decimal is not parseable as f64!"),
)),
stream.get_range().unwrap(),
)
} else {
Expression(
Kind::Literal(Literal::Integer(*v)),
Kind::Literal(Literal::Integer(
v.parse().expect("Integer is not parseable as u128!"),
)),
stream.get_range().unwrap(),
)
}

View File

@ -7,7 +7,7 @@ pub enum Token {
/// Values
Identifier(String),
/// Number with at most one decimal point
DecimalValue(u64),
DecimalValue(String),
/// Some character literal that was surrounded by 'single-quotes'.
CharLit(String),
/// Some string literal that was surrounded by "double-quotes".
@ -318,7 +318,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
value += &c.to_string();
cursor.next();
}
Token::DecimalValue(value.parse().expect("Decimal not parseable to u64"))
Token::DecimalValue(value)
}
'-' if cursor.first() == Some('>') => {
cursor.next(); // Eat `>`

View File

@ -107,6 +107,16 @@ impl TypeKind {
}
}
pub fn binop_hint(&self, op: &BinaryOperator) -> Option<TypeKind> {
match op {
BinaryOperator::Add | BinaryOperator::Minus | BinaryOperator::Mult => {
Some(self.clone())
}
BinaryOperator::And => None,
BinaryOperator::Cmp(_) => None,
}
}
pub fn signed(&self) -> bool {
match self {
TypeKind::Bool => false,
@ -153,7 +163,7 @@ impl TypeKind {
TypeKind::U128 => 128,
TypeKind::Void => 0,
TypeKind::Char => 8,
TypeKind::Array(type_kind, len) => type_kind.size_of() * len,
TypeKind::Array(type_kind, len) => type_kind.size_of() * (*len as u64),
TypeKind::CustomType(..) => 32,
TypeKind::CodegenPtr(_) => 64,
TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"),

View File

@ -171,7 +171,7 @@ pub enum Literal {
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub enum VagueLiteral {
Number(u64),
Number(u128),
Decimal(f64),
}

View File

@ -408,7 +408,11 @@ impl Expression {
ExprKind::BinOp(op, lhs, rhs) => {
// TODO make sure lhs and rhs can actually do this binary
// operation once relevant
let lhs_res = lhs.typecheck(state, &typerefs, hint_t);
let lhs_res = lhs.typecheck(
state,
&typerefs,
hint_t.and_then(|t| t.binop_hint(op)).as_ref(),
);
let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1);
let rhs_res = rhs.typecheck(state, &typerefs, Some(&lhs_type));
let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1);

View File

@ -5,5 +5,5 @@ pub fn OneHalf(var1: f32) -> f32 {
}
pub fn main() -> bool {
return 7.5 > 5.5;
return 7.5 > 5.001;
}