From dca10507c0cfd451fd792239742f8d53cd4c15ed Mon Sep 17 00:00:00 2001 From: Masashi Date: Sat, 20 Dec 2025 01:55:12 +0530 Subject: [PATCH] const kw --- game/client.sui | 218 ------------------------ src/ast.rs | 2 + src/c_ir.rs | 2 + src/c_lowerer/declaration_transpiler.rs | 1 + src/c_lowerer/statements_transpiler.rs | 8 + src/lambda_lower.rs | 2 + src/lexer/mod.rs | 11 ++ src/monomorphize.rs | 2 + src/parser.rs | 10 ++ src/typechecker.rs | 29 +++- 10 files changed, 60 insertions(+), 225 deletions(-) diff --git a/game/client.sui b/game/client.sui index 8758452..e69de29 100644 --- a/game/client.sui +++ b/game/client.sui @@ -1,218 +0,0 @@ -Wildered -wildered.da.programmer -Online - -Masashi - - — 5:27 PM -ill add both -Wildered — 5:27 PM -and allow for using variables obv -duh -ii love you -not in the homo way -xd -Masashi - - — 5:27 PM -okok -love u too bro (no homo) -Wildered — 5:28 PM -lol -Masashi - - — 5:32 PM -fuck -nishi's new version of libfishsoup -broke our compiler -:despair: -bitwise added -now arrays -Masashi - - — 5:39 PM -@Wildered -Wildered — 5:40 PM -yes -Masashi - - — 5:40 PM -because of the way our typesystem works -we DONT have null -ull need to do [Option::None; size] -is that okay? -and whatever ur using just make it Option::Some -oh wait -enums dont work -................ -@Wildered what do we do -wait we can do this -say u want an array of type T -u make struct TWrapper -with val: T and is_used: bool -how's the idea -Wildered — 5:45 PM -hi -yes -that's fine -Wildered — 5:46 PM -this is ok -no worries -Masashi - - — 5:46 PM -homemade Option 😭 -Wildered — 5:46 PM -lmao\ -Masashi - - — 5:46 PM -doesnt work -Masashi - - — 5:46 PM -. -Wildered — 5:46 PM -im fine w it -what's the syntax for it -Masashi - - — 5:46 PM -w -fn main() -> int do - let arr: [int; 5] = [42; 5]; - let x = arr[2]; - x -end -Wildered — 5:47 PM -so 42 is the default -Masashi - - — 5:47 PM -correct -Wildered — 5:47 PM -that's brilliant yay -:D -Masashi - - — 5:48 PM -:3 -Masashi - - — 6:47 PM -progress? -Wildered — 6:55 PM -almost done -sneakpeak -Image -Starting import resolution... - [parsing] game/client.sui -Error: Parse error in game/client.sui: Unexpected token in pattern: KeywordElse. Expected variable names, struct patterns like Struct { field }, or enum patterns like Enum::Variant -34 | else - | ~~~~ - | ^ -fn main() -> int do - suic_init_window(1280, 720, "Soup - Voxel Battle Royale"); - suic_enable_msaa_4x(); - let current_screen = 0; - let player_name = "Player"; - let server_host = "127.0.0.1"; -Expand -message.txt -5 KB - -fn main() -> int do - suic_init_window(1280, 720, "Soup - Voxel Battle Royale"); - suic_enable_msaa_4x(); - let current_screen = 0; - let player_name = "Player"; - let server_host = "127.0.0.1"; - let server_port = 8888; - suic_show_fps_meter(suic_vec2 { x: 10.0, y: 10.0 }); - - while suic_window_should_close() == false do - suic_begin_drawing(); - suic_clear_background(30, 30, 40, 255); - - if current_screen == 0 do - suic_draw_text("SOUP", 450, 80, 120, 100, 200, 255, 255); - suic_draw_text("Voxel Battle Royale", 400, 220, 40, 200, 200, 200, 255); - suic_draw_rectangle(450, 320, 380, 80, 50, 150, 255, 255); - suic_draw_rectangle_lines(450, 320, 380, 80, 100, 200, 255, 255); - suic_draw_text("PLAY", 600, 350, 40, 255, 255, 255, 255); - suic_draw_rectangle(450, 430, 380, 80, 100, 100, 100, 255); - suic_draw_rectangle_lines(450, 430, 380, 80, 150, 150, 150, 255); - suic_draw_text("SETTINGS", 540, 460, 40, 255, 255, 255, 255); - suic_draw_rectangle(450, 540, 380, 80, 150, 50, 50, 255); - suic_draw_rectangle_lines(450, 540, 380, 80, 200, 100, 100, 255); - suic_draw_text("QUIT", 600, 570, 40, 255, 255, 255, 255); - suic_draw_text("v0.1.0 - Early Access", 500, 680, 20, 150, 150, 150, 255); - - let mouse_x = suic_get_mouse_x() as int; - let mouse_y = suic_get_mouse_y() as int; - let is_mouse_clicked = suic_is_mouse_button_pressed(MOUSE_BUTTON_LEFT); - - if mouse_x >= 450 && mouse_x <= 830 && mouse_y >= 320 && mouse_y <= 400 && is_mouse_clicked != 0 do - current_screen = 1; - end - - if mouse_x >= 450 && mouse_x <= 830 && mouse_y >= 430 && mouse_y <= 510 && is_mouse_clicked != 0 do - current_screen = 2; - end - - if mouse_x >= 450 && mouse_x <= 830 && mouse_y >= 540 && mouse_y <= 620 && is_mouse_clicked != 0 do - break; - end - end - if current_screen == 1 do - suic_draw_text("MATCHMAKING", 450, 100, 60, 100, 200, 255, 255); - suic_draw_text("Connecting to server...", 400, 250, 30, 200, 200, 200, 255); - suic_draw_text("Host: 127.0.0.1:8888", 400, 310, 20, 150, 150, 150, 255); - suic_draw_text("Your Name: Player", 400, 380, 20, 200, 200, 200, 255); - suic_draw_text("Players in Queue: 0/100", 400, 420, 20, 200, 200, 200, 255); - suic_draw_text("Loading...", 550, 500, 30, 100, 200, 255, 255); - suic_draw_rectangle(100, 630, 150, 60, 150, 50, 50, 255); - suic_draw_rectangle_lines(100, 630, 150, 60, 200, 100, 100, 255); - suic_draw_text("BACK", 120, 650, 30, 255, 255, 255, 255); - - let mouse_x = suic_get_mouse_x() as int; - let mouse_y = suic_get_mouse_y() as int; - let is_mouse_clicked = suic_is_mouse_button_pressed(MOUSE_BUTTON_LEFT); - - if mouse_x >= 100 && mouse_x <= 250 && mouse_y >= 630 && mouse_y <= 690 && is_mouse_clicked != 0 do - current_screen = 0; - end - end - if current_screen == 2 do - suic_draw_text("SETTINGS", 450, 100, 60, 100, 200, 255, 255); - suic_draw_text("Player Name:", 250, 200, 24, 200, 200, 200, 255); - suic_draw_rectangle(450, 190, 300, 50, 50, 50, 50, 255); - suic_draw_rectangle_lines(450, 190, 300, 50, 100, 100, 100, 255); - suic_draw_text("Player", 460, 205, 20, 255, 255, 255, 255); - suic_draw_text("Server Host:", 250, 300, 24, 200, 200, 200, 255); - suic_draw_rectangle(450, 290, 300, 50, 50, 50, 50, 255); - suic_draw_rectangle_lines(450, 290, 300, 50, 100, 100, 100, 255); - suic_draw_text("127.0.0.1", 460, 305, 20, 255, 255, 255, 255); - suic_draw_text("Server Port:", 250, 400, 24, 200, 200, 200, 255); - suic_draw_rectangle(450, 390, 300, 50, 50, 50, 50, 255); - suic_draw_rectangle_lines(450, 390, 300, 50, 100, 100, 100, 255); - suic_draw_text("8888", 460, 405, 20, 255, 255, 255, 255); - suic_draw_rectangle(450, 550, 300, 70, 100, 100, 100, 255); - suic_draw_rectangle_lines(450, 550, 300, 70, 150, 150, 150, 255); - suic_draw_text("BACK TO HOME", 495, 577, 30, 255, 255, 255, 255); - - let mouse_x = suic_get_mouse_x() as int; - let mouse_y = suic_get_mouse_y() as int; - let is_mouse_clicked = suic_is_mouse_button_pressed(MOUSE_BUTTON_LEFT); - - if mouse_x >= 450 && mouse_x <= 750 && mouse_y >= 550 && mouse_y <= 620 && is_mouse_clicked != 0 do - current_screen = 0; - end - end - - suic_end_drawing(); - end - - suic_close_window(); - 0 -end \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index 6e694f2..5d413c2 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -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), diff --git a/src/c_ir.rs b/src/c_ir.rs index 44c0638..ccbe882 100644 --- a/src/c_ir.rs +++ b/src/c_ir.rs @@ -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(), diff --git a/src/c_lowerer/declaration_transpiler.rs b/src/c_lowerer/declaration_transpiler.rs index 7d8a0bb..27b6d67 100644 --- a/src/c_lowerer/declaration_transpiler.rs +++ b/src/c_lowerer/declaration_transpiler.rs @@ -180,6 +180,7 @@ impl DeclarationTranspiler { pub fn convert_to_c_type(name: &String) -> Result { 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))), diff --git a/src/c_lowerer/statements_transpiler.rs b/src/c_lowerer/statements_transpiler.rs index 6d27754..41bdf2f 100644 --- a/src/c_lowerer/statements_transpiler.rs +++ b/src/c_lowerer/statements_transpiler.rs @@ -48,6 +48,13 @@ impl StatementsTranspiler { pub fn transpile_expr(&self, expr: &TypedExpr) -> Result { 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 { 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))), diff --git a/src/lambda_lower.rs b/src/lambda_lower.rs index 97e25c7..8d32fc0 100644 --- a/src/lambda_lower.rs +++ b/src/lambda_lower.rs @@ -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(_) diff --git a/src/lexer/mod.rs b/src/lexer/mod.rs index cb73cf5..ddb1916 100644 --- a/src/lexer/mod.rs +++ b/src/lexer/mod.rs @@ -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::().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::().unwrap() @@ -61,6 +69,9 @@ pub enum Token { #[token("string")] KeywordString, + #[token("u8")] + KeywordU8, + #[token("let")] KeywordLet, diff --git a/src/monomorphize.rs b/src/monomorphize.rs index dd47187..ce0d47c 100644 --- a/src/monomorphize.rs +++ b/src/monomorphize.rs @@ -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()), diff --git a/src/parser.rs b/src/parser.rs index 9d9e9c2..9d6fc75 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -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; diff --git a/src/typechecker.rs b/src/typechecker.rs index 9b07ae4..123d0fd 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -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 { 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,