This commit is contained in:
Masashi 2025-12-20 01:55:12 +05:30
commit dca10507c0
10 changed files with 60 additions and 225 deletions

View file

@ -205,6 +205,7 @@ pub struct Expr {
#[derive(Debug, Clone)]
pub enum ExprKind {
Int(i64),
TypedInt(i64, String),
Float(f64),
Bool(bool),
String(String),
@ -400,6 +401,7 @@ pub struct TypedExpr {
#[derive(Debug, Clone)]
pub enum TypedExprKind {
Int(i64),
TypedInt(i64, String),
Float(f64),
Bool(bool),
String(String),

View file

@ -2,6 +2,7 @@
pub enum CType {
Void,
Int,
U8,
Float,
Bool,
Char,
@ -33,6 +34,7 @@ impl CType {
match self {
CType::Void => "void".to_string(),
CType::Int => "int".to_string(),
CType::U8 => "uint8_t".to_string(),
CType::Float => "float".to_string(),
CType::Bool => "bool".to_string(),
CType::Char => "char".to_string(),

View file

@ -180,6 +180,7 @@ impl DeclarationTranspiler {
pub fn convert_to_c_type(name: &String) -> Result<CType, String> {
match String::as_str(name) {
"int" => Ok(CType::Int),
"u8" => Ok(CType::U8),
"float" => Ok(CType::Float),
"bool" => Ok(CType::Bool),
"string" => Ok(CType::Ptr(Box::new(CType::Char))),

View file

@ -48,6 +48,13 @@ impl StatementsTranspiler {
pub fn transpile_expr(&self, expr: &TypedExpr) -> Result<CExpr, String> {
match &expr.kind {
TypedExprKind::Int(i) => Ok(CExpr::IntLit(*i)),
TypedExprKind::TypedInt(i, t) => {
let inner = CExpr::IntLit(*i);
match t.as_str() {
"u8" => Ok(CExpr::Cast(Box::new(inner), CType::U8)),
_ => Err(format!("Unsupported typed integer type: {}", t)),
}
}
TypedExprKind::Float(f) => Ok(CExpr::FloatLit(*f)),
TypedExprKind::Bool(b) => Ok(CExpr::BoolLit(*b)),
TypedExprKind::String(s) => Ok(CExpr::StringLit(s.clone())),
@ -477,6 +484,7 @@ impl StatementsTranspiler {
fn type_to_ctype(&self, ty: &Type) -> Result<CType, String> {
match ty {
Type::Int => Ok(CType::Int),
Type::U8 => Ok(CType::U8),
Type::Float => Ok(CType::Float),
Type::Bool => Ok(CType::Bool),
Type::String => Ok(CType::Ptr(Box::new(CType::Char))),

View file

@ -153,6 +153,7 @@ impl LambdaLowerer {
}
// Terminal expressions don't contain variables
ExprKind::Int(_)
| ExprKind::TypedInt(_, _)
| ExprKind::Float(_)
| ExprKind::Bool(_)
| ExprKind::String(_)
@ -376,6 +377,7 @@ impl LambdaLowerer {
}
// Terminal expressions that don't contain other expressions
ExprKind::Int(_)
| ExprKind::TypedInt(_, _)
| ExprKind::Float(_)
| ExprKind::Bool(_)
| ExprKind::String(_)

View file

@ -20,6 +20,14 @@ pub enum Token {
}, priority = 4)]
Int(i64),
#[regex(r"(0|[1-9][0-9_]*)u8", |lex| {
let s = lex.slice();
let num_part = &s[..s.len()-2];
let num = num_part.replace("_", "").parse::<i64>().unwrap();
(num, "u8".to_string())
}, priority = 5)]
TypedInt((i64, String)),
#[regex(r"(([0-9][0-9_]*\.[0-9_]+|[0-9]*\.[0-9_]+)([eE][+-]?[0-9_]+)?)", |lex| {
let s = lex.slice().replace("_", "");
s.parse::<f64>().unwrap()
@ -61,6 +69,9 @@ pub enum Token {
#[token("string")]
KeywordString,
#[token("u8")]
KeywordU8,
#[token("let")]
KeywordLet,

View file

@ -322,6 +322,7 @@ impl Monomorphizer {
let mut needs = Vec::new();
let new_kind = match &expr.kind {
TypedExprKind::Int(_)
| TypedExprKind::TypedInt(_, _)
| TypedExprKind::Float(_)
| TypedExprKind::Bool(_)
| TypedExprKind::String(_)
@ -786,6 +787,7 @@ impl Monomorphizer {
fn type_to_type_annot(&self, ty: &Type) -> TypeAnnot {
match ty {
Type::Int => TypeAnnot::Var("int".to_string()),
Type::U8 => TypeAnnot::Var("u8".to_string()),
Type::Float => TypeAnnot::Var("float".to_string()),
Type::Bool => TypeAnnot::Var("bool".to_string()),
Type::String => TypeAnnot::Var("string".to_string()),

View file

@ -883,6 +883,7 @@ impl Parser {
Some((Token::KeywordInt, _)) => TypeAnnot::Cons("int".to_string(), vec![]),
Some((Token::KeywordFloat, _)) => TypeAnnot::Cons("float".to_string(), vec![]),
Some((Token::KeywordString, _)) => TypeAnnot::Cons("string".to_string(), vec![]),
Some((Token::KeywordU8, _)) => TypeAnnot::Cons("u8".to_string(), vec![]),
Some((Token::LParen, _)) => {
// Check for unit type: ()
if matches!(self.peek(), Some(Token::RParen)) {
@ -1465,6 +1466,15 @@ impl Parser {
attributes: Vec::new(),
})
}
Some(Token::TypedInt((n, t))) => {
self.next();
let end = self.peek_span().unwrap_or(start..start).end;
Ok(Expr {
kind: ExprKind::TypedInt(n, t),
span: Span::new(&(start..end), self.file.clone()),
attributes: Vec::new(),
})
}
Some(Token::Float(f)) => {
self.next();
let end = self.peek_span().unwrap_or(start..start).end;

View file

@ -6,6 +6,7 @@ use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub enum Type {
Int,
U8,
Float,
Bool,
String,
@ -27,6 +28,7 @@ impl Type {
pub fn to_string(&self) -> String {
match self {
Type::Int => "int".to_string(),
Type::U8 => "u8".to_string(),
Type::Float => "float".to_string(),
Type::Bool => "bool".to_string(),
Type::String => "string".to_string(),
@ -1763,6 +1765,16 @@ impl TypeChecker {
fn typecheck_expr(&mut self, expr: &Expr) -> Result<TypedExpr, TypeError> {
let (kind, ty) = match &expr.kind {
ExprKind::Int(n) => (TypedExprKind::Int(*n), Type::Int),
ExprKind::TypedInt(n, t) => {
let ty = match t.as_str() {
"u8" => Type::U8,
_ => return Err(TypeError {
kind: TypeErrorKind::UndefinedType(t.clone()),
span: expr.span.clone(),
}),
};
(TypedExprKind::TypedInt(*n, t.clone()), ty)
},
ExprKind::Float(f) => (TypedExprKind::Float(*f), Type::Float),
ExprKind::Bool(b) => (TypedExprKind::Bool(*b), Type::Bool),
ExprKind::String(s) => (TypedExprKind::String(s.clone()), Type::String),
@ -2846,13 +2858,14 @@ impl TypeChecker {
TypeInfoKind::Enum(_) => Type::Enum(name.clone(), substituted_args),
}
} else {
match name.as_str() {
"int" => Type::Int,
"float" => Type::Float,
"bool" => Type::Bool,
"string" => Type::String,
"unit" => Type::Unit,
"never" => Type::Never,
match name.as_str() {
"int" => Type::Int,
"u8" => Type::U8,
"float" => Type::Float,
"bool" => Type::Bool,
"string" => Type::String,
"unit" => Type::Unit,
"never" => Type::Never,
_ => Type::Generic(name.clone(), substituted_args),
}
}
@ -2906,6 +2919,7 @@ impl TypeChecker {
match name.as_str() {
"int" => Type::Int,
"u8" => Type::U8,
"float" => Type::Float,
"bool" => Type::Bool,
"string" => Type::String,
@ -2945,6 +2959,7 @@ impl TypeChecker {
match (t1, t2) {
(Type::Unknown, _) | (_, Type::Unknown) => true,
(Type::Int, Type::Int) => true,
(Type::U8, Type::U8) => true,
(Type::Float, Type::Float) => true,
(Type::Bool, Type::Bool) => true,
(Type::String, Type::String) => true,