Compare commits

..

No commits in common. "22afdb20a4df97a4c5abda6ee1988699b61097d0" and "ad868c0c257a7dfdd960fb681ddceb9d4a99d0b0" have entirely different histories.

18 changed files with 1439 additions and 2298 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,218 @@
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

View file

@ -11,7 +11,6 @@ pub enum TypeAnnot {
Function(Vec<TypeAnnot>, Box<TypeAnnot>),
Tuple(Vec<TypeAnnot>),
Array(Box<TypeAnnot>),
FixedArray(Box<TypeAnnot>, i64),
Ptr(Box<TypeAnnot>),
}
@ -67,7 +66,6 @@ pub enum ASTNodeKind {
Function(Function),
Extern(Extern),
Load(Load),
Const(Const),
Struct(Struct),
Enum(Enum),
Impl(Impl),
@ -81,13 +79,6 @@ pub struct Use {
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct Const {
pub name: String,
pub typ: Option<TypeAnnot>,
pub value: Expr,
}
// ? implies OPTIONAL here
// \( implies the presence of (. same for /)
@ -213,12 +204,10 @@ pub struct Expr {
#[derive(Debug, Clone)]
pub enum ExprKind {
Int(i64),
TypedInt(i64, String),
Float(f64),
Bool(bool),
String(String),
Array(Vec<Expr>),
FixedArray(Box<Expr>, i64),
Tuple(Vec<Expr>),
StructLit(String, Vec<(String, Expr)>), // Name { a: expr, b: expr }
@ -273,8 +262,6 @@ pub enum BinOp {
Or,
BitwiseAnd,
BitwiseOr,
LShift,
RShift,
Eq,
Neq,
Lt,
@ -324,7 +311,6 @@ pub enum TypedASTNodeKind {
Function(TypedFunction),
Extern(TypedExtern),
Load(TypedLoad),
Const(TypedConst),
Struct(TypedStruct),
Enum(TypedEnum),
Impl(TypedImpl),
@ -358,13 +344,6 @@ pub struct TypedLoad {
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct TypedConst {
pub name: String,
pub typ: Option<TypeAnnot>,
pub value: TypedExpr,
}
#[derive(Debug, Clone)]
pub struct TypedStruct {
pub name: String,
@ -419,12 +398,10 @@ pub struct TypedExpr {
#[derive(Debug, Clone)]
pub enum TypedExprKind {
Int(i64),
TypedInt(i64, String),
Float(f64),
Bool(bool),
String(String),
Array(Vec<TypedExpr>),
FixedArray(Box<TypedExpr>, usize),
Tuple(Vec<TypedExpr>),
StructLit(String, Vec<(String, TypedExpr)>),
EnumLit(String, String, Vec<TypedExpr>),

View file

@ -2,7 +2,6 @@
pub enum CType {
Void,
Int,
U8,
Float,
Bool,
Char,
@ -10,7 +9,6 @@ pub enum CType {
Struct(String),
UnnamedStruct(Vec<CVarDecl>),
Array(Box<CType>), // heap-allocated array wrapper with data pointer, len, capacity
FixedArray(Box<CType>, usize), // fixed-size array like int[10]
Func(Vec<CType>, Box<CType>), // args and return
}
@ -34,7 +32,6 @@ 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(),
@ -51,7 +48,6 @@ impl CType {
"struct sui_array_{}",
inner.to_string().replace(" ", "_").replace("*", "ptr")
),
CType::FixedArray(inner, size) => format!("{}*", inner.to_string()), // For now, treat as pointer in type strings
CType::Func(args, ret) => {
let arg_strs: Vec<String> = args.iter().map(|t| t.to_string()).collect();
format!("{} (*)({})", ret.to_string(), arg_strs.join(", "))
@ -65,7 +61,6 @@ pub struct CVarDecl {
pub name: String,
pub ty: CType,
pub initializer: Option<CExpr>,
pub is_const: bool,
}
#[derive(Debug, Clone, PartialEq)]
@ -121,8 +116,6 @@ pub enum CBinaryOp {
Or,
BitwiseAnd,
BitwiseOr,
LShift,
RShift,
}
impl CBinaryOp {
@ -143,8 +136,6 @@ impl CBinaryOp {
CBinaryOp::Or => "||",
CBinaryOp::BitwiseAnd => "&",
CBinaryOp::BitwiseOr => "|",
CBinaryOp::LShift => "<<",
CBinaryOp::RShift => ">>",
}
}
}

View file

@ -23,7 +23,6 @@ impl DeclarationTranspiler {
name: field.name.clone(),
ty: field_type,
initializer: None,
is_const: false,
});
}
@ -54,7 +53,6 @@ impl DeclarationTranspiler {
name: name.clone(),
ty: param_type,
initializer: None,
is_const: false,
});
}
@ -83,7 +81,6 @@ impl DeclarationTranspiler {
name: field_name,
ty: c_type,
initializer: None,
is_const: false,
});
}
@ -103,7 +100,6 @@ impl DeclarationTranspiler {
name: field_name,
ty: CType::Struct(struct_name),
initializer: None,
is_const: false,
});
}
@ -119,13 +115,11 @@ impl DeclarationTranspiler {
name: "discriminant".to_string(),
ty: CType::Int,
initializer: None,
is_const: false,
},
CVarDecl {
name: "data".to_string(),
ty: CType::Struct(union_name_clone),
initializer: None,
is_const: false,
},
];
@ -154,10 +148,6 @@ impl DeclarationTranspiler {
// Arrays are pointers to the element type
Ok(CType::Ptr(Box::new(inner_type)))
}
Some(TypeAnnot::FixedArray(inner, size)) => {
let inner_type = self.type_annot_to_c_type(&Some(*inner.clone()))?;
Ok(CType::FixedArray(Box::new(inner_type), *size as usize))
}
Some(TypeAnnot::Tuple(fields)) => {
let mut c_fields = Vec::new();
for (i, field_annot) in fields.iter().enumerate() {
@ -166,7 +156,6 @@ impl DeclarationTranspiler {
name: format!("field{}", i),
ty: field_type,
initializer: None,
is_const: false,
});
}
Ok(CType::UnnamedStruct(c_fields))
@ -187,7 +176,6 @@ 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

@ -30,7 +30,6 @@ impl StatementsTranspiler {
name: name.clone(),
ty,
initializer,
is_const: false,
};
(name, decl)
@ -49,13 +48,6 @@ 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())),
@ -125,11 +117,6 @@ impl StatementsTranspiler {
.collect::<Result<Vec<_>, _>>()?;
Ok(CExpr::ArrayLit(c_exprs))
}
TypedExprKind::FixedArray(expr, size) => {
let c_expr = self.transpile_expr(expr)?;
let c_exprs = vec![c_expr; *size];
Ok(CExpr::ArrayLit(c_exprs))
}
TypedExprKind::Cast(expr, type_annot) => {
let c_expr = self.transpile_expr(expr)?;
// Simplified: assuming we can map type annotations to C types
@ -183,7 +170,6 @@ impl StatementsTranspiler {
name: name.clone(),
ty: c_type,
initializer,
is_const: false,
};
Ok(CStmt::VarDecl(var_decl))
}
@ -235,7 +221,6 @@ impl StatementsTranspiler {
name: var_name.clone(),
ty: CType::Int,
initializer: Some(start_expr),
is_const: false,
};
let cond = CExpr::BinOp(
@ -287,7 +272,6 @@ impl StatementsTranspiler {
)),
Box::new(CExpr::Var(idx_name.clone())),
)),
is_const: false,
});
let mut body_stmts = vec![bind];
@ -337,7 +321,6 @@ impl StatementsTranspiler {
Box::new(CExpr::Var(arr_name.clone())),
Box::new(CExpr::Var(idx_name.clone())),
)),
is_const: false,
});
let mut body_stmts = vec![bind];
@ -473,8 +456,6 @@ impl StatementsTranspiler {
BinOp::Or => Ok(CBinaryOp::Or),
BinOp::BitwiseAnd => Ok(CBinaryOp::BitwiseAnd),
BinOp::BitwiseOr => Ok(CBinaryOp::BitwiseOr),
BinOp::LShift => Ok(CBinaryOp::LShift),
BinOp::RShift => Ok(CBinaryOp::RShift),
}
}
@ -488,10 +469,9 @@ impl StatementsTranspiler {
}
}
pub fn type_to_ctype(&self, ty: &Type) -> Result<CType, String> {
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))),
@ -502,10 +482,6 @@ impl StatementsTranspiler {
// Arrays are pointers to the element type
Ok(CType::Ptr(Box::new(inner_type)))
}
Type::FixedArray(inner, size) => {
let inner_type = self.type_to_ctype(inner)?;
Ok(CType::FixedArray(Box::new(inner_type), *size))
}
Type::Struct(name, _) => Ok(CType::Ptr(Box::new(CType::Struct(name.clone())))),
Type::Enum(name, _) => Ok(CType::Ptr(Box::new(CType::Struct(name.clone())))),
Type::Tuple(types) => {
@ -516,7 +492,6 @@ impl StatementsTranspiler {
name: format!("field{}", i),
ty: c_type,
initializer: None,
is_const: false,
});
}
Ok(CType::UnnamedStruct(fields))
@ -561,10 +536,6 @@ impl StatementsTranspiler {
// Arrays are pointers to the element type
Ok(CType::Ptr(Box::new(inner_type)))
}
TypeAnnot::FixedArray(inner, size) => {
let inner_type = self.type_annot_to_ctype(inner)?;
Ok(CType::FixedArray(Box::new(inner_type), *size as usize))
}
TypeAnnot::Tuple(fields) => {
let mut c_fields = Vec::new();
for (i, field_annot) in fields.iter().enumerate() {
@ -573,7 +544,6 @@ impl StatementsTranspiler {
name: format!("field{}", i),
ty: field_type,
initializer: None,
is_const: false,
});
}
Ok(CType::UnnamedStruct(c_fields))

View file

@ -90,39 +90,6 @@ impl Transpiler {
self.lower_declarations_to_c_ir(node)?;
}
// Add builtin structs
if !self.structs.iter().any(|s| s.name == "Color") {
self.structs.push(CStructDecl {
name: "Color".to_string(),
fields: vec![
CVarDecl { name: "r".to_string(), ty: CType::U8, initializer: None, is_const: false },
CVarDecl { name: "g".to_string(), ty: CType::U8, initializer: None, is_const: false },
CVarDecl { name: "b".to_string(), ty: CType::U8, initializer: None, is_const: false },
CVarDecl { name: "a".to_string(), ty: CType::U8, initializer: None, is_const: false },
],
});
// Generate TypeInfo
let bitmap = Self::generate_pointer_bitmap(&vec![
CVarDecl { name: "r".to_string(), ty: CType::U8, initializer: None, is_const: false },
CVarDecl { name: "g".to_string(), ty: CType::U8, initializer: None, is_const: false },
CVarDecl { name: "b".to_string(), ty: CType::U8, initializer: None, is_const: false },
CVarDecl { name: "a".to_string(), ty: CType::U8, initializer: None, is_const: false },
]);
self.typeinfo_map.insert("Color".to_string(), bitmap);
}
if !self.structs.iter().any(|s| s.name == "Shader") {
self.structs.push(CStructDecl {
name: "Shader".to_string(),
fields: vec![
CVarDecl { name: "id".to_string(), ty: CType::Int, initializer: None, is_const: false },
],
});
let bitmap = Self::generate_pointer_bitmap(&vec![
CVarDecl { name: "id".to_string(), ty: CType::Int, initializer: None, is_const: false },
]);
self.typeinfo_map.insert("Shader".to_string(), bitmap);
}
self.lower_function_bodies_to_c_ir(nodes)?;
// Rename main to suic_main and track that we have a main
@ -271,16 +238,6 @@ impl Transpiler {
self.functions.push(func_decl);
}
}
TypedASTNodeKind::Const(c) => {
let value_code = self.stmt_transpiler.transpile_expr(&c.value)?;
let var_decl = CVarDecl {
name: c.name.clone(),
ty: self.stmt_transpiler.type_to_ctype(&c.value.ty)?,
initializer: Some(value_code),
is_const: true,
};
self.globals.push(var_decl);
}
TypedASTNodeKind::Extern(e) => {
// For externs, we might need to add function prototypes
// But for now, skip as they're handled differently
@ -447,26 +404,9 @@ impl Transpiler {
}
fn generate_var_decl(&self, var: &CVarDecl) -> String {
let mut output = match &var.ty {
CType::FixedArray(elem_ty, size) => format!("{} {}[{}]", elem_ty.to_string(), var.name, size),
_ => format!("{} {}", var.ty.to_string(), var.name),
};
if var.is_const {
output = format!("const {}", output);
}
let mut output = format!("{} {}", var.ty.to_string(), var.name);
if let Some(init) = &var.initializer {
match (&var.ty, init) {
(CType::FixedArray(_, _), CExpr::ArrayLit(elements)) => {
let vec: Vec<String> = elements
.iter()
.map(|expr| self.generate_expr(expr))
.collect();
output.push_str(&format!(" = {{{}}}", vec.join(", ")));
}
_ => {
output.push_str(&format!(" = {}", self.generate_expr(init)));
}
}
output.push_str(&format!(" = {}", self.generate_expr(init)));
}
output
}
@ -698,14 +638,13 @@ impl Transpiler {
"rl_pop_matrix" => "suic_rl_pop_matrix",
"rl_translate_f" => "suic_rl_translate_f",
"rl_rotate_f" => "suic_rl_rotate_f",
// UI Framework Utils
"draw_text" => "DrawText",
"draw_rectangle" => "DrawRectangle",
"draw_rectangle_lines" => "DrawRectangleLines",
"measure_text" => "MeasureText",
"draw_circle" => "DrawCircle",
"draw_line" => "DrawLine",
"draw_fps" => "DrawFPS",
// UI Framework Utils
"draw_text" => "suic_draw_text",
"draw_rectangle" => "suic_draw_rectangle",
"draw_rectangle_lines" => "suic_draw_rectangle_lines",
"measure_text" => "suic_measure_text",
"draw_circle" => "suic_draw_circle",
"draw_line" => "suic_draw_line",
// Player controller functions
"player_controller_create" => "suic_player_controller_create",
"player_controller_destroy" => "suic_player_controller_destroy",
@ -796,7 +735,18 @@ impl Transpiler {
"Vec3" => "suic_vec3".to_string(),
_ => format!("struct {}", struct_name),
};
format!("({}){{ {} }}", c_type_name, field_inits.join(", "))
// For built-in simple structs, generate compound literal directly
// For user-defined structs, use heap allocation
match struct_name.as_str() {
"Vec2" | "Vec3" => format!("({}){{ {} }}", c_type_name, field_inits.join(", ")),
_ => format!(
"suic_alloc_struct(&sui_typeinfo_{}, sizeof({}), &({}){{ {} }})",
struct_name,
c_type_name,
c_type_name,
field_inits.join(", ")
),
}
}
CExpr::EnumLit(enum_name, variant_name, args) => {
// Find the variant index - for simplicity, assume variants are in order

View file

@ -370,22 +370,14 @@ impl ImportResolver {
ASTNodeKind::Load(_) => {
result.push(node);
}
ASTNodeKind::Trait(t) => {
self.symbol_registry.register(
t.name.clone(),
filename.to_string(),
node.span.clone(),
)?;
result.push(node);
}
ASTNodeKind::Const(c) => {
self.symbol_registry.register(
c.name.clone(),
filename.to_string(),
node.span.clone(),
)?;
result.push(node);
}
ASTNodeKind::Trait(t) => {
self.symbol_registry.register(
t.name.clone(),
filename.to_string(),
node.span.clone(),
)?;
result.push(node);
}
}
}

View file

@ -126,9 +126,6 @@ impl LambdaLowerer {
self.collect_free_vars_expr(expr, lambda_params, free_vars, local_scope);
}
}
ExprKind::FixedArray(expr, _) => {
self.collect_free_vars_expr(expr, lambda_params, free_vars, local_scope);
}
ExprKind::Tuple(exprs) => {
for expr in exprs {
self.collect_free_vars_expr(expr, lambda_params, free_vars, local_scope);
@ -153,7 +150,6 @@ impl LambdaLowerer {
}
// Terminal expressions don't contain variables
ExprKind::Int(_)
| ExprKind::TypedInt(_, _)
| ExprKind::Float(_)
| ExprKind::Bool(_)
| ExprKind::String(_)
@ -344,10 +340,6 @@ impl LambdaLowerer {
.collect::<Result<Vec<_>, _>>()?;
ExprKind::Array(lowered_exprs)
}
ExprKind::FixedArray(expr, size) => {
let lowered_expr = self.lower_expr(expr)?;
ExprKind::FixedArray(Box::new(lowered_expr), *size)
}
ExprKind::Tuple(exprs) => {
let lowered_exprs = exprs
.iter()
@ -377,7 +369,6 @@ impl LambdaLowerer {
}
// Terminal expressions that don't contain other expressions
ExprKind::Int(_)
| ExprKind::TypedInt(_, _)
| ExprKind::Float(_)
| ExprKind::Bool(_)
| ExprKind::String(_)

View file

@ -20,14 +20,6 @@ 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()
@ -69,9 +61,6 @@ pub enum Token {
#[token("string")]
KeywordString,
#[token("u8")]
KeywordU8,
#[token("let")]
KeywordLet,
@ -146,9 +135,6 @@ pub enum Token {
#[token("trait")]
KeywordTrait,
#[token("const")]
KeywordConst,
// #[token("type")]
// KeywordType,
//
@ -185,12 +171,6 @@ pub enum Token {
#[token("**", priority = 3)]
Power,
#[token("<<")]
LShift,
#[token(">>")]
RShift,
#[token("$")]
Dollar,

View file

@ -244,9 +244,6 @@ fn run_file(filename: &str, debug: bool) -> Result<(), String> {
suicmez::ast::TypedASTNodeKind::Function(f) => {
format!("Function({})", f.name)
}
suicmez::ast::TypedASTNodeKind::Const(c) => {
format!("Const({})", c.name)
}
suicmez::ast::TypedASTNodeKind::Struct(s) => {
format!("Struct({}) with {} params", s.name, s.parameters.len())
}
@ -300,9 +297,6 @@ fn run_file(filename: &str, debug: bool) -> Result<(), String> {
suicmez::ast::TypedASTNodeKind::Function(f) => {
format!("Function({})", f.name)
}
suicmez::ast::TypedASTNodeKind::Const(c) => {
format!("Const({})", c.name)
}
suicmez::ast::TypedASTNodeKind::Struct(s) => {
format!("Struct({}) with {} params", s.name, s.parameters.len())
}

View file

@ -104,9 +104,6 @@ impl Monomorphizer {
for (_idx, node) in nodes.iter().enumerate() {
match &node.kind {
TypedASTNodeKind::Const(c) => {
result_nodes.push(node.clone());
}
TypedASTNodeKind::Function(f) => {
// Skip generic functions - they'll be added as specialized versions when needed
if !f.parameters.is_empty() {
@ -325,7 +322,6 @@ impl Monomorphizer {
let mut needs = Vec::new();
let new_kind = match &expr.kind {
TypedExprKind::Int(_)
| TypedExprKind::TypedInt(_, _)
| TypedExprKind::Float(_)
| TypedExprKind::Bool(_)
| TypedExprKind::String(_)
@ -346,11 +342,6 @@ impl Monomorphizer {
}
TypedExprKind::Array(new_elems)
}
TypedExprKind::FixedArray(expr, size) => {
let (new_expr, expr_needs) = self.monomorphize_expr(expr)?;
needs.extend(expr_needs);
TypedExprKind::FixedArray(Box::new(new_expr), *size)
}
TypedExprKind::Tuple(elems) => {
let mut new_elems = Vec::new();
@ -776,10 +767,6 @@ impl Monomorphizer {
let new_inner = self.substitute_in_type_annot(inner, subst_map)?;
Ok(TypeAnnot::Array(Box::new(new_inner)))
}
TypeAnnot::FixedArray(inner, size) => {
let new_inner = self.substitute_in_type_annot(inner, subst_map)?;
Ok(TypeAnnot::FixedArray(Box::new(new_inner), *size))
}
TypeAnnot::Ptr(inner) => {
let new_inner = self.substitute_in_type_annot(inner, subst_map)?;
Ok(TypeAnnot::Ptr(Box::new(new_inner)))
@ -790,13 +777,11 @@ 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()),
Type::Unit => TypeAnnot::Tuple(Vec::new()),
Type::Array(inner) => TypeAnnot::Array(Box::new(self.type_to_type_annot(inner))),
Type::FixedArray(inner, size) => TypeAnnot::FixedArray(Box::new(self.type_to_type_annot(inner)), *size as i64),
Type::Ptr(inner) => TypeAnnot::Ptr(Box::new(self.type_to_type_annot(inner))),
Type::Tuple(types) => {
let annots = types.iter().map(|t| self.type_to_type_annot(t)).collect();
@ -916,9 +901,6 @@ impl Monomorphizer {
TypeAnnot::Array(inner) => {
self.collect_needs_from_type(inner, needs);
}
TypeAnnot::FixedArray(inner, _) => {
self.collect_needs_from_type(inner, needs);
}
TypeAnnot::Ptr(inner) => {
self.collect_needs_from_type(inner, needs);
}
@ -950,8 +932,10 @@ impl Monomorphizer {
let tys = types.iter().map(|t| self.type_annot_to_type(t)).collect();
Type::Tuple(tys)
}
TypeAnnot::Array(inner) => Type::Array(Box::new(self.type_annot_to_type(inner))),
TypeAnnot::FixedArray(inner, size) => Type::FixedArray(Box::new(self.type_annot_to_type(inner)), *size as usize),
TypeAnnot::Array(inner) => {
let inner_type = self.type_annot_to_type(inner);
Type::Array(Box::new(inner_type))
}
TypeAnnot::Ptr(inner) => {
let inner_type = self.type_annot_to_type(inner);
Type::Ptr(Box::new(inner_type))
@ -991,9 +975,6 @@ fn check_node_for_typevars(node: &TypedASTNode) -> Result<(), MonomorphizationEr
TypedASTNodeKind::Function(f) => {
check_function_for_typevars(f)?;
}
TypedASTNodeKind::Const(c) => {
// Consts should not have typevars
}
TypedASTNodeKind::Struct(s) => {
check_struct_for_typevars(s)?;
}
@ -1235,7 +1216,6 @@ fn has_typevars_in_type_annot(ty: &TypeAnnot) -> bool {
}
TypeAnnot::Tuple(types) => types.iter().any(has_typevars_in_type_annot),
TypeAnnot::Array(inner) => has_typevars_in_type_annot(inner),
TypeAnnot::FixedArray(inner, _) => has_typevars_in_type_annot(inner),
TypeAnnot::Ptr(inner) => has_typevars_in_type_annot(inner),
}
}

View file

@ -149,16 +149,6 @@ impl Parser {
attributes,
})
}
Some(Token::KeywordConst) => {
self.next();
let const_def = self.parse_const()?;
let end = self.peek_span().unwrap_or(start..start).end;
Ok(ASTNode {
kind: ASTNodeKind::Const(const_def),
span: Span::new(&(start..end), self.file.clone()),
attributes,
})
}
Some(Token::KeywordStruct) => {
self.next();
let struct_def = self.parse_struct()?;
@ -221,33 +211,12 @@ impl Parser {
}
Some(token) => {
let span = self.peek_span().unwrap_or(start..start);
self.error(format!("Unexpected token at top level: {:?}. Expected declarations like 'fn', 'struct', 'enum', 'impl', 'trait', 'const', 'use', 'load', or 'extern'", token), span)
self.error(format!("Unexpected token at top level: {:?}. Expected declarations like 'fn', 'struct', 'enum', 'impl', 'trait', 'use', 'load', or 'extern'", token), span)
}
None => self.error("Unexpected end of file at top level. Expected declarations like 'fn', 'struct', 'enum', etc.".to_string(), start..start),
}
}
fn parse_const(&mut self) -> Result<Const, ParseError> {
let start = self.peek_span().unwrap_or(0..0).start;
let name = match self.next() {
Some((Token::Variable(n), _)) => n,
Some((_, span)) => return self.error("Expected constant name after 'const' keyword. Example: const PI = 3.14".to_string(), span),
None => return self.error("Expected constant name after 'const' keyword. Example: const PI = 3.14".to_string(), start..start),
};
let typ = if matches!(self.peek(), Some(Token::Colon)) {
self.next();
Some(self.parse_type_annot()?)
} else {
None
};
self.expect(Token::Assign)?;
let value = self.parse_expr()?;
Ok(Const { name, typ, value })
}
fn parse_attribute(&mut self) -> Result<Attribute, ParseError> {
self.expect(Token::At)?;
let start = self.peek_span().unwrap_or(0..0).start;
@ -914,7 +883,6 @@ 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)) {
@ -944,23 +912,8 @@ impl Parser {
}
Some((Token::LBracket, _)) => {
let inner = self.parse_type_annot()?;
if matches!(self.peek(), Some(Token::Semicolon)) {
self.next();
let size = match self.next() {
Some((Token::Int(n), _)) => n,
Some((_, span)) => {
return self.error("Expected integer size for fixed array".to_string(), span);
}
None => {
return self.error("Expected integer size for fixed array".to_string(), start..start);
}
};
self.expect(Token::RBracket)?;
TypeAnnot::FixedArray(Box::new(inner), size)
} else {
self.expect(Token::RBracket)?;
TypeAnnot::Array(Box::new(inner))
}
self.expect(Token::RBracket)?;
TypeAnnot::Array(Box::new(inner))
}
Some((Token::Bang, _)) => TypeAnnot::Cons("never".to_string(), vec![]),
Some((_, span)) => {
@ -1204,44 +1157,14 @@ impl Parser {
Ok(left)
}
fn parse_shift_expr(&mut self) -> Result<Expr, ParseError> {
let mut left = self.parse_eq_expr()?;
loop {
let op = if matches!(self.peek(), Some(Token::LShift)) {
Some(BinOp::LShift)
} else if matches!(self.peek(), Some(Token::RShift)) {
Some(BinOp::RShift)
} else {
None
};
if let Some(op) = op {
let start = left.span.start;
self.next();
let right = self.parse_eq_expr()?;
let end = right.span.end;
left = Expr {
kind: ExprKind::BinOp(Box::new(left), op, Box::new(right)),
span: Span::new(&(start..end), self.file.clone()),
attributes: Vec::new(),
};
} else {
break;
}
}
Ok(left)
}
fn parse_bitwise_and_expr(&mut self) -> Result<Expr, ParseError> {
let mut left = self.parse_shift_expr()?;
let mut left = self.parse_eq_expr()?;
loop {
if matches!(self.peek(), Some(Token::BitAnd)) {
let start = left.span.start;
self.next();
let right = self.parse_shift_expr()?;
let right = self.parse_eq_expr()?;
let end = right.span.end;
left = Expr {
kind: ExprKind::BinOp(Box::new(left), BinOp::BitwiseAnd, Box::new(right)),
@ -1527,15 +1450,6 @@ 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;
@ -1693,44 +1607,25 @@ impl Parser {
}
Some(Token::LBracket) => {
self.next();
let first_expr = self.parse_expr()?;
if matches!(self.peek(), Some(Token::Semicolon)) {
self.next();
let size = match self.next() {
Some((Token::Int(n), _)) => n,
Some((_, span)) => {
return self.error("Expected integer size for fixed array".to_string(), span);
}
None => {
return self.error("Expected integer size for fixed array".to_string(), start..start);
}
};
self.expect(Token::RBracket)?;
let end = self.peek_span().unwrap_or(start..start).end;
Ok(Expr {
kind: ExprKind::FixedArray(Box::new(first_expr), size),
span: Span::new(&(start..end), self.file.clone()),
attributes: Vec::new(),
})
} else {
let mut elements = vec![first_expr];
loop {
if matches!(self.peek(), Some(Token::RBracket)) {
self.next();
break;
}
if matches!(self.peek(), Some(Token::Comma)) {
self.next();
}
elements.push(self.parse_expr()?);
let mut elements = Vec::new();
loop {
if matches!(self.peek(), Some(Token::RBracket)) {
self.next();
break;
}
elements.push(self.parse_expr()?);
if matches!(self.peek(), Some(Token::Comma)) {
self.next();
}
let end = self.peek_span().unwrap_or(start..start).end;
Ok(Expr {
kind: ExprKind::Array(elements),
span: Span::new(&(start..end), self.file.clone()),
attributes: Vec::new(),
})
}
let end = self.peek_span().unwrap_or(start..start).end;
Ok(Expr {
kind: ExprKind::Array(elements),
span: Span::new(&(start..end), self.file.clone()),
attributes: Vec::new(),
})
}
Some(Token::KeywordLet) => {
self.next();

View file

@ -6,14 +6,12 @@ use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub enum Type {
Int,
U8,
Float,
Bool,
String,
Unit,
Never,
Array(Box<Type>),
FixedArray(Box<Type>, usize),
Ptr(Box<Type>),
Tuple(Vec<Type>),
Function(Vec<Type>, Box<Type>),
@ -28,14 +26,12 @@ 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(),
Type::Unit => "()".to_string(),
Type::Never => "!".to_string(),
Type::Array(inner) => format!("[{}]", inner.to_string()),
Type::FixedArray(inner, size) => format!("[{}; {}]", inner.to_string(), size),
Type::Ptr(inner) => format!("*{}", inner.to_string()),
Type::Tuple(types) => {
let type_strs: Vec<String> = types.iter().map(|t| t.to_string()).collect();
@ -370,351 +366,6 @@ impl TypeChecker {
}
fn add_builtin_functions(&mut self) {
// Builtin types
self.env.types.insert(
"Vector3".to_string(),
TypeInfo {
kind: TypeInfoKind::Struct(vec![
("x".to_string(), TypeAnnot::Var("float".to_string())),
("y".to_string(), TypeAnnot::Var("float".to_string())),
("z".to_string(), TypeAnnot::Var("float".to_string())),
]),
parameters: vec![],
},
);
self.env.types.insert(
"Color".to_string(),
TypeInfo {
kind: TypeInfoKind::Struct(vec![
("r".to_string(), TypeAnnot::Var("u8".to_string())),
("g".to_string(), TypeAnnot::Var("u8".to_string())),
("b".to_string(), TypeAnnot::Var("u8".to_string())),
("a".to_string(), TypeAnnot::Var("u8".to_string())),
]),
parameters: vec![],
},
);
self.env.types.insert(
"Shader".to_string(),
TypeInfo {
kind: TypeInfoKind::Struct(vec![
("id".to_string(), TypeAnnot::Var("int".to_string())),
]),
parameters: vec![],
},
);
self.env.types.insert(
"Vector2".to_string(),
TypeInfo {
kind: TypeInfoKind::Struct(vec![
("x".to_string(), TypeAnnot::Var("float".to_string())),
("y".to_string(), TypeAnnot::Var("float".to_string())),
]),
parameters: vec![],
},
);
self.env.types.insert(
"sockaddr_in".to_string(),
TypeInfo {
kind: TypeInfoKind::Struct(vec![
("sin_family".to_string(), TypeAnnot::Var("u16".to_string())),
("sin_port".to_string(), TypeAnnot::Var("u16".to_string())),
("sin_addr".to_string(), TypeAnnot::Cons("in_addr".to_string(), vec![])),
("sin_zero".to_string(), TypeAnnot::FixedArray(Box::new(TypeAnnot::Var("u8".to_string())), 8)),
]),
parameters: vec![],
},
);
// Builtin functions
// Raylib
self.env.functions.insert(
"init_window".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Int, Type::String],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"close_window".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"window_should_close".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Bool,
},
);
self.env.functions.insert(
"set_target_fps".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"disable_cursor".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"get_char_pressed".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Int,
},
);
self.env.functions.insert(
"is_key_pressed".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Bool,
},
);
self.env.functions.insert(
"is_key_down".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Bool,
},
);
self.env.functions.insert(
"get_mouse_delta".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Struct("Vector2".to_string(), vec![]),
},
);
self.env.functions.insert(
"is_mouse_button_down".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Bool,
},
);
self.env.functions.insert(
"get_random_value".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Int],
return_type: Type::Int,
},
);
self.env.functions.insert(
"get_frame_time".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Float,
},
);
self.env.functions.insert(
"begin_drawing".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"end_drawing".to_string(),
FunctionType {
type_params: vec![],
params: vec![],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"clear_background".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Int, Type::Int, Type::Int],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"draw_text".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::String, Type::Int, Type::Int, Type::Int, Type::Int, Type::Int, Type::Int, Type::Int],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"draw_fps".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Int],
return_type: Type::Unit,
},
);
// Math functions
self.env.functions.insert(
"sinf".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"cosf".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"sqrtf".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"fmaxf".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float, Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"floorf".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"powf".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float, Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"expf".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float],
return_type: Type::Float,
},
);
// Noise functions
self.env.functions.insert(
"grad2".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Float, Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"simplex_noise_2d".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float, Type::Float],
return_type: Type::Float,
},
);
self.env.functions.insert(
"fbm_noise".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float, Type::Float, Type::Int],
return_type: Type::Float,
},
);
self.env.functions.insert(
"get_terrain_height".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Float, Type::Float],
return_type: Type::Float,
},
);
// Socket functions
self.env.functions.insert(
"socket".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Int, Type::Int],
return_type: Type::Int,
},
);
self.env.functions.insert(
"sendto".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Ptr(Box::new(Type::U8)), Type::Int, Type::Int, Type::Ptr(Box::new(Type::Unit)), Type::Int],
return_type: Type::Int,
},
);
self.env.functions.insert(
"recvfrom".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Ptr(Box::new(Type::U8)), Type::Int, Type::Int, Type::Ptr(Box::new(Type::Unit)), Type::Ptr(Box::new(Type::Int))],
return_type: Type::Int,
},
);
self.env.functions.insert(
"close".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Int,
},
);
self.env.functions.insert(
"htonl".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Int,
},
);
self.env.functions.insert(
"htons".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Int,
},
);
self.env.functions.insert(
"inet_pton".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::String, Type::Ptr(Box::new(Type::Unit))],
return_type: Type::Int,
},
);
// ODE Physics Engine functions
self.env.functions.insert(
"ode_init".to_string(),
@ -1909,19 +1560,6 @@ impl TypeChecker {
fn typecheck_node(&mut self, node: &ASTNode) -> Result<TypedASTNode, TypeError> {
let ty = match &node.kind {
ASTNodeKind::Const(c) => {
let typed_value = self.typecheck_expr(&c.value)?;
return Ok(TypedASTNode {
kind: TypedASTNodeKind::Const(TypedConst {
name: c.name.clone(),
typ: c.typ.clone(),
value: typed_value.clone(),
}),
span: node.span.clone(),
attributes: node.attributes.clone(),
ty: typed_value.ty,
});
}
ASTNodeKind::Function(f) => {
let typed_func = self.typecheck_function(f)?;
let ty = typed_func.ty.clone();
@ -2123,16 +1761,6 @@ 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),
@ -2186,14 +1814,6 @@ impl TypeChecker {
)
}
ExprKind::FixedArray(expr, size) => {
let typed_expr = self.typecheck_expr(expr)?;
(
TypedExprKind::FixedArray(Box::new(typed_expr.clone()), *size as usize),
Type::FixedArray(Box::new(typed_expr.ty), *size as usize),
)
}
ExprKind::Tuple(elements) => {
let mut typed_elements = Vec::new();
let mut types = Vec::new();
@ -2220,7 +1840,7 @@ impl TypeChecker {
let typed_right = self.typecheck_expr(right)?;
let result_type = match op {
BinOp::Add | BinOp::Sub | BinOp::Mul | BinOp::Div | BinOp::Mod | BinOp::BitwiseAnd | BinOp::BitwiseOr | BinOp::LShift | BinOp::RShift => {
BinOp::Add | BinOp::Sub | BinOp::Mul | BinOp::Div | BinOp::Mod | BinOp::BitwiseAnd | BinOp::BitwiseOr => {
if !self.types_compatible(&typed_left.ty, &typed_right.ty) {
return Err(TypeError {
kind: TypeErrorKind::TypeMismatch(
@ -2551,7 +2171,7 @@ impl TypeChecker {
}
let element_type = match &typed_array.ty {
Type::Array(elem_ty) | Type::FixedArray(elem_ty, _) => (**elem_ty).clone(),
Type::Array(elem_ty) => (**elem_ty).clone(),
ty => {
return Err(TypeError {
kind: TypeErrorKind::NotAnArray(ty.clone()),
@ -3216,14 +2836,13 @@ impl TypeChecker {
TypeInfoKind::Enum(_) => Type::Enum(name.clone(), substituted_args),
}
} else {
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,
match name.as_str() {
"int" => Type::Int,
"float" => Type::Float,
"bool" => Type::Bool,
"string" => Type::String,
"unit" => Type::Unit,
"never" => Type::Never,
_ => Type::Generic(name.clone(), substituted_args),
}
}
@ -3231,9 +2850,6 @@ impl TypeChecker {
TypeAnnot::Array(inner) => {
Type::Array(Box::new(self.substitute_type(inner, subst_map)))
}
TypeAnnot::FixedArray(inner, size) => {
Type::FixedArray(Box::new(self.substitute_type(inner, subst_map)), *size as usize)
}
TypeAnnot::Ptr(inner) => Type::Ptr(Box::new(self.substitute_type(inner, subst_map))),
TypeAnnot::Tuple(types) => {
let substituted_types: Vec<Type> = types
@ -3277,7 +2893,6 @@ impl TypeChecker {
match name.as_str() {
"int" => Type::Int,
"u8" => Type::U8,
"float" => Type::Float,
"bool" => Type::Bool,
"string" => Type::String,
@ -3308,7 +2923,6 @@ impl TypeChecker {
Type::Tuple(tuple_types)
}
TypeAnnot::Array(inner) => Type::Array(Box::new(self.type_annot_to_type(inner))),
TypeAnnot::FixedArray(inner, size) => Type::FixedArray(Box::new(self.type_annot_to_type(inner)), *size as usize),
TypeAnnot::Ptr(inner) => Type::Ptr(Box::new(self.type_annot_to_type(inner))),
}
}
@ -3317,14 +2931,12 @@ 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,
(Type::Unit, Type::Unit) => true,
(Type::Never, _) | (_, Type::Never) => true,
(Type::Array(a), Type::Array(b)) => self.types_compatible(a, b),
(Type::FixedArray(a, s1), Type::FixedArray(b, s2)) => s1 == s2 && self.types_compatible(a, b),
(Type::Ptr(a), Type::Ptr(b)) => self.types_compatible(a, b),
(Type::Tuple(a), Type::Tuple(b)) => {
a.len() == b.len()

View file

@ -1,47 +0,0 @@
#include "libsuicmez/libsuicmez.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void* gc_alloc(const TypeInfo* type, size_t size);
void gc_init(void);
void gc_shutdown(void);
// Helper for allocating arrays
static void* suic_alloc_array(const TypeInfo* type, size_t elem_size, size_t len, void* init_data) {
void* ptr = gc_alloc(type, elem_size * len);
if (init_data) memcpy(ptr, init_data, elem_size * len);
return ptr;
}
// Helper for allocating structs
static void* suic_alloc_struct(const TypeInfo* type, size_t size, void* init_data) {
void* ptr = gc_alloc(type, size);
if (init_data) memcpy(ptr, init_data, size);
return ptr;
}
int suic_main(void);
int suic_main(void) {
int arr[5] = {42, 42, 42, 42, 42};
int x = arr[2];
return x;
}
int main(int argc, char* argv[]) {
// Initialize GC
gc_init();
// init globals
// init event loop
int result = suic_main();
// Shutdown GC
gc_shutdown();
return result;
}

Binary file not shown.

View file

@ -1,6 +0,0 @@
# Fixed array test
fn main() -> int do
let arr: [int; 5] = [42; 5];
let x = arr[2];
x
end